system.db.execSProcCall system.db.DECIMAL bug

Reference: support ticket 59493.

A while back a user reported that a value was not being stored properly on the database, so I checked and it was true.

The field in question is of type DECIMAL(15, 8). The value in question was 0.00060606. And the value inserted was 0.00060000.

At first I thought the value was being truncated, but instead it is being rounded to four digits after the decimal point.

Additional info.
Ignition: 8.0.14 (b2020062220)
DB: Microsoft SQL Server 2017
JDBC Driver: mssql-jdbc-8.2.2

To prove this I ran the following code:

call = system.db.createSProcCall(procedureName="[dbo].[decimal_test_insert]", database="MBAMSSQL")
call.registerInParam("val", system.db.DECIMAL, 0.00069606)

# And also this:
from java.math import BigDecimal

call = system.db.createSProcCall(procedureName="[dbo].[decimal_test_insert]", database="MBAMSSQL")
call.registerInParam("val", system.db.DECIMAL, BigDecimal("0.00069606"))

Both calls insert 0.00070000 into the table.

The “workaround” is to register the input parameter as system.db.FLOAT, like this:

call = system.db.createSProcCall(procedureName="[dbo].[decimal_test_insert]")
call.registerInParam("val", system.db.FLOAT, 0.00069606)

This correctly inserts 0.00069606.

I also created a MySQL table and stored procedure, but the value in this case is not being rounded up when using system.db.DECIMAL; it is inserted properly for both system.db.DECIMAL and system.db.FLOAT.

That made me consider that the MSSQL JDBC driver was at fault, so I created a Java project based on this project because my Java skills are not what they used to be.

So I hacked my way and added this method:

public void insertDecimal() {
    CallableStatement cstmt = null;
    try {
        cstmt = connection.getConnection().prepareCall("{call dbo.decimal_test_insert(?)}");
        cstmt.setBigDecimal("val", new BigDecimal("0.00069606"));
    } catch (Exception ex) {
                log(Level.SEVERE, null, ex);
    } finally {
        if (cstmt != null) {
            try {
            } catch (SQLException ex) {
                        log(Level.WARNING, null, ex);

And this correctly inserts 0.00069606 into the database.

Which leads me to the one possible conclusion: there is something wrong when using system.db.DECIMAL for more than four numbers after the decimal point.

While I could definitely just use system.db.FLOAT instead of system.db.DECIMAL I do believe that I should be registering parameters with the same data type as used in the DB.

I am only hoping someone from Inductive Automation confirms this is as a bug or just points me to the error I am making by using system.db.DECIMAL when calling Microsoft SQL Server stored procedures.