Introduction
Division operations involving integer or long datatypes may generate XDMP-DECOVRFLW in MarkLogic 7. This is the expected behavior but it may not be obvious upon initial inspection.
For example, similar queries with similar but different input values executed in Query Console on Linux/Mac machine running MarkLogic 7 gives the following results
1. This query returns correct results
let
$estimate := xs:unsignedLong("
220")
let $total := xs:unsignedLong("
1600")
return
$estimate div $total * 100
==> 13.75
2. This query returns the XDMP-DECOVRFLOW Error
let $estimate := xs:unsignedLong("227")
let $total := xs:unsignedLong("1661")
return $estimate div $total * 100
==> ERROR : XDMP-DECOVRFLW: (err:FOAR0002)
Details
The following defines relevant behaviors in MarkLogic 7 and previous releases.
- In MarkLogic 7, if all the operands involved in div operations are integer, long or integer sub-types in XML, then the resulting value of the
div
operation are stored as xs:decimal.
- In versions previous to MarkLogic 7, if an
xs:decimal
value is large and occupies all digits then it was implicitly cast into an xs:double
for further operations - i.e. beginning with MarkLogic, implict casting no longer occurs in this situation .
xs:decimal
can accomodate 18 digits as a datatype.
- In MarkLogic 7 on Linux & Mac,
xs:decimal
can occupy all digits depending upon actual value ( 227 div 1661 = 0.1366646598434677905
), all 18 digits occupied in xs:decimal
- MarkLogic 7 on Windows does not perform division with full decimal precision (
227 div 1661
produces 0.136664659843468
); as a result, not all 18 digits occupied in xs:decimal
- MarkLogic 7 will generates Overflow Exception : FOAR0002, when an operation is performed on an
xs:decimal
that is already at full decimal precision
In the example above, multiplying the result with 100 gives an error in Linux/Mac, while its OK on Windows.
Recommendations:
We recommend xs:double
be used for all division related operations in order to explicitly cast resulting value to larger data-type.
For example: These will return results
xs:double($estimate) div $total * 100
$estimate div $total * xs:double(100)
.