[teiid-commits] teiid SVN: r2897 - in trunk: api/src/main/java/org/teiid/metadata and 30 other directories.
teiid-commits at lists.jboss.org
teiid-commits at lists.jboss.org
Thu Feb 3 17:15:08 EST 2011
Author: shawkins
Date: 2011-02-03 17:15:05 -0500 (Thu, 03 Feb 2011)
New Revision: 2897
Removed:
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
Modified:
trunk/api/src/main/java/org/teiid/language/Function.java
trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
trunk/api/src/main/java/org/teiid/metadata/Schema.java
trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
Log:
TEIID-231 various refinements to function handling.
Modified: trunk/api/src/main/java/org/teiid/language/Function.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/Function.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/language/Function.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -26,16 +26,18 @@
import java.util.List;
import org.teiid.language.visitor.LanguageObjectVisitor;
+import org.teiid.metadata.FunctionMethod;
/**
* Represents a function. A function has a name and 0..n
* Expressions that are parameters.
*/
-public class Function extends BaseLanguageObject implements Expression {
+public class Function extends BaseLanguageObject implements Expression, MetadataReference<FunctionMethod> {
private String name;
private List<Expression> parameters;
private Class<?> type;
+ private FunctionMethod metadataObject;
public Function(String name, List<? extends Expression> params, Class<?> type) {
this.name = name;
@@ -47,6 +49,15 @@
this.type = type;
}
+ @Override
+ public FunctionMethod getMetadataObject() {
+ return metadataObject;
+ }
+
+ public void setMetadataObject(FunctionMethod metadataObject) {
+ this.metadataObject = metadataObject;
+ }
+
/**
* Get name of the function
* @return Function name
Modified: trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,6 +29,7 @@
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
+import org.teiid.core.util.EquivalenceUtil;
import org.teiid.core.util.HashCodeUtil;
@@ -109,7 +110,8 @@
@XmlElement(name="inputParameters")
protected List<FunctionParameter> inParameters = new ArrayList<FunctionParameter>();
private FunctionParameter outputParameter;
-
+ private Schema parent;
+
protected FunctionMethod() {
}
@@ -371,7 +373,7 @@
List<FunctionParameter> otherInputs = other.getInputParameters();
for(int i=0; i<thisInputs.size(); i++) {
- boolean paramMatch = compareWithNull(thisInputs.get(i), otherInputs.get(i));
+ boolean paramMatch = EquivalenceUtil.areEqual(thisInputs.get(i), otherInputs.get(i));
if(! paramMatch) {
return false;
}
@@ -385,26 +387,6 @@
}
/**
- * Compare two objects that may or may not be null and consider null==null
- * as true.
- * @param o1 Object 1
- * @param o2 Object 2
- * @return True if o1 and o2 are null or if they both aren't and they are equal
- */
- private boolean compareWithNull(Object o1, Object o2) {
- if(o1 == null) {
- if(o2 == null) {
- return true;
- }
- return false;
- }
- if(o2 == null) {
- return false;
- }
- return o1.equals(o2);
- }
-
- /**
* Return string version for debugging purposes
* @return String representation of function method
*/
@@ -473,5 +455,13 @@
}
return false;
}
-
+
+ public void setParent(Schema parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public Schema getParent() {
+ return parent;
+ }
}
Modified: trunk/api/src/main/java/org/teiid/metadata/Schema.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/Schema.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/Schema.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -52,7 +52,10 @@
}
public void addFunction(FunctionMethod function) {
- this.functions.put(function.getName().toLowerCase(), function);
+ function.setParent(this);
+ if (this.functions.put(function.getName().toLowerCase(), function) != null) {
+ throw new AssertionError("Duplicate function " + function.getName()); //$NON-NLS-1$
+ }
}
/**
Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -650,7 +650,7 @@
}
public List<FunctionMethod> getPushDownFunctions(){
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
/**
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,8 @@
<h4>from 7.3</h4>
<ul>
<li>The use of an IN procedure parameter with the name "source_name" in a multi-source model, will now be treated the parameter that controls which source
- the procedure will execute against.
+ the procedure will execute against.
+ <li>Dynamic VDB functions injected via ExecutionFactory.getPushdownFunctions are now scoped to the SYS schema and have a fully qualified name that includes their source type. For example, instead of oracle_model.relate - which was only valid against the oracle_model source, there is now the SYS.oracle_sdo.relate function that is valid for all Oracle sources. Any fully-qualified reference to these functions will need updated.
</ul>
<h4>from 7.2</h4>
@@ -189,9 +190,8 @@
<h2><a name="Licenses">Licenses</a></h2>
<p>Teiid is licensed under the <a href="LICENSE-lgpl-2.1.txt">LGPL</a>. The
-license texts for Teiid and the thirdparty components it uses may be found in the teiid-docs/licenses
-directory of the distribution. <a href="teiid-docs/licenses">Browse
-Licenses</a>
+license texts for Teiid and the thirdparty components it uses may be found in the <a href="teiid-docs/licenses">teiid-docs/licenses</a>
+directory of the distribution.
</p>
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,31 +116,31 @@
@Override
public List<FunctionMethod> getPushDownFunctions(){
List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
- pushdownFunctions.add(new FunctionMethod(JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_ISSAMENODE, JCR_ISSAMENODE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISSAMENODE, JCR_ISSAMENODE, JCR,
new FunctionParameter[] {
new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_CONTAINS, JCR_CONTAINS, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_CONTAINS, JCR_CONTAINS, JCR,
new FunctionParameter[] {
new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("searchExpr", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(JCR_REFERENCE, JCR_REFERENCE, JCR,
+ pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_REFERENCE, JCR_REFERENCE, JCR,
new FunctionParameter[] {
new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -38,42 +38,42 @@
public static final String FILTER = "sdo_filter"; //$NON-NLS-1$
public static final String WITHIN_DISTANCE = "sdo_within_distance"; //$NON-NLS-1$
public static final String NEAREST_NEIGHBOR_DISTANCE = "sdo_nn_distance"; //$NON-NLS-1$
- private static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
+ public static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
public static List<FunctionMethod> getOracleSpatialFunctions(){
List<FunctionMethod> spatialFuncs = new ArrayList<FunctionMethod>();
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -81,7 +81,7 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -89,7 +89,7 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -97,47 +97,47 @@
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,
+ spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,
new FunctionParameter[] {
new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -91,7 +91,7 @@
public void testPredicate() throws Exception {
String input = "SELECT x.jcr_primaryType from nt_base inner join nt_base as x on jcr_issamenode(nt_base.jcr_path, x.jcr_path) = true where jcr_isdescendantnode(nt_base.jcr_path, 'x/y/z') = true and jcr_reference(nt_base.mode_properties) = 'x'"; //$NON-NLS-1$
- String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON issamenode(g_0, g_1) WHERE isdescendantnode(g_0, 'x/y/z') AND reference(g_0.*) = 'x'"; //$NON-NLS-1$
+ String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON ISSAMENODE(g_0, g_1) WHERE ISDESCENDANTNODE(g_0, 'x/y/z') AND REFERENCE(g_0.*) = 'x'"; //$NON-NLS-1$
helpTestVisitor(input, output);
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -128,7 +128,7 @@
@Test
public void testDateFunctions() throws Exception {
String input = "select dayName(timestampValue), dayOfWeek(timestampValue), quarter(timestampValue) from bqt1.smalla"; //$NON-NLS-1$
- String output = "SELECT {fn dayName(SmallA.TimestampValue)}, {fn dayOfWeek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
+ String output = "SELECT {fn dayname(SmallA.TimestampValue)}, {fn dayofweek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
helpTestVisitor(getBQTVDB(),
input,
Modified: trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
===================================================================
--- trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,13 +142,13 @@
@Override
public List<FunctionMethod> getPushDownFunctions(){
List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
- pushdownFunctions.add(new FunctionMethod(INCLUDES, INCLUDES, SALESFORCE,
+ pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' +INCLUDES, INCLUDES, SALESFORCE,
new FunctionParameter[] {
new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
- pushdownFunctions.add(new FunctionMethod(EXCLUDES, EXCLUDES, SALESFORCE,
+ pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' + EXCLUDES, EXCLUDES, SALESFORCE,
new FunctionParameter[] {
new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
Modified: trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
===================================================================
--- trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml 2011-02-03 22:15:05 UTC (rev 2897)
@@ -8,7 +8,7 @@
creating a UDF.</para>
<section id="define_udf">
<title>UDF Definition</title>
- <para>The FunctionDefinition.xmi file provides metadata to the
+ <para>A FunctionDefinition.xmi file provides metadata to the
query engine on User Defined Functions. See the Designer Documentation for more on creating a Function Definition Model.</para>
<itemizedlist>
<para>The following are used to define a UDF.</para>
@@ -19,24 +19,20 @@
mind:
<itemizedlist>
<listitem>
- <para>You cannot use a reserved word, which includes
- existing Teiid System function names. You cannot
- overload existing Teiid System functions.</para>
+ <para>You cannot overload existing Teiid System functions.</para>
</listitem>
<listitem>
<para>The function name must be unique among user-defined
- functions for the number of arguments. You can use the
+ functions in its model for the number of arguments. You can use the
same function name for different numbers of types of
arguments. Hence, you can overload your user-defined
functions.</para>
</listitem>
<listitem>
- <para>The function name can only contain letters,
- numbers, and the underscore (_). Your function name must
- start with a letter.</para>
+ <para>The function name cannot contain the '.' character.</para>
</listitem>
<listitem>
- <para>The function name cannot exceed 128 characters.
+ <para>The function name cannot exceed 255 characters.
</para>
</listitem>
</itemizedlist>
@@ -225,4 +221,18 @@
created in in the Designer Tool, it can be added to the VDB for use
by Teiid.</para>
</section>
+ <section>
+ <title>User Defined Functions in Dynamic VDBs</title>
+ <para>Dynamic VDBs do not use Designer generated artifacts, such as a FunctionDefinition.xmi file.
+ Even with that limitation dynamic vdbs may still utilize UDFs through custom coding.
+ The <code>ExecutionFactory.getMetadata</code> call allows for the definition of metadata via a <code>MetadataFactory.</code>
+ Use the <code>MetadataFactory.addFunction</code> to add function for use only by that translator instance.
+ Functions added directly to the source schema are specific to that schema - their fully qualified name will include the schema and the function can not be pushed to a different source.
+ </para>
+ <para>The <code>ExecutionFactory.getPushdownFunctions</code> method can be used to describe functions that are valid against all instances of a given translator type. The function names are expected to be
+ prefixed by the translator type, or some other logical grouping, e.g. salesforce.includes. The full name of the function once imported into the system will qualified by the SYS schema, e.g. SYS.salesforce.includes.
+ </para>
+ <para>Any funcitons added via these mechanisms do not need to be declared in <code>ExecutionFactory.getSupportedFunctions.</code> Any of the additional handling, such as adding a <code>FunctionModifier</code>, covered above is also applicable here. All pushdown functions will have function name set to only the simple name. Schema or other qualification will be removed.
+ Handling, such as function modifiers, can check the function metadata if there is the potential for an ambiguity.</para>
+ </section>
</chapter>
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -495,12 +495,22 @@
org.teiid.language.Function translate(Function function) {
Expression [] args = function.getArgs();
List<org.teiid.language.Expression> params = new ArrayList<org.teiid.language.Expression>(args.length);
- if (args != null) {
- for (int i = 0; i < args.length; i++) {
- params.add(translate(args[i]));
- }
+ for (int i = 0; i < args.length; i++) {
+ params.add(translate(args[i]));
}
- return new org.teiid.language.Function(function.getName(), params, function.getType());
+ String name = function.getName();
+ if (function.getFunctionDescriptor() != null) {
+ name = function.getFunctionDescriptor().getName();
+ }
+ name = SingleElementSymbol.getShortName(name);
+
+ //if there is any ambiguity in the function name it will be up to the translator logic to check the
+ //metadata
+ org.teiid.language.Function result = new org.teiid.language.Function(name, params, function.getType());
+ if (function.getFunctionDescriptor() != null) {
+ result.setMetadataObject(function.getFunctionDescriptor().getMethod());
+ }
+ return result;
}
SearchedCase translate(SearchedCaseExpression expr) {
@@ -515,7 +525,7 @@
org.teiid.language.Expression translate(ScalarSubquery ss) {
- return new org.teiid.language.ScalarSubquery(translate((QueryCommand)ss.getCommand()));
+ return new org.teiid.language.ScalarSubquery(translate(ss.getCommand()));
}
org.teiid.language.Expression translate(SingleElementSymbol symbol) {
@@ -562,11 +572,12 @@
/* Insert */
org.teiid.language.Insert translate(Insert insert) {
- List elements = insert.getVariables();
+ List<ElementSymbol> elements = insert.getVariables();
List<ColumnReference> translatedElements = new ArrayList<ColumnReference>();
- for (Iterator i = elements.iterator(); i.hasNext();) {
- translatedElements.add(translate((ElementSymbol)i.next()));
- }
+
+ for (ElementSymbol elementSymbol : elements) {
+ translatedElements.add(translate(elementSymbol));
+ }
InsertValueSource valueSource = null;
if (insert.getQueryExpression() != null) {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -694,7 +694,7 @@
this.processWorkerPool = new ThreadReuseExecutor(DQPConfiguration.PROCESS_PLAN_QUEUE_NAME, config.getMaxThreads());
if (cacheFactory.isReplicated()) {
- matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.LRU, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
+ matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.EXPIRATION, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
matTables.setBufferManager(this.bufferManager);
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -31,33 +31,27 @@
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.TransformationException;
-import org.teiid.core.util.Assertion;
-import org.teiid.core.util.HashCodeUtil;
import org.teiid.core.util.PropertiesUtils;
-import org.teiid.metadata.FunctionMethod.PushDown;
+import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.FunctionMethod.Determinism;
+import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.QueryPlugin;
import org.teiid.query.util.CommandContext;
/**
* The FunctionDescriptor describes a particular function instance enough
- * that the function library can retrieve a function instance based on the
- * descriptor.
+ * to invoke the function.
*/
public class FunctionDescriptor implements Serializable, Cloneable {
private static final long serialVersionUID = 5374103983118037242L;
private static final boolean ALLOW_NAN_INFINITY = PropertiesUtils.getBooleanProperty(System.getProperties(), "org.teiid.allowNanInfinity", false); //$NON-NLS-1$
- private String name;
- private PushDown pushdown = PushDown.CAN_PUSHDOWN;
- private Class[] types;
- private Class returnType;
- private int hash;
+ private Class<?>[] types;
+ private Class<?> returnType;
private boolean requiresContext;
- private boolean nullDependent;
- private Determinism deterministic = Determinism.DETERMINISTIC;
+ private FunctionMethod method;
// This is transient as it would be useless to invoke this method in
// a different VM. This function descriptor can be used to look up
@@ -67,52 +61,29 @@
FunctionDescriptor() {
}
- /**
- * Construct a function descriptor with all the info
- * @param name Name of function
- * @param types Types of the arguments
- * @param returnType Type of the return
- * @param invocationMethod Reflection method used to invoke the function
- * @param requiresContext during execution requires command context to be pushed into method as first argument
- */
- FunctionDescriptor(String name, PushDown pushdown, Class[] types, Class returnType, Method invocationMethod, boolean requiresContext, boolean nullDependent, Determinism deterministic) {
- Assertion.isNotNull(name);
- Assertion.isNotNull(types);
- Assertion.isNotNull(returnType);
-
- this.name = name;
- this.pushdown = pushdown;
+ FunctionDescriptor(FunctionMethod method, Class<?>[] types,
+ Class<?> outputType, Method invocationMethod,
+ boolean requiresContext) {
this.types = types;
- this.returnType = returnType;
+ this.returnType = outputType;
this.invocationMethod = invocationMethod;
this.requiresContext = requiresContext;
- this.nullDependent = nullDependent;
- this.deterministic = deterministic;
-
- // Compute hash code
- hash = HashCodeUtil.hashCode(0, name);
- for(int i=0; i<types.length; i++) {
- hash = HashCodeUtil.hashCode(hash, types[i]);
- }
+ this.method = method;
}
public String getName() {
- return this.name;
+ return this.method.getName();
}
public PushDown getPushdown() {
- return this.pushdown;
+ return this.method.getPushdown();
}
- void setPushdown(PushDown pushdown) {
- this.pushdown = pushdown;
- }
-
- public Class[] getTypes() {
+ public Class<?>[] getTypes() {
return this.types;
}
- public Class getReturnType() {
+ public Class<?> getReturnType() {
return this.returnType;
}
@@ -124,51 +95,8 @@
return this.requiresContext;
}
- public int hashCode() {
- return this.hash;
- }
-
- public boolean equals(Object obj) {
- if(obj == this) {
- return true;
- }
-
- if(obj == null || !(obj instanceof FunctionDescriptor)) {
- return false;
- }
- FunctionDescriptor other = (FunctionDescriptor) obj;
-
- // Compare names
- if(! this.getName().equals(other.getName())) {
- return false;
- }
-
- // Compare arg types
- Class[] thisTypes = this.getTypes();
- Class[] otherTypes = other.getTypes();
- if(thisTypes.length != otherTypes.length) {
- return false;
- }
- for(int i=0; i<thisTypes.length; i++) {
- if(! thisTypes[i].equals(otherTypes[i])) {
- return false;
- }
- }
-
- if (this.nullDependent != other.isNullDependent()) {
- return false;
- }
-
- if (this.deterministic != other.deterministic) {
- return false;
- }
-
- // Must be a match
- return true;
- }
-
public String toString() {
- StringBuffer str = new StringBuffer(this.name);
+ StringBuffer str = new StringBuffer(this.method.getName());
str.append("("); //$NON-NLS-1$
for(int i=0; i<types.length; i++) {
if(types[i] != null) {
@@ -190,17 +118,13 @@
}
public boolean isNullDependent() {
- return nullDependent;
+ return !this.method.isNullOnNull();
}
public Determinism getDeterministic() {
- return deterministic;
+ return this.method.getDeterminism();
}
- void setDeterministic(Determinism deterministic) {
- this.deterministic = deterministic;
- }
-
public Object clone() {
try {
return super.clone();
@@ -208,12 +132,15 @@
throw new TeiidRuntimeException(e);
}
}
+
+ public FunctionMethod getMethod() {
+ return method;
+ }
- void setReturnType(Class returnType) {
+ void setReturnType(Class<?> returnType) {
this.returnType = returnType;
}
-
/**
* Invoke the function described in the function descriptor, using the
* values provided. Return the result of the function.
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,7 @@
* information and instead differentiates function signatures based on their
* function name and the names of the arguments.
*/
-public class FunctionForm implements Serializable, Comparable {
+public class FunctionForm implements Serializable, Comparable<FunctionForm> {
private static final long serialVersionUID = 2411783099304320334L;
private String name;
@@ -245,42 +245,32 @@
* @param obj Other object
* @return 1 if other > this, 0 if other == this, -1 if other < this
*/
- public int compareTo(Object obj) {
- if(obj == this) {
- return 0;
- } else if(obj == null) {
- // Should never happen, but sort nulls low
- return -1;
- } else {
- // may throw ClassCastException - this is expected for compareTo()
- FunctionForm other = (FunctionForm) obj;
+ public int compareTo(FunctionForm other) {
+ int compare = this.getName().compareTo( other.getName() );
+ if(compare != 0) {
+ return compare;
+ }
- int compare = this.getName().compareTo( other.getName() );
+ // Look further into arg names to compare as names are ==
+ List otherArgs = other.getArgNames();
+ List myArgs = this.getArgNames();
+
+ // Compare # of args first
+ if(myArgs.size() < otherArgs.size()) {
+ return -1;
+ } else if(myArgs.size() > otherArgs.size()) {
+ return 1;
+ } // else continue
+
+ // Same # of args
+ for(int i=0; i < myArgs.size(); i++) {
+ compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
if(compare != 0) {
return compare;
}
-
- // Look further into arg names to compare as names are ==
- List otherArgs = other.getArgNames();
- List myArgs = this.getArgNames();
-
- // Compare # of args first
- if(myArgs.size() < otherArgs.size()) {
- return -1;
- } else if(myArgs.size() > otherArgs.size()) {
- return 1;
- } // else continue
-
- // Same # of args
- for(int i=0; i < myArgs.size(); i++) {
- compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
- if(compare != 0) {
- return compare;
- }
- }
-
- // Same
- return 0;
}
+
+ // Same
+ return 0;
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,9 +25,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.TreeSet;
import org.teiid.api.exception.query.InvalidFunctionException;
import org.teiid.api.exception.query.QueryResolverException;
@@ -108,9 +108,9 @@
* Get all function categories, sorted in alphabetical order
* @return List of function category names, sorted in alphabetical order
*/
- public List getFunctionCategories() {
+ public List<String> getFunctionCategories() {
// Remove category duplicates
- HashSet categories = new HashSet();
+ TreeSet<String> categories = new TreeSet<String>();
categories.addAll( systemFunctions.getCategories() );
if (this.userFunctions != null) {
for (FunctionTree tree: this.userFunctions) {
@@ -118,9 +118,7 @@
}
}
- // Sort alphabetically
- ArrayList categoryList = new ArrayList(categories);
- Collections.sort(categoryList);
+ ArrayList<String> categoryList = new ArrayList<String>(categories);
return categoryList;
}
@@ -129,8 +127,8 @@
* @param category Category name
* @return List of {@link FunctionForm}s in a category
*/
- public List getFunctionForms(String category) {
- List forms = new ArrayList();
+ public List<FunctionForm> getFunctionForms(String category) {
+ List<FunctionForm> forms = new ArrayList<FunctionForm>();
forms.addAll(systemFunctions.getFunctionForms(category));
if (this.userFunctions != null) {
for (FunctionTree tree: this.userFunctions) {
@@ -170,7 +168,7 @@
* @param types Array of classes representing the types
* @return Descriptor if found, null if not found
*/
- public FunctionDescriptor findFunction(String name, Class[] types) {
+ public FunctionDescriptor findFunction(String name, Class<?>[] types) {
// First look in system functions
FunctionDescriptor descriptor = systemFunctions.getFunction(name, types);
@@ -323,7 +321,7 @@
* @param targetType The target type class
* @return A CONVERT function descriptor or null if not possible
*/
- public FunctionDescriptor findTypedConversionFunction(Class sourceType, Class targetType) {
+ public FunctionDescriptor findTypedConversionFunction(Class<?> sourceType, Class<?> targetType) {
FunctionDescriptor fd = findFunction(CONVERT, new Class[] {sourceType, DataTypeManager.DefaultDataClasses.STRING});
if (fd != null) {
return copyFunctionChangeReturnType(fd, targetType);
@@ -337,7 +335,7 @@
* @param returnType The return type to apply to the copied FunctionDescriptor.
* @return The copy of FunctionDescriptor.
*/
- public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class returnType) {
+ public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class<?> returnType) {
if(fd != null) {
FunctionDescriptor fdImpl = fd;
FunctionDescriptor copy = (FunctionDescriptor)fdImpl.clone();
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,15 +29,14 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.teiid.core.CoreConstants;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.Assertion;
import org.teiid.core.util.ReflectionHelper;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
@@ -75,55 +74,32 @@
*/
private Map treeRoot = new HashMap();
private boolean validateClass;
-
+
/**
* Construct a new tree with the given source of function metadata.
* @param source The metadata source
*/
- public FunctionTree(FunctionMetadataSource source) {
- this(source, false);
+ public FunctionTree(String name, FunctionMetadataSource source) {
+ this(name, source, false);
}
/**
* Construct a new tree with the given source of function metadata.
* @param source The metadata source
*/
- public FunctionTree(FunctionMetadataSource source, boolean validateClass) {
+ public FunctionTree(String name, FunctionMetadataSource source, boolean validateClass) {
// Load data structures
this.validateClass = validateClass;
- addSource(source);
- }
- /**
- * Add all functions from a metadata source to the data structures.
- * @param source The source of the functions
- */
- private void addSource(FunctionMetadataSource source) {
- if(source == null) {
- return;
+ Collection<FunctionMethod> functions = source.getFunctionMethods();
+ for (FunctionMethod method : functions) {
+ if (!containsIndistinguishableFunction(method)){
+ // Add to tree
+ addFunction(name, source, method);
+ } else if (!CoreConstants.SYSTEM_MODEL.equalsIgnoreCase(name)) {
+ LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
+ }
}
-
- Collection functions = source.getFunctionMethods();
- if(functions != null) {
- Iterator functionIter = functions.iterator();
- while(functionIter.hasNext()) {
- Object functionObj = functionIter.next();
- if(! (functionObj instanceof FunctionMethod)) {
- Assertion.failed(QueryPlugin.Util.getString("ERR.015.001.0045", functionObj.getClass().getName())); //$NON-NLS-1$
- }
- FunctionMethod method = (FunctionMethod) functionObj;
-
- if (!containsIndistinguishableFunction(method)){
- // Store method metadata for retrieval
- addMetadata(method);
-
- // Add to tree
- addFunction(source, method);
- } else {
- LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
- }
- }
- }
}
// ---------------------- FUNCTION SELECTION USE METHODS ----------------------
@@ -143,51 +119,6 @@
}
/**
- * Store the method in the function metadata.
- * @param method The function metadata for a particular method signature
- */
- private void addMetadata(FunctionMethod method) {
- String categoryKey = method.getCategory();
- if (categoryKey == null) {
- method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
- categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
- }
- categoryKey = categoryKey.toUpperCase();
- String nameKey = method.getName().toUpperCase();
-
- // Look up function map (create if necessary)
- Set<String> functions = categories.get(categoryKey);
- if (functions == null) {
- functions = new HashSet<String>();
- categories.put(categoryKey, functions);
- }
-
- int index = -1;
- while (true){
- // Look up function in function map
- functions.add(nameKey);
-
- // Add method to list by function name
- List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
- if(knownMethods == null) {
- knownMethods = new ArrayList<FunctionMethod>();
- functionsByName.put(nameKey, knownMethods);
- }
- knownMethods.add(method);
-
- // if the function is "." delimited, then add all possible forms
- index = nameKey.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
- if (index != -1) {
- nameKey = nameKey.substring(index+1);
- }
- else {
- break;
- }
- }
- allFunctions.add(method);
- }
-
- /**
* Get collection of category names.
* @return Category names
*/
@@ -258,28 +189,94 @@
* @param source The function metadata source, which knows how to obtain the invocation class
* @param method The function metadata for a particular method signature
*/
- private void addFunction(FunctionMetadataSource source, FunctionMethod method) {
+ private void addFunction(String schema, FunctionMetadataSource source, FunctionMethod method) {
+ String categoryKey = method.getCategory();
+ if (categoryKey == null) {
+ method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
+ categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
+ }
+ categoryKey = categoryKey.toUpperCase();
+
+ // Look up function map (create if necessary)
+ Set<String> functions = categories.get(categoryKey);
+ if (functions == null) {
+ functions = new HashSet<String>();
+ categories.put(categoryKey, functions);
+ }
+
// Get method name
- String methodName = method.getName();
+ String methodName = schema + AbstractMetadataRecord.NAME_DELIM_CHAR + method.getName();
// Get input types for path
List<FunctionParameter> inputParams = method.getInputParameters();
- List<Class> inputTypes = new LinkedList<Class>();
+ List<Class<?>> inputTypes = new LinkedList<Class<?>>();
if(inputParams != null) {
for(int i=0; i<inputParams.size(); i++) {
String typeName = inputParams.get(i).getType();
inputTypes.add(DataTypeManager.getDataTypeClass(typeName));
}
}
- Class[] types = inputTypes.toArray(new Class[inputTypes.size()]);
+ Class<?>[] types = inputTypes.toArray(new Class[inputTypes.size()]);
if (method.isVarArgs()) {
inputTypes.set(inputTypes.size() - 1, Array.newInstance(inputTypes.get(inputTypes.size() - 1), 0).getClass());
}
- // Get return type
+ FunctionDescriptor descriptor = createFunctionDescriptor(source, method, inputTypes, types);
+ // Store this path in the function tree
+
+ int index = -1;
+ while(true) {
+ String nameKey = methodName.toUpperCase();
+
+ // Look up function in function map
+ functions.add(nameKey);
+
+ // Add method to list by function name
+ List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
+ if(knownMethods == null) {
+ knownMethods = new ArrayList<FunctionMethod>();
+ functionsByName.put(nameKey, knownMethods);
+ }
+ knownMethods.add(method);
+
+ Map node = treeRoot;
+ Object[] path = buildPath(methodName, types);
+ for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
+ Object pathPart = path[pathIndex];
+ Map children = (Map) node.get(pathPart);
+ if(children == null) {
+ children = new HashMap();
+ node.put(pathPart, children);
+ }
+ if (method.isVarArgs() && pathIndex == path.length - 1) {
+ node.put(DESCRIPTOR_KEY, descriptor);
+ }
+ node = children;
+ }
+
+ if (method.isVarArgs()) {
+ node.put(types[types.length - 1], node);
+ }
+ // Store the leaf descriptor in the tree
+ node.put(DESCRIPTOR_KEY, descriptor);
+
+ index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
+ if (index == -1) {
+ break;
+ }
+ methodName = methodName.substring(index+1);
+ }
+
+ allFunctions.add(method);
+ }
+
+ private FunctionDescriptor createFunctionDescriptor(
+ FunctionMetadataSource source, FunctionMethod method,
+ List<Class<?>> inputTypes, Class<?>[] types) {
+ // Get return type
FunctionParameter outputParam = method.getOutputParameter();
- Class outputType = null;
+ Class<?> outputType = null;
if(outputParam != null) {
outputType = DataTypeManager.getDataTypeClass(outputParam.getType());
}
@@ -329,39 +326,8 @@
inputTypes.add(0, CommandContext.class);
}
- FunctionDescriptor descriptor = new FunctionDescriptor(method.getName(), method.getPushdown(), types, outputType, invocationMethod, requiresContext, !method.isNullOnNull(), method.getDeterminism());
- // Store this path in the function tree
-
- int index = -1;
- while(true) {
- Map node = treeRoot;
- Object[] path = buildPath(methodName, types);
- for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
- Object pathPart = path[pathIndex];
- Map children = (Map) node.get(pathPart);
- if(children == null) {
- children = new HashMap();
- node.put(pathPart, children);
- }
- if (method.isVarArgs() && pathIndex == path.length - 1) {
- node.put(DESCRIPTOR_KEY, descriptor);
- }
- node = children;
- }
-
- if (method.isVarArgs()) {
- node.put(types[types.length - 1], node);
- }
- // Store the leaf descriptor in the tree
- node.put(DESCRIPTOR_KEY, descriptor);
-
- index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
- if (index == -1) {
- break;
- }
- methodName = methodName.substring(index+1);
- }
- }
+ return new FunctionDescriptor(method, types, outputType, invocationMethod, requiresContext);
+ }
/**
* Look up a function descriptor by signature in the tree. If none is
@@ -370,7 +336,7 @@
* @param argTypes Types of each argument in the function
* @return Descriptor which can be used to invoke the function
*/
- FunctionDescriptor getFunction(String name, Class[] argTypes) {
+ FunctionDescriptor getFunction(String name, Class<?>[] argTypes) {
// Build search path
Object[] path = buildPath(name, argTypes);
@@ -399,7 +365,7 @@
* @param argTypes Types of each arguments
* @return Path in function storage tree
*/
- private Object[] buildPath(String name, Class[] argTypes) {
+ private Object[] buildPath(String name, Class<?>[] argTypes) {
Object[] path = new Object[argTypes.length + 1];
path[0] = name.toUpperCase();
System.arraycopy(argTypes, 0, path, 1, argTypes.length);
Modified: trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,8 +22,8 @@
package org.teiid.query.function;
import java.util.Collection;
-import java.util.Collections;
+import org.teiid.core.CoreConstants;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.metadata.FunctionMetadataValidator;
import org.teiid.query.function.source.SystemSource;
@@ -47,13 +47,13 @@
// Should never happen as SystemSourcTe doesn't change
System.err.println(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
}
- systemFunctionTree = new FunctionTree(systemSource, true);
+ systemFunctionTree = new FunctionTree(CoreConstants.SYSTEM_MODEL, systemSource, true);
}
return systemFunctionTree;
}
public FunctionLibrary getSystemFunctionLibrary() {
- return new FunctionLibrary(getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+ return new FunctionLibrary(getSystemFunctions());
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -36,11 +36,11 @@
this.methods = methods;
}
- public Collection getFunctionMethods() {
+ public Collection<FunctionMethod> getFunctionMethods() {
return this.methods;
}
- public Class getInvocationClass(String className) throws ClassNotFoundException {
+ public Class<?> getInvocationClass(String className) throws ClassNotFoundException {
return Class.forName(className);
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -253,26 +253,9 @@
* @throws FunctionMetadataException Thrown when string uses characters not in allowed character sets
*/
private static final void validateNameCharacters(String name, String strName) throws FunctionMetadataException {
- // First check first character
- if(name.length() > 0) {
- // Check special cases
- if(name.equals("+") || name.equals("-") || name.equals("*") || name.equals("/") || name.equals("||")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- return;
- }
-
- char firstChar = name.charAt(0);
- if(! Character.isLetter(firstChar)) {
- throw new FunctionMetadataException("ERR.015.001.0056", QueryPlugin.Util.getString("ERR.015.001.0056",strName, new Character(firstChar))); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- // Then check the rest of the characters
- for(int i=1; i<name.length(); i++) {
- char ch = name.charAt(i);
- if(! (Character.isLetterOrDigit(ch) || ch == '_')) {
- throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, new Character(ch))); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
+ if (name.indexOf('.') > 0) {
+ throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, '.')); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
/**
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,7 +142,7 @@
* TransformationMetadata constructor
* @param context Object containing the info needed to lookup metadta.
*/
- public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, FunctionTree... udfFunctions) {
+ public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, Collection<FunctionTree> functionTrees) {
ArgCheck.isNotNull(store);
this.vdbMetaData = vdbMetadata;
this.store = store;
@@ -151,7 +151,11 @@
} else {
this.vdbEntries = vdbEntries;
}
- this.functionLibrary = new FunctionLibrary(systemFunctions, udfFunctions);
+ if (functionTrees == null) {
+ this.functionLibrary = new FunctionLibrary(systemFunctions);
+ } else {
+ this.functionLibrary = new FunctionLibrary(systemFunctions, functionTrees.toArray(new FunctionTree[functionTrees.size()]));
+ }
}
//==================================================================================
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -30,6 +30,7 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.metadata.Schema;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -206,12 +207,20 @@
if (metadata.isVirtualModel(modelID)){
return false;
}
+
+ //capabilities check is only valid for non-schema scoped functions
+ //technically the other functions are scoped to SYS, but that's
+ //not formally part of their metadata yet
+ Schema schema = function.getFunctionDescriptor().getMethod().getParent();
+ if (schema == null) {
+ // Find capabilities
+ SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
- // Find capabilities
- SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
-
- if (!caps.supportsFunction(function.getName().toLowerCase())) {
- return false;
+ if (!caps.supportsFunction(function.getFunctionDescriptor().getName().toLowerCase())) {
+ return false;
+ }
+ } else if (!schema.getFullName().equalsIgnoreCase(metadata.getFullName(modelID))) {
+ return false; //not the right schema
}
//special check to ensure that special conversions are not pushed down (this can be removed after we support type based function pushdown)
Modified: trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -88,5 +88,10 @@
public Collection<R> getItems() {
return items;
}
+
+ @Override
+ public String toString() {
+ return reportType + " " + getItems(); //$NON-NLS-1$
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -2221,11 +2221,19 @@
//rewrite alias functions
String functionLowerName = function.getName().toLowerCase();
String actualName =ALIASED_FUNCTIONS.get(functionLowerName);
+ FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
+
if (actualName != null) {
function.setName(actualName);
+ Expression[] args = function.getArgs();
+ Class<?>[] types = new Class[args.length];
+ for(int i=0; i<args.length; i++) {
+ types[i] = args[i].getType();
+ }
+ FunctionDescriptor descriptor = funcLibrary.findFunction(actualName, types);
+ function.setFunctionDescriptor(descriptor);
}
- FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
Integer code = FUNCTION_MAP.get(functionLowerName);
if (code != null) {
switch (code) {
Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -192,12 +192,16 @@
return true;
}
- if(obj == null || ! (obj instanceof Function)) {
+ if(! (obj instanceof Function)) {
return false;
}
Function other = (Function) obj;
- if(! other.getName().equalsIgnoreCase(getName())) {
+ if (this.descriptor != null && other.descriptor != null) {
+ if (!this.descriptor.getMethod().getFullName().equals(other.descriptor.getMethod().getFullName())) {
+ return false;
+ }
+ } else if(! other.getName().equalsIgnoreCase(getName())) {
return false;
}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2011-02-03 22:15:05 UTC (rev 2897)
@@ -39,7 +39,6 @@
ERR.015.001.0042 = Illegal argument for formating: {0}
ERR.015.001.0043 = Parse Exception occurs for executing: {0} {1}
ERR.015.001.0044 = Function metadata source is of invalid type: {0}
-ERR.015.001.0045 = Function method is of invalid type: {0}
ERR.015.001.0046 = The function "{0}" will not be added because a function with the same name and signature already exists.
ERR.015.001.0047 = Unexpected exception while loading "{1}.{2}" for UDF "{0}"
FunctionTree.not_void = UDF "{0}" method "{1}" must not return void.
Deleted: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -1,115 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.query.function;
-
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.UnitTestUtil;
-import org.teiid.metadata.FunctionMethod.Determinism;
-import org.teiid.metadata.FunctionMethod.PushDown;
-
-
-public class TestFunctionDescriptorImpl extends TestCase {
-
- /**
- * Constructor for TestFunctionDescriptorImpl.
- * @param name
- */
- public TestFunctionDescriptorImpl(String name) {
- super(name);
- }
-
- /**
- * Find the invocation method for a function.
- * @param source The function metadata source, which knows how to obtain the invocation class
- * @param invocationClass The class to invoke for this function
- * @param invocationMethod The method to invoke for this function
- * @param numArgs Number of arguments in method
- * @throws NoSuchMethodException
- * @throws SecurityException
- */
- private Method lookupMethod(String invocationClass, String invocationMethod, int numArgs) throws SecurityException, NoSuchMethodException {
- // Build signature
- Class[] objectSignature = new Class[numArgs];
- for(int i=0; i<numArgs; i++) {
- objectSignature[i] = Integer.TYPE;
- }
-
- // Find Method
- Method method = null;
- try {
- Class methodClass = Class.forName(invocationClass);
- method = methodClass.getMethod(invocationMethod, objectSignature);
- } catch(ClassNotFoundException e) {
- // Failed to load class, so can't load method - this will fail at invocation time.
- // We don't fail here because this situation can occur in the modeler, which does
- // not have the function jar files. The modeler never invokes, so this isn't a
- // problem.
- return null;
- }
-
- return method;
- }
-
- public void test1() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN, //$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2) , false, true, Determinism.DETERMINISTIC); //$NON-NLS-1$ //$NON-NLS-2$
-
- UnitTestUtil.helpTestEquivalence(0, f1, f1);
- }
-
- public void test2() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- UnitTestUtil.helpTestEquivalence(0, f1, f2);
- }
-
- public void test3() throws Exception {
- FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, false, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
-
- FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
- new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
- DataTypeManager.DefaultDataClasses.INTEGER,
- lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
- assertNotSame("objects should not be equal", f1, f2); //$NON-NLS-1$
- }
-
-}
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,12 +22,7 @@
package org.teiid.query.function;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -38,7 +33,6 @@
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Iterator;
import java.util.Properties;
import java.util.TimeZone;
@@ -84,7 +78,7 @@
private static final Class<Date> T_DATE = DataTypeManager.DefaultDataClasses.DATE;
private static final Class<Timestamp> T_TIMESTAMP = DataTypeManager.DefaultDataClasses.TIMESTAMP;
- private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+ private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions());
@Before public void setUp() {
TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$
Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -50,7 +50,7 @@
*/
@Test public void testWalkTree() {
SystemSource source = new SystemSource(false);
- FunctionTree ft = new FunctionTree(source);
+ FunctionTree ft = new FunctionTree("foo", source);
Collection<String> categories = ft.getCategories();
for (String category : categories) {
@@ -78,11 +78,11 @@
new FunctionParameter("output", DataTypeManager.DefaultDataTypes.STRING), false, Determinism.DETERMINISTIC); //$NON-NLS-1$
//allowed, since we're not validating the class
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method))));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method))));
//should fail, no class
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -92,7 +92,7 @@
//should fail, no method
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -102,7 +102,7 @@
//should fail, not void
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -112,7 +112,7 @@
//should fail, not public
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -122,7 +122,7 @@
//should fail, not static
try {
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
fail();
} catch (TeiidRuntimeException e) {
@@ -131,7 +131,7 @@
method.setInvocationMethod("y");
//valid!
- new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+ new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
}
@Test public void testNullCategory() {
@@ -144,7 +144,7 @@
Collection<org.teiid.metadata.FunctionMethod> list = Arrays.asList(method);
FunctionMetadataSource fms = Mockito.mock(FunctionMetadataSource.class);
Mockito.stub(fms.getFunctionMethods()).toReturn(list);
- FunctionTree ft = new FunctionTree(fms);
+ FunctionTree ft = new FunctionTree("foo", fms);
assertEquals(1, ft.getFunctionForms(FunctionCategoryConstants.MISCELLANEOUS).size());
}
Modified: trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -92,12 +92,8 @@
helpTestValidateNameFail(null);
}
- public void testValidateNameFail2() {
- helpTestValidateNameFail("123"); //$NON-NLS-1$
- }
-
public void testValidateNameFail3() {
- helpTestValidateNameFail("a b"); //$NON-NLS-1$
+ helpTestValidateNameFail("a.b"); //$NON-NLS-1$
}
public void testValidateFunction1() {
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -27,7 +27,6 @@
import java.util.List;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.metadata.Datatype;
import org.teiid.metadata.FunctionParameter;
import org.teiid.metadata.FunctionMethod.PushDown;
import org.teiid.query.function.FunctionMetadataSource;
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,11 +22,7 @@
package org.teiid.query.optimizer;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
@@ -46,7 +42,6 @@
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -4265,7 +4260,7 @@
caps.setFunctionSupport("xyz", true); //$NON-NLS-1$
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,7 +25,10 @@
import java.util.ArrayList;
import java.util.List;
+import junit.framework.TestCase;
+
import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.core.TeiidComponentException;
import org.teiid.language.SQLConstants.NonReserved;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -33,7 +36,7 @@
import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
import org.teiid.query.optimizer.capabilities.SourceCapabilities;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
-import org.teiid.query.optimizer.relational.rules.CapabilitiesUtil;
+import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.symbol.AggregateSymbol;
@@ -46,9 +49,7 @@
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.unittest.FakeMetadataObject;
-import junit.framework.TestCase;
-
/**
*/
public class TestCapabilitiesUtil extends TestCase {
@@ -369,7 +370,7 @@
helpTestSupportsAggregateFunction(caps, aggregate, true);
}
- public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException {
+ public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException, QueryResolverException {
// Set up metadata
FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
FakeMetadataObject modelID = metadata.getStore().findObject("pm1", FakeMetadataObject.MODEL); //$NON-NLS-1$
@@ -377,7 +378,7 @@
// Set up capabilities
FakeCapabilitiesFinder finder = new FakeCapabilitiesFinder();
finder.addCapabilities("pm1", caps); //$NON-NLS-1$
-
+ ResolverVisitor.resolveLanguageObject(function, metadata);
// Test capabilities util
boolean actual = CapabilitiesUtil.supportsScalarFunction(modelID, function, metadata, finder);
assertEquals("Got wrong answer for supports", expectedValue, actual); //$NON-NLS-1$
@@ -387,7 +388,7 @@
public void testSupportsScalar1() throws Exception {
BasicSourceCapabilities caps = new BasicSourceCapabilities();
- Function func = new Function("+", new Expression[] { new ElementSymbol("x"), new ElementSymbol("y") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Function func = new Function("+", new Expression[] { new Constant(1), new Constant(2) }); //$NON-NLS-1$
helpTestSupportsScalar(caps, func, false);
}
@@ -409,14 +410,6 @@
helpTestSupportsScalar(caps, func, true);
}
- // Test where function is unknown
- public void testSupportsScalar5() throws Exception {
- BasicSourceCapabilities caps = new BasicSourceCapabilities();
-
- Function func = new Function("sasquatch", new Expression[] { }); //$NON-NLS-1$
- helpTestSupportsScalar(caps, func, false);
- }
-
public void testSupportsDistinct1() throws Exception {
// Set up metadata
FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -62,7 +62,6 @@
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataAdapter;
@@ -5261,7 +5260,7 @@
caps.setFunctionSupport("myrtrim", true); //$NON-NLS-1$
capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
processPreparedStatement(sql, expected, dataManager, capFinder,
@@ -5309,7 +5308,7 @@
caps.setFunctionSupport("concat", true); //$NON-NLS-1$
capFinder.addCapabilities("pm4", caps); //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
processPreparedStatement(sql, expected, dataManager, capFinder,
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,13 +22,7 @@
package org.teiid.query.resolver;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -57,7 +51,6 @@
import org.teiid.query.function.FunctionDescriptor;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
@@ -1587,7 +1580,7 @@
@Test public void testNamespacedFunction() throws Exception {
String sql = "SELECT namespace.func('e1') FROM vm1.g1 "; //$NON-NLS-1$
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
Query command = (Query) helpParse(sql);
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -46,7 +46,6 @@
import org.teiid.core.util.TimestampWithTimezone;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.optimizer.FakeFunctionMetadataSource;
import org.teiid.query.parser.QueryParser;
@@ -2364,7 +2363,7 @@
}
@Test public void testUDFParse() throws Exception {
- FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+ FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
String sql = "parsedate_(pm1.g1.e1) = {d'2001-01-01'}";
helpTestRewriteCriteria(sql, parseCriteria(sql, metadata), metadata);
Modified: trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -302,9 +302,11 @@
List<FunctionTree> udfs = new ArrayList<FunctionTree>();
for (Schema schema : metadataStore.getSchemas().values()) {
vdbMetaData.addModel(FakeMetadataFactory.createModel(schema.getName(), schema.isPhysical()));
- udfs.add(new FunctionTree(new UDFSource(schema.getFunctions().values()), true));
+ if (!schema.getFunctions().isEmpty()) {
+ udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values()), true));
+ }
}
- return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs.toArray(new FunctionTree[udfs.size()]));
+ return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs);
}
/**
Modified: trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -104,7 +104,7 @@
@Override
public FunctionLibrary getFunctionLibrary() {
SystemFunctionManager sfm = new SystemFunctionManager();
- return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods)));
+ return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree("foo", new UDFSource(methods))); //$NON-NLS-1$
}
};
}
Modified: trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -83,11 +83,14 @@
IndexMetadataFactory imf = loadMetadata(vdbURL);
Collection <FunctionMethod> methods = null;
+ Collection<FunctionTree> trees = null;
if (udfFile != null) {
+ String schema = FileUtils.getFilenameWithoutExtension(udfFile.getPath());
methods = FunctionMetadataReader.loadFunctionMethods(udfFile.openStream());
+ trees = Arrays.asList(new FunctionTree(schema, new UDFSource(methods), true));
}
SystemFunctionManager sfm = new SystemFunctionManager();
- vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods), true));
+ vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), trees);
VDB_CACHE.put(vdbURL, vdbmetadata);
return vdbmetadata;
} catch (URISyntaxException e) {
Modified: trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,15 +25,16 @@
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import org.teiid.adminapi.DataPolicy;
import org.teiid.adminapi.Model;
import org.teiid.adminapi.impl.DataPolicyMetadata;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.core.CoreConstants;
import org.teiid.dqp.internal.datamgr.ConnectorManager;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
-import org.teiid.metadata.AbstractMetadataRecord;
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.MetadataStore;
import org.teiid.metadata.Schema;
@@ -100,8 +101,8 @@
private TransformationMetadata buildTransformationMetaData(VDBMetaData vdb, LinkedHashMap<String, Resource> visibilityMap, MetadataStoreGroup stores, UDFMetaData udf, FunctionTree systemFunctions) {
Collection <FunctionTree> udfs = new ArrayList<FunctionTree>();
if (udf != null) {
- for (Collection<FunctionMethod> methods:udf.getFunctions()) {
- udfs.add(new FunctionTree(new UDFSource(methods), true));
+ for (Map.Entry<String, Collection<FunctionMethod>> entry : udf.getFunctions().entrySet()) {
+ udfs.add(new FunctionTree(entry.getKey(), new UDFSource(entry.getValue()), true));
}
}
@@ -110,7 +111,7 @@
compositeStore.addMetadataStore(s);
}
- TransformationMetadata metadata = new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs.toArray(new FunctionTree[udfs.size()]));
+ TransformationMetadata metadata = new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs);
return metadata;
}
@@ -161,28 +162,23 @@
mergedUDF.addFunctions(this.udf);
}
if (this.stores != null) {
+ //schema scoped source functions - this is only a dynamic vdb concept
for(MetadataStore store:this.stores.getStores()) {
for (Schema schema:store.getSchemas().values()) {
Collection<FunctionMethod> funcs = schema.getFunctions().values();
- for(FunctionMethod func:funcs) {
- func.setNameInSource(func.getName());
- func.setName(schema.getName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- }
- mergedUDF.addFunctions(funcs);
+ mergedUDF.addFunctions(schema.getName(), funcs);
}
}
}
if (this.cmr != null) {
+ //system scoped common source functions
for (ConnectorManager cm:this.cmr.getConnectorManagers().values()) {
List<FunctionMethod> funcs = cm.getPushDownFunctions();
- for(FunctionMethod func:funcs) {
- func.setNameInSource(cm.getTranslatorName()+ AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- func.setName(cm.getModelName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
- }
- mergedUDF.addFunctions(funcs);
+ mergedUDF.addFunctions(CoreConstants.SYSTEM_MODEL, funcs);
}
}
if (this.children != null) {
+ //udf model functions - also scoped to the model
for (CompositeVDB child:this.children.values()) {
UDFMetaData funcs = child.getUDF();
if (funcs != null) {
Modified: trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,20 +25,26 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import javax.xml.bind.JAXBException;
import org.jboss.managed.api.annotation.ManagementObject;
import org.jboss.virtual.VirtualFile;
+import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.metadata.FunctionMethod;
+import org.teiid.query.QueryPlugin;
import org.teiid.query.function.metadata.FunctionMetadataReader;
+import org.teiid.query.function.metadata.FunctionMetadataValidator;
+import org.teiid.query.report.ActivityReport;
+import org.teiid.query.report.ReportItem;
import org.teiid.runtime.RuntimePlugin;
@ManagementObject
public class UDFMetaData {
- private Collection<Collection <FunctionMethod>> methods = new ArrayList<Collection<FunctionMethod>>();
-
+ private HashMap<String, Collection <FunctionMethod>> methods = new HashMap<String, Collection<FunctionMethod>>();
private HashMap<String, VirtualFile> files = new HashMap<String, VirtualFile>();
public void addModelFile(VirtualFile file) {
@@ -46,31 +52,45 @@
}
- void buildFunctionModelFile(String name) throws IOException, JAXBException {
+ void buildFunctionModelFile(String name, String path) throws IOException, JAXBException, QueryMetadataException {
for (String f:files.keySet()) {
- if (f.endsWith(name)) {
- name = f;
+ if (f.endsWith(path)) {
+ path = f;
break;
}
}
- VirtualFile file =this.files.get(name);
- if (file != null) {
- this.methods.add(FunctionMetadataReader.loadFunctionMethods(file.openStream()));
- }
- else {
+ VirtualFile file =this.files.get(path);
+ if (file == null) {
throw new IOException(RuntimePlugin.Util.getString("udf_model_not_found", name)); //$NON-NLS-1$
}
+ List<FunctionMethod> udfMethods = FunctionMetadataReader.loadFunctionMethods(file.openStream());
+ ActivityReport<ReportItem> report = new ActivityReport<ReportItem>("UDF load"); //$NON-NLS-1$
+ FunctionMetadataValidator.validateFunctionMethods(udfMethods,report);
+ if(report.hasItems()) {
+ throw new QueryMetadataException(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
+ }
+ this.methods.put(name, udfMethods);
}
- public Collection<Collection <FunctionMethod>> getFunctions(){
+ public Map<String, Collection <FunctionMethod>> getFunctions(){
return this.methods;
}
- public void addFunctions(Collection <FunctionMethod> funcs){
- this.methods.add(funcs);
+ public void addFunctions(String name, Collection <FunctionMethod> funcs){
+ if (funcs.isEmpty()) {
+ return;
+ }
+ Collection <FunctionMethod> old = this.methods.put(name, funcs);
+ if (old != null) {
+ ArrayList<FunctionMethod> combined = new ArrayList<FunctionMethod>(old);
+ combined.addAll(funcs);
+ this.methods.put(name, combined);
+ }
}
public void addFunctions(UDFMetaData funcs){
- this.methods.addAll(funcs.getFunctions());
+ for (Map.Entry<String, Collection<FunctionMethod>> entry : funcs.getFunctions().entrySet()) {
+ addFunctions(entry.getKey(), entry.getValue());
+ }
}
}
Modified: trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -168,7 +168,7 @@
if (path == null) {
throw new DeploymentException(RuntimePlugin.Util.getString("invalid_udf_file", model.getName())); //$NON-NLS-1$
}
- udf.buildFunctionModelFile(path);
+ udf.buildFunctionModelFile(model.getName(), path);
}
}
Modified: trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,7 +116,7 @@
@Test
public void testTranslatorDefinedFunction() throws Exception {
- helpResolve("SELECT bqt1.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
+ helpResolve("SELECT SYS.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
}
@Test
@@ -126,7 +126,7 @@
@Test
public void testFullyQualifiedDuplicate() throws Exception {
- helpResolve("SELECT bqt1.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
+ helpResolve("SELECT SYS.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
}
@Test
More information about the teiid-commits
mailing list