[teiid-commits] teiid SVN: r1884 - in trunk: engine/src/main/java/com/metamatrix/query/function and 1 other directories.
teiid-commits at lists.jboss.org
teiid-commits at lists.jboss.org
Mon Mar 1 16:33:09 EST 2010
Author: shawkins
Date: 2010-03-01 16:33:09 -0500 (Mon, 01 Mar 2010)
New Revision: 1884
Modified:
trunk/common-core/src/main/java/com/metamatrix/common/types/DataTypeManager.java
trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java
trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java
Log:
TEIID-1004 adding a check to filter nan/infinite values
Modified: trunk/common-core/src/main/java/com/metamatrix/common/types/DataTypeManager.java
===================================================================
--- trunk/common-core/src/main/java/com/metamatrix/common/types/DataTypeManager.java 2010-03-01 21:26:34 UTC (rev 1883)
+++ trunk/common-core/src/main/java/com/metamatrix/common/types/DataTypeManager.java 2010-03-01 21:33:09 UTC (rev 1884)
@@ -97,7 +97,6 @@
private static class HashedValueCache<T> implements ValueCache<T> {
final Object[] cache;
- final boolean weak = false;
HashedValueCache(int size) {
cache = new Object[1 << size];
@@ -842,10 +841,9 @@
}
//TODO: this initial lookup is inefficient, since there are likely collisions
ValueCache valueCache = valueMaps.get(value.getClass());
- if (valueCache == null) {
- return value;
+ if (valueCache != null) {
+ value = (T)valueCache.getValue(value);
}
- return (T)valueCache.getValue(value);
}
return value;
}
Modified: trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java 2010-03-01 21:26:34 UTC (rev 1883)
+++ trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java 2010-03-01 21:33:09 UTC (rev 1884)
@@ -31,6 +31,7 @@
import com.metamatrix.api.exception.query.QueryResolverException;
import com.metamatrix.common.types.DataTypeManager;
import com.metamatrix.common.types.TransformationException;
+import com.metamatrix.common.util.PropertiesUtils;
import com.metamatrix.query.QueryPlugin;
import com.metamatrix.query.function.metadata.FunctionMethod;
import com.metamatrix.query.function.metadata.FunctionParameter;
@@ -45,8 +46,10 @@
* functions are available, resolve function signatures, and invoke system
* and user-defined functions.
*/
-public class FunctionLibrary {
-
+public class FunctionLibrary {
+
+ private static final boolean ALLOW_NAN_INFINITY = PropertiesUtils.getBooleanProperty(System.getProperties(), "org.teiid.allowNanInfinity", false); //$NON-NLS-1$
+
// Special type conversion functions
public static final String CONVERT = "convert"; //$NON-NLS-1$
public static final String CAST = "cast"; //$NON-NLS-1$
@@ -393,6 +396,19 @@
values = newValues;
}
Object result = method.invoke(null, values);
+ if (!ALLOW_NAN_INFINITY) {
+ if (result instanceof Double) {
+ Double floatVal = (Double)result;
+ if (Double.isInfinite(floatVal) || Double.isNaN(floatVal)) {
+ throw new FunctionExecutionException(new ArithmeticException("Infinite or invalid result"), ErrorMessageKeys.FUNCTION_0003, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0003, fd.getName())); //$NON-NLS-1$
+ }
+ } else if (result instanceof Float) {
+ Float floatVal = (Float)result;
+ if (Float.isInfinite(floatVal) || Float.isNaN(floatVal)) {
+ throw new FunctionExecutionException(new ArithmeticException("Infinite or invalid result"), ErrorMessageKeys.FUNCTION_0003, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0003, fd.getName())); //$NON-NLS-1$
+ }
+ }
+ }
result = DataTypeManager.convertToRuntimeType(result);
result = DataTypeManager.transformValue(result, fd.getReturnType());
return result;
Modified: trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java 2010-03-01 21:26:34 UTC (rev 1883)
+++ trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java 2010-03-01 21:33:09 UTC (rev 1884)
@@ -168,19 +168,31 @@
}
private void helpInvokeMethod(String fname, Object[] inputs, Object expectedOutput) {
- // Build type signature
- Class[] types = new Class[inputs.length];
- for(int i=0; i<inputs.length; i++) {
- types[i] = DataTypeManager.determineDataTypeClass(inputs[i]);
- }
try {
- helpInvokeMethod(fname, types, inputs, new CommandContext(), expectedOutput);
+ helpInvokeMethod(fname, null, inputs, null, expectedOutput);
} catch (Exception err) {
throw new RuntimeException(err);
}
}
- private void helpInvokeMethod(String fname, Class[] types, Object[] inputs, CommandContext context , Object expectedOutput) throws InvalidFunctionException, FunctionExecutionException {
+ private void helpInvokeMethod(String fname, Class[] types, Object[] inputs, CommandContext context, Object expectedOutput) throws InvalidFunctionException, FunctionExecutionException {
+ Object actualOutput = helpInvokeMethod(fname, types, inputs, context);
+ assertEquals("Actual function output not equal to expected: ", expectedOutput, actualOutput); //$NON-NLS-1$
+ }
+
+ private Object helpInvokeMethod(String fname, Class[] types,
+ Object[] inputs, CommandContext context)
+ throws InvalidFunctionException, FunctionExecutionException {
+ if (types == null) {
+ // Build type signature
+ types = new Class[inputs.length];
+ for(int i=0; i<inputs.length; i++) {
+ types[i] = DataTypeManager.determineDataTypeClass(inputs[i]);
+ }
+ }
+ if (context == null) {
+ context = new CommandContext();
+ }
Object actualOutput = null;
// Find function descriptor
FunctionDescriptor descriptor = library.findFunction(fname, types);
@@ -197,64 +209,18 @@
// Invoke function with inputs
actualOutput = library.invokeFunction(descriptor, inputs);
}
- assertEquals("Actual function output not equal to expected: ", expectedOutput, actualOutput); //$NON-NLS-1$
- }
+ return actualOutput;
+ }
- private void helpInvokeMethodFail(String fname, Object[] inputs, Object expectedException) {
- Object actualOutput = null;
- try {
- // Build type signature
- Class[] types = new Class[inputs.length];
- for(int i=0; i<inputs.length; i++) {
- types[i] = DataTypeManager.determineDataTypeClass(inputs[i]);
- }
-
- // Find function descriptor
- FunctionDescriptor descriptor = library.findFunction(fname, types);
- if (descriptor != null && descriptor.requiresContext()) {
- // Invoke function with inputs
- Object[] in = new Object[inputs.length+1];
- in[0] = new CommandContext();
- for (int i = 0; i < inputs.length; i++) {
- in[i+1] = inputs[i];
- }
- actualOutput = library.invokeFunction(descriptor, in);
- }
- else {
- // Invoke function with inputs
- actualOutput = library.invokeFunction(descriptor, inputs);
- }
-
- } catch(Throwable e) {
- //e.printStackTrace();
- assertNull(actualOutput);
- assertEquals("Unexpected exception.", e.getClass().getName(), ((FunctionExecutionException)expectedException).getClass().getName()); //$NON-NLS-1$
- }
+ private void helpInvokeMethodFail(String fname, Object[] inputs) throws InvalidFunctionException {
+ helpInvokeMethodFail(fname, null, inputs);
}
- private void helpInvokeMethodFail(String fname, Class types[], Object[] inputs, Object expectedException) {
- Object actualOutput = null;
- try {
- // Find function descriptor
- FunctionDescriptor descriptor = library.findFunction(fname, types);
- if (descriptor != null && descriptor.requiresContext()) {
- // Invoke function with inputs
- Object[] in = new Object[inputs.length+1];
- in[0] = new CommandContext();
- for (int i = 0; i < inputs.length; i++) {
- in[i+1] = inputs[i];
- }
- actualOutput = library.invokeFunction(descriptor, in);
- }
- else {
- // Invoke function with inputs
- actualOutput = library.invokeFunction(descriptor, inputs);
- }
-
- } catch(Throwable e) {
- //e.printStackTrace();
- assertNull(actualOutput);
- assertEquals("Unexpected exception.", e.getClass().getName(), ((FunctionExecutionException)expectedException).getClass().getName()); //$NON-NLS-1$
+ private void helpInvokeMethodFail(String fname, Class<?> types[], Object[] inputs) throws InvalidFunctionException {
+ try {
+ helpInvokeMethod(fname, types, inputs, null);
+ fail("expected exception"); //$NON-NLS-1$
+ } catch (FunctionExecutionException err) {
}
}
// ################################## ACTUAL TESTS ################################
@@ -635,6 +601,10 @@
helpInvokeMethod("/", new Object[] { new BigDecimal("3"), new BigDecimal("2") }, new BigDecimal("2")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
+ @Test public void testInvokeDivide7() throws Exception {
+ helpInvokeMethodFail("/", new Object[] { new Float("3"), new Float("0") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+
@Test public void testInvokeDivideMod() {
helpInvokeMethod("mod", new Object[] { new BigDecimal("3.1"), new BigDecimal("2") }, new BigDecimal("1.1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
@@ -802,9 +772,8 @@
helpInvokeMethod("formatTimestamp", new Object[] {TimestampUtil.createTimestamp(103, 2, 5, 3, 4, 12, 255), new String("yyyy-mm-dd hh:mm:ss.SSSS") }, "2003-04-05 03:04:12.0000"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
- @Test public void testInvokeFormatTimestampFail() {
- helpInvokeMethodFail("formatTimestamp", new Object[] {TimestampUtil.createTimestamp(103, 2, 5, 3, 4, 12, 255), new String("mm/dd/nn h:mm a") }, //$NON-NLS-1$ //$NON-NLS-2$
- new FunctionExecutionException("")); //$NON-NLS-1$
+ @Test public void testInvokeFormatTimestampFail() throws Exception {
+ helpInvokeMethodFail("formatTimestamp", new Object[] {TimestampUtil.createTimestamp(103, 2, 5, 3, 4, 12, 255), new String("mm/dd/nn h:mm a") }); //$NON-NLS-1$
}
@Test public void testInvokeParseTimestamp1() {
@@ -991,15 +960,15 @@
}
/** should fail, with start > string1.length() */
- @Test public void testInvokeInsert4() {
+ @Test public void testInvokeInsert4() throws Exception {
helpInvokeMethodFail("insert", new Object[] {new String(""), new Integer(2), //$NON-NLS-1$ //$NON-NLS-2$
- new Integer(0), new String("cat")}, new FunctionExecutionException("")); //$NON-NLS-1$ //$NON-NLS-2$
+ new Integer(0), new String("cat")}); //$NON-NLS-1$ //$NON-NLS-2$
}
/** should fail, with length > 0 and input string1.length() = 0 */
- @Test public void testInvokeInsert5() {
+ @Test public void testInvokeInsert5() throws Exception {
helpInvokeMethodFail("insert", new Object[] {new String(""), new Integer(1), //$NON-NLS-1$ //$NON-NLS-2$
- new Integer(1), new String("cat")}, new FunctionExecutionException("")); //$NON-NLS-1$ //$NON-NLS-2$
+ new Integer(1), new String("cat")}); //$NON-NLS-1$ //$NON-NLS-2$
}
/** (length + start) > string1.length(), then just append str2 starting at start position */
@@ -1210,11 +1179,10 @@
helpInvokeMethod("modifyTimeZone", new Object[] {ts, "America/New_York" }, out); //$NON-NLS-1$ //$NON-NLS-2$
}
- @Test public void testInvokeRand() {
+ @Test public void testInvokeRand() throws Exception {
helpInvokeMethod("rand", new Object[] {new Integer(100)}, new Double(0.7220096548596434)); //$NON-NLS-1$
- helpInvokeMethodFail("rand", new Class[] {Integer.class}, new Object[] {new Double(100)}, new FunctionExecutionException("")); //$NON-NLS-1$ //$NON-NLS-2$
// this does not actually fail but returns a result
- helpInvokeMethodFail("rand", new Class[] {Integer.class}, new Object[] {null}, new FunctionExecutionException("")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertNotNull(helpInvokeMethod("rand", new Class[] {Integer.class}, new Object[] {null}, null)); //$NON-NLS-1$
}
@Test public void testInvokeUser() throws Exception {
@@ -1271,6 +1239,10 @@
helpInvokeMethod("log10", new Object[] { new Double("10") }, new Double("1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
+ @Test public void testInvokeLog10Error() throws Exception {
+ helpInvokeMethodFail("log10", new Object[] { new Double("0") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
@Test public void testInvokePower() {
helpInvokeMethod("power", new Object[] { new Double("10"), new Double("2") }, new Double("100")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
More information about the teiid-commits
mailing list