Uh oh!
There was an error while loading. Please reload this page.
GH-42247: [C++] Support casting to and from utf8_view/binary_view - #43302
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Is this a TODO for this PR? Otherwise, perhaps create a GH issue for it.
There was a problem hiding this comment.
@mapleFU this one needs to be fixed with the same fix I added in line 477 // Check against offset overflow. I forgot that there were two places with this TODO.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
mapleFU
left a comment
There was a problem hiding this comment.
Great work! memset to 0 really handle some tricky problem in protocol layer, thanks for your effort!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
(Unrelated to this pr: What reminds me is the utf8 checking in arrow-rs, maybe we can use same algorithm? apache/arrow-rs#6009 )
There was a problem hiding this comment.
That sounds like a good [Parquet] issue to open
There was a problem hiding this comment.
Oh, I think I see what you mean: we could similarly assemble larger contiguous byte ranges on which we run a single Utf8 validation pass.
For the common case of views whose out-of-line data directly follows the previous out-of-line bytes, this would yield one long byte range for Utf8 validation.
Inline strings would also always be valid Utf8 since their size would consist of 3 zero bytes and one small byte plus the inline data and padding zero bytes, so we could validate on runs of inline views too.
Uh oh!
There was an error while loading. Please reload this page.
@github-actions crossbow submit -g cpp |
Revision: 2416d19 Submitted crossbow builds: ursacomputing/crossbow @ actions-aaf4a45dfc |
pitrou
commented
Sep 12, 2024
CI failures are unrelated, I'll merge |
mapleFU
commented
Sep 13, 2024
Thanks! |
After merging your PR, Conbench analyzed the 4 benchmarking runs that have been run so far on merge-commit 85fc3eb. There were no benchmark performance regressions. 🎉 The full Conbench report has more details. It also includes information about 97 possible false positives for unstable benchmarks that are known to sometimes produce them. |
…ew (apache#43302) ### Rationale for this change We need casts between string (binary) and string-view (binary-view) types since they are semantically equivalent. ### What changes are included in this PR? - Add `is_binary_view_like()` type predicate - Add `BinaryViewTypes()` list including `STRING_VIEW/BINARY_VIEW` - New cast kernels ### Are these changes tested? Yes, but test coverage might be improved. ### Are there any user-facing changes? More casts are available. * GitHub Issue: apache#42247 Lead-authored-by: Felipe Oliveira Carvalho <felipekde@gmail.com> Co-authored-by: mwish <maplewish117@gmail.com> Signed-off-by: Antoine Pitrou <antoine@python.org>
…tring and binary types (#44822) ### Rationale for this change Use `CopyBitmap` to optimize performance in string casting from string-view to offset string. ### What changes are included in this PR? Originally, the way we create the bitmap is by appending one bit at a time, which is slow. Since casting should not change the values in bitmap, this feature takes advantage of `CopyBitmap` to create the entire bitmap at once. Then, to create offsets and buffer array, I use `TypedBufferBuilder` as suggested in the original comment #43302 (comment). ### Are these changes tested? The original unit tests have passed. ### Are there any user-facing changes? No, the casting behavior should remain unchanged. closes [ #43573 ](#43573) * GitHub Issue: #43573 Lead-authored-by: Crystal Zhou <crystal.zhouxiaoyue@hotmail.com> Co-authored-by: mwish <maplewish117@gmail.com> Co-authored-by: Crystal Zhou <45134936+CrystalZhou0529@users.noreply.github.com> Co-authored-by: Crystal <45134936+CrystalZhou0529@users.noreply.github.com> Co-authored-by: Felipe Oliveira Carvalho <felipekde@gmail.com> Signed-off-by: mwish <maplewish117@gmail.com>
…fset string and binary types (apache#44822) ### Rationale for this change Use `CopyBitmap` to optimize performance in string casting from string-view to offset string. ### What changes are included in this PR? Originally, the way we create the bitmap is by appending one bit at a time, which is slow. Since casting should not change the values in bitmap, this feature takes advantage of `CopyBitmap` to create the entire bitmap at once. Then, to create offsets and buffer array, I use `TypedBufferBuilder` as suggested in the original comment apache#43302 (comment). ### Are these changes tested? The original unit tests have passed. ### Are there any user-facing changes? No, the casting behavior should remain unchanged. closes [ apache#43573 ](apache#43573) * GitHub Issue: apache#43573 Lead-authored-by: Crystal Zhou <crystal.zhouxiaoyue@hotmail.com> Co-authored-by: mwish <maplewish117@gmail.com> Co-authored-by: Crystal Zhou <45134936+CrystalZhou0529@users.noreply.github.com> Co-authored-by: Crystal <45134936+CrystalZhou0529@users.noreply.github.com> Co-authored-by: Felipe Oliveira Carvalho <felipekde@gmail.com> Signed-off-by: mwish <maplewish117@gmail.com>
…tring and binary types (#44822) ### Rationale for this change Use `CopyBitmap` to optimize performance in string casting from string-view to offset string. ### What changes are included in this PR? Originally, the way we create the bitmap is by appending one bit at a time, which is slow. Since casting should not change the values in bitmap, this feature takes advantage of `CopyBitmap` to create the entire bitmap at once. Then, to create offsets and buffer array, I use `TypedBufferBuilder` as suggested in the original comment apache/arrow#43302 (comment). ### Are these changes tested? The original unit tests have passed. ### Are there any user-facing changes? No, the casting behavior should remain unchanged. closes [ #43573 ](apache/arrow#43573) * GitHub Issue: #43573 Lead-authored-by: Crystal Zhou <crystal.zhouxiaoyue@hotmail.com> Co-authored-by: mwish <maplewish117@gmail.com> Co-authored-by: Crystal Zhou <45134936+CrystalZhou0529@users.noreply.github.com> Co-authored-by: Crystal <45134936+CrystalZhou0529@users.noreply.github.com> Co-authored-by: Felipe Oliveira Carvalho <felipekde@gmail.com> Signed-off-by: mwish <maplewish117@gmail.com>
…ring_view (#802) ### Rationale for this change Fixes#184. `compute.CastArray` currently fails with `unsupported cast to string_view from utf8` (and symmetrically for `binary_view`, inverse directions, and FixedSizeBinary) because no cast kernels are registered for the view variants. PyArrow has supported this since 18.0.0 (apache/arrow#43302); this PR brings arrow-go to parity. ### What changes are included in this PR? **New cast kernels** in `arrow/compute/internal/kernels/binary_view_casts.go`: | Direction | Kernel | Notes | |---|---|---| | `binary`, `large_binary`, `string`, `large_string`, `fixed_size_binary` → `binary_view`/`string_view` | `CastBinaryToBinaryView` | Uses `BinaryViewBuilder`/`StringViewBuilder`. UTF-8 validated when destination is `string_view` and source is non-utf8, unless `CastOptions.AllowInvalidUtf8` is set. | | `binary_view`, `string_view` → `binary`, `large_binary`, `string`, `large_string` | `CastBinaryViewToBinary[OutOffsetT]` | Materializes into a contiguous data buffer. UTF-8 validated when casting `binary_view` → `string`/`large_string`, unless `AllowInvalidUtf8` is set. Checks `int32` overflow when targeting `string`/`binary`. | | `binary_view` ↔ `string_view` (and identity) | `CastBinaryViewToBinaryView` | Zero-copy via `ZeroCopyCastExec`; UTF-8 validated on `binary_view` → `string_view` direction. | These are wired into the dispatch table via `cast_binary_view` and `cast_string_view` entries in `cast.go`, and `addToBinaryKernels` now also registers `view → base-binary` kernels so the existing `cast_binary`/`cast_string`/etc. paths accept view inputs. **Related executor/array fixes** (required to get view types through the generic dispatch): * `arrow/compute/exec.getNumBuffers` now returns 3 for `binary_view`/`string_view` (bitmap + view headers + one overflow data buffer), matching `ArraySpan`'s fixed `[3]BufferSpan`. Previously this fell through to the `default: return 2` case, so the data buffer was dropped when `ArraySpan.MakeData` sliced to `bufs[:NumBuffers()]`, which crashed any cast that read non-inline values via `input.MakeArray()`. * `arrow/array.getMaxBufferLen` and the `nullArrayFactory` now handle `BinaryViewDataType`, so `MakeArrayOfNull` works for view outputs. Without this, casting a zero-length input array to a view type panicked with `arrayofnull not implemented for type string_view`. ### Are these changes tested? Yes. Added four new `CastSuite` tests in `arrow/compute/cast_test.go`: * `TestBinaryLikeToBinaryView` - all base-binary → view, FSB → view, short (inline) + long (out-of-line) values + nulls, UTF-8 validation + opt-out via `AllowInvalidUtf8`. * `TestBinaryViewToBinaryLike` - view → all base-binary, UTF-8 validation for `binary_view` → `string`. * `TestBinaryViewToBinaryView` - cross-view casts with UTF-8 validation. * `TestCanCastViewTypes` - `CanCast` coverage for the new paths. These use a simple array-level comparison (`checkCastArrayOnly`) rather than the existing `checkCast` because the latter iterates via `scalar.GetScalar`, which does not yet support view types (separate limitation, outside scope). Full `arrow/compute/...` and `arrow/array/...` test suites pass; `arrow/compute` also passes with `-race`. The exact reproducer from #184 now succeeds: ``` input: ["a" "b" "c" "this is a longer string beyond 12 bytes"] cast to string_view: ["a" "b" "c" "this is a longer string beyond 12 bytes"] type: string_view ``` ### Are there any user-facing changes? Yes - previously-unsupported cast paths now work: * `compute.CastArray(ctx, arr, {ToType: BinaryTypes.StringView})` and inverse. * `compute.CastArray(ctx, arr, {ToType: BinaryTypes.BinaryView})` and inverse. * `binary_view` ↔ `string_view` casts. * FSB → `binary_view`/`string_view`. * `compute.CanCast` advertises all of the above. No existing behavior changes. The change to `getNumBuffers` could in principle affect other compute paths that manipulate view arrays, but the previous value of `2` was incorrect for views (causing data-buffer loss), so this is a bug fix rather than a behavioral change.
Rationale for this change
We need casts between string (binary) and string-view (binary-view) types since they are semantically equivalent.
What changes are included in this PR?
is_binary_view_like()type predicateBinaryViewTypes()list includingSTRING_VIEW/BINARY_VIEWAre these changes tested?
Yes, but test coverage might be improved.
Are there any user-facing changes?
More casts are available.