I think there are still a number of issues or deficiencies with the
DECFLOAT implementation that I think need to be addressed and fixed.
I'm not sure of the best way to address these. Please let me know how to
move forward with these points (create/update tickets in Jira, further
discussion, etc)?
Below is an inventory of the problems I think need addressing; I might
come up with others later.
1. NaN and infinities
NaN and infinities can currently be stored (using string conversion, or
by inserting a +NaN, -NaN, +sNaN, -sNaN, +Infinity or -Infinity using
the Decimal64 or Decimal128 byte representation (eg using Jaybird).
As I mentioned in my email on the 6th of January, Firebird currently
returns errors during fetch when comparing with a column that has a NaN
value (error: Decimal float invalid operation. An indeterminant error
occurred during an operation)
The SQL:2016 is silent on the matter, it just defines decimal floating
points with implementation-defined values for precision and limits to
the exponents. This suggests that neither NaNs nor Infinities should be
supported (or they would have been mentioned explicitly).
I think it would be best if attempts if Firebird would disallow NaN and
infinities, and any expression, parameter value, conversions or results
of calculations that yield a NaN or Infinity should yield an exception.
Otherwise, we will need to address the problems with comparisons with
NaN values in some way.
Tickets:
CORE-5699 - DECFLOAT should disallow +/-NaN, +/-sNaN and +/-Infinity
2. Underflow should yield zero, not an error
Currently, underflow conditions raise an error, instead it should round
to zero.
The SQL:2016 specification in 5.3 <literal> and 6.13 <cast
specification> explicitly mention that underflow with literals or casts
should yield zero, not an exception, so for example a literal 1.0E-7000
or cast('1.0E-7000' as decfloat(34)) (which is too small to be
represented) should not raise an errors, but instead yield 0.
The wording in section 6.29 <numeric value expression> at first glance
would seem to suggest that we would need to raise an exception if the
result of an expression is an underflow, but I don't think that is how
it is intended and instead we should yield zero as well. Similar to what
happens with calculations involving real and double precision.
This would be allowed because of the phrasing "If the most specific type
MST of the result of an arithmetic operation is the decimal floating
point type, then the result is an implementation-defined value IV of MST
such that no other value of MST is strictly between IV and the
mathematical result MR of the operation."
In the case of calculations that yield such a small value, there is no
other value than 0 that is "strictly between IV and the mathematical
result MR of the operation". This would also nicely fit with the
behaviour described for literals and cast
Tickets:
CORE-5700 - DECFLOAT underflow should yield zero instead of an error
3. Signed zeroes
The underlying Decimal64 and Decimal128 types support the notion of a
positive and negative zero (+0 or 0, and -0). The SQL:2016 standard is
silent on this and seems to assume a single notion of zero.
Comparisons between +0 and -0 are considered equal, but should we allow
these implementation details to leak into what is surfaced to clients,
or should we normalize to a single zero (ie 0 or 0E+0)?
See also next point
Tickets TBD
4. Zeroes with exponents
Similar to the previous one, the underlying Decimal64 and Decimal128
types support the notion of a zero with an exponent, for example
0E+6111. The SQL:2016 standard is silent on this and seems to assume a
single notion of zero.
Comparisons between, for example 0E+400 and 0 are considered equal, but
should we allow these implementation details to leak into what is
surfaced to clients, or should we normalize to a single zero (ie 0 or 0E+0)?
Related ticket (may need to be closed):
CORE-5696 - Conversion from zero numeric literals to DECFLOAT results in
incorrect value
Other tickets TBD
5. Literals do not work as expected
I have not explored this fully yet, but it looks like approximate
numeric literals have precision and conversion issues.
I have also noticed weird problems with double precision in this regard.
Tickets:
CORE-5696 - Conversion from zero numeric literals to DECFLOAT results in
incorrect value
CORE-5697 - Conversion from numeric literals to DECFLOAT adds precision
that is not originally present
6. DECFLOAT type declaration without explicit precision
We currently only allow DECFLOAT(16) and DECFLOAT(34), but the SQL:2016
standard specifies we should support type declaration DECFLOAT (that is,
without a specified precision) which should use a implementation-defined
default precision (eg 34).
Tickets:
CORE-5710 - Datatype declaration DECFLOAT without precision should use a
default precision
7. Include precision in system tables
RDB$FIELD_PRECISION should contain the precision of the field (16 or
34), this is helpful for client tools, and keeps the door open for
supporting other DECFLOAT(n) values backed by the same storage types.
Tickets:
CORE-5705 - Store precision of DECFLOAT in RDB$FIELDS
That is it for now, although I have the feeling I'm missing one or two
things I've come across.
Mark
--
Mark Rotteveel
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Firebird-Devel mailing list, web interface at
https://lists.sourceforge.net/lists/listinfo/firebird-devel