Skip to content

Commit

Permalink
Support nullable Arrow unions using virtual union arms (#2708)
Browse files Browse the repository at this point in the history
**Commit by commit!**

This PR implements support for top-level nullable Arrow unions using the
"virtual arm" strategy.

Specifically, all unions derived from Flatbuffers definitions now have
an auto-generated arm at type index `0` of type `DataType::Null`.
The data values in this arm are irrelevant: the deserialization code
will treat the union as a whole as `null` any time the type buffer
indicates a value of `0`.

I've decided to make the auto-generated arm visible in the
auto-generated `DataType` definition because... why wouldn't we? It
makes it all much less magical and acts as a reminder that this thing is
indeed here.

The choice of using type index `0` rather than e.g. `nb_arms` is to make
things A) more stable and B) forwards compatible.
It cannot surprise end users in any way since user-defined types defined
in Flatbuffers would just do the right thing, while user-defined types
in raw Arrow don't even go through our (de)serialization logic but
rather through theirs.

In addition, this PR greatly improves error handling in the
auto-generated code, giving the end-user very specific context and a
context-correct backtrace when something goes wrong.


Fixes #2684

### What

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested [demo.rerun.io](https://demo.rerun.io/pr/2708) (if
applicable)

- [PR Build Summary](https://build.rerun.io/pr/2708)
- [Docs
preview](https://rerun.io/preview/pr%3Acmc%2Frust_virtual_union_arms/docs)
- [Examples
preview](https://rerun.io/preview/pr%3Acmc%2Frust_virtual_union_arms/examples)
  • Loading branch information
teh-cmc authored Jul 19, 2023
1 parent d77d5ec commit 2c2c46d
Show file tree
Hide file tree
Showing 53 changed files with 4,079 additions and 2,596 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/re_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ glam = ["dep:glam", "dep:macaw"]


[dependencies]
# Rerun
re_error.workspace = true

# External
arrow2 = { workspace = true, features = [
Expand All @@ -36,6 +38,7 @@ arrow2 = { workspace = true, features = [
"compute_concatenate",
] }
anyhow.workspace = true
backtrace = "0.3"
bytemuck = { version = "1.11", features = ["derive", "extern_crate_alloc"] }
document-features = "0.2"
itertools.workspace = true
Expand Down
12 changes: 4 additions & 8 deletions crates/re_types/definitions/rerun/testing/archetypes/fuzzy.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ table AffixFuzzer1 (
fuzz1012: rerun.testing.components.AffixFuzzer12 ("attr.rerun.component_required", order: 1012);
fuzz1013: rerun.testing.components.AffixFuzzer13 ("attr.rerun.component_required", order: 1013);
fuzz1014: rerun.testing.components.AffixFuzzer14 ("attr.rerun.component_required", order: 1014);
// NOTE: nullable union -- illegal!
// fuzz1015: rerun.testing.components.AffixFuzzer15 ("attr.rerun.component_required", order: 1015);
fuzz1015: rerun.testing.components.AffixFuzzer15 ("attr.rerun.component_required", order: 1015);
fuzz1016: rerun.testing.components.AffixFuzzer16 ("attr.rerun.component_required", order: 1016);
fuzz1017: rerun.testing.components.AffixFuzzer17 ("attr.rerun.component_required", order: 1017);
fuzz1018: rerun.testing.components.AffixFuzzer18 ("attr.rerun.component_required", order: 1018);
Expand All @@ -50,8 +49,7 @@ table AffixFuzzer1 (
fuzz1112: [rerun.testing.components.AffixFuzzer12] ("attr.rerun.component_required", order: 1112);
fuzz1113: [rerun.testing.components.AffixFuzzer13] ("attr.rerun.component_required", order: 1113);
fuzz1114: [rerun.testing.components.AffixFuzzer14] ("attr.rerun.component_required", order: 1114);
// NOTE: nullable union -- illegal!
// fuzz1115: [rerun.testing.components.AffixFuzzer15] ("attr.rerun.component_required", order: 1115);
fuzz1115: [rerun.testing.components.AffixFuzzer15] ("attr.rerun.component_required", order: 1115);
fuzz1116: [rerun.testing.components.AffixFuzzer16] ("attr.rerun.component_required", order: 1116);
fuzz1117: [rerun.testing.components.AffixFuzzer17] ("attr.rerun.component_required", order: 1117);
fuzz1118: [rerun.testing.components.AffixFuzzer18] ("attr.rerun.component_required", order: 1118);
Expand All @@ -70,8 +68,7 @@ table AffixFuzzer1 (
fuzz2012: rerun.testing.components.AffixFuzzer12 ("attr.rerun.component_optional", nullable, order: 2012);
fuzz2013: rerun.testing.components.AffixFuzzer13 ("attr.rerun.component_optional", nullable, order: 2013);
fuzz2014: rerun.testing.components.AffixFuzzer14 ("attr.rerun.component_optional", nullable, order: 2014);
// NOTE: nullable union -- illegal!
// fuzz2015: rerun.testing.components.AffixFuzzer15 ("attr.rerun.component_optional", nullable, order: 2015);
fuzz2015: rerun.testing.components.AffixFuzzer15 ("attr.rerun.component_optional", nullable, order: 2015);
fuzz2016: rerun.testing.components.AffixFuzzer16 ("attr.rerun.component_optional", nullable, order: 2016);
fuzz2017: rerun.testing.components.AffixFuzzer17 ("attr.rerun.component_optional", nullable, order: 2017);
fuzz2018: rerun.testing.components.AffixFuzzer18 ("attr.rerun.component_optional", nullable, order: 2018);
Expand All @@ -90,8 +87,7 @@ table AffixFuzzer1 (
fuzz2112: [rerun.testing.components.AffixFuzzer12] ("attr.rerun.component_optional", nullable, order: 2112);
fuzz2113: [rerun.testing.components.AffixFuzzer13] ("attr.rerun.component_optional", nullable, order: 2113);
fuzz2114: [rerun.testing.components.AffixFuzzer14] ("attr.rerun.component_optional", nullable, order: 2114);
// NOTE: nullable union -- illegal!
// fuzz2115: [rerun.testing.components.AffixFuzzer15] ("attr.rerun.component_optional", nullable, order: 2115);
fuzz2115: [rerun.testing.components.AffixFuzzer15] ("attr.rerun.component_optional", nullable, order: 2115);
fuzz2116: [rerun.testing.components.AffixFuzzer16] ("attr.rerun.component_optional", nullable, order: 2116);
fuzz2117: [rerun.testing.components.AffixFuzzer17] ("attr.rerun.component_optional", nullable, order: 2117);
fuzz2118: [rerun.testing.components.AffixFuzzer18] ("attr.rerun.component_optional", nullable, order: 2118);
Expand Down
13 changes: 6 additions & 7 deletions crates/re_types/definitions/rerun/testing/components/fuzzy.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,12 @@ table AffixFuzzer14 (
single_required_union: rerun.testing.datatypes.AffixFuzzer3 (order: 114);
}

// NOTE: Illegal: union don't have top-level bitmaps! Commenting out will/should break the build.
// table AffixFuzzer15 (
// "attr.rust.derive": "PartialEq",
// order: 1500
// ) {
// single_optional_union: rerun.testing.datatypes.AffixFuzzer3 (nullable, order: 115);
// }
table AffixFuzzer15 (
"attr.rust.derive": "PartialEq",
order: 1500
) {
single_optional_union: rerun.testing.datatypes.AffixFuzzer3 (nullable, order: 115);
}

table AffixFuzzer16 (
"attr.rust.derive": "PartialEq",
Expand Down
2 changes: 1 addition & 1 deletion crates/re_types/source_hash.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This is a sha256 hash for all direct and indirect dependencies of this crate's build script.
# It can be safely removed at anytime to force the build script to run again.
# Check out build.rs to see how it's computed.
289571cd5bcef516a43ead1678f39054c300890396d13933dc26d9294a07dffe
ba58a7d123c5fa81f04a58a6325ef65029d93f330d571176101db87596a9c0cf
Loading

0 comments on commit 2c2c46d

Please sign in to comment.