Wrong results when converting single digit string into DECIMAL(x,x)
Details
| Detail name | Value |
|---|---|
| Changelog Number | 32309 |
| Type | Bug |
| Status | Resolved |
| Affected Versions | Exasol 8.6.0, Exasol 8.29.0, Exasol 2025.1.0, Exasol 2025.2.0, Exasol 2026.1.0 |
| Fix Versions | Exasol 2026.1.2 |
| Resolution Date | 2026-09-14 |
Description
In rare cases, converting a single-digit string other than zero (for example, '1') to a DECIMAL whose precision equals its scale (for example, DECIMAL(1,1)) could produce an incorrect result.
Variant 1:
- The CPU does not support the BMI2 instruction-set. BMI2 instruction-set extension was introduced with Intel’s Haswell CPUs in 2013.
- The query contains a single-digit number string other than zero ('1', ‘2', ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, '-1', ‘-2', ‘-3’, ‘-4’, ‘-5’, ‘-6’, ‘-7’, ‘-8’, ‘-9’).
- The query or optimizer casts the string to a
DECIMALwhose precision equals its scale (for example,DECIMAL(1,1),DECIMAL(9,9)).
Variant 2:
- The query contains a negative single-digit number string other than zero ('-1', ‘-2', ‘-3’, ‘-4’, ‘-5’, ‘-6’, ‘-7’, ‘-8’, ‘-9’).
- The query or optimizer casts the string to a
DECIMALwhose precision equals its scale (for example,DECIMAL(1,1),DECIMAL(9,9)).
Example
-- Variant 1 (CPU does not support the BMI2 instruction-set), example 1
-- Observed: true
-- Expected: false
select json_value ('{"x": "1"}', '$.x' returning decimal(1,1) default 0.5 on error) = 1;
-- Variant 1 (CPU does not support the BMI2 instruction-set), example 2
-- Observed: exception "data exception - numeric value out of range: value 1 (internal number representation) is not in [ -0.9 .. 0.9 ]"
-- Expected: query finishes with error written into ERROR_COLUMN
select JSON_EXTRACT('{"x": "1"}', '$.x', '$.error()')
EMITS (d1_1 decimal(1,1), error_column varchar(2000000))
from dual;
-- Variant 2:
-- Observed: false
-- Expected: true
select '-1' < CAST(0 AS DECIMAL(9,9));
Workaround
- When using virtual machines make sure that BMI2 is activated.
- On SQL level workaround is to use decimal with larger precision, for example:
select json_value ('{"x": "1"}', '$.x' returning decimal(2,1) default 0.5 on error) = 1;
select JSON_EXTRACT('{"x": "1"}', '$.x', '$.error()')
EMITS (d2_1 decimal(2,1), error_column varchar(2000000))
from dual;
select '-1' < CAST(0 AS DECIMAL(10,9));
Fix
Query runs as expected.