Skip to content

[BUG]: MSSQL real() column returns imprecise float64 values -- missing mapFromDriverValue #5527

Closed

Description

@valerii-kuzivanov

Report hasn't been filed before.

  • I have verified that the bug I'm about to report hasn't been filed before.

What version of drizzle-orm are you using?

1.0.0-beta.18-7eb39f0

What version of drizzle-kit are you using?

1.0.0-beta.18-7eb39f0

Other packages

No response

Describe the Bug

Issue

The MSSQL real() column type returns imprecise float64 representations of float32 values. A value stored as 0.01 in a SQL Server real column is returned to JavaScript as 0.009999999776482582.

SQL Server's real type is IEEE 754 single-precision (float32, ~7 significant digits). The mssql Node.js driver (tedious) reads the 4-byte float32 from the wire and widens it to a JavaScript number (float64). This widening exposes the float32 representation error -- 0.01 cannot be represented exactly in 32 bits, so the float64 value becomes 0.009999999776482582.

The MsSqlReal class in drizzle-orm/mssql-core/columns/real.js has no mapFromDriverValue override, so the raw widened value is passed through as-is:

var MsSqlReal = class extends MsSqlColumnWithIdentity {
    static [entityKind] = "MsSqlReal";
    getSQLType() {
        return "real";
    }
    // no mapFromDriverValue -- raw float64 value is used
};

By contrast, MsSqlFloat (which maps to float(53) / float64) does not have this problem because the driver value is already native float64 precision.

Expected behavior:

real() columns should return values rounded to 7 significant digits (the actual precision of float32), so 0.01 in the database comes back as 0.01 in JavaScript, not 0.009999999776482582.

Suggested fix:

Add a mapFromDriverValue to MsSqlReal that rounds to float32 precision:

class MsSqlReal extends MsSqlColumnWithIdentity {
    static [entityKind] = "MsSqlReal";
    getSQLType() {
        return "real";
    }
    mapFromDriverValue(value: number): number {
        return parseFloat(value.toPrecision(7));
    }
}

Alternatively, Math.fround(value) could be used, but parseFloat(value.toPrecision(7)) produces cleaner decimal output.

Reproduction

import { drizzle } from 'drizzle-orm/node-mssql';
import { mssqlTable, real, int } from 'drizzle-orm/mssql-core';
const testTable = mssqlTable('test', {
    id: int().primaryKey(),
    tolerance: real(),
});
// Assume a row with tolerance = 0.01 exists in SQL Server
const rows = await db.select().from(testTable);
console.log(rows[0].tolerance);
// Actual:   0.009999999776482582
// Expected: 0.01

Current workaround

Replace real with a customType that includes fromDriver rounding:

import { customType } from 'drizzle-orm/mssql-core';

const real = customType<{ data: number; driverData: number }>({
    dataType() { return 'real'; },
    fromDriver(value: number): number {
        return parseFloat(value.toPrecision(7));
    },
});

Activity

  1. added a commit that references this issue on Mar 29, 2026
    07e5afa
  2. AndriiSherman commented on Apr 16, 2026

    @AndriiSherman
    Member

    Should be fix in drizzle-orm@1.0.0-beta.22 and drizzle-kit@1.0.0-beta.22

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions