Skip to content

Commit 5ed6ca8

Browse files
authored
feat: Support int32 to uint64 in reverseTransformArray (#728)
## Summary - Add `reverseTransformFromInt32` to handle int32 to uint64 array widening in parquet reads - Add corresponding case in `reverseTransformArray` switch for `*array.Int32` - Mirrors the existing `reverseTransformFromUint32` implementation ## Test plan - [x] `TestReverseTransformArray_Int32ToUint64` — basic values (0, 42, null, max int32) - [x] `TestReverseTransformArray_Int32ToUint64_Empty` — empty array - [x] `TestReverseTransformArray_Int32ToUint64_ListOf` — list of int32 → list of uint64
1 parent ccf6a31 commit 5ed6ca8

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

parquet/read.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ func reverseTransformArray(dt arrow.DataType, arr arrow.Array) arrow.Array {
6868
return reverseTransformTime64(dt.(*arrow.Time64Type), arr)
6969
case *array.Date32:
7070
return reverseTransformFromDate32(dt, arr)
71+
case *array.Int32:
72+
return reverseTransformFromInt32(dt, arr)
7173
case *array.Uint32:
7274
return reverseTransformFromUint32(dt, arr)
7375
case *array.Struct:
@@ -102,6 +104,27 @@ func reverseTransformArray(dt arrow.DataType, arr arrow.Array) arrow.Array {
102104
}
103105
}
104106

107+
func reverseTransformFromInt32(dt arrow.DataType, arr *array.Int32) arrow.Array {
108+
switch dt {
109+
case arrow.PrimitiveTypes.Uint64:
110+
builder := array.NewUint64Builder(memory.DefaultAllocator)
111+
for i := 0; i < arr.Len(); i++ {
112+
if arr.IsNull(i) {
113+
builder.AppendNull()
114+
continue
115+
}
116+
v := arr.Value(i)
117+
if v < 0 {
118+
panic(fmt.Errorf("negative int32 value %d at index %d cannot be converted to uint64", v, i))
119+
}
120+
builder.Append(uint64(v))
121+
}
122+
return builder.NewArray()
123+
default:
124+
panic(fmt.Errorf("unsupported conversion from %s to %s", arr.DataType(), dt))
125+
}
126+
}
127+
105128
func reverseTransformFromUint32(dt arrow.DataType, arr *array.Uint32) arrow.Array {
106129
switch dt {
107130
case arrow.PrimitiveTypes.Uint64:

parquet/read_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,98 @@ func TestReverseTransformArray_Uint32ToUint64_ListOf(t *testing.T) {
8989
require.Equal(t, uint64(2), values.Value(1))
9090
require.Equal(t, uint64(3), values.Value(2))
9191
}
92+
93+
func TestReverseTransformArray_Int32ToUint64(t *testing.T) {
94+
builder := array.NewInt32Builder(memory.DefaultAllocator)
95+
defer builder.Release()
96+
97+
builder.Append(0)
98+
builder.Append(42)
99+
builder.AppendNull()
100+
builder.Append(2147483647) // max int32
101+
102+
arr := builder.NewArray()
103+
defer arr.Release()
104+
105+
result := reverseTransformArray(arrow.PrimitiveTypes.Uint64, arr)
106+
defer result.Release()
107+
108+
require.Equal(t, arrow.PrimitiveTypes.Uint64, result.DataType())
109+
require.Equal(t, 4, result.Len())
110+
111+
u64 := result.(*array.Uint64)
112+
require.Equal(t, uint64(0), u64.Value(0))
113+
require.False(t, u64.IsNull(0))
114+
115+
require.Equal(t, uint64(42), u64.Value(1))
116+
require.False(t, u64.IsNull(1))
117+
118+
require.True(t, u64.IsNull(2))
119+
120+
require.Equal(t, uint64(2147483647), u64.Value(3))
121+
require.False(t, u64.IsNull(3))
122+
}
123+
124+
func TestReverseTransformArray_Int32ToUint64_Empty(t *testing.T) {
125+
builder := array.NewInt32Builder(memory.DefaultAllocator)
126+
defer builder.Release()
127+
128+
arr := builder.NewArray()
129+
defer arr.Release()
130+
131+
result := reverseTransformArray(arrow.PrimitiveTypes.Uint64, arr)
132+
defer result.Release()
133+
134+
require.Equal(t, arrow.PrimitiveTypes.Uint64, result.DataType())
135+
require.Equal(t, 0, result.Len())
136+
}
137+
138+
func TestReverseTransformArray_Int32ToUint64_ListOf(t *testing.T) {
139+
bldr := array.NewListBuilder(memory.DefaultAllocator, arrow.PrimitiveTypes.Int32)
140+
defer bldr.Release()
141+
142+
vb := bldr.ValueBuilder().(*array.Int32Builder)
143+
144+
bldr.Append(true)
145+
vb.Append(1)
146+
vb.Append(2)
147+
148+
bldr.Append(true)
149+
vb.Append(3)
150+
151+
bldr.AppendNull()
152+
153+
arr := bldr.NewArray()
154+
defer arr.Release()
155+
156+
targetDt := arrow.ListOf(arrow.PrimitiveTypes.Uint64)
157+
result := reverseTransformArray(targetDt, arr)
158+
defer result.Release()
159+
160+
require.True(t, arrow.TypeEqual(targetDt, result.DataType()))
161+
require.Equal(t, 3, result.Len())
162+
163+
listArr := result.(*array.List)
164+
require.False(t, listArr.IsNull(0))
165+
require.False(t, listArr.IsNull(1))
166+
require.True(t, listArr.IsNull(2))
167+
168+
values := listArr.ListValues().(*array.Uint64)
169+
require.Equal(t, uint64(1), values.Value(0))
170+
require.Equal(t, uint64(2), values.Value(1))
171+
require.Equal(t, uint64(3), values.Value(2))
172+
}
173+
174+
func TestReverseTransformArray_Int32ToUint64_NegativePanics(t *testing.T) {
175+
builder := array.NewInt32Builder(memory.DefaultAllocator)
176+
defer builder.Release()
177+
178+
builder.Append(-1)
179+
180+
arr := builder.NewArray()
181+
defer arr.Release()
182+
183+
require.PanicsWithError(t, "negative int32 value -1 at index 0 cannot be converted to uint64", func() {
184+
reverseTransformArray(arrow.PrimitiveTypes.Uint64, arr)
185+
})
186+
}

0 commit comments

Comments
 (0)