Skip to content

Arithmetic operations with decimals return incorrect results #2189

@OS-veracardoso

Description

@OS-veracardoso

Driver version

12.4.0.jre11

SQL Server version

Microsoft SQL Server 2019 (RTM-CU15) (KB5008996) - 15.0.4198.2 (X64) 
Jan 12 2022 22:30:08 
Copyright (C) 2019 Microsoft Corporation
Express Edition (64-bit) on Linux (Ubuntu 20.04.3 LTS) <X64>

Client Operating System

Ubuntu on Windows version 2004.2022.1.0

JAVA/JVM version

1.17

Table schema

CREATE TABLE dbo.df_test_all_types
(
    ID           INT PRIMARY KEY,
    COL_TINYINT  TINYINT,
    COL_SMALLINT SMALLINT,
    COL_INT      INT,
    COL_BIGINT   BIGINT,
    COL_FLOAT    FLOAT,
    COL_NUMERIC  NUMERIC,
    COL_DECIMAL  DECIMAL(19, 8),
    COL_BOOLEAN  BIT,
    COL_DATE     DATE,
    COL_TIME     TIME,
    COL_DATETIME DATETIME,
    COL_VARCHAR  VARCHAR(100),
    COL_NVARCHAR NVARCHAR(100),
    COL_TEXT     TEXT,
    COL_BLOB     VARBINARY(5000)
);


INSERT INTO dbo.df_test_all_types (ID, COL_INT, COL_BIGINT, COL_DECIMAL, COL_BOOLEAN,
                                   COL_VARCHAR, COL_NVARCHAR, COL_TEXT)
VALUES (1, 1, 1000, 48.9, 0, 'Some string', 'Some other string', 'Some Text');
INSERT INTO dbo.df_test_all_types (ID, COL_INT, COL_BIGINT, COL_DECIMAL, COL_BOOLEAN,
                                   COL_TEXT)
VALUES (2, 2, 2000, -48.999, 1, ' TrimText ');
INSERT INTO dbo.df_test_all_types (ID, COL_INT, COL_BIGINT, COL_DECIMAL, COL_BOOLEAN,
                                   COL_VARCHAR, COL_NVARCHAR, COL_TEXT)
VALUES (3, 3, 3000, 25, 1, '1234', '1234', '1234');
INSERT INTO dbo.df_test_all_types (ID, COL_INT, COL_BIGINT, COL_DECIMAL, COL_BOOLEAN,
                                   COL_VARCHAR, COL_NVARCHAR, COL_TEXT)
VALUES (4, 4, 4000, 12.34, 1, '2147483650', '2147483650', '2147483650');
INSERT INTO dbo.df_test_all_types (ID, COL_INT, COL_BIGINT, COL_DECIMAL)
VALUES (5, 5, 10, 2.5);
INSERT INTO dbo.df_test_all_types (ID, COL_TINYINT)
VALUES (6, 19);

Problem description

This new version of the driver introduces some changes on how arithmetic operations with decimals work.
For a better understanding consider the follwing examples.

Sum of 3 big decimals with different precision rounds the value to the closest integer:

Query: SELECT ? + ? + ? TABLE_EXAMPLE WHERE "ID" = 4
Dynamic Parameters: new BigDecimal("4"), new BigDecimal("5") and new BigDecimal("3.14")
Expected Result: 5.86
Actual Result: 6

Multiplication followed by a Subtraction of 3 big decimals with different precision returns a decimal without precision:

Query: SELECT ? * ? - ? FROM TABLE_EXAMPLE WHERE "ID" = 4
Dynamic Parameters: new BigDecimal("4"), new BigDecimal("2") and new BigDecimal("1.00")
Expected Result: 7.00
Actual Result: 7

Subtraction of 2 big decimals rounds the result to the closest integer:

Query: SELECT ? - ? FROM TABLE_EXAMPLE WHERE "ID" = 4
Dynamic Parameters: new BigDecimal("4.0") and new BigDecimal("3.14")
Expected Result: 0.86
Actual Result: 1

Subtraction of 2 big decimals round the result to a decimal with the lowest precision:

Example 1

Query: SELECT ? - ? TABLE_EXAMPLE WHERE "ID" = 4
Dynamic Parameters: new BigDecimal("4.0") and new BigDecimal("3.14")
Expected Result: 0.86
Actual Result: 0.9

Example 2

Query: SELECT ? - ? TABLE_EXAMPLE WHERE "ID" = 4]
Dynamic Parameters: new BigDecimal("1.23") and new BigDecimal("1.2")
Expected Result: 0.03
Actual Result: 0.0

Incorrect precision when using CAST

Example 1

Query: SELECT ? - CAST("COL_INT" AS DECIMAL(38, 2) FROM TABLE_EXAMPLE WHERE "ID" = 4
Dynamic Parameters: new BigDecimal("0.00")
Expected Result: 0.00
Actual Result: 0

Example 2

Query: SELECT ? - CAST("COL_BIGINT" AS DECIMAL(38, 2) FROM TABLE_EXAMPLE WHERE "ID" = 4
Dynamic Parameters: new BigDecimal("-3996.00")
Expected Result: -3996.00
Actual Result: -3996

Example 3

Query: SELECT ? - "COL_DECIMAL" FROM TABLE_EXAMPLE WHERE "ID" = 4
Dynamic Parameters: new BigDecimal("-3996.00")
Expected Result: -8.34000000
Actual Result: -8

Error message/stack trace

Not applicable. The driver returns no error. The result though is no the expected one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    EnhancementAn enhancement to the driver. Lower priority than bugs.

    Type

    No type

    Projects

    Status

    Closed Issues

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions