Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions arrow/array/dictionary.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func checkIndexBounds(indices *Data, upperlimit uint64) error {
case arrow.INT8:
data := arrow.Int8Traits.CastFromBytes(indices.buffers[1].Bytes())
min, max := utils.GetMinMaxInt8(data[start:end])
if min < 0 || max >= int8(upperlimit) {
if min < 0 || uint64(max) >= upperlimit {
return fmt.Errorf("contains out of bounds index: min: %d, max: %d", min, max)
}
case arrow.UINT8:
Expand All @@ -122,7 +122,7 @@ func checkIndexBounds(indices *Data, upperlimit uint64) error {
case arrow.INT16:
data := arrow.Int16Traits.CastFromBytes(indices.buffers[1].Bytes())
min, max := utils.GetMinMaxInt16(data[start:end])
if min < 0 || max >= int16(upperlimit) {
if min < 0 || uint64(max) >= upperlimit {
return fmt.Errorf("contains out of bounds index: min: %d, max: %d", min, max)
}
case arrow.UINT16:
Expand All @@ -134,7 +134,7 @@ func checkIndexBounds(indices *Data, upperlimit uint64) error {
case arrow.INT32:
data := arrow.Int32Traits.CastFromBytes(indices.buffers[1].Bytes())
min, max := utils.GetMinMaxInt32(data[start:end])
if min < 0 || max >= int32(upperlimit) {
if min < 0 || uint64(max) >= upperlimit {
return fmt.Errorf("contains out of bounds index: min: %d, max: %d", min, max)
}
case arrow.UINT32:
Expand All @@ -146,7 +146,7 @@ func checkIndexBounds(indices *Data, upperlimit uint64) error {
case arrow.INT64:
data := arrow.Int64Traits.CastFromBytes(indices.buffers[1].Bytes())
min, max := utils.GetMinMaxInt64(data[start:end])
if min < 0 || max >= int64(upperlimit) {
if min < 0 || uint64(max) >= upperlimit {
return fmt.Errorf("contains out of bounds index: min: %d, max: %d", min, max)
}
case arrow.UINT64:
Expand Down
26 changes: 26 additions & 0 deletions arrow/array/dictionary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,32 @@ func TestDictionaryFromArrays(t *testing.T) {
}
}

func TestValidatedDictionaryAllowsSignedIndexAtTypeLimit(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)

indicesBuilder := array.NewInt8Builder(mem)
indicesBuilder.Append(127)
indices := indicesBuilder.NewArray()
indicesBuilder.Release()
defer indices.Release()

dictBuilder := array.NewStringBuilder(mem)
for i := 0; i < 128; i++ {
dictBuilder.AppendString(fmt.Sprintf("value-%d", i))
}
dict := dictBuilder.NewArray()
dictBuilder.Release()
defer dict.Release()

dictType := &arrow.DictionaryType{IndexType: arrow.PrimitiveTypes.Int8, ValueType: arrow.BinaryTypes.String}
result, err := array.NewValidatedDictionaryArray(dictType, indices, dict)
assert.NoError(t, err)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: this asserts the error is nil but never checks the result, so a (nil, nil) return would pass the test just as happily. require.NotNil(t, result) would close that gap — and then the if result != nil guard below becomes unnecessary.

if result != nil {
defer result.Release()
}
}

func TestListOfDictionary(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
Expand Down
Loading