use arrow_array::{Array, Int32Array, StringArray, UnionArray};
use typed_arrow::{bridge::ArrowBinding, prelude::*};
#[derive(Union)]
#[union(tags(Num = 10, Str = 7))]
enum Value {
#[union(null, field = "int_value")]
Num(i32),
#[union(field = "str_value")]
Str(String),
}
#[derive(Union)]
#[union(mode = "sparse")]
enum ValueSparse {
I(i32),
S(String),
}
#[derive(Record)]
struct Row {
id: i32,
value: Value,
}
fn main() {
let udt = <Value as ArrowBinding>::data_type();
println!("Union DataType: {udt:?}");
let col_dt = <Row as ColAt<1>>::data_type();
println!("Record column[1] DataType: {col_dt:?}");
let mut b = <Value as ArrowBinding>::new_builder(4);
<Value as ArrowBinding>::append_value(&mut b, &Value::Str("x".into())); <Value as ArrowBinding>::append_value(&mut b, &Value::Num(1)); <Value as ArrowBinding>::append_null(&mut b); <Value as ArrowBinding>::append_value(&mut b, &Value::Num(7)); let arr: UnionArray = <Value as ArrowBinding>::finish(b);
let ints = arr.child(10).as_any().downcast_ref::<Int32Array>().unwrap();
let strs = arr.child(7).as_any().downcast_ref::<StringArray>().unwrap();
for i in 0..arr.len() {
let tid = arr.type_id(i);
let off = arr.value_offset(i);
match tid {
10 => {
if ints.is_null(off) {
println!("row {i} => Num = null");
} else {
println!("row {} => Num = {}", i, ints.value(off));
}
}
7 => {
println!("row {} => Str = {}", i, strs.value(off));
}
_ => unreachable!(),
}
}
let rows = vec![
Row {
id: 1,
value: Value::Num(5),
},
Row {
id: 2,
value: Value::Str("a".into()),
},
Row {
id: 3,
value: Value::Num(8),
},
];
let mut rb = <Row as BuildRows>::new_builders(rows.len());
rb.append_rows(rows);
let arrays = rb.finish();
let batch = arrays.into_record_batch();
println!(
"RecordBatch rows={}, fields={}",
batch.num_rows(),
batch.schema().fields().len()
);
let mut bs = <ValueSparse as ArrowBinding>::new_builder(4);
<ValueSparse as ArrowBinding>::append_value(&mut bs, &ValueSparse::I(2));
<ValueSparse as ArrowBinding>::append_value(&mut bs, &ValueSparse::S("y".into()));
<ValueSparse as ArrowBinding>::append_null(&mut bs); <ValueSparse as ArrowBinding>::append_value(&mut bs, &ValueSparse::I(8));
let arr_s: UnionArray = <ValueSparse as ArrowBinding>::finish(bs);
println!(
"Sparse len={}, mode_is_sparse={}",
arr_s.len(),
matches!(
<ValueSparse as ArrowBinding>::data_type(),
arrow_schema::DataType::Union(_, arrow_schema::UnionMode::Sparse)
)
);
let ints_s = arr_s
.child(0)
.as_any()
.downcast_ref::<Int32Array>()
.unwrap();
let strs_s = arr_s
.child(1)
.as_any()
.downcast_ref::<StringArray>()
.unwrap();
for i in 0..arr_s.len() {
match arr_s.type_id(i) {
0 => {
if ints_s.is_null(i) {
println!("sparse row {i} => I = null");
} else {
println!("sparse row {i} => I = {}", ints_s.value(i));
}
}
1 => println!("sparse row {i} => S = {}", strs_s.value(i)),
_ => unreachable!(),
}
}
}