Skip to content

Commit

Permalink
Merge pull request #128 from otan-cockroach/decimal_fix
Browse files Browse the repository at this point in the history
format: format 0E-x where x > 6 like PostgreSQL does
  • Loading branch information
otan authored May 15, 2023
2 parents 0c42067 + ffd11b1 commit 4c2545f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
# staticcheck requires go1.19.
if: ${{ matrix.arch == 'x64' && matrix.go >= '1.19' }}
run: |
go install honnef.co/go/tools/cmd/staticcheck@latest
go install honnef.co/go/tools/cmd/staticcheck@v0.4.3
staticcheck ./...
- name: 'GCAssert'
Expand Down
6 changes: 6 additions & 0 deletions decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,12 @@ func TestFormat(t *testing.T) {
f: "000",
g: "0e+2",
},
"0E-9": {
e: "0e-9",
f: "0.000000000",
g: "0.000000000",
G: "0.000000000",
},
}
verbs := []string{"%e", "%E", "%f", "%g", "%G"}

Expand Down
12 changes: 11 additions & 1 deletion format.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,19 @@ func (d *Decimal) Append(buf []byte, fmt byte) []byte {
case 'f':
return fmtF(buf, d, digits)
case 'g', 'G':
// Ensure that we correctly display all 0s like PostgreSQL does.
// For 0.00000000, the co-efficient is represented as 0
// and hence the digits is incorrectly 0 (for 1.000000, it'd be
// 10000000). Hence, pad the digit length before calculating the
// adjExponentLimit.
// See: https://github.com/cockroachdb/cockroach/issues/102217.
digitLen := len(digits)
if d.Coeff.BitLen() == 0 && d.Exponent < 0 {
digitLen += int(-d.Exponent)
}
// See: http://speleotrove.com/decimal/daconvs.html#reftostr
const adjExponentLimit = -6
adj := int(d.Exponent) + (len(digits) - 1)
adj := int(d.Exponent) + (digitLen - 1)
if d.Exponent <= 0 && adj >= adjExponentLimit {
return fmtF(buf, d, digits)
}
Expand Down
22 changes: 20 additions & 2 deletions gda_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,26 @@ func gdaTest(t *testing.T, path string, tcs []TestCase) {
if strings.HasPrefix(tc.Result, "SNAN") {
tc.Result = "sNaN"
}
if !strings.EqualFold(s, tc.Result) {
t.Fatalf("expected %s, got %s", tc.Result, s)
expected := tc.Result
// Adjust 0E- or -0E- tests to match PostgreSQL behavior.
// See: https://github.com/cockroachdb/cockroach/issues/102217.
if pos, neg := strings.HasPrefix(expected, "0E-"), strings.HasPrefix(expected, "-0E-"); pos || neg {
startIdx := 3
if neg {
startIdx = 4
}
p, err := strconv.ParseInt(expected[startIdx:], 10, 64)
if err != nil {
t.Fatalf("unexpected error converting int: %v", err)
}
expected = ""
if neg {
expected = "-"
}
expected += "0." + strings.Repeat("0", int(p))
}
if !strings.EqualFold(s, expected) {
t.Fatalf("expected %s, got %s", expected, s)
}
return
}
Expand Down
12 changes: 12 additions & 0 deletions sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,16 @@ func TestSQL(t *testing.T) {
if nd.Valid {
t.Fatal("expected null")
}

var g Decimal
if err := db.QueryRow("select 0::decimal(19,9)").Scan(&g); err != nil {
t.Fatal(err)
}
zeroD, _, err := NewFromString("0.000000000")
if err != nil {
t.Fatal(err)
}
if g.String() != zeroD.String() {
t.Fatalf("expected 0::decimal(19.9) pg value %s match, found %s", g.String(), zeroD.String())
}
}

0 comments on commit 4c2545f

Please sign in to comment.