use of org.teiid.query.function.FunctionLibrary.ConversionResult in project teiid by teiid.
the class TestFunctionLibrary method helpFindConversions.
private void helpFindConversions(String fname, Class<?>[] types, FunctionDescriptor[] expected) {
FunctionDescriptor[] actual;
try {
ConversionResult result = library.determineNecessaryConversions(fname, null, new Expression[types.length], types, false);
if (result.needsConverion) {
actual = library.getConverts(result.method, types);
} else if (result.method != null) {
actual = new FunctionDescriptor[types.length];
} else {
actual = null;
}
} catch (InvalidFunctionException e) {
actual = null;
}
if (expected == null) {
if (actual != null) {
// $NON-NLS-1$ //$NON-NLS-2$
fail("Expected to find no conversion for " + fname + Arrays.asList(types) + " but found: " + Arrays.asList(actual));
}
} else {
if (actual == null) {
// $NON-NLS-1$ //$NON-NLS-2$
fail("Expected to find conversion for " + fname + Arrays.asList(types) + " but found none");
} else {
// Compare returned descriptors with expected descriptor
for (int i = 0; i < expected.length; i++) {
if (expected[i] == null) {
if (actual[i] != null) {
// $NON-NLS-1$ //$NON-NLS-2$
fail("Expected no conversion at index " + i + ", but found: " + actual[i]);
}
} else {
if (actual[i] == null) {
// $NON-NLS-1$ //$NON-NLS-2$
fail("Expected conversion at index " + i + ", but found none.");
} else {
// $NON-NLS-1$
assertEquals("Expected conversion function names do not match: ", expected[i].getName(), actual[i].getName());
// $NON-NLS-1$
assertEquals("Expected conversion arg lengths do not match: ", expected[i].getTypes().length, actual[i].getTypes().length);
}
}
}
}
}
}
use of org.teiid.query.function.FunctionLibrary.ConversionResult in project teiid by teiid.
the class ResolverVisitor method findWithImplicitConversions.
/**
* Find possible matches based on implicit conversions of the arguments.
* NOTE: This method has the side-effect of explicitly inserting conversions into the function arguments,
* and thereby changing the structure of the function call.
* @param library
* @param function
* @param types
* @return
* @throws TeiidComponentException
* @throws InvalidFunctionException
* @since 4.3
*/
private List<FunctionDescriptor> findWithImplicitConversions(FunctionLibrary library, Function function, Expression[] args, Class<?>[] types, boolean hasArgWithoutType) throws QueryResolverException, TeiidComponentException, InvalidFunctionException {
// Try to find implicit conversion path to still perform this function
ConversionResult cr = library.determineNecessaryConversions(function.getName(), function.getType(), args, types, hasArgWithoutType);
if (cr.method == null) {
return Collections.emptyList();
}
Class<?>[] newSignature = types;
if (cr.needsConverion) {
FunctionDescriptor[] conversions = library.getConverts(cr.method, types);
newSignature = new Class[conversions.length];
// Insert new conversion functions as necessary, while building new signature
for (int i = 0; i < conversions.length; i++) {
Class<?> newType = types[i];
if (conversions[i] != null) {
newType = conversions[i].getReturnType();
setDesiredType(args[i], newType, function);
// only currently typed expressions need conversions
if (types[i] != null && newType != DataTypeManager.DefaultDataClasses.OBJECT) {
// directly resolve constants
if (args[i] instanceof Constant && newType == DataTypeManager.DefaultDataClasses.TIMESTAMP) {
args[i] = ResolverUtil.getProperlyTypedConstant(((Constant) args[i]).getValue(), newType);
} else {
function.insertConversion(i, conversions[i]);
}
}
}
newSignature[i] = newType;
}
}
String name = cr.method.getFullName();
// Now resolve using the new signature to get the function's descriptor
return library.findAllFunctions(name, newSignature);
}
Aggregations