Skip to content

fix(arrow/array): use scale-aware ValueStr in decimal array String()#849

Merged
zeroshade merged 1 commit into
apache:mainfrom
zeroshade:fix/decimal-string-scale
Jun 10, 2026
Merged

fix(arrow/array): use scale-aware ValueStr in decimal array String()#849
zeroshade merged 1 commit into
apache:mainfrom
zeroshade:fix/decimal-string-scale

Conversation

@zeroshade

Copy link
Copy Markdown
Member

Rationale for this change

Decimal arrays stringify the raw decimal.Num struct instead of the scaled logical value. fmt.Println on a decimal array — or on a Record/RecordBatch containing one — prints e.g. {1999 0} instead of 19.99, even though ValueStr already formats the value correctly using the type's scale. This is inconsistent with ValueStr/JSON output and with other Arrow implementations (e.g. PyArrow prints 19.99).

What changes are included in this PR?

  • baseDecimal[T].String() now formats each non-null value via ValueStr (which applies the type's scale through GetOneForMarshal) instead of fmt.Sprintf("%v", Value(i)). Because baseDecimal is generic, this corrects Decimal32/64/128/256 at once, and RecordBatch printing inherits the fix through the column String() path (record.go).
  • Updated two existing slice-test assertions in decimal128_test.go / decimal256_test.go that pinned the old raw-struct output (they were already inconsistent with the adjacent ValueStr expectations on the next lines).
  • Added TestDecimal128StringScaled, reproducing the issue (decimal128(5, 2) = 19.99) and asserting both the array String() and the RecordBatch output.

Are these changes tested?

Yes. go test ./arrow/array/ passes, including the new regression test and the updated slice tests. go build ./... and go vet/golangci-lint (via pre-commit) pass.

Are there any user-facing changes?

Yes — the textual output of String() on decimal arrays, and of any Record/RecordBatch containing decimal columns, now shows scaled decimal values (e.g. 19.99) instead of the internal struct (e.g. {1999 0}). This only affects human-readable stringification; binary/IPC/JSON representations are unchanged.

Closes #848

Decimal arrays printed the raw decimal.Num struct (e.g. {1999 0}) from String(), so printing an array or RecordBatch showed unscaled values instead of the logical decimal. Switch to ValueStr, which already formats using the type's scale (matching GetOneForMarshal and JSON output).

baseDecimal is generic, so this fixes Decimal32/64/128/256, and RecordBatch printing inherits the corrected output via the column String() path.
@zeroshade zeroshade requested review from ianmcook and lidavidm June 9, 2026 20:50
@zeroshade zeroshade merged commit 55f6fd0 into apache:main Jun 10, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decimal array and RecordBatch stringification prints raw unscaled Decimal128 values

2 participants