From e7f3aa37a712a82b2753050787111864de36cdc2 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sat, 31 Mar 2018 02:36:50 +0000 Subject: [PATCH] fix null handling for string funcs git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1145 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../jackcess/impl/expr/DefaultFunctions.java | 38 +++++++++++++++++-- .../impl/expr/DefaultTextFunctions.java | 6 +-- .../impl/expr/DefaultFunctionsTest.java | 9 +++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java index 77ddb74..e88f6c8 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java @@ -222,6 +222,40 @@ public class DefaultFunctions protected abstract Value evalVar(EvalContext ctx, Value[] params); } + public static class StringFuncWrapper implements Function + { + private final String _name; + private final Function _delegate; + + public StringFuncWrapper(Function delegate) { + _delegate = delegate; + _name = _delegate.getName() + NON_VAR_SUFFIX; + } + + public String getName() { + return _name; + } + + public boolean isPure() { + return _delegate.isPure(); + } + + public Value eval(EvalContext ctx, Value... params) { + Value result = _delegate.eval(ctx, params); + if(result.isNull()) { + // non-variant version does not do null-propagation, so force + // exception to be thrown here + result.getAsString(); + } + return result; + } + + @Override + public String toString() { + return getName() + "()"; + } + } + public static final Function IIF = registerFunc(new Func3("IIf") { @Override @@ -497,10 +531,8 @@ public class DefaultFunctions } static Function registerStringFunc(Function func) { - // for our purposes the non-variant versions are the same function - // (e.g. "Foo" and "Foo$") registerFunc(func.getName(), func); - registerFunc(func.getName() + NON_VAR_SUFFIX, func); + registerFunc(new StringFuncWrapper(func)); return func; } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java index 96c6115..2217c68 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java @@ -66,7 +66,7 @@ public class DefaultTextFunctions } }); - public static final Function CHR = registerStringFunc(new Func1("Chr") { + public static final Function CHR = registerStringFunc(new Func1NullIsNull("Chr") { @Override protected Value eval1(EvalContext ctx, Value param1) { int lv = param1.getAsLongInt(); @@ -79,7 +79,7 @@ public class DefaultTextFunctions } }); - public static final Function CHRW = registerStringFunc(new Func1("ChrW") { + public static final Function CHRW = registerStringFunc(new Func1NullIsNull("ChrW") { @Override protected Value eval1(EvalContext ctx, Value param1) { int lv = param1.getAsLongInt(); @@ -88,7 +88,7 @@ public class DefaultTextFunctions } }); - public static final Function STR = registerStringFunc(new Func1("Str") { + public static final Function STR = registerStringFunc(new Func1NullIsNull("Str") { @Override protected Value eval1(EvalContext ctx, Value param1) { BigDecimal bd = param1.getAsBigDecimal(); diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java index 0eec59b..ae9916c 100644 --- a/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java +++ b/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java @@ -59,6 +59,15 @@ public class DefaultFunctionsTest extends TestCase assertEquals("23072", eval("=Oct(9786)")); assertEquals(" 9786", eval("=Str(9786)")); assertEquals("-42", eval("=Str(-42)")); + assertEquals("-42", eval("=Str$(-42)")); + assertNull(eval("=Str(Null)")); + + try { + eval("=Str$(Null)"); + fail("UnsupportedOperationException should have been thrown"); + } catch(UnsupportedOperationException expected) { + // success + } assertEquals(-1, eval("=CBool(\"1\")")); assertEquals(13, eval("=CByte(\"13\")")); -- 2.39.5