I'm trying to fix https://issues.apache.org/jira/browse/DAFFODIL-2574. The core
issue is that Java arithmetic operations return Int, even if for example you are
adding two Shorts. Our DPath implementation doesn't expect that, and assumes
xs:short + xs:short always result in an xs:short, that way it knows all the
types at compile time and can put in appropriate conversions.
I was looking through the Xpath/XQuery spec to figure what the corret behavior
is, and it feels kindof ambiguous. It defines arithmetic functions like:
op:numeric-add($arg1 as numeric, $arg2 as numeric) as numeric
But it doesn't really say what the resulting numeric should be. It really just
says
op:operation(xs:integer, xs:integer)
should return "xs:integer", but it's not completely clear if that's saying the
result should be promoted to an xs:integer, or the result just should derive
xs:integer. The later is my interpretation, suggesting we should not promote,
and I think is what DPath intends.
But that then has issues with underflow/overflow--what happens when a short +
short doesn't fit into a short. Do we promote to an int? Do we error. The spec
does say this regarding overflow underflow:
For xs:integer operations, implementations that support limited-precision
integer operations ·must· select from the following options:
They ·may· choose to always raise an error [err:FOAR0002].
They ·may· provide an ·implementation-defined· mechanism that allows users to
choose between raising an error and returning a result that is modulo the
largest representable integer value. See [ISO 10967].
So we could just detect overflow and error, but that feels like short/byte
operations are likely to overflow. Which might break usability, but it might
detect cases people weren't expecting?
Or we could do what Java does and just promote arithmetic operations to Int,
which is likely to just do the right thing and not overflow. But does me you
would likely need to add downcasts that might not be expected,e.g.
<element name="foo" type="xs:short"
dfdl:inputValueCalc="{ xs:short(../short1 + ../short2) }" />
In order for DPath to work the way it does, I think we do need to make a compile
time decision, I don't think DPath really wants to promote things at runtime to
whatever type fits the arithmetic result and just assume everything is a
Numeric. But I guess that could be an option too, and there just might be little
bit of runtime overhead to check types and arithmetic results.
Thoughts?