use of org.teiid.metadata.FunctionParameter in project teiid by teiid.
the class TestMatViews method setUp.
@Before
public void setUp() throws Exception {
server = new FakeServer(true);
HashMap<String, Collection<FunctionMethod>> udfs = new HashMap<String, Collection<FunctionMethod>>();
udfs.put("funcs", Arrays.asList(new FunctionMethod("pause", null, null, PushDown.CANNOT_PUSHDOWN, TestMatViews.class.getName(), "pause", null, new FunctionParameter("return", DataTypeManager.DefaultDataTypes.INTEGER), true, Determinism.NONDETERMINISTIC)));
server.deployVDB(MATVIEWS, UnitTestUtil.getTestDataPath() + "/matviews.vdb", new DeployVDBParameter(udfs, null));
conn = server.createConnection("jdbc:teiid:matviews");
}
use of org.teiid.metadata.FunctionParameter in project teiid by teiid.
the class FunctionTree method createFunctionDescriptor.
private FunctionDescriptor createFunctionDescriptor(FunctionMetadataSource source, FunctionMethod method, Class<?>[] types, boolean system) {
// Get return type
FunctionParameter outputParam = method.getOutputParameter();
Class<?> outputType = null;
if (outputParam != null) {
outputType = DataTypeManager.getDataTypeClass(outputParam.getRuntimeType());
}
List<Class<?>> inputTypes = new ArrayList<Class<?>>(Arrays.asList(types));
boolean hasWrappedArg = false;
if (!system) {
for (int i = 0; i < types.length; i++) {
if (types[i] == DataTypeManager.DefaultDataClasses.VARBINARY) {
hasWrappedArg = true;
inputTypes.set(i, byte[].class);
}
}
}
if (method.isVarArgs()) {
inputTypes.set(inputTypes.size() - 1, DataTypeManager.getArrayType(inputTypes.get(inputTypes.size() - 1)));
}
Method invocationMethod = method.getMethod();
boolean requiresContext = false;
// Defect 20007 - Ignore the invocation method if pushdown is not required.
if (validateClass && (method.getPushdown() == PushDown.CAN_PUSHDOWN || method.getPushdown() == PushDown.CANNOT_PUSHDOWN)) {
if (invocationMethod == null) {
if (method.getInvocationClass() == null || method.getInvocationMethod() == null) {
throw new MetadataException(QueryPlugin.Event.TEIID31123, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31123, method.getName()));
}
try {
Class<?> methodClass = source.getInvocationClass(method.getInvocationClass());
ReflectionHelper helper = new ReflectionHelper(methodClass);
try {
invocationMethod = helper.findBestMethodWithSignature(method.getInvocationMethod(), inputTypes);
} catch (NoSuchMethodException e) {
inputTypes.add(0, CommandContext.class);
invocationMethod = helper.findBestMethodWithSignature(method.getInvocationMethod(), inputTypes);
requiresContext = true;
}
} catch (ClassNotFoundException e) {
throw new MetadataException(QueryPlugin.Event.TEIID30387, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30387, method.getName(), method.getInvocationClass()));
} catch (NoSuchMethodException e) {
throw new MetadataException(QueryPlugin.Event.TEIID30388, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30388, method, method.getInvocationClass(), method.getInvocationMethod()));
} catch (Exception e) {
throw new MetadataException(QueryPlugin.Event.TEIID30389, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30389, method, method.getInvocationClass(), method.getInvocationMethod()));
}
} else {
requiresContext = (invocationMethod.getParameterTypes().length > 0 && org.teiid.CommandContext.class.isAssignableFrom(invocationMethod.getParameterTypes()[0]));
}
if (invocationMethod != null) {
// Check return type is non void
Class<?> methodReturn = invocationMethod.getReturnType();
if (method.getAggregateAttributes() == null && methodReturn.equals(Void.TYPE)) {
throw new MetadataException(QueryPlugin.Event.TEIID30390, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30390, method.getName(), invocationMethod));
}
// Check that method is public
int modifiers = invocationMethod.getModifiers();
if (!Modifier.isPublic(modifiers)) {
throw new MetadataException(QueryPlugin.Event.TEIID30391, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30391, method.getName(), invocationMethod));
}
// Check that method is static
if (!Modifier.isStatic(modifiers)) {
if (method.getAggregateAttributes() == null) {
throw new MetadataException(QueryPlugin.Event.TEIID30392, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30392, method.getName(), invocationMethod));
}
} else if (method.getAggregateAttributes() != null) {
throw new MetadataException(QueryPlugin.Event.TEIID30600, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30600, method.getName(), invocationMethod));
}
if (method.getAggregateAttributes() != null && !(UserDefinedAggregate.class.isAssignableFrom(invocationMethod.getDeclaringClass()))) {
throw new MetadataException(QueryPlugin.Event.TEIID30601, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30601, method.getName(), method.getInvocationClass(), UserDefinedAggregate.class.getName()));
}
try {
// turn off access checks for a small performance boost
invocationMethod.setAccessible(true);
} catch (SecurityException e) {
// just ignore
}
method.setMethod(invocationMethod);
}
}
FunctionDescriptor result = new FunctionDescriptor(method, types, outputType, invocationMethod, requiresContext, source.getClassLoader());
if (validateClass && method.getAggregateAttributes() != null && (method.getPushdown() == PushDown.CAN_PUSHDOWN || method.getPushdown() == PushDown.CANNOT_PUSHDOWN)) {
try {
result.newInstance();
} catch (FunctionExecutionException e) {
// should only happen if the method is null / not found
throw new MetadataException(QueryPlugin.Event.TEIID30387, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30387, method.getName(), method.getInvocationClass()));
}
}
result.setHasWrappedArgs(hasWrappedArg);
return result;
}
use of org.teiid.metadata.FunctionParameter in project teiid by teiid.
the class FunctionMetadataReader method parseScalarFunction.
private static FunctionMethod parseScalarFunction(XMLStreamReader reader) throws XMLStreamException {
FunctionMethod function = new FunctionMethod();
if (reader.getAttributeCount() > 0) {
for (int i = 0; i < reader.getAttributeCount(); i++) {
String attrName = reader.getAttributeLocalName(i);
String attrValue = reader.getAttributeValue(i);
if (Element.NAME.getLocalName().equals(attrName)) {
function.setName(attrValue);
} else if (Element.CATEGORY.getLocalName().equals(attrName)) {
function.setCategory(attrValue);
} else if (Element.INVOCATION_CLASS.getLocalName().equals(attrName)) {
function.setInvocationClass(attrValue);
// TODO: set class loader
// function.setClassloader();
} else if (Element.INVOCATION_METHOD.getLocalName().equals(attrName)) {
function.setInvocationMethod(attrValue);
} else if (Element.PUSHDOWN.getLocalName().equals(attrName)) {
function.setPushDown(attrValue);
} else if (Element.DETERMINISTIC.getLocalName().equals(attrName)) {
function.setDeterministicBoolean(Boolean.parseBoolean(attrValue));
}
}
}
LinkedList<FunctionParameter> inputs = new LinkedList<FunctionParameter>();
while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
switch(Element.forName(reader.getLocalName())) {
case INPUT_PARAMTERS:
inputs.addLast(parseParameter(reader));
break;
case RETURN_PARAMETER:
function.setOutputParameter(parseParameter(reader));
break;
}
}
function.setInputParameters(inputs);
return function;
}
use of org.teiid.metadata.FunctionParameter in project teiid by teiid.
the class SystemSource method addConstantDateFunction.
/**
* Date functions a marked as command deterministic, since we prefer pre-evaluation rather than row-by-row
* evaluation.
*/
private void addConstantDateFunction(String name, String description, String methodName, String returnType, Determinism determinism) {
FunctionMethod method = new FunctionMethod(name, description, DATETIME, FUNCTION_CLASS, methodName, new FunctionParameter[] {}, // $NON-NLS-1$
new FunctionParameter("result", returnType, description));
method.setDeterminism(determinism);
functions.add(method);
}
use of org.teiid.metadata.FunctionParameter in project teiid by teiid.
the class SystemSource method addTimeFunction.
private void addTimeFunction(String name, String methodName, String timeDesc, String timestampDesc, String returnType) {
functions.add(new FunctionMethod(name, timeDesc, DATETIME, FUNCTION_CLASS, methodName, new FunctionParameter[] { // $NON-NLS-1$
new FunctionParameter("time", DataTypeManager.DefaultDataTypes.TIME, timeDesc) }, // $NON-NLS-1$
new FunctionParameter("result", returnType, timeDesc)));
functions.add(new FunctionMethod(name, timestampDesc, DATETIME, FUNCTION_CLASS, methodName, new FunctionParameter[] { // $NON-NLS-1$
new FunctionParameter("timestamp", DataTypeManager.DefaultDataTypes.TIMESTAMP, timestampDesc) }, // $NON-NLS-1$
new FunctionParameter("result", returnType, timestampDesc)));
}
Aggregations