fix: use decimal notation for float formatting to match ODBC sqlcmd by dlevy-msft-sql · Pull Request #706 · microsoft/go-sqlcmd

Problem

go-sqlcmd displays float values using scientific notation while ODBC sqlcmd uses decimal notation:

go-sqlcmd ODBC sqlcmd
4.713347310380896e+06 4713347.3103808956

This causes compatibility issues for scripts expecting consistent output.

Root Cause

Float values were falling through to the default fmt.Sprintf("%v", x) case which uses Go's default formatting (scientific notation for large values).

Code Change

Added explicit float formatting using strconv.FormatFloat with 'f' format for decimal notation:

func formatFloat(x float64, bitSize int, col columnDetail) string {
    formatted := strconv.FormatFloat(x, 'f', -1, bitSize)
    
    // Fall back to scientific for extreme values that exceed column width
    if int64(len(formatted)) > threshold {
        formatted = strconv.FormatFloat(x, 'g', -1, bitSize)
    }
    return formatted
}
  • Uses 32-bit precision for REAL/SMALLMONEY, 64-bit for FLOAT/MONEY
  • Falls back to scientific notation for extreme values (1e100) to avoid truncation
  • Centralized display width constants (realDefaultWidth=14, floatDefaultWidth=24)

Testing

  • Build passes: go build ./...
  • TestFormatterFloatDecimalNotation - verifies decimal notation for typical values
  • TestFormatterFloatScientificFallback - verifies scientific notation for extreme values
  • Both tests pass with live database (10.0.0.8)

Fixes #555