Describe the bug, including details regarding any error messages, version, and platform.
For a sliced primitive array, the data pointer of the exported
MemoryView is advanced by offset bytes instead of
offset × element size bytes, so values wider than one byte come
out wrong (no error is raised).
require "arrow"
require "fiddle"
a = Arrow::Int32Array.new([0, 1, 2, 3, 4, 5, 6, 7])
p Fiddle::MemoryView.new(a.slice(1, 3)).to_s.unpack("l*")
# => [16777216, 33554432, 50331648] expected [1, 2, 3]
p Fiddle::MemoryView.new(a.slice(4, 3)).to_s.unpack("l*")
# => [1, 2, 3] expected [4, 5, 6]
The cause is GetValuesSafe<uint8_t>(1) in PrimitiveArrayGetter::fill
(ext/arrow/memory-view.cpp): it adds the offset in units of uint8_t.
The offset should be scaled by the element width.
A possible fix is to take the buffer start and scale the offset by the
element width:
const auto type =
std::static_pointer_cast<const arrow::FixedWidthType>(array.type());
view_->item_size = type->bit_width() / 8;
const auto base = array_data->GetValuesSafe<uint8_t>(1, 0);
const auto data = base + array_data->offset * view_->item_size;
view_->data = const_cast<void *>(reinterpret_cast<const void *>(data));
view_->byte_size = view_->item_size * array.length();
red-arrow 25.0.1, Ruby 3.4.1, macOS (arm64).
Component(s)
Ruby
Describe the bug, including details regarding any error messages, version, and platform.
For a sliced primitive array, the
datapointer of the exportedMemoryView is advanced by
offsetbytes instead ofoffset× element size bytes, so values wider than one byte comeout wrong (no error is raised).
The cause is
GetValuesSafe<uint8_t>(1)inPrimitiveArrayGetter::fill(
ext/arrow/memory-view.cpp): it adds the offset in units ofuint8_t.The offset should be scaled by the element width.
A possible fix is to take the buffer start and scale the offset by the
element width:
red-arrow 25.0.1, Ruby 3.4.1, macOS (arm64).
Component(s)
Ruby