stevedlawrence opened a new pull request, #1571:
URL: https://github.com/apache/daffodil/pull/1571

   The current logic of numeric operations using in DFDL expressions is not 
correct in a couple of ways
   
   First, numeric operations using shorts and bytes are just broken and can 
least to ClassCastExceptions. The main reason is that Java promotes short and 
byte operations to ints but our logic did not account for that, so data values 
had ints when we expected short/byte.
   
   Second, the currently logic does not correctly implement the XPath 2.0 
specification for numeric operations. For example, if two arguments have a 
least upper bound of SignedNumeric we cast them to Double. An example where 
this breaks if xs:double and xs:decimal, which has a least upper bound of 
SignedNumeric. These should should be promoted to Decimal instead of Double. We 
also did not handle underflow/overflow correctly. For example, 
xs:long(xs:byte(255) + xs:byte(1)) results in an out of range error rather than 
correctly returning xs:long(256).
   
   This changes our numeric operations fix these problems and match the XPath 
2.0 spec.
   
   To achieve this we first promote numeric operands to one of decimal, 
integer, double, float, or long, based on the least upper bound of the operand 
types. Java does not perform any type promotion with these, so it avoids 
accidental changes of expected types. Note that we long where possible to 
maintain performant operations, rather than simply promoting everything to 
xs:integer as implied by the XPath 2.0 specification. This does mean 
underflow/overflow is possible, but this is much less likely. Note that such 
overflow will not be detected in intermediate operations, but will be detect if 
the result does not fit withing the range of the target type.
   
   This also changes the results of div and idv operations to return 
Decimal/Float/Double or Integer/Long for similar reasons.
   
   This means many of the NumericOps can not be removed (e.g. PlusShort) since 
the set of types we perform operations on is much smaller. We also update the 
NumericOps implementations to use DataValue's, since we know exactly what the 
types should be, rather than relying on asFoo to convert the operand to the 
expected type.
   
   This also changes the resulting type of numeric if-branches. This are only 
promoted to the least upper bound rather than also doing the numeric operation 
conversions. The numeric results can will be promoted if then used in a numeric 
operation.
   
   DAFFODIL-2574


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to