[teiid-commits] teiid SVN: r1799 - in branches/JCA: connector-sdk/src/main/java/com/metamatrix/cdk/api and 30 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Wed Feb 3 12:56:30 EST 2010


Author: rareddy
Date: 2010-02-03 12:56:28 -0500 (Wed, 03 Feb 2010)
New Revision: 1799

Added:
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/SystemFunctionManager.java
   branches/JCA/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
Removed:
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibraryManager.java
Modified:
   branches/JCA/common-core/src/main/java/com/metamatrix/core/vdb/VdbConstants.java
   branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/ConnectorHost.java
   branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/TranslationUtility.java
   branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/TranslationHelper.java
   branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionDescriptor.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionMetadataSource.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionTree.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/UDFSource.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadata.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadataWrapper.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/QueryMetadataInterface.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCollapseSource.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCopyCriteria.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleMergeCriteria.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushLimit.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/AccessNode.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/BatchedUpdateNode.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/InsertPlanExecutionNode.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/ExecResolver.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/InsertResolver.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java
   branches/JCA/engine/src/main/java/com/metamatrix/query/util/CommandContext.java
   branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java
   branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
   branches/JCA/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionTree.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestResolvedFunctions.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/FakeFunctionMetadataSource.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCalculateCostUtil.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestGroupRecontext.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/TestProcessor.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/proc/TestProcedureProcessor.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestBatchedUpdateNode.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestJoinNode.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestSelectNode.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java
   branches/JCA/engine/src/test/java/com/metamatrix/query/unittest/FakeMetadataFacade.java
   branches/JCA/engine/src/test/java/org/teiid/metadata/TestTransformationMetadata.java
   branches/JCA/metadata/src/main/java/org/teiid/metadata/index/VDBMetadataFactory.java
   branches/JCA/runtime/src/main/java/com/metamatrix/dqp/embedded/services/EmbeddedConfigurationService.java
   branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java
   branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
Log:
TEIID-502: Adding the VDB scoped UDF support to runtime; it is expected that FunctionDefinitons.xmi be bundled inside the VDB

Modified: branches/JCA/common-core/src/main/java/com/metamatrix/core/vdb/VdbConstants.java
===================================================================
--- branches/JCA/common-core/src/main/java/com/metamatrix/core/vdb/VdbConstants.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/common-core/src/main/java/com/metamatrix/core/vdb/VdbConstants.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -40,6 +40,7 @@
     public final static String INDEX_EXT        = ".INDEX";     //$NON-NLS-1$
     public final static String SEARCH_INDEX_EXT = ".SEARCH_INDEX";     //$NON-NLS-1$
     public final static String MODEL_EXT = ".xmi";     //$NON-NLS-1$
+    public final static String UDF_FILE_NAME = "FunctionDefinitions.xmi";     //$NON-NLS-1$
     
     /**
      * These are virtual database status.

Modified: branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/ConnectorHost.java
===================================================================
--- branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/ConnectorHost.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/ConnectorHost.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,9 +22,6 @@
 
 package com.metamatrix.cdk.api;
 
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;

Modified: branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/TranslationUtility.java
===================================================================
--- branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/TranslationUtility.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/connector-sdk/src/main/java/com/metamatrix/cdk/api/TranslationUtility.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -24,6 +24,7 @@
 
 import java.io.IOException;
 import java.net.URL;
+import java.util.Collection;
 
 import org.teiid.connector.language.ICommand;
 import org.teiid.connector.metadata.runtime.RuntimeMetadata;
@@ -31,6 +32,12 @@
 import org.teiid.metadata.index.VDBMetadataFactory;
 
 import com.metamatrix.cdk.CommandBuilder;
+import com.metamatrix.query.function.FunctionLibrary;
+import com.metamatrix.query.function.FunctionTree;
+import com.metamatrix.query.function.SystemFunctionManager;
+import com.metamatrix.query.function.UDFSource;
+import com.metamatrix.query.function.metadata.FunctionMethod;
+import com.metamatrix.query.metadata.BasicQueryMetadataWrapper;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 
 /**
@@ -57,7 +64,7 @@
     
     public TranslationUtility(URL url) {
         try {
-			metadata = VDBMetadataFactory.getVDBMetadata(url);
+			metadata = VDBMetadataFactory.getVDBMetadata(url, null);
 		} catch (IOException e) {
 			throw new RuntimeException(e);
 		}     
@@ -91,4 +98,13 @@
     public RuntimeMetadata createRuntimeMetadata() {
         return new RuntimeMetadataImpl(metadata);
     }
+
+	public void setUDF(final Collection<FunctionMethod> methods) {
+		this.metadata = new BasicQueryMetadataWrapper(this.metadata) {
+			@Override
+			public FunctionLibrary getFunctionLibrary() {
+				return new FunctionLibrary(SystemFunctionManager.getSystemFunctions(), new FunctionTree(new UDFSource(methods)));
+			}
+		};
+	}
 }

Modified: branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/TranslationHelper.java
===================================================================
--- branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/TranslationHelper.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/TranslationHelper.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -23,6 +23,10 @@
 package org.teiid.connector.jdbc;
 
 import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Collection;
+
 import junit.framework.Assert;
 
 import org.mockito.Mockito;
@@ -34,6 +38,9 @@
 
 import com.metamatrix.cdk.api.TranslationUtility;
 import com.metamatrix.cdk.unittest.FakeTranslationFactory;
+import com.metamatrix.core.MetaMatrixRuntimeException;
+import com.metamatrix.query.function.metadata.FunctionMetadataReader;
+import com.metamatrix.query.function.metadata.FunctionMethod;
 
 public class TranslationHelper {
 	
@@ -41,6 +48,10 @@
     public static final String BQT_VDB = "/bqt.vdb"; //$NON-NLS-1$
 
     public static ICommand helpTranslate(String vdbFileName, String sql) {
+    	return helpTranslate(vdbFileName, null, sql);
+    }
+    
+    public static ICommand helpTranslate(String vdbFileName, String udf, String sql) {
     	TranslationUtility util = null;
     	if (PARTS_VDB.equals(vdbFileName)) {
     		util = new TranslationUtility(TranslationHelper.class.getResource(vdbFileName));
@@ -49,15 +60,28 @@
     	} else {
     		Assert.fail("unknown vdb"); //$NON-NLS-1$
     	}
+    	
+    	if (udf != null) {
+    		try {
+				Collection <FunctionMethod> methods = FunctionMetadataReader.loadFunctionMethods(TranslationHelper.class.getResource(udf).openStream());
+				util.setUDF(methods);
+			} catch (IOException e) {
+				throw new MetaMatrixRuntimeException("failed to load UDF");
+			}
+    	}
         return util.parseCommand(sql);        
-    }
+    }    
 
 	public static void helpTestVisitor(String vdb, String input, String expectedOutput, Translator translator) throws ConnectorException {
+		helpTestVisitor(vdb,null,input, expectedOutput, translator);
+	}
+	
+	public static void helpTestVisitor(String vdb, String udf, String input, String expectedOutput, Translator translator) throws ConnectorException {
 	    // Convert from sql to objects
-	    ICommand obj = helpTranslate(vdb, input);
+	    ICommand obj = helpTranslate(vdb, udf, input);
 	    
 	    helpTestVisitor(expectedOutput, translator, obj);
-	}
+	}	
 
 	public static void helpTestVisitor(String expectedOutput,
 			Translator translator, ICommand obj) throws ConnectorException {

Modified: branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java
===================================================================
--- branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/connectors/connector-jdbc/src/test/java/org/teiid/connector/jdbc/oracle/TestOracleTranslator.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,11 +22,7 @@
 
 package org.teiid.connector.jdbc.oracle;
 
-import java.io.File;
-import java.net.URL;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
+import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.teiid.connector.api.ConnectorException;
@@ -38,47 +34,21 @@
 import org.teiid.connector.language.ICommand;
 
 import com.metamatrix.cdk.unittest.FakeTranslationFactory;
-import com.metamatrix.query.function.FunctionLibraryManager;
-import com.metamatrix.query.function.UDFSource;
 
 public class TestOracleTranslator {
 	
     /**
      * An instance of {@link Translator} which has already been initialized.  
      */
-    private static Translator TRANSLATOR; 
+    private Translator TRANSLATOR;
+    private String UDF = "/OracleSpatialFunctions.xmi"; //$NON-NLS-1$;
 
-    @BeforeClass public static void oneTimeSetup() throws Exception {
-        TRANSLATOR = new OracleSQLTranslator();        
+    @Before 
+    public void setup() throws Exception {
+        TRANSLATOR = new OracleSQLTranslator();     
         TRANSLATOR.initialize(new JDBCManagedConnectionFactory());
-        // Define a UDFSource to hold the reference to our function definitions
-        File udfFile = new File("src/main/resources/OracleSpatialFunctions.xmi"); //$NON-NLS-1$;
-        URL[] urls = new URL[0];            
-        UDFSource udfSource = new UDFSource(udfFile.toURI().toURL(), urls);
-        FunctionLibraryManager.deregisterSource(udfSource);
-        FunctionLibraryManager.registerSource(udfSource);
     }
 
-    /**
-     * Performs cleanup tasks that should be executed after all test methods 
-     * have been executed.  This method should only be executed once and does 
-     * not protect from multiple executions.  It is intended to be executed by 
-     * the JUnit4 test framework.
-     * <p>
-     * This method unloads the function definitions supported by the Oracle Spatial 
-     * Connector from the global instance of <code>FunctionLibraryManager</code> 
-     * so that they are no longer resolvable during query parsing. 
-     * 
-     * @throws Exception
-     */
-    @AfterClass public static void oneTimeFinished() throws Exception {
-        // Define a UDFSource to hold the reference to our function definitions
-        File udfFile = new File("src/main/resources/OracleSpatialFunctions.xmi"); //$NON-NLS-1$;
-        URL[] urls = new URL[0];            
-        UDFSource udfSource = new UDFSource(udfFile.toURI().toURL(), urls);
-        FunctionLibraryManager.deregisterSource(udfSource);
-    }
-
 	private void helpTestVisitor(String input, String expectedOutput) throws ConnectorException {
         // Convert from sql to objects
         ICommand obj = FakeTranslationFactory.getInstance().getAutoIncrementTranslationUtility().parseCommand(input);
@@ -102,7 +72,7 @@
         String input = "select smalla.intkey from bqt1.smalla inner join bqt1.smallb on smalla.stringkey=smallb.stringkey cross join bqt1.mediuma"; //$NON-NLS-1$
         String output = "SELECT SmallA.IntKey FROM SmallA INNER JOIN SmallB ON SmallA.StringKey = SmallB.StringKey CROSS JOIN MediumA"; //$NON-NLS-1$
           
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
             input, 
             output, TRANSLATOR);        
     }
@@ -111,7 +81,7 @@
         String input = "select smalla.intkey from bqt1.smalla cross join (bqt1.smallb cross join bqt1.mediuma)"; //$NON-NLS-1$
         String output = "SELECT SmallA.IntKey FROM SmallA CROSS JOIN (SmallB CROSS JOIN MediumA)"; //$NON-NLS-1$
       
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
             input, 
             output, TRANSLATOR);        
     }
@@ -120,7 +90,7 @@
         String input = "SELECT char(convert(STRINGNUM, integer) + 100) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT chr((trunc(to_number(SmallA.StringNum)) + 100)) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
             input, output, 
             TRANSLATOR);
     }
@@ -129,7 +99,7 @@
         String input = "SELECT convert(STRINGNUM, long) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT trunc(to_number(SmallA.StringNum)) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -138,7 +108,7 @@
         String input = "SELECT convert(convert(STRINGNUM, long), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT to_char(trunc(to_number(SmallA.StringNum))) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -147,7 +117,7 @@
         String input = "SELECT convert(convert(TIMESTAMPVALUE, date), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT to_char(trunc(cast(SmallA.TimestampValue AS date)), 'YYYY-MM-DD') FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -155,7 +125,7 @@
         String input = "SELECT convert(convert(TIMEVALUE, timestamp), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT to_char(cast(SmallA.TimeValue AS timestamp), 'YYYY-MM-DD HH24:MI:SS.FF') FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -163,7 +133,7 @@
         String input = "SELECT nvl(INTNUM, 'otherString') FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT nvl(to_char(SmallA.IntNum), 'otherString') FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -171,7 +141,7 @@
         String input = "SELECT convert(convert(STRINGNUM, integer), string) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT to_char(trunc(to_number(SmallA.StringNum))) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -188,7 +158,7 @@
         String input = "SELECT locate(INTNUM, 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT INSTR('chimp', to_char(SmallA.IntNum), 1) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -205,7 +175,7 @@
         String input = "SELECT locate(STRINGNUM, 'chimp') FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT INSTR('chimp', SmallA.StringNum) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -222,7 +192,7 @@
         String input = "SELECT locate(INTNUM, '234567890', 1) FROM BQT1.SMALLA WHERE INTKEY = 26"; //$NON-NLS-1$
         String output = "SELECT INSTR('234567890', to_char(SmallA.IntNum), 1) FROM SmallA WHERE SmallA.IntKey = 26";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -239,7 +209,7 @@
         String input = "SELECT locate('c', 'chimp', 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT 1 FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -256,7 +226,7 @@
         String input = "SELECT locate(STRINGNUM, 'chimp', -5) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT INSTR('chimp', SmallA.StringNum, 1) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -273,7 +243,7 @@
         String input = "SELECT locate(STRINGNUM, 'chimp', INTNUM) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT INSTR('chimp', SmallA.StringNum, CASE WHEN SmallA.IntNum < 1 THEN 1 ELSE SmallA.IntNum END) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -290,7 +260,7 @@
         String input = "SELECT locate(STRINGNUM, 'chimp', LOCATE(STRINGNUM, 'chimp') + 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT INSTR('chimp', SmallA.StringNum, CASE WHEN (INSTR('chimp', SmallA.StringNum) + 1) < 1 THEN 1 ELSE (INSTR('chimp', SmallA.StringNum) + 1) END) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -299,7 +269,7 @@
         String input = "SELECT substring(StringNum, 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT substr(SmallA.StringNum, 1) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -307,7 +277,7 @@
         String input = "SELECT substring(StringNum, 1, 1) FROM BQT1.SMALLA"; //$NON-NLS-1$
         String output = "SELECT substr(SmallA.StringNum, 1, 1) FROM SmallA";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -315,7 +285,7 @@
         String input = "SELECT IntKey FROM BQT1.SMALLA UNION SELECT IntKey FROM BQT1.SMALLB ORDER BY IntKey"; //$NON-NLS-1$
         String output = "SELECT SmallA.IntKey FROM SmallA UNION SELECT SmallB.IntKey FROM SmallB ORDER BY IntKey NULLS FIRST";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -323,7 +293,7 @@
         String input = "select intkey from bqt1.smalla limit 10, 0"; //$NON-NLS-1$
         String output = "SELECT * FROM (SELECT VIEW_FOR_LIMIT.*, ROWNUM ROWNUM_ FROM (SELECT SmallA.IntKey FROM SmallA) VIEW_FOR_LIMIT WHERE ROWNUM <= 10) WHERE ROWNUM_ > 10"; //$NON-NLS-1$
                
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -331,7 +301,7 @@
         String input = "select intkey from bqt1.smalla limit 0, 10"; //$NON-NLS-1$
         String output = "SELECT * FROM (SELECT SmallA.IntKey FROM SmallA) WHERE ROWNUM <= 10"; //$NON-NLS-1$
                
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -339,7 +309,7 @@
         String input = "select intkey from bqt1.smalla limit 1, 10"; //$NON-NLS-1$
         String output = "SELECT * FROM (SELECT VIEW_FOR_LIMIT.*, ROWNUM ROWNUM_ FROM (SELECT SmallA.IntKey FROM SmallA) VIEW_FOR_LIMIT WHERE ROWNUM <= 11) WHERE ROWNUM_ > 1"; //$NON-NLS-1$
                
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -347,7 +317,7 @@
         String input = "select intkey from bqt1.mediuma limit 100"; //$NON-NLS-1$
         String output = "SELECT * FROM (SELECT MediumA.IntKey FROM MediumA) WHERE ROWNUM <= 100"; //$NON-NLS-1$
                
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -355,7 +325,7 @@
         String input = "select intkey from bqt1.mediuma limit 50, 100"; //$NON-NLS-1$
         String output = "SELECT * FROM (SELECT VIEW_FOR_LIMIT.*, ROWNUM ROWNUM_ FROM (SELECT MediumA.IntKey FROM MediumA) VIEW_FOR_LIMIT WHERE ROWNUM <= 150) WHERE ROWNUM_ > 50"; //$NON-NLS-1$
                
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -363,7 +333,7 @@
     @Test public void testConcat2_useLiteral() throws Exception {        
         String input = "select concat2(stringnum,'_xx') from bqt1.Smalla"; //$NON-NLS-1$
         String output = "SELECT concat(nvl(SmallA.StringNum, ''), '_xx') FROM SmallA"; //$NON-NLS-1$
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -371,7 +341,7 @@
     @Test public void testConcat2() throws Exception {        
         String input = "select concat2(stringnum, stringkey) from bqt1.Smalla"; //$NON-NLS-1$
         String output = "SELECT CASE WHEN (SmallA.StringNum IS NULL) AND (SmallA.StringKey IS NULL) THEN NULL ELSE concat(nvl(SmallA.StringNum, ''), nvl(SmallA.StringKey, '')) END FROM SmallA"; //$NON-NLS-1$
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -387,7 +357,7 @@
         String input = "SELECT a.INTKEY FROM BQT1.SMALLA A, BQT1.SMALLB B WHERE sdo_relate(A.OBJECTVALUE, b.OBJECTVALUE, 'mask=ANYINTERACT') = true"; //$NON-NLS-1$
         String output = "SELECT /*+ ORDERED */ A.IntKey FROM SmallA A, SmallB B WHERE sdo_relate(A.ObjectValue, B.ObjectValue, 'mask=ANYINTERACT') = 'true'";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -403,7 +373,7 @@
         String input = "SELECT INTKEY FROM BQT1.SMALLA WHERE sdo_within_distance(OBJECTVALUE, 'SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL)', 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
         String output = "SELECT SmallA.IntKey FROM SmallA WHERE sdo_within_distance(SmallA.ObjectValue, SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL), 'DISTANCE=25.0 UNIT=NAUT_MILE') = 'true'";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -419,7 +389,7 @@
         String input = "SELECT INTKEY FROM BQT1.SMALLA WHERE sdo_within_distance('SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL)', OBJECTVALUE, 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
         String output = "SELECT SmallA.IntKey FROM SmallA WHERE sdo_within_distance(SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL), SmallA.ObjectValue, 'DISTANCE=25.0 UNIT=NAUT_MILE') = 'true'";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -440,7 +410,7 @@
         // as the signature was the best match for this query.
         String output = "SELECT SmallA.IntKey FROM SmallA WHERE sdo_within_distance(SmallA.StringKey, SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL), 'DISTANCE=25.0 UNIT=NAUT_MILE') = ?";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -461,7 +431,7 @@
         // as the signature was the best match for this query.
         String output = "SELECT SmallA.IntKey FROM SmallA WHERE sdo_within_distance(SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL), SDO_GEOMETRY(2001, 8307, MDSYS.SDO_POINT_TYPE(90.0, -45.0, NULL), NULL, NULL), 'DISTANCE=25.0 UNIT=NAUT_MILE') = ?";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -477,7 +447,7 @@
         String input = "SELECT a.INTKEY FROM BQT1.SMALLA A, BQT1.SMALLB B WHERE sdo_within_distance(a.OBJECTVALUE, b.OBJECTVALUE, 'DISTANCE=25.0 UNIT=NAUT_MILE') = true"; //$NON-NLS-1$
         String output = "SELECT A.IntKey FROM SmallA A, SmallB B WHERE sdo_within_distance(A.ObjectValue, B.ObjectValue, 'DISTANCE=25.0 UNIT=NAUT_MILE') = 'true'";  //$NON-NLS-1$
 
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -486,7 +456,7 @@
         String input = "SELECT log(CONVERT(stringkey, INTEGER)) FROM bqt1.smalla"; //$NON-NLS-1$
         String output = "SELECT ln(trunc(to_number(SmallA.StringKey))) FROM SmallA"; //$NON-NLS-1$
     
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -495,7 +465,7 @@
         String input = "SELECT log10(CONVERT(stringkey, INTEGER)) FROM bqt1.smalla"; //$NON-NLS-1$
         String output = "SELECT log(10, trunc(to_number(SmallA.StringKey))) FROM SmallA"; //$NON-NLS-1$
     
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }
@@ -504,7 +474,7 @@
         String input = "SELECT char(CONVERT(stringkey, INTEGER)), lcase(stringkey), ucase(stringkey), ifnull(stringkey, 'x') FROM bqt1.smalla"; //$NON-NLS-1$
         String output = "SELECT chr(trunc(to_number(SmallA.StringKey))), lower(SmallA.StringKey), upper(SmallA.StringKey), nvl(SmallA.StringKey, 'x') FROM SmallA"; //$NON-NLS-1$
         
-        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB,
+        TranslationHelper.helpTestVisitor(TranslationHelper.BQT_VDB, UDF,
                 input, output, 
                 TRANSLATOR);
     }    

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/eval/Evaluator.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -45,7 +45,6 @@
 import com.metamatrix.query.QueryPlugin;
 import com.metamatrix.query.function.FunctionDescriptor;
 import com.metamatrix.query.function.FunctionLibrary;
-import com.metamatrix.query.function.FunctionLibraryManager;
 import com.metamatrix.query.function.metadata.FunctionMethod;
 import com.metamatrix.query.processor.ProcessorDataManager;
 import com.metamatrix.query.sql.LanguageObject;
@@ -638,8 +637,7 @@
 	    } 
 	    
 		// Execute function
-		FunctionLibrary library = FunctionLibraryManager.getFunctionLibrary();
-		Object result = library.invokeFunction(fd, values);
+		Object result = fd.invokeFunction(values);
 		return result;        
 	}
 	

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionDescriptor.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionDescriptor.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionDescriptor.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -23,11 +23,20 @@
 package com.metamatrix.query.function;
 
 import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Arrays;
 
+import com.metamatrix.api.exception.query.FunctionExecutionException;
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.common.types.TransformationException;
 import com.metamatrix.core.MetaMatrixRuntimeException;
+import com.metamatrix.core.util.Assertion;
 import com.metamatrix.core.util.HashCodeUtil;
-import com.metamatrix.core.util.Assertion;
+import com.metamatrix.query.QueryPlugin;
+import com.metamatrix.query.function.metadata.FunctionMethod;
+import com.metamatrix.query.util.CommandContext;
+import com.metamatrix.query.util.ErrorMessageKeys;
 
 /**
  * The FunctionDescriptor describes a particular function instance enough
@@ -199,4 +208,55 @@
         this.returnType = returnType;
     }
     
+    
+	/**
+	 * Invoke the function described in the function descriptor, using the
+	 * values provided.  Return the result of the function.
+	 * @param fd Function descriptor describing the name and types of the arguments
+	 * @param values Values that should match 1-to-1 with the types described in the
+	 * function descriptor
+	 * @return Result of invoking the function
+	 */
+	public Object invokeFunction(Object[] values) throws FunctionExecutionException {
+
+        if (!isNullDependent()) {
+        	for (int i = 0; i < values.length; i++) {
+				if (values[i] == null) {
+					return null;
+				}
+			}
+        }
+
+        // If descriptor is missing invokable method, find this VM's descriptor
+        // give name and types from fd
+        Method method = getInvocationMethod();
+        if(method == null) {
+        	throw new FunctionExecutionException(ErrorMessageKeys.FUNCTION_0002, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0002, getName()));
+        }
+        
+        if (getDeterministic() >= FunctionMethod.SESSION_DETERMINISTIC && values.length > 0 && values[0] instanceof CommandContext) {
+        	CommandContext cc = (CommandContext)values[0];
+        	cc.setSessionFunctionEvaluated(true);
+        }
+        
+        // Invoke the method and return the result
+        try {
+        	if (method.isVarArgs()) {
+        		int i = method.getParameterTypes().length;
+        		Object[] newValues = Arrays.copyOf(values, i);
+        		newValues[i - 1] = Arrays.copyOfRange(values, i - 1, values.length);
+        		values = newValues;
+        	}
+            Object result = method.invoke(null, values);
+            result = DataTypeManager.convertToRuntimeType(result);
+            result = DataTypeManager.transformValue(result, getReturnType());
+            return result;
+        } catch(InvocationTargetException e) {
+            throw new FunctionExecutionException(e.getTargetException(), ErrorMessageKeys.FUNCTION_0003, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0003, getName()));
+        } catch(IllegalAccessException e) {
+            throw new FunctionExecutionException(e, ErrorMessageKeys.FUNCTION_0004, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0004, method.toString()));
+        } catch (TransformationException e) {
+        	throw new FunctionExecutionException(e, e.getMessage());
+		}
+	}    
 }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -95,17 +95,16 @@
     // Function tree for system functions (never reloaded)
     private FunctionTree systemFunctions;
 
-    // Function tree for user-defined functions (reloadable)
+    // Function tree for user-defined functions
     private FunctionTree userFunctions;
 
 	/**
 	 * Construct the function library.  This should be called only once by the
 	 * FunctionLibraryManager.
 	 */
-	FunctionLibrary() {
-        // Put empty trees here to avoid null checks throughout the class
-        systemFunctions = new FunctionTree(Collections.EMPTY_LIST);
-        userFunctions = new FunctionTree(Collections.EMPTY_LIST);
+	public FunctionLibrary(FunctionTree systemFuncs, FunctionTree userFuncs) {
+        systemFunctions = systemFuncs;
+       	userFunctions = userFuncs;
 	}
 
     /**
@@ -153,33 +152,6 @@
         return form;
     }
 
-    /**
-     * Add the system functions to the library.  This should be done
-     * exactly once by the FunctionLibraryManager.
-     * @param source System metadata source
-     */
-    void setSystemFunctions(FunctionMetadataSource source) {
-        this.systemFunctions = new FunctionTree(source);
-    }
-
-    /**
-     * Replace the existing set of reloadable functions with a new set.  This
-     * is called by the FunctionLibraryManager every time it reloads the
-     * reloadable sources.
-     * @param sources Collection of {@link FunctionMetadataSource} objects
-     */
-    void replaceReloadableFunctions(Collection sources) {
-        // Build new function tree
-        FunctionTree reloadedFunctions = new FunctionTree(sources);
-
-        // Switch to new user-defined functions - this is not synchronized
-        // because it is merely an object reference change.  There is no
-        // way for other code to get part of the old tree and part of the new
-        // tree - they will get either one or the other.  The old tree is
-        // dropped.
-        this.userFunctions = reloadedFunctions;
-    }
-
 	/**
 	 * Find a function descriptor given a name and the types of the arguments.
 	 * This method matches based on case-insensitive function name and
@@ -340,71 +312,8 @@
         return null;
     }
 
-	/**
-	 * Invoke the function described in the function descriptor, using the
-	 * values provided.  Return the result of the function.
-	 * @param fd Function descriptor describing the name and types of the arguments
-	 * @param values Values that should match 1-to-1 with the types described in the
-	 * function descriptor
-	 * @return Result of invoking the function
-	 */
-	public Object invokeFunction(FunctionDescriptor fd, Object[] values)
-		throws InvalidFunctionException, FunctionExecutionException {
 
-        if(fd == null) {
-            throw new InvalidFunctionException(ErrorMessageKeys.FUNCTION_0001, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0001, fd));
-        }
-        
-        if (!fd.isNullDependent()) {
-        	for (int i = 0; i < values.length; i++) {
-				if (values[i] == null) {
-					return null;
-				}
-			}
-        }
 
-        // If descriptor is missing invokable method, find this VM's descriptor
-        // give name and types from fd
-        Method method = fd.getInvocationMethod();
-        if(method == null) {
-            FunctionDescriptor localDescriptor = findFunction(fd.getName(), fd.getTypes());
-            if(localDescriptor == null) {
-                throw new InvalidFunctionException(ErrorMessageKeys.FUNCTION_0001, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0001, fd));
-            }
-
-            // Get local invocation method, which should never be null
-            method = localDescriptor.getInvocationMethod();
-            if (method == null){
-                throw new FunctionExecutionException(ErrorMessageKeys.FUNCTION_0002, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0002, localDescriptor.getName()));
-            }
-        }
-        
-        if (fd.getDeterministic() >= FunctionMethod.SESSION_DETERMINISTIC && values.length > 0 && values[0] instanceof CommandContext) {
-        	CommandContext cc = (CommandContext)values[0];
-        	cc.setSessionFunctionEvaluated(true);
-        }
-        
-        // Invoke the method and return the result
-        try {
-        	if (method.isVarArgs()) {
-        		int i = method.getParameterTypes().length;
-        		Object[] newValues = Arrays.copyOf(values, i);
-        		newValues[i - 1] = Arrays.copyOfRange(values, i - 1, values.length);
-        		values = newValues;
-        	}
-            Object result = method.invoke(null, values);
-            result = DataTypeManager.convertToRuntimeType(result);
-            result = DataTypeManager.transformValue(result, fd.getReturnType());
-            return result;
-        } catch(InvocationTargetException e) {
-            throw new FunctionExecutionException(e.getTargetException(), ErrorMessageKeys.FUNCTION_0003, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0003, fd.getName()));
-        } catch(IllegalAccessException e) {
-            throw new FunctionExecutionException(e, ErrorMessageKeys.FUNCTION_0004, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0004, method.toString()));
-        } catch (TransformationException e) {
-        	throw new FunctionExecutionException(e, e.getMessage());
-		}
-	}
-
 	/**
 	 * Return a copy of the given FunctionDescriptor with the sepcified return type.
 	 * @param fd FunctionDescriptor to be copied.

Deleted: branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibraryManager.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibraryManager.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionLibraryManager.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -1,152 +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 com.metamatrix.query.function;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import com.metamatrix.query.QueryPlugin;
-import com.metamatrix.query.function.metadata.FunctionMetadataValidator;
-import com.metamatrix.query.function.source.SystemSource;
-import com.metamatrix.query.report.ActivityReport;
-import com.metamatrix.query.util.ErrorMessageKeys;
-
-/**
- * Factory to obtain the local FunctionLibrary and register sources of function metadata.
- */
-public class FunctionLibraryManager {
-
-	// Reference to singleton FunctionLibrary
-	private static FunctionLibrary LIB;
-
-	// List of reloadable (user-defined) sources of metadata
-    private static List RELOADABLE_SOURCES;
-
-    // Static initializer
-    static {
-        // Create the function library instance
-        LIB = new FunctionLibrary();
-
-        // Create the system source and add it to the source list
-        FunctionMetadataSource systemSource = new SystemSource();
-
-        // Load the system source
-        LIB.setSystemFunctions(systemSource);
-
-		// Validate the system source - should never fail
-        ActivityReport report = new ActivityReport("Function Validation"); //$NON-NLS-1$
-       	validateSource(systemSource, report);
-		if(report.hasItems()) {
-		    // Should never happen as SystemSource doesn't change
-		    System.err.println(QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0005, report));
-		}
-
-        // Initialize the reloadable sources
-        RELOADABLE_SOURCES = new ArrayList();
-
-    }
-
-    /**
-     * Can't construct - just a factory
-     */
-	private FunctionLibraryManager() {}
-
-    /**
-     * Factory method to obtain a reference to a function.
-     * @return Function library to find and invoke functions
-     */
-	public static FunctionLibrary getFunctionLibrary() {
-		return LIB;
-	}
-
-    /**
-     * Register a new source of function metadata.  The method
-     * {@link #reloadSources} will be called as a result.
-     * @param source A new source of function metadata
-     * @return Report of any invalid FunctionMethod objects
-     */
-    public static synchronized ActivityReport registerSource(FunctionMetadataSource source) {
-        // Add the reloadable source
-        RELOADABLE_SOURCES.add(source);
-
-        // Reload
-        return reloadSources();
-    }
-
-    /**
-     * Register a new source of function metadata.  The method
-     * {@link #reloadSources} will be called as a result.
-     * @param source A new source of function metadata
-     * @return Report of any invalid FunctionMethod objects
-     */
-    public static synchronized ActivityReport deregisterSource(FunctionMetadataSource source) {
-        // Add the reloadable source
-        RELOADABLE_SOURCES.remove(source);
-
-        // Reload
-        return reloadSources();
-    }
-    
-    /**
-     * Reload all sources.  All valid functions in the registered function sources
-     * are reloaded.  Any invalid functions are noted in the report.
-     * @return Report of any invalid FunctionMethod objects.
-     */
-    public static synchronized ActivityReport reloadSources() {
-        // Create activity report
-        ActivityReport report = new ActivityReport("Function Validation"); //$NON-NLS-1$
-
-        // Reload and re-validate all metadata sources
-        Iterator iter = RELOADABLE_SOURCES.iterator();
-        while(iter.hasNext()) {
-        	FunctionMetadataSource source = (FunctionMetadataSource) iter.next();
-
-        	// Reload - even though it is reload it is never called
-        	// other than the register methods, so it may of no use.
-        	// if need it we will get this back.
-        	//source.reloadMethods();
-
-        	// Validate
-        	validateSource(source, report);
-        }
-
-        // Upload all new reloadable functions into function library in bulk
-        LIB.replaceReloadableFunctions(RELOADABLE_SOURCES);
-
-        // Return report of failures during reload
-        return report;
-    }
-
-    /**
-     * Validate all function metadata in the source with the FunctionMetadataValidator.  Add
-     * any problems to the specified report.
-     * @param source Source of function metadata
-     * @param report Report to update with any problems
-     */
-    private static void validateSource(FunctionMetadataSource source, ActivityReport report) {
-        Collection functionMethods = source.getFunctionMethods();
-    	FunctionMetadataValidator.validateFunctionMethods(functionMethods,report);
-    }
-}

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionMetadataSource.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionMetadataSource.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionMetadataSource.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,10 +22,10 @@
 
 package com.metamatrix.query.function;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.Collection;
 
+import com.metamatrix.query.function.metadata.FunctionMethod;
+
 /**
  * A FunctionMetadataSource represents a source of function metadata for
  * the function library.  A FunctionMetadataSource needs to know how to 
@@ -42,7 +42,7 @@
      * always return the newest information available.
      * @return Collection of FunctionMethod objects
      */
-    Collection getFunctionMethods();
+    Collection<FunctionMethod> getFunctionMethods();
     
     /**
      * This method determines where the invocation classes specified in the 
@@ -52,7 +52,4 @@
      * @throws ClassNotFoundException If class could not be found
      */
     Class getInvocationClass(String className) throws ClassNotFoundException;    
-    
-    
-    void loadFunctions(InputStream source) throws IOException;
 }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionTree.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionTree.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/FunctionTree.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -57,7 +57,7 @@
  * are concerned with function metadata EXCEPT {@link #getFunction} which is used to find a function
  * for execution.
  */
-class FunctionTree {
+public class FunctionTree {
 
     // Constant used to look up the special descriptor key in a node map
     private static final Integer DESCRIPTOR_KEY = new Integer(-1);
@@ -83,7 +83,7 @@
      * Construct a new tree with the given source of function metadata.
      * @param source The metadata source
      */
-    FunctionTree(FunctionMetadataSource source) {
+    public FunctionTree(FunctionMetadataSource source) {
         // Load data structures
         addSource(source);
     }

Added: branches/JCA/engine/src/main/java/com/metamatrix/query/function/SystemFunctionManager.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/SystemFunctionManager.java	                        (rev 0)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/SystemFunctionManager.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -0,0 +1,71 @@
+/*
+ * 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 com.metamatrix.query.function;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import com.metamatrix.query.QueryPlugin;
+import com.metamatrix.query.function.metadata.FunctionMetadataValidator;
+import com.metamatrix.query.function.source.SystemSource;
+import com.metamatrix.query.report.ActivityReport;
+import com.metamatrix.query.util.ErrorMessageKeys;
+
+public class SystemFunctionManager {
+
+	private static FunctionTree systemFunctionTree;
+	
+    static {
+        // Create the system source and add it to the source list
+    	SystemSource systemSource = new SystemSource();
+
+		// Validate the system source - should never fail
+        ActivityReport report = new ActivityReport("Function Validation"); //$NON-NLS-1$
+       	validateSource(systemSource, report);
+		if(report.hasItems()) {
+		    // Should never happen as SystemSource doesn't change
+		    System.err.println(QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0005, report));
+		}
+		
+		systemFunctionTree = new FunctionTree(systemSource);
+    }
+	
+    
+    public static FunctionTree getSystemFunctions() {
+    	return systemFunctionTree;
+    }
+    
+    public static FunctionLibrary getSystemFunctionLibrary() {
+    	return new FunctionLibrary(systemFunctionTree, new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+    }
+    
+    /**
+     * Validate all function metadata in the source with the FunctionMetadataValidator.  Add
+     * any problems to the specified report.
+     * @param source Source of function metadata
+     * @param report Report to update with any problems
+     */
+    private static void validateSource(FunctionMetadataSource source, ActivityReport report) {
+        Collection functionMethods = source.getFunctionMethods();
+    	FunctionMetadataValidator.validateFunctionMethods(functionMethods,report);
+    }
+}

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/function/UDFSource.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/UDFSource.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/UDFSource.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,63 +22,24 @@
 
 package com.metamatrix.query.function;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
 import java.util.Collection;
 
-import com.metamatrix.common.classloader.PostDelegatingClassLoader;
-import com.metamatrix.common.protocol.MetaMatrixURLStreamHandlerFactory;
-import com.metamatrix.query.function.metadata.FunctionMetadataReader;
 import com.metamatrix.query.function.metadata.FunctionMethod;
 
 
 public class UDFSource implements FunctionMetadataSource {
 	
-    private URL[] classpath = null;
-    private ClassLoader classLoader = null;
     private Collection <FunctionMethod> methods = null;
     
-    public UDFSource(URL url) throws IOException {
-    	loadFunctions(url.openStream());
+    public UDFSource(Collection <FunctionMethod> methods) {
+    	this.methods = methods;
     }    
     
-    public UDFSource(URL url, URL[] classpath) throws IOException{
-        this.classpath = classpath;
-        loadFunctions(url.openStream());
-    }
-    
-    public UDFSource(InputStream udfStream, URL[] classpath) throws IOException {
-        this.classpath = classpath;
-        loadFunctions(udfStream);
-    }
-    
-    public UDFSource(InputStream udfStream, ClassLoader classloader) throws IOException {
-        this.classLoader = classloader;
-        loadFunctions(udfStream);
-    }    
-    
-    
     public Collection getFunctionMethods() {
         return this.methods;
     }
 
     public Class getInvocationClass(String className) throws ClassNotFoundException {
-        // If no classpath is specified then use the default classpath
-        if (this.classLoader == null && (classpath == null || classpath.length == 0)) {
-            return Class.forName(className);
-        }
-        
-        // If the class loader is not created for the UDF functions then create 
-        // one and cache it.
-        if (classLoader == null) {
-            classLoader = new PostDelegatingClassLoader(this.classpath, Thread.currentThread().getContextClassLoader(), new MetaMatrixURLStreamHandlerFactory());                        
-        }
-        
-        return classLoader.loadClass(className);
+        return Class.forName(className);
     }
-
-    public void loadFunctions(InputStream in) throws IOException{
-        methods = FunctionMetadataReader.loadFunctionMethods(in);
-    }  
 }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -952,12 +952,4 @@
     public Class getInvocationClass(String className) throws ClassNotFoundException {
         return Class.forName(className);    
     }
-    
-    /**
-     * Never need to reload - do nothing.
-     */
-    public void loadFunctions(InputStream source) throws IOException{
-    }
-    
-    
 }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadata.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadata.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadata.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -29,6 +29,7 @@
 
 import com.metamatrix.api.exception.MetaMatrixComponentException;
 import com.metamatrix.api.exception.query.QueryMetadataException;
+import com.metamatrix.query.function.FunctionLibrary;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.mapping.xml.MappingNode;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
@@ -514,5 +515,10 @@
 			throws MetaMatrixComponentException, QueryMetadataException {
 		return false;
 	}
+
+	@Override
+	public FunctionLibrary getFunctionLibrary() {
+		return null;
+	}
     
 }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadataWrapper.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadataWrapper.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/BasicQueryMetadataWrapper.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -28,6 +28,7 @@
 
 import com.metamatrix.api.exception.MetaMatrixComponentException;
 import com.metamatrix.api.exception.query.QueryMetadataException;
+import com.metamatrix.query.function.FunctionLibrary;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.mapping.xml.MappingNode;
 
@@ -362,4 +363,9 @@
 		return actualMetadata.isScalarGroup(groupID);
 	}
 
+	@Override
+	public FunctionLibrary getFunctionLibrary() {
+		return actualMetadata.getFunctionLibrary();
+	}
+
 }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/QueryMetadataInterface.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/QueryMetadataInterface.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/metadata/QueryMetadataInterface.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,12 +22,13 @@
 
 package com.metamatrix.query.metadata;
 
-import java.util.*;
 import java.util.Collection;
 import java.util.List;
+import java.util.Properties;
 
 import com.metamatrix.api.exception.MetaMatrixComponentException;
 import com.metamatrix.api.exception.query.QueryMetadataException;
+import com.metamatrix.query.function.FunctionLibrary;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.mapping.xml.MappingNode;
 
@@ -675,4 +676,5 @@
     boolean isScalarGroup(Object groupID) 
     	throws MetaMatrixComponentException, QueryMetadataException;
 
+    FunctionLibrary getFunctionLibrary();
 }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -168,7 +168,7 @@
                         Object modelID = metadata.getModelID(groupID);
                         String modelName = metadata.getFullName(modelID);
                         if (metadata.isVirtualGroup(groupID)) {
-                        	InsertPlanExecutionNode ipen = new InsertPlanExecutionNode(getID());
+                        	InsertPlanExecutionNode ipen = new InsertPlanExecutionNode(getID(), metadata);
                         	ipen.setProcessorPlan((ProcessorPlan)node.getFirstChild().getProperty(Info.PROCESSOR_PLAN));
                         	ipen.setReferences(insert.getValues());
                         	processNode = ipen;

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -78,7 +78,7 @@
         while(current != endNode) { 
             
             // Make translations as defined in node in each current node
-            convertNode(current, oldGroup, newGroups, symbolMap);
+            convertNode(current, oldGroup, newGroups, symbolMap, metadata);
             
             PlanNode parent = current.getParent(); 
             
@@ -159,7 +159,7 @@
     // symbols.  In that case, some additional work can be done because we can assume 
     // that an oldElement isn't being replaced by an expression using elements from 
     // multiple new groups.  
-    static void convertNode(PlanNode node, GroupSymbol oldGroup, Set<GroupSymbol> newGroups, Map symbolMap)
+    static void convertNode(PlanNode node, GroupSymbol oldGroup, Set<GroupSymbol> newGroups, Map symbolMap, QueryMetadataInterface metadata)
         throws QueryPlannerException {
 
         // Update groups for current node   
@@ -202,7 +202,7 @@
         
         if(type == NodeConstants.Types.SELECT) { 
             Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
-            crit = convertCriteria(crit, symbolMap);
+            crit = convertCriteria(crit, symbolMap, metadata);
             node.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit);
             
             if (!singleMapping) {
@@ -222,7 +222,7 @@
             List<Criteria> joinCrits = (List<Criteria>) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
             if(joinCrits != null && !joinCrits.isEmpty()) {
             	Criteria crit = new CompoundCriteria(joinCrits);
-            	crit = convertCriteria(crit, symbolMap);
+            	crit = convertCriteria(crit, symbolMap, metadata);
             	if (crit instanceof CompoundCriteria) {
             		node.setProperty(NodeConstants.Info.JOIN_CRITERIA, ((CompoundCriteria)crit).getCriteria());
             	} else {
@@ -276,14 +276,14 @@
         return expression;
     }   
         
-    static Criteria convertCriteria(Criteria criteria, final Map symbolMap)
+    static Criteria convertCriteria(Criteria criteria, final Map symbolMap, QueryMetadataInterface metadata)
         throws QueryPlannerException {
 
         ExpressionMappingVisitor.mapExpressions(criteria, symbolMap);
         
         // Simplify criteria if possible
         try {
-            return QueryRewriter.rewriteCriteria(criteria, null, null, null);
+            return QueryRewriter.rewriteCriteria(criteria, null, null, metadata);
         } catch(QueryValidatorException e) {
             throw new QueryPlannerException(e, QueryExecPlugin.Util.getString(ErrorMessageKeys.OPTIMIZER_0023, criteria));
         }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCollapseSource.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCollapseSource.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -197,7 +197,7 @@
             }
             PlanNode limit = NodeEditor.findNodePreOrder(node, NodeConstants.Types.TUPLE_LIMIT, NodeConstants.Types.SET_OP);
             if (limit != null) {
-                processLimit(limit, unionCommand);
+                processLimit(limit, unionCommand, metadata);
             }
             int count = 0;
             for (PlanNode child : setOpNode.getChildren()) {
@@ -222,7 +222,7 @@
 		query.setFrom(new From());
 		buildQuery(accessRoot, node, query, metadata, capFinder);
 		if (query.getCriteria() instanceof CompoundCriteria) {
-            query.setCriteria(QueryRewriter.optimizeCriteria((CompoundCriteria)query.getCriteria()));
+            query.setCriteria(QueryRewriter.optimizeCriteria((CompoundCriteria)query.getCriteria(), metadata));
         }
 		if (!CapabilitiesUtil.useAnsiJoin(RuleRaiseAccess.getModelIDFromAccess(accessRoot, metadata), metadata, capFinder)) {
 			simplifyFromClause(query);
@@ -337,7 +337,7 @@
             }
             case NodeConstants.Types.TUPLE_LIMIT:
             {
-                processLimit(node, query);
+                processLimit(node, query, metadata);
                 break;
             }
         }        
@@ -374,7 +374,7 @@
 	}
 
     private void processLimit(PlanNode node,
-                              QueryCommand query) {
+                              QueryCommand query, QueryMetadataInterface metadata) {
         Expression limit = (Expression)node.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
         if (limit != null) {
             if (query.getLimit() != null) {
@@ -388,7 +388,7 @@
         if (offset != null) {
             if (query.getLimit() != null) {
                 Expression oldoffset = query.getLimit().getOffset();
-                query.getLimit().setOffset(RulePushLimit.getSum(offset, oldoffset)); 
+                query.getLimit().setOffset(RulePushLimit.getSum(offset, oldoffset, metadata.getFunctionLibrary())); 
             } else {
                 query.setLimit(new Limit(offset, null));
             }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCopyCriteria.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCopyCriteria.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleCopyCriteria.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -93,7 +93,7 @@
             return plan;
         }
         
-        if (tryToCopy(plan, new Set[2])) {
+        if (tryToCopy(plan, new Set[2], metadata)) {
             //Push any newly created criteria nodes and try to copy them afterwards
             rules.push(RuleConstants.COPY_CRITERIA);
             rules.push(RuleConstants.PUSH_NON_JOIN_CRITERIA);
@@ -123,13 +123,14 @@
                                  Map tgtMap,
                                  List joinCriteria,
                                  Set combinedCriteria,
-                                 boolean checkForGroupReduction) {
+                                 boolean checkForGroupReduction,
+                                 QueryMetadataInterface metadata) {
         int startGroups = GroupsUsedByElementsVisitor.getGroups(crit).size();
         
         Criteria tgtCrit = (Criteria) crit.clone();
         
         try {
-            tgtCrit = FrameUtil.convertCriteria(tgtCrit, tgtMap);
+            tgtCrit = FrameUtil.convertCriteria(tgtCrit, tgtMap, metadata);
         } catch (QueryPlannerException err) {
             LogManager.logDetail(LogConstants.CTX_QUERY_PLANNER, err, "Could not remap target criteria in RuleCopyCriteria"); //$NON-NLS-1$
             return false;
@@ -164,7 +165,7 @@
      * @param node
      * @return true if criteria has been created
      */
-    private boolean tryToCopy(PlanNode node, Set[] criteriaInfo) {
+    private boolean tryToCopy(PlanNode node, Set[] criteriaInfo, QueryMetadataInterface metadata) {
         boolean changedTree = false;
         
         if (node == null) {
@@ -176,14 +177,14 @@
             JoinType jt = (JoinType)node.getProperty(NodeConstants.Info.JOIN_TYPE);
             
             if (jt == JoinType.JOIN_FULL_OUTER) {
-                return visitChildern(node, criteriaInfo, changedTree);
+                return visitChildern(node, criteriaInfo, changedTree, metadata);
             }
             
             Set[] leftChildCriteria = new Set[2];
             Set[] rightChildCriteria = new Set[2];
             
-            changedTree |= tryToCopy(node.getFirstChild(), leftChildCriteria);
-            changedTree |= tryToCopy(node.getLastChild(), rightChildCriteria);
+            changedTree |= tryToCopy(node.getFirstChild(), leftChildCriteria, metadata);
+            changedTree |= tryToCopy(node.getLastChild(), rightChildCriteria, metadata);
 
             List joinCrits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
             Set combinedCriteria = null;
@@ -214,11 +215,11 @@
     
                 List newJoinCrits = new LinkedList();
     
-                changedTree = createCriteriaFromSelectCriteria(changedTree, combinedCriteria, toCopy, srcToTgt, newJoinCrits);
+                changedTree = createCriteriaFromSelectCriteria(changedTree, combinedCriteria, toCopy, srcToTgt, newJoinCrits, metadata);
                 
                 srcToTgt = buildElementMap(allCriteria);
                             
-                changedTree = createCriteriaFromJoinCriteria(changedTree, joinCrits, combinedCriteria, srcToTgt, newJoinCrits);
+                changedTree = createCriteriaFromJoinCriteria(changedTree, joinCrits, combinedCriteria, srcToTgt, newJoinCrits, metadata);
                 
                 joinCrits.addAll(newJoinCrits);
             }
@@ -235,7 +236,7 @@
             return changedTree;
         }
         
-        changedTree = visitChildern(node, criteriaInfo, changedTree);
+        changedTree = visitChildern(node, criteriaInfo, changedTree, metadata);
 
         //visit select nodes on the way back up
         switch (node.getType()) {
@@ -281,7 +282,8 @@
                                                    List joinCrits,
                                                    Set combinedCriteria,
                                                    Map srcToTgt,
-                                                   List newJoinCrits) {
+                                                   List newJoinCrits,
+                                                   QueryMetadataInterface metadata) {
         if (srcToTgt.size() == 0) {
             return changedTree;
         }
@@ -289,7 +291,7 @@
         while (i.hasNext()) {
             Criteria crit = (Criteria)i.next();
             
-            if (copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, true)) {
+            if (copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, true, metadata)) {
             	changedTree = true;
             	if (crit instanceof CompareCriteria) {
             		CompareCriteria cc = (CompareCriteria)crit;
@@ -317,14 +319,15 @@
                                                      Set combinedCriteria,
                                                      Set toCopy,
                                                      Map srcToTgt,
-                                                     List newJoinCrits) {
+                                                     List newJoinCrits,
+                                                     QueryMetadataInterface metadata) {
         if (srcToTgt.size() == 0) {
             return changedTree;
         }
         Iterator i = toCopy.iterator();
         while (i.hasNext()) {
             Criteria crit = (Criteria)i.next();
-            changedTree |= copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, false);            
+            changedTree |= copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, false, metadata);            
         }
         return changedTree;
     }
@@ -352,12 +355,13 @@
 
     private boolean visitChildern(PlanNode node,
                                   Set[] criteriaInfo,
-                                  boolean changedTree) {
+                                  boolean changedTree,
+                                  QueryMetadataInterface metadata) {
         if (node.getChildCount() > 0) {
             List children = node.getChildren();
             for (int i = 0; i < children.size(); i++) {
                 PlanNode childNode = (PlanNode)children.get(i);
-                changedTree |= tryToCopy(childNode, i==0?criteriaInfo:new Set[2]);
+                changedTree |= tryToCopy(childNode, i==0?criteriaInfo:new Set[2], metadata);
             }
         }
         return changedTree;

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleMergeCriteria.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleMergeCriteria.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleMergeCriteria.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -58,7 +58,7 @@
 
         // Merge chains
         for (PlanNode critNode : criteriaChains) {
-            mergeChain(critNode);
+            mergeChain(critNode, metadata);
         }
 
         return plan;
@@ -93,7 +93,7 @@
         }
     }
 
-    static void mergeChain(PlanNode chainRoot) {
+    static void mergeChain(PlanNode chainRoot, QueryMetadataInterface metadata) {
 
         // Remove all of chain except root, collect crit from each
         CompoundCriteria critParts = new CompoundCriteria();
@@ -115,7 +115,7 @@
 
         }
         
-        Criteria combinedCrit = QueryRewriter.optimizeCriteria(critParts);
+        Criteria combinedCrit = QueryRewriter.optimizeCriteria(critParts, metadata);
 
         if (isDependentSet) {
             chainRoot.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushAggregates.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -233,7 +233,7 @@
 		for (Expression expr : aggMap.values()) {
 			ExpressionMappingVisitor.mapExpressions(expr, projectedMap);
 		}
-		mapExpressions(groupNode.getParent(), aggMap);
+		mapExpressions(groupNode.getParent(), aggMap, metadata);
 	}
 
 	private boolean canPushGroupByToUnionChild(QueryMetadataInterface metadata,
@@ -352,7 +352,7 @@
     				projectedViewSymbols.add(new ExpressionSymbol("stagedAgg", count)); //$NON-NLS-1$
         		} else { //min, max, sum
         			Expression ex = agg.getExpression();
-        			ex = ResolverUtil.convertExpression(ex, DataTypeManager.getDataTypeName(agg.getType()));
+        			ex = ResolverUtil.convertExpression(ex, DataTypeManager.getDataTypeName(agg.getType()), metadata);
         			projectedViewSymbols.add(new ExpressionSymbol("stagedAgg", ex)); //$NON-NLS-1$
         		}
         	}
@@ -531,7 +531,7 @@
             try {
                 Set<AggregateSymbol> newAggs = new HashSet<AggregateSymbol>();
                 Map<AggregateSymbol, Expression> aggMap = buildAggregateMap(aggregates, metadata, newAggs);
-                mapExpressions(groupNode.getParent(), aggMap);
+                mapExpressions(groupNode.getParent(), aggMap, metadata);
                 aggregates.clear();
                 aggregates.addAll(newAggs);
             } catch (QueryResolverException err) {
@@ -670,9 +670,7 @@
                 // Build conversion function to convert SUM (which returns LONG) back to INTEGER
                 Constant convertTargetType = new Constant(DataTypeManager.getDataTypeName(partitionAgg.getType()),
                                                           DataTypeManager.DefaultDataClasses.STRING);
-                Function convertFunc = new Function(FunctionLibrary.CONVERT, new Expression[] {
-                    newAgg, convertTargetType
-                });
+                Function convertFunc = new Function(FunctionLibrary.CONVERT, new Expression[] {newAgg, convertTargetType});
                 ResolverVisitor.resolveLanguageObject(convertFunc, metadata);
 
                 newExpression = convertFunc;  
@@ -702,11 +700,11 @@
         return aggMap;
     }
     
-    static void mapExpressions(PlanNode node, Map<? extends Expression, ? extends Expression> exprMap) 
+    static void mapExpressions(PlanNode node, Map<? extends Expression, ? extends Expression> exprMap, QueryMetadataInterface metadata) 
     throws QueryPlannerException {
         
         while (node != null) {
-            FrameUtil.convertNode(node, null, null, exprMap);
+            FrameUtil.convertNode(node, null, null, exprMap, metadata);
             
             switch (node.getType()) {
                 case NodeConstants.Types.SOURCE:

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushLimit.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushLimit.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushLimit.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -31,7 +31,7 @@
 import com.metamatrix.api.exception.query.QueryPlannerException;
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.analysis.AnalysisRecord;
-import com.metamatrix.query.function.FunctionLibraryManager;
+import com.metamatrix.query.function.FunctionLibrary;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.optimizer.capabilities.CapabilitiesFinder;
 import com.metamatrix.query.optimizer.relational.OptimizerRule;
@@ -120,7 +120,7 @@
             {
                 //combine the limits
                 Expression minLimit = getMinValue((Expression)limitNode.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT), (Expression)child.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT)); 
-                Expression offSet = getSum((Expression)limitNode.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT), (Expression)child.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT)); 
+                Expression offSet = getSum((Expression)limitNode.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT), (Expression)child.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT), metadata.getFunctionLibrary()); 
                 
                 NodeEditor.removeChildNode(limitNode, child);
                 
@@ -142,7 +142,7 @@
                     PlanNode newLimit = NodeFactory.getNewNode(NodeConstants.Types.TUPLE_LIMIT);
                     Expression limit = (Expression)limitNode.getProperty(NodeConstants.Info.MAX_TUPLE_LIMIT);
                     Expression offset = (Expression)limitNode.getProperty(NodeConstants.Info.OFFSET_TUPLE_COUNT);
-                    newLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, getSum(limit, offset));
+                    newLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, getSum(limit, offset, metadata.getFunctionLibrary()));
                     grandChild.addAsParent(newLimit);
                     limitNodes.add(newLimit);
                 }
@@ -205,7 +205,7 @@
                 
                 // since we're pushing underneath the offset, we want enough rows to satisfy both the limit and the row offset
                 
-                pushedLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, getSum(limit, offset)); 
+                pushedLimit.setProperty(NodeConstants.Info.MAX_TUPLE_LIMIT, getSum(limit, offset, metadata.getFunctionLibrary())); 
                 
                 if (accessNode.getChildCount() == 0) {
                     accessNode.addFirstChild(pushedLimit);
@@ -224,7 +224,7 @@
      * @param limitNode
      * @param child
      */
-    static Expression getSum(Expression expr1, Expression expr2) {
+    static Expression getSum(Expression expr1, Expression expr2, FunctionLibrary functionLibrary) {
         if (expr1 == null) {
             return expr2;
         }
@@ -233,7 +233,7 @@
         }
         
         Function newExpr = new Function("+", new Expression[] {expr1, expr2}); //$NON-NLS-1$
-        newExpr.setFunctionDescriptor(FunctionLibraryManager.getFunctionLibrary().findFunction("+", new Class[] {DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER})); //$NON-NLS-1$
+        newExpr.setFunctionDescriptor(functionLibrary.findFunction("+", new Class[] {DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER})); //$NON-NLS-1$
         newExpr.setType(newExpr.getFunctionDescriptor().getReturnType());
         return newExpr;
     }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -112,7 +112,7 @@
                 switch (sourceNode.getType()) {
                     case NodeConstants.Types.SOURCE:
                     {
-                        moved = pushAcrossFrame(sourceNode, critNode);
+                        moved = pushAcrossFrame(sourceNode, critNode, metadata);
                         break;
                     }
                     case NodeConstants.Types.JOIN:
@@ -249,7 +249,7 @@
         NodeEditor.removeChildNode(critNode.getParent(), critNode);
         destination.addAsParent(critNode);
         if (groupSelects && destination == sourceNode) {
-        	RuleMergeCriteria.mergeChain(critNode);
+        	RuleMergeCriteria.mergeChain(critNode, metadata);
         }
 	}
 
@@ -325,7 +325,7 @@
 		return sourceNode;
 	}
 
-	boolean pushAcrossFrame(PlanNode sourceNode, PlanNode critNode)
+	boolean pushAcrossFrame(PlanNode sourceNode, PlanNode critNode, QueryMetadataInterface metadata)
 		throws QueryPlannerException {
         
         //ensure that the criteria can be pushed further
@@ -341,7 +341,7 @@
             	//only allow criteria without subqueires - node cloning doesn't allow for the proper creation of 
             	//multiple nodes with the same subqueries
                 if (child == sourceNode.getFirstChild() && critNode.getSubqueryContainers().isEmpty()) {
-                    return pushAcrossSetOp(critNode, child);
+                    return pushAcrossSetOp(critNode, child, metadata);
                 } 
                 //this could be an access node in the middle of the source and set op,
                 //it is an odd case that is not supported for now
@@ -350,7 +350,7 @@
         }
         
 		// See if we can move it towards the SOURCE node
-        return moveNodeAcrossFrame(critNode, sourceNode);
+        return moveNodeAcrossFrame(critNode, sourceNode, metadata);
 	}
 
 	/**
@@ -370,7 +370,7 @@
 		return true;
 	}
 
-	boolean moveNodeAcrossFrame(PlanNode critNode, PlanNode sourceNode)
+	boolean moveNodeAcrossFrame(PlanNode critNode, PlanNode sourceNode, QueryMetadataInterface metadata)
 		throws QueryPlannerException {
 
 		Assertion.isNotNull(critNode.getParent());
@@ -387,7 +387,7 @@
         
         SymbolMap symbolMap = (SymbolMap) sourceNode.getProperty(NodeConstants.Info.SYMBOL_MAP);
         
-        if (!createConvertedSelectNode(critNode, sourceNode.getGroups().iterator().next(), projectNode, symbolMap)) {
+        if (!createConvertedSelectNode(critNode, sourceNode.getGroups().iterator().next(), projectNode, symbolMap, metadata)) {
             return false;
         }
 		
@@ -473,7 +473,7 @@
 	    return copyNode;
 	}
 
-	boolean pushAcrossSetOp(PlanNode critNode, PlanNode setOp)
+	boolean pushAcrossSetOp(PlanNode critNode, PlanNode setOp, QueryMetadataInterface metadata)
 		throws QueryPlannerException {
         
         // Find source node above union and grab the symbol map
@@ -499,7 +499,7 @@
 	        }
 		    
 			// Move the node
-			if(createConvertedSelectNode(critNode, virtualGroup, projectNode, childMap)) {
+			if(createConvertedSelectNode(critNode, virtualGroup, projectNode, childMap, metadata)) {
                 movedCount++;
             }
 			
@@ -529,7 +529,8 @@
     private boolean createConvertedSelectNode(PlanNode critNode,
     							   GroupSymbol sourceGroup,
                                    PlanNode projectNode,
-                                   SymbolMap symbolMap) throws QueryPlannerException {
+                                   SymbolMap symbolMap,
+                                   QueryMetadataInterface metadata) throws QueryPlannerException {
         // If projectNode has children, then it is from a SELECT without a FROM and the criteria should not be pushed
         if(projectNode.getChildCount() == 0) {
             return false;
@@ -554,7 +555,7 @@
             copyNode.setProperty(NodeConstants.Info.IS_HAVING, Boolean.TRUE);
         }
 
-        FrameUtil.convertNode(copyNode, sourceGroup, null, symbolMap.asMap());  
+        FrameUtil.convertNode(copyNode, sourceGroup, null, symbolMap.asMap(), metadata);  
         PlanNode intermediateParent = NodeEditor.findParent(projectNode, NodeConstants.Types.ACCESS, NodeConstants.Types.SOURCE | NodeConstants.Types.SET_OP);
         if (intermediateParent != null) {
             intermediateParent.addAsParent(copyNode);

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/AccessNode.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/AccessNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/AccessNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -35,6 +35,7 @@
 import com.metamatrix.common.buffer.TupleBatch;
 import com.metamatrix.common.buffer.TupleSource;
 import com.metamatrix.query.execution.QueryExecPlugin;
+import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.rewriter.QueryRewriter;
 import com.metamatrix.query.sql.lang.Command;
 import com.metamatrix.query.util.CommandContext;
@@ -107,15 +108,15 @@
 	}
 
     protected boolean prepareNextCommand(Command atomicCommand) throws MetaMatrixComponentException, MetaMatrixProcessingException {
-    	return prepareCommand(atomicCommand, this, this.getContext());
+    	return prepareCommand(atomicCommand, this, this.getContext(), this.getContext().getMetadata());
     }
 
-	static boolean prepareCommand(Command atomicCommand, RelationalNode node, CommandContext context)
+	static boolean prepareCommand(Command atomicCommand, RelationalNode node, CommandContext context, QueryMetadataInterface metadata)
 			throws ExpressionEvaluationException, MetaMatrixComponentException,
 			MetaMatrixProcessingException, CriteriaEvaluationException {
         try {
             // Defect 16059 - Rewrite the command once the references have been replaced with values.
-            QueryRewriter.evaluateAndRewrite(atomicCommand, node.getDataManager(), context);
+            QueryRewriter.evaluateAndRewrite(atomicCommand, node.getDataManager(), context, metadata);
         } catch (QueryValidatorException e) {
             throw new MetaMatrixProcessingException(e, QueryExecPlugin.Util.getString("AccessNode.rewrite_failed", atomicCommand)); //$NON-NLS-1$
         }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/BatchedUpdateNode.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/BatchedUpdateNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/BatchedUpdateNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -97,7 +97,7 @@
             boolean needProcessing = false;
             if(shouldEvaluate != null && shouldEvaluate.get(i)) {
                 updateCommand = (Command) updateCommand.clone();
-                needProcessing = AccessNode.prepareCommand(updateCommand, this, context);
+                needProcessing = AccessNode.prepareCommand(updateCommand, this, context, context.getMetadata());
             } else {
                 needProcessing = RelationalNodeUtil.shouldExecute(updateCommand, true);
             }

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/InsertPlanExecutionNode.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/InsertPlanExecutionNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/processor/relational/InsertPlanExecutionNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -31,6 +31,7 @@
 import com.metamatrix.api.exception.MetaMatrixProcessingException;
 import com.metamatrix.common.buffer.BlockedException;
 import com.metamatrix.common.buffer.TupleBatch;
+import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.sql.symbol.Reference;
 
 public class InsertPlanExecutionNode extends PlanExecutionNode {
@@ -40,9 +41,11 @@
     private int batchRow = 1;
     private int insertCount = 0;
     private TupleBatch currentBatch;
+    private QueryMetadataInterface metadata;
 	
-	public InsertPlanExecutionNode(int nodeID) {
+	public InsertPlanExecutionNode(int nodeID, QueryMetadataInterface metadata) {
 		super(nodeID);
+		this.metadata = metadata;
 	}
 	
 	public void setReferences(List<Reference> references) {
@@ -82,13 +85,13 @@
 			return false;
 		}
 		//assign the reference values.
-		PreparedStatementRequest.resolveParameterValues(this.references, this.currentBatch.getTuple(this.batchRow), getProcessorPlan().getContext());
+		PreparedStatementRequest.resolveParameterValues(this.references, this.currentBatch.getTuple(this.batchRow), getProcessorPlan().getContext(), this.metadata);
 		this.batchRow++;
 		return true;
 	}
 	
 	public Object clone(){
-		InsertPlanExecutionNode clonedNode = new InsertPlanExecutionNode(super.getID());
+		InsertPlanExecutionNode clonedNode = new InsertPlanExecutionNode(super.getID(), this.metadata);
 		copy(this, clonedNode);
         return clonedNode;
 	}

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/ExecResolver.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/ExecResolver.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/ExecResolver.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -276,7 +276,7 @@
                     Expression result = null;
                     
                     try {
-                        result = ResolverUtil.convertExpression(expr, tgtType);
+                        result = ResolverUtil.convertExpression(expr, tgtType, metadata);
                     } catch (QueryResolverException e) {
                         throw new QueryResolverException(e, QueryPlugin.Util.getString("ExecResolver.Param_convert_fail", new Object[] { srcType, tgtType}));                                     //$NON-NLS-1$
                     }                                                       

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/InsertResolver.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/InsertResolver.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/InsertResolver.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -102,7 +102,7 @@
             resolveVariables(metadata, insert, groups);
         }
 
-        resolveTypes(insert);
+        resolveTypes(insert, metadata);
         
         if (!insert.getGroup().isResolved()) { //define the implicit temp group
             if(insert.getQueryExpression() != null) {
@@ -113,7 +113,7 @@
             resolveVariables(metadata, insert, groups);
             
             //ensure that the types match
-            resolveTypes(insert);
+            resolveTypes(insert, metadata);
         }
         
         if (insert.getQueryExpression() != null && metadata.isVirtualGroup(insert.getGroup().getMetadataID())) {
@@ -151,7 +151,7 @@
      * @param insert
      * @throws QueryResolverException
      */
-    public void resolveTypes(Insert insert) throws QueryResolverException {
+    public void resolveTypes(Insert insert, TempMetadataAdapter metadata) throws QueryResolverException {
         
         boolean usingQuery = insert.getQueryExpression() != null;
         
@@ -183,7 +183,7 @@
             if(element.getType() != null && expression.getType() != null) {
                 String elementTypeName = DataTypeManager.getDataTypeName(element.getType());
                 if (!usingQuery) {
-                    newValues.add(ResolverUtil.convertExpression(expression, elementTypeName));
+                    newValues.add(ResolverUtil.convertExpression(expression, elementTypeName, metadata));
                 } else if (element.getType() != expression.getType()
                            && !DataTypeManager.isImplicitConversion(DataTypeManager.getDataTypeName(expression.getType()),
                                                                     DataTypeManager.getDataTypeName(element.getType()))) {

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/SetQueryResolver.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -34,6 +34,7 @@
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.QueryPlugin;
 import com.metamatrix.query.analysis.AnalysisRecord;
+import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.metadata.TempMetadataAdapter;
 import com.metamatrix.query.metadata.TempMetadataID;
 import com.metamatrix.query.resolver.CommandResolver;
@@ -89,7 +90,7 @@
             }
         }
 
-        setQuery.setProjectedTypes(firstProjectTypes);
+        setQuery.setProjectedTypes(firstProjectTypes, metadata.getMetadata());
         
         // ORDER BY clause
         if(setQuery.getOrderBy() != null) {
@@ -97,7 +98,7 @@
             ResolverUtil.resolveOrderBy(setQuery.getOrderBy(), setQuery, metadata);
         } 
 
-        setProjectedTypes(setQuery, firstProjectTypes);
+        setProjectedTypes(setQuery, firstProjectTypes, metadata.getMetadata());
         
         if (setQuery.getLimit() != null) {
             ResolverUtil.resolveLimit(setQuery.getLimit());
@@ -107,7 +108,7 @@
     }
 
     private void setProjectedTypes(SetQuery setQuery,
-                                   List firstProjectTypes) throws QueryResolverException {
+                                   List firstProjectTypes, QueryMetadataInterface metadata) throws QueryResolverException {
         for (QueryCommand subCommand : setQuery.getQueryCommands()) {
             if (!(subCommand instanceof SetQuery)) {
                 continue;
@@ -126,8 +127,8 @@
                     }
                 }
             }
-            child.setProjectedTypes(firstProjectTypes);
-            setProjectedTypes(child, firstProjectTypes);
+            child.setProjectedTypes(firstProjectTypes, metadata);
+            setProjectedTypes(child, firstProjectTypes, metadata);
         }
     }
     

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/command/UpdateProcedureResolver.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -277,7 +277,7 @@
                         throw new QueryResolverException(QueryPlugin.Util.getString("ResolveVariablesVisitor.datatype_for_the_expression_not_resolvable")); //$NON-NLS-1$
                     }
                     String varTypeName = DataTypeManager.getDataTypeName(varType);
-                    assStmt.setExpression(ResolverUtil.convertExpression(expr, varTypeName));                    
+                    assStmt.setExpression(ResolverUtil.convertExpression(expr, varTypeName, metadata));                    
                 }
                 
                 break;

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverUtil.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -43,7 +43,6 @@
 import com.metamatrix.query.QueryPlugin;
 import com.metamatrix.query.function.FunctionDescriptor;
 import com.metamatrix.query.function.FunctionLibrary;
-import com.metamatrix.query.function.FunctionLibraryManager;
 import com.metamatrix.query.metadata.GroupInfo;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.metadata.StoredProcedureInfo;
@@ -187,10 +186,10 @@
      * @return
      * @throws QueryResolverException 
      */
-    public static Expression convertExpression(Expression sourceExpression, String targetTypeName) throws QueryResolverException {
+    public static Expression convertExpression(Expression sourceExpression, String targetTypeName, QueryMetadataInterface metadata) throws QueryResolverException {
         return convertExpression(sourceExpression,
                                  DataTypeManager.getDataTypeName(sourceExpression.getType()),
-                                 targetTypeName);
+                                 targetTypeName, metadata);
     }
 
     /**
@@ -203,14 +202,14 @@
      * @return
      * @throws QueryResolverException 
      */
-    public static Expression convertExpression(Expression sourceExpression, String sourceTypeName, String targetTypeName) throws QueryResolverException {
+    public static Expression convertExpression(Expression sourceExpression, String sourceTypeName, String targetTypeName, QueryMetadataInterface metadata) throws QueryResolverException {
         if (sourceTypeName.equals(targetTypeName)) {
             return sourceExpression;
         }
         
         if(canImplicitlyConvert(sourceTypeName, targetTypeName) 
                         || (sourceExpression instanceof Constant && convertConstant(sourceTypeName, targetTypeName, (Constant)sourceExpression) != null)) {
-            return getConversion(sourceExpression, sourceTypeName, targetTypeName, true);
+            return getConversion(sourceExpression, sourceTypeName, targetTypeName, true, metadata.getFunctionLibrary());
         }
 
         //Expression is wrong type and can't convert
@@ -258,10 +257,9 @@
     public static Function getConversion(Expression sourceExpression,
                                             String sourceTypeName,
                                             String targetTypeName,
-                                            boolean implicit) {
+                                            boolean implicit, FunctionLibrary library) {
         Class<?> srcType = DataTypeManager.getDataTypeClass(sourceTypeName);
 
-        FunctionLibrary library = FunctionLibraryManager.getFunctionLibrary();
         FunctionDescriptor fd = library.findTypedConversionFunction(srcType, DataTypeManager.getDataTypeClass(targetTypeName));
 
         Function conversion = new Function(fd.getName(), new Expression[] { sourceExpression, new Constant(targetTypeName) });
@@ -783,7 +781,7 @@
 	 * @throws QueryResolverException if a conversion is necessary but none can
 	 * be found
 	 */
-	static Expression resolveSubqueryPredicateCriteria(Expression expression, SubqueryContainer crit)
+	static Expression resolveSubqueryPredicateCriteria(Expression expression, SubqueryContainer crit, QueryMetadataInterface metadata)
 		throws QueryResolverException {
 	
 		// Check that type of the expression is same as the type of the
@@ -802,7 +800,7 @@
 		String subqueryTypeName = DataTypeManager.getDataTypeName(subqueryType);
 		Expression result = null;
 	    try {
-	        result = convertExpression(expression, exprTypeName, subqueryTypeName);
+	        result = convertExpression(expression, exprTypeName, subqueryTypeName, metadata);
 	    } catch (QueryResolverException qre) {
 	        throw new QueryResolverException(qre, ErrorMessageKeys.RESOLVER_0033, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0033, crit));
 	    }
@@ -847,7 +845,7 @@
             throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0062, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0062, keyElementName));
         }
 		result.setKeyElement(keyElement);
-		args[3] = convertExpression(args[3], DataTypeManager.getDataTypeName(keyElement.getType()));
+		args[3] = convertExpression(args[3], DataTypeManager.getDataTypeName(keyElement.getType()), metadata);
 		return result;
 	}
 

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -44,7 +44,6 @@
 import com.metamatrix.query.function.FunctionDescriptor;
 import com.metamatrix.query.function.FunctionForm;
 import com.metamatrix.query.function.FunctionLibrary;
-import com.metamatrix.query.function.FunctionLibraryManager;
 import com.metamatrix.query.metadata.GroupInfo;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.sql.LanguageObject;
@@ -264,7 +263,7 @@
 
     public void visit(SubqueryCompareCriteria obj) {
         try {
-            obj.setLeftExpression(ResolverUtil.resolveSubqueryPredicateCriteria(obj.getLeftExpression(), obj));
+            obj.setLeftExpression(ResolverUtil.resolveSubqueryPredicateCriteria(obj.getLeftExpression(), obj, metadata));
         } catch(QueryResolverException e) {
             handleException(e);
         }
@@ -273,7 +272,7 @@
 
     public void visit(SubquerySetCriteria obj) {
         try {
-            obj.setExpression(ResolverUtil.resolveSubqueryPredicateCriteria(obj.getExpression(), obj));
+            obj.setExpression(ResolverUtil.resolveSubqueryPredicateCriteria(obj.getExpression(), obj, metadata));
         } catch(QueryResolverException e) {
             handleException(e);
         }
@@ -289,7 +288,7 @@
     
     public void visit(Function obj) {
         try {
-            resolveFunction(obj);
+            resolveFunction(obj, this.metadata.getFunctionLibrary());
         } catch(QueryResolverException e) {
         	if (unresolvedFunctions == null) {
         		unresolvedFunctions = new LinkedHashMap<Function, QueryResolverException>();
@@ -320,7 +319,7 @@
     	String type = DataTypeManager.getDataTypeName(obj.getSymbol().getType());
     	try {
     		setDesiredType(obj.getValue(), obj.getSymbol().getType(), obj);
-            obj.setValue(ResolverUtil.convertExpression(obj.getValue(), type));                    
+            obj.setValue(ResolverUtil.convertExpression(obj.getValue(), type, metadata));                    
         } catch(QueryResolverException e) {
             handleException(new QueryResolverException(e, QueryPlugin.Util.getString("SetClause.resolvingError", new Object[] {obj.getValue(), obj.getSymbol(), type}))); //$NON-NLS-1$
         } 
@@ -367,7 +366,7 @@
 	/**
 	 * Resolve function such that all functions are resolved and type-safe.
 	 */
-	void resolveFunction(Function function)
+	void resolveFunction(Function function, FunctionLibrary library)
 	    throws QueryResolverException, MetaMatrixComponentException {
 	
 	    // Check whether this function is already resolved
@@ -388,8 +387,6 @@
 	            hasArgWithoutType = true;
 	        }
 	    }
-	        
-	    FunctionLibrary library = FunctionLibraryManager.getFunctionLibrary();
 	
 	    //special case handling for convert of an untyped reference
 	    if (FunctionLibrary.isConvert(function) && hasArgWithoutType) {
@@ -543,9 +540,9 @@
 	
 	    String commonType = ResolverUtil.getCommonType(new String[] {expTypeName, lowerTypeName, upperTypeName});
 	    if (commonType != null) {
-	        criteria.setExpression(ResolverUtil.convertExpression(exp, expTypeName, commonType));
-	        criteria.setLowerExpression(ResolverUtil.convertExpression(lower, lowerTypeName, commonType));
-	        criteria.setUpperExpression(ResolverUtil.convertExpression(upper, upperTypeName, commonType));
+	        criteria.setExpression(ResolverUtil.convertExpression(exp, expTypeName, commonType, metadata));
+	        criteria.setLowerExpression(ResolverUtil.convertExpression(lower, lowerTypeName, commonType, metadata));
+	        criteria.setUpperExpression(ResolverUtil.convertExpression(upper, upperTypeName, commonType, metadata));
 	    } else {
 	        // Couldn't find a common type to implicitly convert to
 	        throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0027, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0027, expTypeName, lowerTypeName, criteria));
@@ -575,7 +572,7 @@
 	    if(rightExpression instanceof Constant) {
 	        // Auto-convert constant string on right to expected type on left
 	        try {
-	            ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName));
+	            ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata));
 	            return;
 	        } catch (QueryResolverException qre) {
 	            //ignore
@@ -586,7 +583,7 @@
 	    if(leftExpression instanceof Constant) {
 	        // Auto-convert constant string on left to expected type on right
 	        try {
-	            ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName));
+	            ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata));
 	            return;                                           
 	        } catch (QueryResolverException qre) {
 	            //ignore
@@ -596,12 +593,12 @@
 	    // Try to apply a conversion generically
 		
 	    if(ResolverUtil.canImplicitlyConvert(leftTypeName, rightTypeName)) {
-			ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName) );
+			ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, rightTypeName, metadata) );
 			return;
 		}
 	
 		if(ResolverUtil.canImplicitlyConvert(rightTypeName, leftTypeName)) {
-			ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName) );
+			ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, leftTypeName, metadata) );
 			return;
 	    }
 	
@@ -611,8 +608,8 @@
 	        // Neither are aggs, but types can't be reconciled
 	        throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0027, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0027, new Object[] { leftTypeName, rightTypeName, ccrit }));
 		}
-		ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, commonType) );
-		ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, commonType) );
+		ccrit.setLeftExpression(ResolverUtil.convertExpression(leftExpression, leftTypeName, commonType, metadata) );
+		ccrit.setRightExpression(ResolverUtil.convertExpression(rightExpression, rightTypeName, commonType, metadata) );
 	}
 
 	void resolveMatchCriteria(MatchCriteria mcrit)
@@ -644,12 +641,12 @@
 	            if(!(expr instanceof AggregateSymbol) &&
 	                ResolverUtil.canImplicitlyConvert(type, DataTypeManager.DefaultDataTypes.STRING)) {
 	
-	                result = ResolverUtil.convertExpression(expr, type, DataTypeManager.DefaultDataTypes.STRING);
+	                result = ResolverUtil.convertExpression(expr, type, DataTypeManager.DefaultDataTypes.STRING, metadata);
 	                
 	            } else if (!(expr instanceof AggregateSymbol) &&
 	                ResolverUtil.canImplicitlyConvert(type, DataTypeManager.DefaultDataTypes.CLOB)){
 	                    
-	                result = ResolverUtil.convertExpression(expr, type, DataTypeManager.DefaultDataTypes.CLOB);
+	                result = ResolverUtil.convertExpression(expr, type, DataTypeManager.DefaultDataTypes.CLOB, metadata);
 	
 	            } else {
 	                throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0029, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0029, mcrit));
@@ -687,7 +684,7 @@
 	            String valTypeName = DataTypeManager.getDataTypeName(value.getType());
 	            if(ResolverUtil.canImplicitlyConvert(valTypeName, exprTypeName)) {
 	                // Apply cast and replace current value
-	                newVals.add(ResolverUtil.convertExpression(value, valTypeName, exprTypeName) );
+	                newVals.add(ResolverUtil.convertExpression(value, valTypeName, exprTypeName, metadata) );
 	                changed = true;
 	            } else {
 	                convertLeft = true;
@@ -716,7 +713,7 @@
 	            }
 	
 	            // Convert left expression to type of values in the set
-	            scrit.setExpression(ResolverUtil.convertExpression(scrit.getExpression(), exprTypeName, setTypeName ));
+	            scrit.setExpression(ResolverUtil.convertExpression(scrit.getExpression(), exprTypeName, setTypeName, metadata));
 	
 	        } else {
 	            throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0031, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0031, scrit));
@@ -799,16 +796,16 @@
 	    if (thenTypeName == null) {
 	        throw new QueryResolverException(ErrorMessageKeys.RESOLVER_0068, QueryPlugin.Util.getString(ErrorMessageKeys.RESOLVER_0068, "THEN/ELSE", obj)); //$NON-NLS-1$
 	    }
-	    obj.setExpression(ResolverUtil.convertExpression(obj.getExpression(), whenTypeName));
+	    obj.setExpression(ResolverUtil.convertExpression(obj.getExpression(), whenTypeName, metadata));
 	    ArrayList whens = new ArrayList(whenCount);
 	    ArrayList thens = new ArrayList(whenCount);
 	    for (int i = 0; i < whenCount; i++) {
-	        whens.add(ResolverUtil.convertExpression(obj.getWhenExpression(i), whenTypeName));
-	        thens.add(ResolverUtil.convertExpression(obj.getThenExpression(i), thenTypeName));
+	        whens.add(ResolverUtil.convertExpression(obj.getWhenExpression(i), whenTypeName, metadata));
+	        thens.add(ResolverUtil.convertExpression(obj.getThenExpression(i), thenTypeName, metadata));
 	    }
 	    obj.setWhen(whens, thens);
 	    if (elseExpr != null) {
-	        obj.setElseExpression(ResolverUtil.convertExpression(elseExpr, thenTypeName));
+	        obj.setElseExpression(ResolverUtil.convertExpression(elseExpr, thenTypeName, metadata));
 	    }
 	    // Set this CASE expression's type to the common THEN type, and we're done.
 	    obj.setType(DataTypeManager.getDataTypeClass(thenTypeName));
@@ -887,11 +884,11 @@
 	    }
 	    ArrayList thens = new ArrayList(whenCount);
 	    for (int i = 0; i < whenCount; i++) {
-	        thens.add(ResolverUtil.convertExpression(obj.getThenExpression(i), thenTypeName));
+	        thens.add(ResolverUtil.convertExpression(obj.getThenExpression(i), thenTypeName, metadata));
 	    }
 	    obj.setWhen(obj.getWhen(), thens);
 	    if (elseExpr != null) {
-	        obj.setElseExpression(ResolverUtil.convertExpression(elseExpr, thenTypeName));
+	        obj.setElseExpression(ResolverUtil.convertExpression(elseExpr, thenTypeName, metadata));
 	    }
 	    // Set this CASE expression's type to the common THEN type, and we're done.
 	    obj.setType(DataTypeManager.getDataTypeClass(thenTypeName));

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -48,7 +48,6 @@
 import com.metamatrix.api.exception.query.CriteriaEvaluationException;
 import com.metamatrix.api.exception.query.ExpressionEvaluationException;
 import com.metamatrix.api.exception.query.FunctionExecutionException;
-import com.metamatrix.api.exception.query.InvalidFunctionException;
 import com.metamatrix.api.exception.query.QueryMetadataException;
 import com.metamatrix.api.exception.query.QueryResolverException;
 import com.metamatrix.api.exception.query.QueryValidatorException;
@@ -60,7 +59,6 @@
 import com.metamatrix.query.execution.QueryExecPlugin;
 import com.metamatrix.query.function.FunctionDescriptor;
 import com.metamatrix.query.function.FunctionLibrary;
-import com.metamatrix.query.function.FunctionLibraryManager;
 import com.metamatrix.query.function.FunctionMethods;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.metadata.TempMetadataAdapter;
@@ -188,8 +186,8 @@
 		this.procCommand = procCommand;
 	}
     
-    public static Command evaluateAndRewrite(Command command, ProcessorDataManager dataMgr, CommandContext context) throws MetaMatrixProcessingException, MetaMatrixComponentException {
-    	QueryRewriter queryRewriter = new QueryRewriter(null, context, null);
+    public static Command evaluateAndRewrite(Command command, ProcessorDataManager dataMgr, CommandContext context, QueryMetadataInterface metadata) throws MetaMatrixProcessingException, MetaMatrixComponentException {
+    	QueryRewriter queryRewriter = new QueryRewriter(metadata, context, null);
     	queryRewriter.dataMgr = dataMgr;
     	queryRewriter.rewriteSubcommands = true;
     	try {
@@ -932,7 +930,7 @@
         
         List symbols = query.getSelect().getProjectedSymbols();
         
-        List newSymbols = SetQuery.getTypedProjectedSymbols(symbols, actualSymbolTypes);
+        List newSymbols = SetQuery.getTypedProjectedSymbols(symbols, actualSymbolTypes, this.metadata);
         
         query.getSelect().setSymbols(newSymbols);
     } 
@@ -947,7 +945,7 @@
                 }
                 correctProjectedTypes(setQuery.getProjectedTypes(), (Query)command);
             }
-            setQuery.setProjectedTypes(null);
+            setQuery.setProjectedTypes(null, null);
         }
         
         setQuery.setLeftQuery((QueryCommand)rewriteCommand(setQuery.getLeftQuery(), true));
@@ -1090,9 +1088,9 @@
      * @param criteria
      * @return
      */
-    public static Criteria optimizeCriteria(CompoundCriteria criteria) {
+    public static Criteria optimizeCriteria(CompoundCriteria criteria, QueryMetadataInterface metadata) {
         try {
-            return new QueryRewriter(null, null, null).rewriteCriteria(criteria, false);
+            return new QueryRewriter(metadata, null, null).rewriteCriteria(criteria, false);
         } catch (QueryValidatorException err) {
             //shouldn't happen
             return criteria;
@@ -1377,7 +1375,7 @@
 
         // Create a function of the two constants and evaluate it
         Expression combinedConst = null;
-        FunctionLibrary funcLib = FunctionLibraryManager.getFunctionLibrary();
+        FunctionLibrary funcLib = this.metadata.getFunctionLibrary();
         FunctionDescriptor descriptor = funcLib.findFunction(oppFunc, new Class[] { rightExpr.getType(), const1.getType() });
         if (descriptor == null){
             //See defect 9380 - this can be caused by const2 being a null Constant, for example (? + 1) < null
@@ -1388,13 +1386,10 @@
         if (rightExpr instanceof Constant) {
             Constant const2 = (Constant)rightExpr;
             try {
-                Object result = funcLib.invokeFunction(
-                    descriptor, new Object[] { const2.getValue(), const1.getValue() } );
+                Object result = descriptor.invokeFunction(new Object[] { const2.getValue(), const1.getValue() } );
                 combinedConst = new Constant(result, descriptor.getReturnType());
-            } catch(InvalidFunctionException e) {
+            } catch(FunctionExecutionException e) {
             	throw new QueryValidatorException(e, ErrorMessageKeys.REWRITER_0003, QueryExecPlugin.Util.getString(ErrorMessageKeys.REWRITER_0003, e.getMessage()));
-        	} catch(FunctionExecutionException e) {
-            	throw new QueryValidatorException(e, ErrorMessageKeys.REWRITER_0003, QueryExecPlugin.Util.getString(ErrorMessageKeys.REWRITER_0003, e.getMessage()));
         	}
         } else {
             Function conversion = new Function(descriptor.getName(), new Expression[] { rightExpr, const1 });
@@ -1616,21 +1611,18 @@
             return crit;
         }
         String format = (String)((Constant)formatExpr).getValue();
-        FunctionLibrary funcLib = FunctionLibraryManager.getFunctionLibrary();
+        FunctionLibrary funcLib = this.metadata.getFunctionLibrary();
         FunctionDescriptor descriptor = funcLib.findFunction(inverseFunction, new Class[] { rightExpr.getType(), formatExpr.getType() });
         if(descriptor == null){
             return crit;
         }
     	Object value = ((Constant)rightExpr).getValue();
     	try {
-    		Object result = funcLib.invokeFunction(descriptor, new Object[] {((Constant)rightExpr).getValue(), format});
-    		result = funcLib.invokeFunction(leftFunction.getFunctionDescriptor(), new Object[] { result, format } );
+    		Object result = descriptor.invokeFunction(new Object[] {((Constant)rightExpr).getValue(), format});
+    		result = leftFunction.getFunctionDescriptor().invokeFunction(new Object[] { result, format } );
     		if (((Comparable)value).compareTo(result) != 0) {
     			return getSimpliedCriteria(crit, leftExpr, crit.getOperator() != CompareCriteria.EQ, true);
     		}
-    	} catch(InvalidFunctionException e) {
-            String errorMsg = QueryExecPlugin.Util.getString("QueryRewriter.criteriaError", crit); //$NON-NLS-1$
-            throw new QueryValidatorException(e, errorMsg);
     	} catch(FunctionExecutionException e) {
             //Not all numeric formats are invertable, so just return the criteria as it may still be valid
             return crit;
@@ -1972,7 +1964,7 @@
 				&& EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
 			try {
 				return new ExpressionSymbol(expression.getName(), ResolverUtil
-						.convertExpression(expression.getExpression(),DataTypeManager.getDataTypeName(expression.getType())));
+						.convertExpression(expression.getExpression(),DataTypeManager.getDataTypeName(expression.getType()), metadata));
 			} catch (QueryResolverException e) {
 				//should not happen, so throw as a runtime
 				throw new MetaMatrixRuntimeException(e);
@@ -2004,6 +1996,7 @@
 			function.setName(actualName);
 		}
 		
+		FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
 		Integer code = FUNCTION_MAP.get(functionLowerName);
 		if (code != null) {
 			switch (code) {
@@ -2012,7 +2005,7 @@
 						new Expression[] {new Constant(" "), function.getArg(0)}); //$NON-NLS-1$
 				//resolve the function
 				FunctionDescriptor descriptor = 
-		        	FunctionLibraryManager.getFunctionLibrary().findFunction(SourceSystemFunctions.REPEAT, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER});
+					funcLibrary.findFunction(SourceSystemFunctions.REPEAT, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER});
 				result.setFunctionDescriptor(descriptor);
 				result.setType(DataTypeManager.DefaultDataClasses.STRING);
 				function = result;
@@ -2023,7 +2016,7 @@
 						new Expression[] {new Constant(ReservedWords.SQL_TSI_SECOND), function.getArg(0), new Constant(new Timestamp(0)) });
 				//resolve the function
 				FunctionDescriptor descriptor = 
-		        	FunctionLibraryManager.getFunctionLibrary().findFunction(FunctionLibrary.TIMESTAMPADD, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP });
+					funcLibrary.findFunction(FunctionLibrary.TIMESTAMPADD, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP });
 				result.setFunctionDescriptor(descriptor);
 				result.setType(DataTypeManager.DefaultDataClasses.TIMESTAMP);
 				function = result;
@@ -2045,7 +2038,7 @@
 							new Expression[] {function.getArg(0), function.getArg(1) });
 					//resolve the function
 					FunctionDescriptor descriptor = 
-			        	FunctionLibraryManager.getFunctionLibrary().findFunction(SourceSystemFunctions.IFNULL, new Class[] { function.getType(), function.getType()  });
+						funcLibrary.findFunction(SourceSystemFunctions.IFNULL, new Class[] { function.getType(), function.getType()  });
 					result.setFunctionDescriptor(descriptor);
 					result.setType(function.getType());
 					function = result;
@@ -2061,14 +2054,14 @@
 					newArgs[i].setType(args[i].getType());
 					Assertion.assertTrue(args[i].getType() == DataTypeManager.DefaultDataClasses.STRING);
 			        FunctionDescriptor descriptor = 
-			        	FunctionLibraryManager.getFunctionLibrary().findFunction(SourceSystemFunctions.IFNULL, new Class[] { args[i].getType(), DataTypeManager.DefaultDataClasses.STRING });
+			        	funcLibrary.findFunction(SourceSystemFunctions.IFNULL, new Class[] { args[i].getType(), DataTypeManager.DefaultDataClasses.STRING });
 			        newArgs[i].setFunctionDescriptor(descriptor);
 				}
 				
 				Function concat = new Function(SourceSystemFunctions.CONCAT, newArgs);
 				concat.setType(DataTypeManager.DefaultDataClasses.STRING);
 				FunctionDescriptor descriptor = 
-		        	FunctionLibraryManager.getFunctionLibrary().findFunction(SourceSystemFunctions.CONCAT, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING });
+					funcLibrary.findFunction(SourceSystemFunctions.CONCAT, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING });
 				concat.setFunctionDescriptor(descriptor);
 				
 				List when = Arrays.asList(new Criteria[] {new CompoundCriteria(CompoundCriteria.AND, new IsNullCriteria(args[0]), new IsNullCriteria(args[1]))});
@@ -2082,33 +2075,33 @@
 			case 5: {
 				if (function.getType() != DataTypeManager.DefaultDataClasses.TIMESTAMP) {
 					FunctionDescriptor descriptor = 
-			        	FunctionLibraryManager.getFunctionLibrary().findFunction(SourceSystemFunctions.TIMESTAMPADD, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP });
+						funcLibrary.findFunction(SourceSystemFunctions.TIMESTAMPADD, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.TIMESTAMP });
 					function.setFunctionDescriptor(descriptor);
 					Class<?> type = function.getType();
 					function.setType(DataTypeManager.DefaultDataClasses.TIMESTAMP);
-					function.getArgs()[2] = ResolverUtil.getConversion(function.getArg(2), DataTypeManager.getDataTypeName(type), DataTypeManager.DefaultDataTypes.TIMESTAMP, false);
-					function = ResolverUtil.getConversion(function, DataTypeManager.DefaultDataTypes.TIMESTAMP, DataTypeManager.getDataTypeName(type), false);
+					function.getArgs()[2] = ResolverUtil.getConversion(function.getArg(2), DataTypeManager.getDataTypeName(type), DataTypeManager.DefaultDataTypes.TIMESTAMP, false, funcLibrary);
+					function = ResolverUtil.getConversion(function, DataTypeManager.DefaultDataTypes.TIMESTAMP, DataTypeManager.getDataTypeName(type), false, funcLibrary);
 				}
 				break;
 			}
 			case 6:
 			case 7: {
 				FunctionDescriptor descriptor = 
-		        	FunctionLibraryManager.getFunctionLibrary().findFunction(SourceSystemFunctions.PARSETIMESTAMP, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING });
+					funcLibrary.findFunction(SourceSystemFunctions.PARSETIMESTAMP, new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING });
 				function.setName(SourceSystemFunctions.PARSETIMESTAMP);
 				function.setFunctionDescriptor(descriptor);
 				Class<?> type = function.getType();
 				function.setType(DataTypeManager.DefaultDataClasses.TIMESTAMP);
-				function = ResolverUtil.getConversion(function, DataTypeManager.DefaultDataTypes.TIMESTAMP, DataTypeManager.getDataTypeName(type), false);
+				function = ResolverUtil.getConversion(function, DataTypeManager.DefaultDataTypes.TIMESTAMP, DataTypeManager.getDataTypeName(type), false, funcLibrary);
 				break;
 			}
 			case 8:
 			case 9: {
 				FunctionDescriptor descriptor = 
-		        	FunctionLibraryManager.getFunctionLibrary().findFunction(SourceSystemFunctions.FORMATTIMESTAMP, new Class[] { DataTypeManager.DefaultDataClasses.TIMESTAMP, DataTypeManager.DefaultDataClasses.STRING });
+					funcLibrary.findFunction(SourceSystemFunctions.FORMATTIMESTAMP, new Class[] { DataTypeManager.DefaultDataClasses.TIMESTAMP, DataTypeManager.DefaultDataClasses.STRING });
 				function.setName(SourceSystemFunctions.FORMATTIMESTAMP);
 				function.setFunctionDescriptor(descriptor);
-				function.getArgs()[0] = ResolverUtil.getConversion(function.getArg(0), DataTypeManager.getDataTypeName(function.getArg(0).getType()), DataTypeManager.DefaultDataTypes.TIMESTAMP, false);
+				function.getArgs()[0] = ResolverUtil.getConversion(function.getArg(0), DataTypeManager.getDataTypeName(function.getArg(0).getType()), DataTypeManager.DefaultDataTypes.TIMESTAMP, false, funcLibrary);
 				break;
 			}
 			}
@@ -2381,7 +2374,7 @@
         for (SingleElementSymbol ses : actualSymbols) {
             actualTypes.add(ses.getType());
         }
-        List<SingleElementSymbol> selectSymbols = SetQuery.getTypedProjectedSymbols(ResolverUtil.resolveElementsInGroup(inlineGroup, tma), actualTypes);
+        List<SingleElementSymbol> selectSymbols = SetQuery.getTypedProjectedSymbols(ResolverUtil.resolveElementsInGroup(inlineGroup, tma), actualTypes, tma);
         Iterator<SingleElementSymbol> iter = actualSymbols.iterator();
         for (SingleElementSymbol ses : selectSymbols) {
         	ses = (SingleElementSymbol)ses.clone();

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/sql/lang/SetQuery.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -62,6 +62,7 @@
     private QueryCommand rightQuery;
     
     private List<Class<?>> projectedTypes = null;  //set during resolving
+    private QueryMetadataInterface metadata = null; // set during resolving
      
     /**
      * Construct query with operation type
@@ -123,12 +124,12 @@
 	    Query query = getProjectedQuery();
 	    List projectedSymbols = query.getProjectedSymbols();
         if (projectedTypes != null) {
-            return getTypedProjectedSymbols(projectedSymbols, projectedTypes);
+            return getTypedProjectedSymbols(projectedSymbols, projectedTypes, metadata);
         } 
         return projectedSymbols;
     }
     
-    public static List getTypedProjectedSymbols(List acutal, List projectedTypes) {
+    public static List getTypedProjectedSymbols(List acutal, List projectedTypes, QueryMetadataInterface metadata) {
         List newProject = new ArrayList();
         for (int i = 0; i < acutal.size(); i++) {
             SingleElementSymbol originalSymbol = (SingleElementSymbol)acutal.get(i);
@@ -145,7 +146,7 @@
                 } 
                 
                 try {
-                    symbol = new ExpressionSymbol(originalSymbol.getShortName(), ResolverUtil.convertExpression(expr, DataTypeManager.getDataTypeName(type)));
+                    symbol = new ExpressionSymbol(originalSymbol.getShortName(), ResolverUtil.convertExpression(expr, DataTypeManager.getDataTypeName(type), metadata));
                 } catch (QueryResolverException err) {
                     throw new MetaMatrixRuntimeException(err);
                 }
@@ -252,8 +253,9 @@
     /** 
      * @param projectedSymbols The projectedSymbols to set.
      */
-    public void setProjectedTypes(List<Class<?>> projectedTypes) {
+    public void setProjectedTypes(List<Class<?>> projectedTypes, QueryMetadataInterface metadata) {
         this.projectedTypes = projectedTypes;
+        this.metadata = metadata;
     }
 
     /** 

Modified: branches/JCA/engine/src/main/java/com/metamatrix/query/util/CommandContext.java
===================================================================
--- branches/JCA/engine/src/main/java/com/metamatrix/query/util/CommandContext.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/com/metamatrix/query/util/CommandContext.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -36,6 +36,7 @@
 import com.metamatrix.query.QueryPlugin;
 import com.metamatrix.query.eval.SecurityFunctionEvaluator;
 import com.metamatrix.query.execution.QueryExecPlugin;
+import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.optimizer.relational.PlanToProcessConverter;
 import com.metamatrix.query.processor.QueryProcessor;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
@@ -96,6 +97,8 @@
 	    private long timeSliceEnd = Long.MAX_VALUE;
 	    
 	    private long timeoutEnd = Long.MAX_VALUE;
+	    
+	    private QueryMetadataInterface metadata; 
 	}
 	
 	private GlobalState globalState = new GlobalState();
@@ -425,5 +428,12 @@
 	public void setTimeoutEnd(long timeoutEnd) {
 		globalState.timeoutEnd = timeoutEnd;
 	}
+
+	public void setMetadata(QueryMetadataInterface metadata) {
+		globalState.metadata = metadata;
+	}
 	
+	public QueryMetadataInterface getMetadata() {
+		return globalState.metadata;
+	}
 }

Modified: branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java
===================================================================
--- branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/PreparedStatementRequest.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -42,6 +42,7 @@
 import com.metamatrix.dqp.util.LogConstants;
 import com.metamatrix.query.QueryPlugin;
 import com.metamatrix.query.eval.Evaluator;
+import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.optimizer.batch.BatchedUpdatePlanner;
 import com.metamatrix.query.optimizer.capabilities.SourceCapabilities;
 import com.metamatrix.query.processor.ProcessorPlan;
@@ -167,7 +168,7 @@
 	        List<Reference> params = prepPlan.getReferences();
 	        List<?> values = requestMsg.getParameterValues();
 	
-	    	PreparedStatementRequest.resolveParameterValues(params, values, this.context);
+	    	PreparedStatementRequest.resolveParameterValues(params, values, this.context, this.metadata);
         }
     }
 
@@ -206,7 +207,7 @@
 		List<VariableContext> contexts = new LinkedList<VariableContext>();
 		List<List<Object>> multiValues = new ArrayList<List<Object>>(this.prepPlan.getReferences().size());
 		for (List<?> values : paramValues) {
-	    	PreparedStatementRequest.resolveParameterValues(this.prepPlan.getReferences(), values, this.context);
+	    	PreparedStatementRequest.resolveParameterValues(this.prepPlan.getReferences(), values, this.context, this.metadata);
 			contexts.add(this.context.getVariableContext());
 			if(supportPreparedBatchUpdate){
 				if (multiValues.isEmpty()) {
@@ -257,7 +258,7 @@
 	 * @throws QueryValidatorException 
 	 */
 	public static void resolveParameterValues(List<Reference> params,
-	                                    List values, CommandContext context) throws QueryResolverException, MetaMatrixComponentException, QueryValidatorException {
+	                                    List values, CommandContext context, QueryMetadataInterface metadata) throws QueryResolverException, MetaMatrixComponentException, QueryValidatorException {
 		VariableContext result = new VariableContext();
 	    //the size of the values must be the same as that of the parameters
 	    if (params.size() != values.size()) {
@@ -275,7 +276,7 @@
         	if(value != null && !(value instanceof List)) {
                 try {
                     String targetTypeName = DataTypeManager.getDataTypeName(param.getType());
-                    Expression expr = ResolverUtil.convertExpression(new Constant(value), targetTypeName);
+                    Expression expr = ResolverUtil.convertExpression(new Constant(value), targetTypeName, metadata);
                     value = Evaluator.evaluate(expr);
 				} catch (ExpressionEvaluationException e) {
                     String msg = QueryPlugin.Util.getString("QueryUtil.Error_executing_conversion_function_to_convert_value", new Integer(i + 1), value, DataTypeManager.getDataTypeName(param.getType())); //$NON-NLS-1$

Modified: branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
===================================================================
--- branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -253,6 +253,7 @@
         context.setSecurityFunctionEvaluator(this.authService);
         context.setTempTableStore(tempTableStore);
         context.setQueryProcessorFactory(this);
+        context.setMetadata(this.metadata);
     }
 
     protected void checkReferences(List<Reference> references) throws QueryValidatorException {

Modified: branches/JCA/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java
===================================================================
--- branches/JCA/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -66,6 +66,11 @@
 import com.metamatrix.core.util.StringUtil;
 import com.metamatrix.dqp.DQPPlugin;
 import com.metamatrix.query.QueryPlugin;
+import com.metamatrix.query.function.FunctionLibrary;
+import com.metamatrix.query.function.FunctionTree;
+import com.metamatrix.query.function.SystemFunctionManager;
+import com.metamatrix.query.function.UDFSource;
+import com.metamatrix.query.function.metadata.FunctionMethod;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.mapping.xml.MappingDocument;
 import com.metamatrix.query.mapping.xml.MappingLoader;
@@ -96,6 +101,7 @@
     private String vdbName;
     private int vdbVersion;
     private Map<VirtualFile, Visibility> vdbEntries;
+    private FunctionLibrary functionLibrary;
     
     /*
      * TODO: move caching to jboss cache structure
@@ -108,12 +114,16 @@
      * TransformationMetadata constructor
      * @param context Object containing the info needed to lookup metadta.
      */
-    public TransformationMetadata(String vdbName, int version, final CompositeMetadataStore store, Map<VirtualFile, Visibility> vdbEntries) {
+    public TransformationMetadata(String vdbName, int version, final CompositeMetadataStore store, Map<VirtualFile, Visibility> vdbEntries, Collection <FunctionMethod> udfMethods) {
     	ArgCheck.isNotNull(store);
         this.store = store;
         this.vdbName = vdbName;
         this.vdbVersion = version;
         this.vdbEntries = vdbEntries;
+        if (udfMethods == null) {
+        	udfMethods = Collections.EMPTY_LIST;
+        }
+        this.functionLibrary = new FunctionLibrary(SystemFunctionManager.getSystemFunctions(), new FunctionTree(new UDFSource(udfMethods)));
     }
     
     //==================================================================================
@@ -1084,4 +1094,8 @@
 		return record.getUUID() + "/" + key; //$NON-NLS-1$
 	}
 
+	@Override
+	public FunctionLibrary getFunctionLibrary() {
+		return this.functionLibrary;
+	}
 }
\ No newline at end of file

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,7 +22,12 @@
 
 package com.metamatrix.query.function;
 
-import static org.junit.Assert.*;
+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 java.math.BigDecimal;
 import java.math.BigInteger;
@@ -30,6 +35,7 @@
 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;
@@ -40,7 +46,6 @@
 import org.teiid.connector.api.SourceSystemFunctions;
 
 import com.metamatrix.api.exception.query.FunctionExecutionException;
-import com.metamatrix.api.exception.query.InvalidFunctionException;
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.common.util.TimestampWithTimezone;
 import com.metamatrix.query.function.metadata.FunctionMethod;
@@ -63,7 +68,7 @@
 	private static final Class T_DATE = DataTypeManager.DefaultDataClasses.DATE;
 	private static final Class T_TIMESTAMP = DataTypeManager.DefaultDataClasses.TIMESTAMP;
 	
-	private FunctionLibrary library = FunctionLibraryManager.getFunctionLibrary();
+	private FunctionLibrary library = new FunctionLibrary(SystemFunctionManager.getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
 
 	@Before public void setUp() { 
 		TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$ 
@@ -180,7 +185,7 @@
         } 
 	}
     
-    private void helpInvokeMethod(String fname, Class[] types, Object[] inputs, CommandContext context , Object expectedOutput) throws InvalidFunctionException, FunctionExecutionException {
+    private void helpInvokeMethod(String fname, Class[] types, Object[] inputs, CommandContext context , Object expectedOutput) throws FunctionExecutionException {
         Object actualOutput = null;
         // Find function descriptor
         FunctionDescriptor descriptor = library.findFunction(fname, types);         
@@ -191,11 +196,11 @@
             for (int i = 0; i < inputs.length; i++) {
                 in[i+1] = inputs[i];
             }
-            actualOutput = library.invokeFunction(descriptor, in);
+            actualOutput = descriptor.invokeFunction(in);
         }
         else {
             // Invoke function with inputs
-            actualOutput = library.invokeFunction(descriptor, inputs);                
+            actualOutput = descriptor.invokeFunction(inputs);                
         }
         assertEquals("Actual function output not equal to expected: ", expectedOutput, actualOutput); //$NON-NLS-1$
     }
@@ -218,11 +223,11 @@
                 for (int i = 0; i < inputs.length; i++) {
                     in[i+1] = inputs[i];
                 }
-                actualOutput = library.invokeFunction(descriptor, in);
+                actualOutput = descriptor.invokeFunction(in);
             }
             else {
                 // Invoke function with inputs
-                actualOutput = library.invokeFunction(descriptor, inputs);                
+                actualOutput = descriptor.invokeFunction(inputs);                
             }	  
 		    
 		} catch(Throwable e) { 
@@ -244,11 +249,11 @@
                 for (int i = 0; i < inputs.length; i++) {
                     in[i+1] = inputs[i];
                 }
-                actualOutput = library.invokeFunction(descriptor, in);
+                actualOutput = descriptor.invokeFunction(in);
             }
             else {
                 // Invoke function with inputs
-                actualOutput = library.invokeFunction(descriptor, inputs);                
+                actualOutput = descriptor.invokeFunction(inputs);                
             }     
             
         } catch(Throwable e) { 
@@ -494,15 +499,13 @@
 
     // Walk through all functions by metadata 
     @Test public void testEnumerateForms() {
-        FunctionLibrary lib = FunctionLibraryManager.getFunctionLibrary();
-        
-        Collection categories = lib.getFunctionCategories();
+        Collection categories = library.getFunctionCategories();
         Iterator catIter = categories.iterator();
         while(catIter.hasNext()) { 
             String category = (String) catIter.next();
             //System.out.println("Category: " + category);
             
-            Collection functions = lib.getFunctionForms(category);
+            Collection functions = library.getFunctionForms(category);
             Iterator functionIter = functions.iterator();
             while(functionIter.hasNext()) { 
                 FunctionForm form = (FunctionForm) functionIter.next();

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionTree.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionTree.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestFunctionTree.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,8 +22,6 @@
 
 package com.metamatrix.query.function;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -99,13 +97,9 @@
     	 	public Class getInvocationClass(String className) throws ClassNotFoundException { 
     	 	    throw new ClassNotFoundException("Could not find class " + className); //$NON-NLS-1$
     	 	}
-    	 	
-    	 	public void loadFunctions(InputStream source) throws IOException{
-    	 	}
     	};	 
     	
-    	FunctionLibraryManager.registerSource(dummySource);
-    	FunctionLibraryManager.reloadSources();
+    	new FunctionLibrary(SystemFunctionManager.getSystemFunctions(), new FunctionTree(new UDFSource(dummySource.getFunctionMethods())));
     }
     
     public void testNullCategory() {

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestResolvedFunctions.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestResolvedFunctions.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/function/TestResolvedFunctions.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -34,6 +34,8 @@
 import com.metamatrix.query.parser.QueryParser;
 import com.metamatrix.query.resolver.util.ResolverVisitor;
 import com.metamatrix.query.sql.symbol.Expression;
+import com.metamatrix.query.unittest.FakeMetadataFacade;
+import com.metamatrix.query.unittest.FakeMetadataFactory;
 
 public class TestResolvedFunctions extends TestCase {
 
@@ -88,7 +90,7 @@
                                               BlockedException,
                                               MetaMatrixComponentException, QueryResolverException {
         Expression expr = QueryParser.getQueryParser().parseExpression(sql);
-        ResolverVisitor.resolveLanguageObject(expr, null);
+        ResolverVisitor.resolveLanguageObject(expr, FakeMetadataFactory.example1());
         return Evaluator.evaluate(expr);
     }
     

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/FakeFunctionMetadataSource.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/FakeFunctionMetadataSource.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/FakeFunctionMetadataSource.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,13 +22,10 @@
 
 package com.metamatrix.query.optimizer;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
-import com.metamatrix.query.function.FunctionLibraryManager;
 import com.metamatrix.query.function.FunctionMetadataSource;
 import com.metamatrix.query.function.metadata.FunctionMethod;
 import com.metamatrix.query.function.metadata.FunctionParameter;
@@ -54,9 +51,6 @@
         return Class.forName(className); 
     }
     
- 	public void loadFunctions(InputStream source) throws IOException{
- 	}
-    
     // dummy function
     public static Object xyz() {
         return null;
@@ -67,9 +61,4 @@
         String string = (String)astring;
         return string.trim();
     }
-    
-    public static void setupFunctionLibrary() {
-        FunctionLibraryManager.registerSource(new FakeFunctionMetadataSource());        
-    }
-    
 }

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -43,6 +43,10 @@
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.core.MetaMatrixRuntimeException;
 import com.metamatrix.query.analysis.AnalysisRecord;
+import com.metamatrix.query.function.FunctionLibrary;
+import com.metamatrix.query.function.FunctionTree;
+import com.metamatrix.query.function.SystemFunctionManager;
+import com.metamatrix.query.function.UDFSource;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -4359,7 +4363,6 @@
     }
 
     @Test public void testPushdownFunctionNotEvaluated() {
-        FakeFunctionMetadataSource.setupFunctionLibrary();
         
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
         BasicSourceCapabilities caps = new BasicSourceCapabilities();
@@ -4369,7 +4372,9 @@
         caps.setFunctionSupport("xyz", true);         //$NON-NLS-1$
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
 
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
+        FunctionLibrary funcLibrary = new FunctionLibrary(SystemFunctionManager.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
+        
          
         ProcessorPlan plan = helpPlan(
             "SELECT e1 FROM pm1.g1 WHERE xyz() > 0",  //$NON-NLS-1$

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCalculateCostUtil.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCalculateCostUtil.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestCalculateCostUtil.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -59,7 +59,7 @@
 
         Criteria result = QueryParser.getQueryParser().parseCriteria(critString);
         QueryResolver.resolveCriteria(result, metadata);
-        result = QueryRewriter.rewriteCriteria(result, null, new CommandContext(), null);
+        result = QueryRewriter.rewriteCriteria(result, null, new CommandContext(), metadata);
 
         return result;
     }

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestGroupRecontext.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestGroupRecontext.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestGroupRecontext.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -119,7 +119,7 @@
         SubqueryCompareCriteria crit = new SubqueryCompareCriteria(e1, query, SubqueryCompareCriteria.EQ, SubqueryCompareCriteria.ALL);
         SubqueryCompareCriteria expected = new SubqueryCompareCriteria(x1, query, SubqueryCompareCriteria.EQ, SubqueryCompareCriteria.ALL);
 
-        FrameUtil.convertCriteria(crit, symbolMap);  
+        FrameUtil.convertCriteria(crit, symbolMap, null);  
         
         assertEquals(crit, expected);
     }

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/TestProcessor.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/TestProcessor.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/TestProcessor.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -57,6 +57,10 @@
 import com.metamatrix.core.MetaMatrixRuntimeException;
 import com.metamatrix.dqp.message.ParameterInfo;
 import com.metamatrix.query.analysis.AnalysisRecord;
+import com.metamatrix.query.function.FunctionLibrary;
+import com.metamatrix.query.function.FunctionTree;
+import com.metamatrix.query.function.SystemFunctionManager;
+import com.metamatrix.query.function.UDFSource;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.optimizer.FakeFunctionMetadataSource;
@@ -131,14 +135,14 @@
     static ProcessorPlan helpGetPlan(Command command, QueryMetadataInterface metadata) {
         return helpGetPlan(command, metadata, new DefaultCapabilitiesFinder());
     }
-
+    
 	static ProcessorPlan helpGetPlan(Command command, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) {
         CommandContext context = new CommandContext();
         context.setProcessorBatchSize(2000);
         context.setConnectorBatchSize(2000);
 	    return helpGetPlan(command, metadata, capFinder, context);
     }
-    
+	
     static ProcessorPlan helpGetPlan(Command command, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, CommandContext context) {
 		if(DEBUG) System.out.println("\n####################################\n" + command); //$NON-NLS-1$
 		AnalysisRecord analysisRecord = new AnalysisRecord(false, false, DEBUG);
@@ -1198,6 +1202,7 @@
         CommandContext context = createCommandContext();
         context.setProcessorBatchSize(2);
         context.setConnectorBatchSize(2);
+        context.setMetadata(FakeMetadataFactory.example1Cached());
         
         // Plan query
         ProcessorPlan plan = helpGetPlan(helpParse(sql), FakeMetadataFactory.example1Cached(), new DefaultCapabilitiesFinder(), context);
@@ -5200,7 +5205,9 @@
         g2.putProperty(FakeMetadataObject.Props.CARDINALITY, new Integer(RuleChooseDependent.DEFAULT_INDEPENDENT_CARDINALITY - 1));
         
         Command command = helpParse(sql);   
-        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder);
+        CommandContext context = createCommandContext();
+        context.setMetadata(metadata);
+        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder,context);
         
         //Verify a dependent join (not merge join) was used
         assertTrue(plan instanceof RelationalPlan);
@@ -5210,7 +5217,7 @@
         assertTrue("Expected instance of JoinNode (for dep join) but got " + join.getClass(), join instanceof JoinNode); //$NON-NLS-1$
 
         // Run query
-        helpProcess(plan, dataManager, expected);        
+        helpProcess(plan, context, dataManager, expected);        
     }     
 
     /** RLM Case 2077 */
@@ -5244,7 +5251,9 @@
         g2.putProperty(FakeMetadataObject.Props.CARDINALITY, new Integer(RuleChooseDependent.DEFAULT_INDEPENDENT_CARDINALITY - 1));
         
         Command command = helpParse(sql);   
-        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder);
+        CommandContext context = createCommandContext();
+        context.setMetadata(metadata);
+        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder, context);
         
         //Verify a dependent join (not merge join) was used
         assertTrue(plan instanceof RelationalPlan);
@@ -5254,7 +5263,7 @@
         assertTrue("Expected instance of JoinNode (for dep join) but got " + join.getClass(), join instanceof JoinNode); //$NON-NLS-1$
 
         // Run query
-        helpProcess(plan, dataManager, expected);        
+        helpProcess(plan, context, dataManager, expected);        
     }      
     
     @Test public void testPushingCriteriaUnderJoinButNotToSource() {
@@ -5359,7 +5368,6 @@
     
     /** defect 15348*/
     @Test public void testPreparedStatementDefect15348(){
-        FakeFunctionMetadataSource.setupFunctionLibrary();
         String sql = "SELECT e1 from pm1.g1 where myrtrim(?)=e1"; //$NON-NLS-1$
 
         // Create expected results
@@ -5378,16 +5386,19 @@
         caps.setFunctionSupport("myrtrim", true); //$NON-NLS-1$
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
 
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
+        FunctionLibrary funcLibrary = new FunctionLibrary(SystemFunctionManager.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
         
+        
         Command command = helpParse(sql);   
-        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder);
+        CommandContext context = createCommandContext();
+        context.setMetadata(metadata);        
+        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder, context);
         
         // Collect reference, set value
         Reference ref = ReferenceCollectorVisitor.getReferences(command).iterator().next();
         VariableContext vc = new VariableContext();
         vc.setGlobalValue(ref.getContextSymbol(),  "a    "); //$NON-NLS-1$
-        CommandContext context = createCommandContext();
         context.setVariableContext(vc);
         // Run query
         helpProcess(plan, context, dataManager, expected);        
@@ -5396,8 +5407,6 @@
 
     /** defect 15348*/
     @Test public void testPreparedStatementDefect15348b(){
-        FakeFunctionMetadataSource.setupFunctionLibrary();  
-        
         String sql = "SELECT e1 from pm4.g1 where myrtrim(concat(?, 'a  '))=e1"; //$NON-NLS-1$
 
         // Create expected results
@@ -5417,16 +5426,19 @@
         caps.setFunctionSupport("concat", true); //$NON-NLS-1$
         capFinder.addCapabilities("pm4", caps); //$NON-NLS-1$
 
-        FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
+        FunctionLibrary funcLibrary = new FunctionLibrary(SystemFunctionManager.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
         
+        
         Command command = helpParse(sql);   
-        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder);
+        CommandContext context = createCommandContext();
+        context.setMetadata(metadata);        
+        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder, context);
         
         // Collect reference, set value
         Reference ref = ReferenceCollectorVisitor.getReferences(command).iterator().next();
         VariableContext vc = new VariableContext();
         vc.setGlobalValue(ref.getContextSymbol(), "a"); //$NON-NLS-1$
-        CommandContext context = createCommandContext();
         context.setVariableContext(vc);
         
         // Run query
@@ -6842,8 +6854,11 @@
 
         // Plan query
         String sql = "SELECT e1 FROM pm1.g2 WHERE LOOKUP('pm1.g1','e1', 'e2', 1) = e1";//$NON-NLS-1$
+        QueryMetadataInterface metadata = FakeMetadataFactory.example1Cached();
         Command command = TestProcessor.helpParse(sql);   
-        ProcessorPlan plan = helpGetPlan(command, FakeMetadataFactory.example1Cached(), capFinder);
+        CommandContext context = createCommandContext();
+        context.setMetadata(metadata);
+        ProcessorPlan plan = helpGetPlan(command, metadata, capFinder, context);
         
         // Run query
         List[] expected = new List[] {
@@ -6857,7 +6872,7 @@
         dataManager.defineCodeTable("pm1.g1", "e2", "e1", valueMap); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         dataManager.setThrowBlocked(true);
         
-        helpProcess(plan, dataManager, expected);
+        helpProcess(plan, context, dataManager, expected);
     } 
     
     @Test public void testRaiseNullWithSelectInto() {

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/eval/TestExpressionEvaluator.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -39,7 +39,7 @@
 import com.metamatrix.common.buffer.BlockedException;
 import com.metamatrix.query.eval.Evaluator;
 import com.metamatrix.query.function.FunctionDescriptor;
-import com.metamatrix.query.function.FunctionLibraryManager;
+import com.metamatrix.query.function.SystemFunctionManager;
 import com.metamatrix.query.processor.FakeDataManager;
 import com.metamatrix.query.processor.ProcessorDataManager;
 import com.metamatrix.query.sql.lang.CollectionValueIterator;
@@ -198,7 +198,7 @@
         e2.setType(String.class);
         
         Function func = new Function("concat", new Expression[] { e1, e2 }); //$NON-NLS-1$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("concat", new Class[] { String.class, String.class } ); //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("concat", new Class[] { String.class, String.class } ); //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
 
         SingleElementSymbol[] elements = new SingleElementSymbol[] {
@@ -220,7 +220,7 @@
         e2.setType(String.class);
         
         Function func = new Function("concat", new Expression[] { e2, e1 }); //$NON-NLS-1$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("concat", new Class[] { String.class, String.class } ); //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("concat", new Class[] { String.class, String.class } ); //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
 
         SingleElementSymbol[] elements = new SingleElementSymbol[] {
@@ -241,7 +241,7 @@
         e1.setType(Integer.class);        
         
         Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), e1 }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, String.class } ); //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, String.class } ); //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
 
         SingleElementSymbol[] elements = new SingleElementSymbol[] {
@@ -313,7 +313,7 @@
 
     public void testUser() throws Exception {
         Function func = new Function("user", new Expression[] {}); //$NON-NLS-1$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("user", new Class[] {} );         //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("user", new Class[] {} );         //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
 
         FakeDataManager dataMgr = new FakeDataManager();
@@ -330,7 +330,7 @@
      */
     public void testEnv() throws Exception {
         Function func = new Function("env", new Expression[] {}); //$NON-NLS-1$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("env", new Class[] {String.class} );         //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("env", new Class[] {String.class} );         //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
         
         FakeDataManager dataMgr = new FakeDataManager();
@@ -356,7 +356,7 @@
         } else {
             parameterSignature = new Class[] { String.class };
         }        
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("commandpayload", parameterSignature );         //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("commandpayload", parameterSignature );         //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
         
         FakeDataManager dataMgr = new FakeDataManager();       

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/proc/TestProcedureProcessor.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/proc/TestProcedureProcessor.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/proc/TestProcedureProcessor.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -111,13 +111,11 @@
         }
     }
     
-    static void helpTestProcess(ProcessorPlan procPlan, int rowsUpdated, List[] expectedResults, boolean shouldFail, ProcessorDataManager dataMgr) throws SQLException, MetaMatrixCoreException {
+    static void helpTestProcess(ProcessorPlan procPlan, int rowsUpdated, List[] expectedResults, boolean shouldFail, ProcessorDataManager dataMgr, CommandContext context) throws SQLException, MetaMatrixCoreException {
         // Process twice, testing reset and clone method of Processor plan
         for (int i=1; i<=2; i++) {
 	        BufferManager bufferMgr = BufferManagerFactory.getStandaloneBufferManager();
-            CommandContext context = new CommandContext("pID", null, null, null, 1); //$NON-NLS-1$
-            context.getNextRand(0);
-            context.setProcessDebug(DEBUG);
+
             QueryProcessor processor = new QueryProcessor(procPlan, context, bufferMgr, dataMgr);
             processor.setNonBlocking(true);
             BatchCollector collector = processor.createBatchCollector();  
@@ -193,12 +191,18 @@
     }
     
     private void helpTestProcess(ProcessorPlan procPlan, int expectedRows, FakeDataManager dataMgr) throws SQLException, MetaMatrixCoreException {
-        helpTestProcess(procPlan, expectedRows, null, false, dataMgr);
+        CommandContext context = new CommandContext("pID", null, null, null, 1); //$NON-NLS-1$
+        context.getNextRand(0);
+        context.setProcessDebug(DEBUG);
+        helpTestProcess(procPlan, expectedRows, null, false, dataMgr, context);
     }
     
     static void helpTestProcess(boolean optimistic, ProcessorPlan procPlan, List[] expectedResults, 
     		ProcessorDataManager dataMgr, boolean shouldFail) throws SQLException, MetaMatrixCoreException {
-        helpTestProcess(procPlan, 0, expectedResults, shouldFail, dataMgr);
+        CommandContext context = new CommandContext("pID", null, null, null, 1); //$NON-NLS-1$
+        context.getNextRand(0);
+        context.setProcessDebug(DEBUG);
+        helpTestProcess(procPlan, 0, expectedResults, shouldFail, dataMgr, context);
     }
 
     // Helper to create a list of elements - used in creating sample data
@@ -2258,9 +2262,14 @@
 
         ProcessorPlan plan = getProcedurePlan(userUpdateStr, metadata);
         
-        helpTestProcess(plan, new List[] {
+        CommandContext context = new CommandContext("pID", null, null, null, 1); //$NON-NLS-1$
+        context.getNextRand(0);
+        context.setProcessDebug(DEBUG);
+        context.setMetadata(metadata);
+        
+        helpTestProcess(plan, 0, new List[] {
             Arrays.asList(new Object[] {new Integer(240)}),
-            Arrays.asList(new Object[] {new Integer(637)})}, dataMgr);
+            Arrays.asList(new Object[] {new Integer(637)})}, false, dataMgr, context);
     }
 
     private FakeMetadataFacade createProcedureMetadata(String procedure) {

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestBatchedUpdateNode.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestBatchedUpdateNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestBatchedUpdateNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -61,6 +61,7 @@
         BatchedUpdateNode node = new BatchedUpdateNode(1, commands, Collections.EMPTY_LIST, shouldEvaluate, "myModelName"); //$NON-NLS-1$
         CommandContext context = new CommandContext();
         context.setProcessorID("myProcessorID"); //$NON-NLS-1$
+        context.setMetadata(md);
         node.initialize(context, Mockito.mock(BufferManager.class), pdm); 
         return node;
     }

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestGroupingNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -41,7 +41,7 @@
 import com.metamatrix.common.buffer.impl.BufferManagerImpl;
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.function.FunctionDescriptor;
-import com.metamatrix.query.function.FunctionLibraryManager;
+import com.metamatrix.query.function.SystemFunctionManager;
 import com.metamatrix.query.function.aggregate.AggregateFunction;
 import com.metamatrix.query.function.aggregate.NullFilter;
 import com.metamatrix.query.processor.FakeDataManager;
@@ -320,7 +320,7 @@
         col2.setType(Integer.class);
         
         Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), col2 }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class } ); //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class } ); //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
         func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
         

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestJoinNode.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestJoinNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestJoinNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,7 +22,7 @@
 
 package com.metamatrix.query.processor.relational;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -40,7 +40,7 @@
 import com.metamatrix.common.buffer.TupleBatch;
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.function.FunctionDescriptor;
-import com.metamatrix.query.function.FunctionLibraryManager;
+import com.metamatrix.query.function.SystemFunctionManager;
 import com.metamatrix.query.processor.FakeDataManager;
 import com.metamatrix.query.processor.relational.MergeJoinStrategy.SortOption;
 import com.metamatrix.query.sql.lang.CompareCriteria;
@@ -203,7 +203,7 @@
 
             case FUNCTION_CRITERIA :
                 Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), es1 }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-                FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class }); //$NON-NLS-1$
+                FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class }); //$NON-NLS-1$
                 func.setFunctionDescriptor(desc);
                 func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
                 CompareCriteria joinCriteria = new CompareCriteria(es2, CompareCriteria.EQ, func);

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestProjectNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -39,7 +39,7 @@
 import com.metamatrix.common.buffer.TupleBatch;
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.function.FunctionDescriptor;
-import com.metamatrix.query.function.FunctionLibraryManager;
+import com.metamatrix.query.function.SystemFunctionManager;
 import com.metamatrix.query.processor.FakeDataManager;
 import com.metamatrix.query.processor.ProcessorDataManager;
 import com.metamatrix.query.sql.symbol.Constant;
@@ -211,7 +211,7 @@
         elements.add(es1);
         
         Function func = new Function("concat", new Expression[] { es1, new Constant("abc")}); //$NON-NLS-1$ //$NON-NLS-2$
-        FunctionDescriptor fd = FunctionLibraryManager.getFunctionLibrary().findFunction("concat", new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING }); //$NON-NLS-1$
+        FunctionDescriptor fd = SystemFunctionManager.getSystemFunctionLibrary().findFunction("concat", new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING }); //$NON-NLS-1$
         func.setFunctionDescriptor(fd);
         func.setType(DataTypeManager.DefaultDataClasses.STRING);
         ExpressionSymbol expr = new ExpressionSymbol("expr", func); //$NON-NLS-1$
@@ -235,7 +235,7 @@
         elements.add(es1);
         
         Function func = new Function("convert", new Expression[] { es1, new Constant("integer")}); //$NON-NLS-1$ //$NON-NLS-2$
-        FunctionDescriptor fd = FunctionLibraryManager.getFunctionLibrary().findFunction("convert", new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING }); //$NON-NLS-1$
+        FunctionDescriptor fd = SystemFunctionManager.getSystemFunctionLibrary().findFunction("convert", new Class[] { DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING }); //$NON-NLS-1$
         func.setFunctionDescriptor(fd);
         func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
         ExpressionSymbol expr = new ExpressionSymbol("expr", func); //$NON-NLS-1$
@@ -258,7 +258,7 @@
         elements.add(es1);
 
         Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), es1 }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, String.class } ); //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, String.class } ); //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
         func.setType(DataTypeManager.DefaultDataClasses.STRING);
         

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestSelectNode.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestSelectNode.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/processor/relational/TestSelectNode.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -38,7 +38,7 @@
 import com.metamatrix.common.buffer.TupleBatch;
 import com.metamatrix.common.types.DataTypeManager;
 import com.metamatrix.query.function.FunctionDescriptor;
-import com.metamatrix.query.function.FunctionLibraryManager;
+import com.metamatrix.query.function.SystemFunctionManager;
 import com.metamatrix.query.processor.BatchIterator;
 import com.metamatrix.query.processor.FakeDataManager;
 import com.metamatrix.query.processor.ProcessorDataManager;
@@ -203,7 +203,7 @@
         elements.add(es1);
 
         Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), es1 }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        FunctionDescriptor desc = FunctionLibraryManager.getFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class } ); //$NON-NLS-1$
+        FunctionDescriptor desc = SystemFunctionManager.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class } ); //$NON-NLS-1$
         func.setFunctionDescriptor(desc);
         func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
         CompareCriteria crit = new CompareCriteria(func, CompareCriteria.EQ, new Constant(new Integer(1))); 

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/resolver/TestResolver.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -22,7 +22,13 @@
 
 package com.metamatrix.query.resolver;
 
-import static org.junit.Assert.*;
+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 java.math.BigDecimal;
 import java.math.BigInteger;
@@ -49,7 +55,7 @@
 import com.metamatrix.query.analysis.AnalysisRecord;
 import com.metamatrix.query.function.FunctionDescriptor;
 import com.metamatrix.query.function.FunctionLibrary;
-import com.metamatrix.query.function.FunctionLibraryManager;
+import com.metamatrix.query.function.SystemFunctionManager;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 import com.metamatrix.query.metadata.TempMetadataAdapter;
@@ -1396,7 +1402,7 @@
         String tgtTypeName = DataTypeManager.DefaultDataTypes.DATE;
         Expression expression = new Constant("2003-02-27"); //$NON-NLS-1$
         
-		FunctionLibrary library = FunctionLibraryManager.getFunctionLibrary();                          
+		FunctionLibrary library = SystemFunctionManager.getSystemFunctionLibrary();                         
 		FunctionDescriptor fd = library.findFunction(FunctionLibrary.CONVERT, new Class[] { srcType, DataTypeManager.DefaultDataClasses.STRING });
 
 		Function conversion = new Function(fd.getName(), new Expression[] { expression, new Constant(tgtTypeName) });
@@ -1432,7 +1438,7 @@
 		String tgtTypeName = DataTypeManager.DefaultDataTypes.DATE;
 		Expression expression = new Constant("2003-02-27"); //$NON-NLS-1$
         
-		FunctionLibrary library = FunctionLibraryManager.getFunctionLibrary();                          
+		FunctionLibrary library = SystemFunctionManager.getSystemFunctionLibrary();                        
 		FunctionDescriptor fd = library.findFunction(FunctionLibrary.CONVERT, new Class[] { srcType, DataTypeManager.DefaultDataClasses.STRING });
 
 		Function conversion = new Function(fd.getName(), new Expression[] { expression, new Constant(tgtTypeName) });
@@ -1882,7 +1888,7 @@
         //String sql = "select intkey from SmallA where user() = 'bqt2'";
 
         // Expected left expression
-        FunctionLibrary library = FunctionLibraryManager.getFunctionLibrary();                          
+        FunctionLibrary library = SystemFunctionManager.getSystemFunctionLibrary();                          
         FunctionDescriptor fd = library.findFunction(FunctionLibrary.USER, new Class[] { });
         Function user = new Function(fd.getName(), new Expression[] {});
         user.setFunctionDescriptor(fd);

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/rewriter/TestQueryRewriter.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -118,7 +118,7 @@
         Criteria actual = null;
         // rewrite
         try { 
-            actual = QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            actual = QueryRewriter.rewriteCriteria(origCrit, null, null, metadata);
             assertEquals("Did not rewrite correctly: ", expectedCrit, actual); //$NON-NLS-1$
         } catch(QueryValidatorException e) { 
         	throw new RuntimeException(e);
@@ -1491,11 +1491,12 @@
         QueryParser parser = new QueryParser();
         Command command = parser.parseCommand("exec pm1.sp4(5)");             //$NON-NLS-1$
         
-        // resolve
-        QueryResolver.resolveCommand(command, FakeMetadataFactory.example1Cached());
+        // resolve
+        QueryMetadataInterface metadata = FakeMetadataFactory.example1Cached();
+        QueryResolver.resolveCommand(command, metadata);
         
         // rewrite
-        Command rewriteCommand = QueryRewriter.rewrite(command, null, null);
+        Command rewriteCommand = QueryRewriter.rewrite(command, metadata, null);
         
         List<SPParameter> parameters = ((StoredProcedure)rewriteCommand).getParameters();
 
@@ -1512,7 +1513,7 @@
         
         // rewrite
         try { 
-            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            QueryRewriter.rewriteCriteria(origCrit, null, null, metadata);
             fail("Expected QueryValidatorException due to divide by 0"); //$NON-NLS-1$
         } catch(QueryValidatorException e) {
         	// looks like message is being wrapped with another exception with same message
@@ -1526,7 +1527,7 @@
         
         // rewrite
         try { 
-            QueryRewriter.rewriteCriteria(origCrit, null, null, null);
+            QueryRewriter.rewriteCriteria(origCrit, null, null, metadata);
             fail("Expected QueryValidatorException due to invalid string"); //$NON-NLS-1$
         } catch(QueryValidatorException e) {
             assertEquals("Error Code:ERR.015.009.0004 Message:Unable to convert 'x' of type [string] to the expected type [integer].", e.getMessage()); //$NON-NLS-1$
@@ -1735,7 +1736,7 @@
         Properties props = new Properties();
         props.setProperty(ContextProperties.SESSION_ID, "1"); //$NON-NLS-1$
         context.setEnvironmentProperties(props);
-        Command rewriteCommand = QueryRewriter.rewrite(command, null, context);
+        Command rewriteCommand = QueryRewriter.rewrite(command, FakeMetadataFactory.example1Cached(), context);
         
         assertEquals("EXEC pm1.sq2('1')", rewriteCommand.toString()); //$NON-NLS-1$
     }

Modified: branches/JCA/engine/src/test/java/com/metamatrix/query/unittest/FakeMetadataFacade.java
===================================================================
--- branches/JCA/engine/src/test/java/com/metamatrix/query/unittest/FakeMetadataFacade.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/com/metamatrix/query/unittest/FakeMetadataFacade.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -35,6 +35,8 @@
 import com.metamatrix.core.util.ArgCheck;
 import com.metamatrix.core.util.Assertion;
 import com.metamatrix.dqp.message.ParameterInfo;
+import com.metamatrix.query.function.FunctionLibrary;
+import com.metamatrix.query.function.SystemFunctionManager;
 import com.metamatrix.query.mapping.relational.QueryNode;
 import com.metamatrix.query.mapping.xml.MappingBaseNode;
 import com.metamatrix.query.mapping.xml.MappingDocument;
@@ -51,10 +53,17 @@
 public class FakeMetadataFacade extends BasicQueryMetadata {
 
 	private FakeMetadataStore store;
+	private FunctionLibrary functionLibrary;
 
 	public FakeMetadataFacade(FakeMetadataStore store) {
 		this.store = store;
+		this.functionLibrary = SystemFunctionManager.getSystemFunctionLibrary();
 	}
+	
+	public FakeMetadataFacade(FakeMetadataStore store, FunctionLibrary funcLibrary) {
+		this.store = store;
+		this.functionLibrary = funcLibrary;
+	}
 
 	public FakeMetadataStore getStore() {
 		return this.store;
@@ -759,4 +768,9 @@
         	return object.getProperty(key);
 		}
     }
+    
+    @Override
+    public FunctionLibrary getFunctionLibrary() {
+    	return this.functionLibrary;
+    }
 }

Modified: branches/JCA/engine/src/test/java/org/teiid/metadata/TestTransformationMetadata.java
===================================================================
--- branches/JCA/engine/src/test/java/org/teiid/metadata/TestTransformationMetadata.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/engine/src/test/java/org/teiid/metadata/TestTransformationMetadata.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -56,7 +56,7 @@
 		MetadataFactory mf1 = new MetadataFactory("x1", datatypes, new Properties()); //$NON-NLS-1$
 		mf1.addProcedure("y"); //$NON-NLS-1$
 		CompositeMetadataStore cms = new CompositeMetadataStore(Arrays.asList(mf.getMetadataStore(), mf1.getMetadataStore()));
-		TransformationMetadata tm = new TransformationMetadata("vdb", 1, cms, null);
+		TransformationMetadata tm = new TransformationMetadata("vdb", 1, cms, null, null);
 		
 		VDBMetaData vdb = new VDBMetaData();
 		vdb.setName("vdb");
@@ -93,7 +93,7 @@
 		MetadataSource ms = Mockito.mock(MetadataSource.class);
 		Mockito.stub(ms.getName()).toReturn("foo"); //$NON-NLS-1$
 		CompositeMetadataStore cms = new CompositeMetadataStore(Arrays.asList(mf.getMetadataStore(), mf1.getMetadataStore()));
-		TransformationMetadata tm = new TransformationMetadata("vdb", 1, cms, null);
+		TransformationMetadata tm = new TransformationMetadata("vdb", 1, cms, null, null);
 		Collection result = tm.getGroupsForPartialName("y"); //$NON-NLS-1$
 		assertEquals(2, result.size());
 		
@@ -113,7 +113,7 @@
 		
 		FakeMetadataFactory.buildWorkContext(tm, vdb);
 		
-		tm = new TransformationMetadata("vdb", 1, cms, null); //$NON-NLS-1$
+		tm = new TransformationMetadata("vdb", 1, cms, null, null); //$NON-NLS-1$
 		result = tm.getGroupsForPartialName("y"); //$NON-NLS-1$
 		assertEquals(1, result.size());
 		

Modified: branches/JCA/metadata/src/main/java/org/teiid/metadata/index/VDBMetadataFactory.java
===================================================================
--- branches/JCA/metadata/src/main/java/org/teiid/metadata/index/VDBMetadataFactory.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/metadata/src/main/java/org/teiid/metadata/index/VDBMetadataFactory.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -27,6 +27,8 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import org.jboss.virtual.VFS;
@@ -38,6 +40,8 @@
 
 import com.metamatrix.core.MetaMatrixRuntimeException;
 import com.metamatrix.core.util.LRUCache;
+import com.metamatrix.query.function.metadata.FunctionMetadataReader;
+import com.metamatrix.query.function.metadata.FunctionMethod;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 
 public class VDBMetadataFactory {
@@ -46,13 +50,13 @@
 	
 	public static QueryMetadataInterface getVDBMetadata(String vdbFile) {
 		try {
-			return getVDBMetadata(new File(vdbFile).toURI().toURL());
+			return getVDBMetadata(new File(vdbFile).toURI().toURL(), null);
 		} catch (IOException e) {
 			throw new MetaMatrixRuntimeException(e);
 		}
     }
 	
-	public static QueryMetadataInterface getVDBMetadata(URL vdbURL) throws IOException {
+	public static QueryMetadataInterface getVDBMetadata(URL vdbURL, URL udfFile) throws IOException {
 		QueryMetadataInterface vdbmetadata = VDB_CACHE.get(vdbURL);
 		if (vdbmetadata != null) {
 			return vdbmetadata;
@@ -75,7 +79,12 @@
 				imf.addIndexFile(f);
 			}
 			
-			vdbmetadata = new TransformationMetadata("foo", 1, new CompositeMetadataStore(Arrays.asList(imf.getMetadataStore())), null);
+			Collection <FunctionMethod> methods = Collections.EMPTY_LIST;
+			if (udfFile != null) {
+				methods = FunctionMetadataReader.loadFunctionMethods(udfFile.openStream());
+			}
+			
+			vdbmetadata = new TransformationMetadata("foo", 1, new CompositeMetadataStore(Arrays.asList(imf.getMetadataStore())), null, methods);
 			VDB_CACHE.put(vdbURL, vdbmetadata);
 			return vdbmetadata;
 		} catch (URISyntaxException e) {

Modified: branches/JCA/runtime/src/main/java/com/metamatrix/dqp/embedded/services/EmbeddedConfigurationService.java
===================================================================
--- branches/JCA/runtime/src/main/java/com/metamatrix/dqp/embedded/services/EmbeddedConfigurationService.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/runtime/src/main/java/com/metamatrix/dqp/embedded/services/EmbeddedConfigurationService.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -40,7 +40,6 @@
 import com.metamatrix.common.config.api.ConnectorBinding;
 import com.metamatrix.common.config.api.ConnectorBindingType;
 import com.metamatrix.common.config.model.BasicConnectorBinding;
-import com.metamatrix.common.log.LogManager;
 import com.metamatrix.common.protocol.URLHelper;
 import com.metamatrix.common.vdb.api.ModelInfo;
 import com.metamatrix.common.vdb.api.VDBArchive;
@@ -53,8 +52,6 @@
 import com.metamatrix.dqp.embedded.configuration.VDBConfigurationWriter;
 import com.metamatrix.dqp.service.ConnectorBindingLifeCycleListener;
 import com.metamatrix.dqp.service.VDBLifeCycleListener;
-import com.metamatrix.dqp.util.LogConstants;
-import com.metamatrix.query.function.FunctionLibraryManager;
 import com.metamatrix.query.function.UDFSource;
 import com.metamatrix.vdb.runtime.BasicModelInfo;
 import com.metamatrix.vdb.runtime.BasicVDBDefn;
@@ -575,27 +572,7 @@
         return false;
     }
     
-    /**
-     * Load the User defined functions file 
-     * @throws MetaMatrixComponentException
-     * @since 4.3
-     */
-    public void loadUDF() throws MetaMatrixComponentException {
-        URL udfFile = getUDFFile();
-        if(udfFile != null && exists(udfFile)) {
-            try {
-            	
-            	// un-register the old UDF model, if there is one.
-            	unloadUDF();
 
-        		this.udfSource = new UDFSource(udfFile.openStream(), Thread.currentThread().getContextClassLoader());
-				FunctionLibraryManager.registerSource(this.udfSource);
-				LogManager.logInfo(LogConstants.CTX_DQP, DQPEmbeddedPlugin.Util.getString("EmbeddedConfigurationService.udf_load", udfFile)); //$NON-NLS-1$
-			} catch (IOException e) {
-				LogManager.logError(LogConstants.CTX_DQP, e, e.getMessage());
-			}
-        }
-    }
     
     /**
      * Makes sure the URL is pointing to a valid resource
@@ -612,19 +589,6 @@
 		return false;
     }
     
-    /**
-     * Unload the UDF file at the end of the DQP, because the same JVM could be used
-     * to load another DQP and we do want the static function library hanging on to
-     * old function libraries   
-     */
-    public void unloadUDF() {
-        if (this.udfSource != null) {
-            FunctionLibraryManager.deregisterSource(this.udfSource);
-            this.udfSource = null;
-            DQPEmbeddedPlugin.logInfo("EmbeddedConfigurationService.udf_unload", new Object[] {}); //$NON-NLS-1$
-        }
-    }
-    
     /** 
      * @see com.metamatrix.dqp.embedded.services.EmbeddedBaseDQPService#initializeService(java.util.Properties)
      * @since 4.3
@@ -637,9 +601,6 @@
                         
             DQPEmbeddedPlugin.logInfo("EmbeddedConfigurationService.dqp_loading", new Object[] {getProcessName()}); //$NON-NLS-1$
             
-            // Load the User defined functions 
-            loadUDF();
-                        
             // Find all the VDB File in the configuration
             // Load them the available VDBs
             loadVDBs();
@@ -650,21 +611,6 @@
     }
 
 
-    /** 
-     * @see com.metamatrix.dqp.embedded.services.EmbeddedBaseDQPService#stopService()
-     * @since 4.3
-     */
-    public void stopService() {       
-    	for(VDBArchive vdb: loadedVDBs.values()) {
-    		vdb.close();
-    	}
-        loadedVDBs.clear();
-        loadedConnectorBindings.clear();                       
-        availableVDBFiles.clear();
-        unloadUDF();
-    }
-
-
 	/** 
      * Add the connector binding with new deployment name
      * @param binding

Added: branches/JCA/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
===================================================================
--- branches/JCA/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java	                        (rev 0)
+++ branches/JCA/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -0,0 +1,41 @@
+/*
+ * 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.deployers;
+
+import java.util.Collection;
+
+import org.jboss.managed.api.annotation.ManagementObject;
+
+import com.metamatrix.query.function.metadata.FunctionMethod;
+
+ at ManagementObject
+public class UDFMetaData {
+	private Collection <FunctionMethod> methods = null;
+	
+	public UDFMetaData(Collection <FunctionMethod> methods) {
+		this.methods = methods;
+	}
+	
+	public Collection <FunctionMethod> getMethods(){
+		return this.methods;
+	}
+}

Modified: branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java
===================================================================
--- branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBDeployer.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -21,6 +21,7 @@
  */
 package org.teiid.deployers;
 
+import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
@@ -44,6 +45,7 @@
 
 import com.metamatrix.core.CoreConstants;
 import com.metamatrix.dqp.embedded.DQPEmbeddedPlugin;
+import com.metamatrix.query.function.metadata.FunctionMethod;
 import com.metamatrix.query.metadata.QueryMetadataInterface;
 
 public class VDBDeployer extends AbstractSimpleRealDeployer<VDBMetaData> implements ManagedObjectCreator {
@@ -75,15 +77,16 @@
 		
 		// check if this is a VDB with index files, if there are then build the TransformationMetadata
 		IndexMetadataFactory indexFactory = unit.getAttachment(IndexMetadataFactory.class);
+		UDFMetaData udf = unit.removeAttachment(UDFMetaData.class);
 		if (indexFactory != null) {
 			Map<VirtualFile, Visibility> visibilityMap = indexFactory.getEntriesPlusVisibilities();
-			metadata = buildTransformationMetaData(deployment, visibilityMap, store);
+			metadata = buildTransformationMetaData(deployment, visibilityMap, store, udf);
 		}
 		else {
 			// this dynamic VDB
-			metadata = buildTransformationMetaData(deployment, null, store);
+			metadata = buildTransformationMetaData(deployment, null, store, udf);
 		}
-		
+				
 		// add the metadata objects as attachments
 		deployment.removeAttachment(IndexMetadataFactory.class);
 		deployment.addAttchment(QueryMetadataInterface.class, metadata);
@@ -116,7 +119,7 @@
     }	
 
 	// does this need to be synchronized? 
-	private TransformationMetadata buildTransformationMetaData(VDBMetaData vdb, Map<VirtualFile, Visibility> visibilityMap, CompositeMetadataStore store) throws DeploymentException {
+	private TransformationMetadata buildTransformationMetaData(VDBMetaData vdb, Map<VirtualFile, Visibility> visibilityMap, CompositeMetadataStore store, UDFMetaData udf) throws DeploymentException {
 		
 		// get the system VDB metadata store
 		MetadataStore systemStore = this.vdbRepository.getMetadataStore(CoreConstants.SYSTEM_VDB, 1);
@@ -124,7 +127,12 @@
 			throw new DeploymentException("System.vdb needs to be loaded before any other VDBs.");
 		}
 		
-		TransformationMetadata metadata =  new TransformationMetadata(vdb.getName(), vdb.getVersion(), store, visibilityMap);
+		Collection <FunctionMethod> methods = null;
+		if (udf != null) {
+			methods = udf.getMethods();
+		}
+		
+		TransformationMetadata metadata =  new TransformationMetadata(vdb.getName(), vdb.getVersion(), store, visibilityMap, methods);
 				
 		return metadata;
 	}	

Modified: branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
===================================================================
--- branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java	2010-02-02 20:46:07 UTC (rev 1798)
+++ branches/JCA/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java	2010-02-03 17:56:28 UTC (rev 1799)
@@ -40,6 +40,7 @@
 import com.metamatrix.core.CoreConstants;
 import com.metamatrix.core.util.StringUtil;
 import com.metamatrix.core.vdb.VdbConstants;
+import com.metamatrix.query.function.metadata.FunctionMetadataReader;
 import com.metamatrix.vdb.materialization.ScriptType;
 
 /**
@@ -58,6 +59,7 @@
 		Map<String, Class<?>> mappings = new HashMap<String, Class<?>>();
 		mappings.put(VdbConstants.DEF_FILE_NAME, VDBMetaData.class);
 		mappings.put(VdbConstants.MANIFEST_MODEL_NAME, ManifestMetaData.class);
+		mappings.put(VdbConstants.UDF_FILE_NAME, UDFMetaData.class);
 		return mappings;
 	}
 	
@@ -71,6 +73,10 @@
 			ManifestMetaData manifest = ManifestParser.load(file.openStream());
 			return expectedType.cast(manifest);
 		}
+		else if (expectedType.equals(UDFMetaData.class)) {
+			UDFMetaData udf = new UDFMetaData(FunctionMetadataReader.loadFunctionMethods(file.openStream()));
+			return expectedType.cast(udf);
+		}		
 		else if (expectedType.equals(IndexMetadataFactory.class)) {
 			if (root == null) {
 				root = unit.getAttachment(IndexMetadataFactory.class);
@@ -92,6 +98,7 @@
 	protected VDBMetaData mergeMetaData(VFSDeploymentUnit unit, Map<Class<?>, List<Object>> metadata) throws Exception {
 		VDBMetaData def = getInstance(metadata, VDBMetaData.class);
 		ManifestMetaData manifest = getInstance(metadata, ManifestMetaData.class);
+		UDFMetaData udf = getInstance(metadata, UDFMetaData.class);
 		
 		if (def == null || manifest == null) {
 			log.error("Invalid VDB file deployment failed ="+unit.getRoot().getName());
@@ -132,6 +139,11 @@
 			}
 		}
 		
+		// If the UDF file is enclosed then attach it to the deployment artifact
+		if (udf != null) {
+			def.addAttchment(UDFMetaData.class, udf);
+		}
+		
 		log.debug("VDB "+unit.getRoot().getName()+" has been parsed.");
 		return def;
 	}



More information about the teiid-commits mailing list