This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new 998203ce fix(arrow/scalar): preserve metadata in FromScalar (#1100)
998203ce is described below
commit 998203ce85ff783d2003488e6cce15add8805fd3
Author: Minh Vu <[email protected]>
AuthorDate: Fri Aug 7 18:11:26 2026 +0200
fix(arrow/scalar): preserve metadata in FromScalar (#1100)
### Rationale for this change
FromScalar creates metadata slices with a non-zero length and then
appends to them. Each decoded metadata entry therefore gets an extra
empty key and value.
### What changes are included in this PR?
Build the slices with zero length and the required capacity, then add a
metadata round-trip regression test.
### Are these changes tested?
- `go test ./arrow/scalar`
### Are there any user-facing changes?
No API changes. This corrects the reported behavior while preserving the
existing ownership and compatibility contracts.
---
arrow/scalar/parse.go | 4 ++--
arrow/scalar/scalar_test.go | 22 ++++++++++++++++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/arrow/scalar/parse.go b/arrow/scalar/parse.go
index 3ac57738..6d1e6a33 100644
--- a/arrow/scalar/parse.go
+++ b/arrow/scalar/parse.go
@@ -345,8 +345,8 @@ func fromListScalar(s ListScalar, v reflect.Value) error {
start := o
end := offsets[i+1]
- metaKeys = make([]string, end-start)
- metaValues = make([]string, end-start)
+ metaKeys = make([]string, 0, end-start)
+ metaValues = make([]string, 0, end-start)
for j := start; j < end; j++ {
metaKeys = append(metaKeys,
keys.ValueString(int(j)))
metaValues = append(metaValues,
values.ValueString(int(j)))
diff --git a/arrow/scalar/scalar_test.go b/arrow/scalar/scalar_test.go
index 056da477..e0084e33 100644
--- a/arrow/scalar/scalar_test.go
+++ b/arrow/scalar/scalar_test.go
@@ -1213,6 +1213,10 @@ type OptionListTest struct {
ValUint []uint `compute:"valuint"`
}
+type MetadataScalarTest struct {
+ FieldMeta []*arrow.Metadata `compute:"field_metadata"`
+}
+
type OptionValTest struct {
ToType arrow.DataType `compute:"type"`
Allow bool `compute:"allow"`
@@ -1268,6 +1272,24 @@ func TestToScalar(t *testing.T) {
assert.Equal(t, expected, sc.String())
}
+func TestFromScalarMetadataDoesNotPrependEmptyEntries(t *testing.T) {
+ meta := arrow.NewMetadata(
+ []string{"option", "captain", "souper"},
+ []string{"val", "planet", "bowl"},
+ )
+ in := MetadataScalarTest{FieldMeta: []*arrow.Metadata{&meta}}
+
+ sc, err := scalar.ToScalar(in, memory.DefaultAllocator)
+ require.NoError(t, err)
+
+ var out MetadataScalarTest
+ require.NoError(t, scalar.FromScalar(sc.(*scalar.Struct), &out))
+ require.Len(t, out.FieldMeta, 1)
+ require.NotNil(t, out.FieldMeta[0])
+ assert.Equal(t, meta.Keys(), out.FieldMeta[0].Keys())
+ assert.Equal(t, meta.Values(), out.FieldMeta[0].Values())
+}
+
var dictIndexTypes = []arrow.DataType{
arrow.PrimitiveTypes.Int8,
arrow.PrimitiveTypes.Uint8,