#[repr(C, align(64))]pub struct Table {
pub cols: Vec<FieldArray>,
pub n_rows: usize,
pub name: String,
}Expand description
§Table
§Description
- Standard columnar table with named columns (
FieldArray), a fixed number of rows, and an optional logical table name. - All columns are required to be equal length and have consistent schema.
- Supports zero-copy slicing, efficient iteration, and bulk operations.
- Equivalent to the
RecordBatchin Apache Arrow.
§Structure
cols: A vector ofFieldArray, each representing a column with metadata and data.n_rows: The logical number of rows (guaranteed equal for all columns).name: Optional logical name or alias for this table instance.
§Usage
- Use
Tableas a general-purpose, in-memory columnar data container. - Good for analytics, and transformation pipelines.
- For batched/partitioned tables, see [
SuperTable] or windowed/chunked abstractions. - Cast into Polars dataframe via
.to_polars()or Apache Arrow via.to_apache_arrow() - FFI-compatible
§Notes
- Table instances are typically lightweight to clone and pass by value.
- For mutation, construct a new table or replace individual columns as needed.
- There is an alias
RecordBatchunder crate::aliases::RecordBatch
§Example
use minarrow::{FieldArray, Print, Table, arr_i32, arr_str32, vec64};
let col1 = FieldArray::from_inner("numbers", arr_i32![1, 2, 3]);
let col2 = FieldArray::from_inner("letters", arr_str32!["x", "y", "z"]);
let mut tbl = Table::new("Demo".into(), vec![col1, col2].into());
tbl.print();Fields§
§cols: Vec<FieldArray>FieldArrays representing named columns.
n_rows: usizeNumber of rows in the table.
name: StringTable name
Implementations§
Source§impl Table
impl Table
Sourcepub fn new(name: String, cols: Option<Vec<FieldArray>>) -> Self
pub fn new(name: String, cols: Option<Vec<FieldArray>>) -> Self
Constructs a new Table with a specified name and optional columns.
If cols is provided, the number of rows will be inferred from the first column.
Examples found in repository?
13fn main() {
14 // Inner arrays
15
16 // Numeric
17 let col_i32 = IntArr::<i32>::from_slice(&[1, 2, 3, 4, 5]);
18 let col_u32 = IntArr::<u32>::from_slice(&[100, 200, 300, 400, 500]);
19 let col_i64 = IntArr::<i64>::from_slice(&[10, 20, 30, 40, 50]);
20 let col_u64 = IntArr::<u64>::from_slice(&[101, 201, 301, 401, 501]);
21 let col_f32 = FltArr::<f32>::from_slice(&[1.1, 2.2, 3.3, 4.4, 5.5]);
22 let col_f64 = FltArr::<f64>::from_slice(&[2.2, 3.3, 4.4, 5.5, 6.6]);
23
24 // Boolean with nulls
25 let mut col_bool = BoolArr::from_slice(&[true, false, true, false, true]);
26 col_bool.set_null_mask(Some(Bitmask::from_bools(&[true, true, true, false, true])));
27
28 // String and Dictionary/Categorical
29 let col_str32 = StrArr::<u32>::from_slice(&["red", "blue", "green", "yellow", "purple"]);
30 let col_cat32 = CatArr::<u32>::from_values(
31 ["apple", "banana", "cherry", "banana", "apple"].iter().copied()
32 );
33
34 // Datetime
35 #[cfg(feature = "datetime")]
36 let col_dt32 = DatetimeArray::<i32>::from_slice(
37 &[1000, 2000, 3000, 4000, 5000],
38 Some(TimeUnit::Milliseconds)
39 );
40 #[cfg(feature = "datetime")]
41 let col_dt64 = DatetimeArray::<i64>::from_slice(
42 &[1_000_000_000, 2_000_000_000, 3_000_000_000, 4_000_000_000, 5_000_000_000],
43 Some(TimeUnit::Nanoseconds)
44 );
45
46 // FieldArray (column) construction
47 let fa_i32 = FieldArray::from_inner("int32_col", col_i32);
48 let fa_u32 = FieldArray::from_inner("uint32_col", col_u32);
49 let fa_i64 = FieldArray::from_inner("int64_col", col_i64);
50 let fa_u64 = FieldArray::from_inner("uint64_col", col_u64);
51 let fa_f32 = FieldArray::from_inner("float32_col", col_f32);
52 let fa_f64 = FieldArray::from_inner("float64_col", col_f64);
53 let fa_bool = FieldArray::from_inner("bool_col", col_bool);
54 let fa_str32 = FieldArray::from_inner("utf8_col", col_str32);
55 let fa_cat32 = FieldArray::from_inner("dict32_col", col_cat32);
56 #[cfg(feature = "datetime")]
57 let fa_dt32 = FieldArray::from_inner("datetime32_col", col_dt32);
58 #[cfg(feature = "datetime")]
59 let fa_dt64 = FieldArray::from_inner("datetime64_col", col_dt64);
60
61 // Build Table
62 let mut tbl = Table::new("MyTable".to_string(), None);
63 tbl.add_col(fa_i32);
64 tbl.add_col(fa_u32);
65 tbl.add_col(fa_i64);
66 tbl.add_col(fa_u64);
67 tbl.add_col(fa_f32);
68 tbl.add_col(fa_f64);
69 tbl.add_col(fa_bool);
70 tbl.add_col(fa_str32);
71 tbl.add_col(fa_cat32);
72 #[cfg(feature = "datetime")]
73 tbl.add_col(fa_dt32);
74 #[cfg(feature = "datetime")]
75 tbl.add_col(fa_dt64);
76
77 // Print the table
78 tbl.print();
79}More examples
31 fn build_minarrow_table() -> Table {
32 // Arrays
33 #[cfg(feature = "extended_numeric_types")]
34 let arr_int8 = Arc::new(minarrow::IntegerArray::<i8>::from_slice(&[1, 2, -1])) as Arc<_>;
35 #[cfg(feature = "extended_numeric_types")]
36 let arr_int16 =
37 Arc::new(minarrow::IntegerArray::<i16>::from_slice(&[10, 20, -10])) as Arc<_>;
38 let arr_int32 =
39 Arc::new(minarrow::IntegerArray::<i32>::from_slice(&[100, 200, -100])) as Arc<_>;
40 let arr_int64 =
41 Arc::new(minarrow::IntegerArray::<i64>::from_slice(&[1000, 2000, -1000])) as Arc<_>;
42
43 #[cfg(feature = "extended_numeric_types")]
44 let arr_uint8 = Arc::new(minarrow::IntegerArray::<u8>::from_slice(&[1, 2, 255]))
45 as Arc<minarrow::IntegerArray<u8>>;
46 #[cfg(feature = "extended_numeric_types")]
47 let arr_uint16 = Arc::new(minarrow::IntegerArray::<u16>::from_slice(&[1, 2, 65535]))
48 as Arc<minarrow::IntegerArray<u16>>;
49 let arr_uint32 = Arc::new(minarrow::IntegerArray::<u32>::from_slice(&[1, 2, 4294967295]))
50 as Arc<minarrow::IntegerArray<u32>>;
51 let arr_uint64 =
52 Arc::new(minarrow::IntegerArray::<u64>::from_slice(&[1, 2, 18446744073709551615]))
53 as Arc<minarrow::IntegerArray<u64>>;
54
55 let arr_float32 = Arc::new(minarrow::FloatArray::<f32>::from_slice(&[1.5, -0.5, 0.0]))
56 as Arc<minarrow::FloatArray<f32>>;
57 let arr_float64 = Arc::new(minarrow::FloatArray::<f64>::from_slice(&[1.0, -2.0, 0.0]))
58 as Arc<minarrow::FloatArray<f64>>;
59
60 let arr_bool = Arc::new(minarrow::BooleanArray::<()>::from_slice(&[true, false, true]))
61 as Arc<minarrow::BooleanArray<()>>;
62
63 let arr_string32 = Arc::new(minarrow::StringArray::<u32>::from_slice(&["abc", "def", ""]))
64 as Arc<minarrow::StringArray<u32>>;
65 let arr_categorical32 = Arc::new(minarrow::CategoricalArray::<u32>::from_slices(
66 &[0, 1, 2],
67 &["A".to_string(), "B".to_string(), "C".to_string()],
68 )) as Arc<minarrow::CategoricalArray<u32>>;
69
70 #[cfg(feature = "datetime")]
71 let arr_datetime32 = Arc::new(minarrow::DatetimeArray::<i32> {
72 data: minarrow::Buffer::<i32>::from_slice(&[
73 1_600_000_000 / 86_400,
74 1_600_000_001 / 86_400,
75 1_600_000_002 / 86_400,
76 ]),
77 null_mask: None,
78 time_unit: TimeUnit::Days,
79 });
80 #[cfg(feature = "datetime")]
81 let arr_datetime64 = Arc::new(minarrow::DatetimeArray::<i64> {
82 data: minarrow::Buffer::<i64>::from_slice(&[
83 1_600_000_000_000,
84 1_600_000_000_001,
85 1_600_000_000_002,
86 ]),
87 null_mask: None,
88 time_unit: TimeUnit::Milliseconds,
89 }) as Arc<_>;
90
91 // Wrap in Array enums
92 #[cfg(feature = "extended_numeric_types")]
93 let minarr_int8 = Array::NumericArray(NumericArray::Int8(arr_int8));
94 #[cfg(feature = "extended_numeric_types")]
95 let minarr_int16 = Array::NumericArray(NumericArray::Int16(arr_int16));
96 let minarr_int32 = Array::NumericArray(NumericArray::Int32(arr_int32));
97 let minarr_int64 = Array::NumericArray(NumericArray::Int64(arr_int64));
98 #[cfg(feature = "extended_numeric_types")]
99 let minarr_uint8 = Array::NumericArray(NumericArray::UInt8(arr_uint8));
100 #[cfg(feature = "extended_numeric_types")]
101 let minarr_uint16 = Array::NumericArray(NumericArray::UInt16(arr_uint16));
102 let minarr_uint32 = Array::NumericArray(NumericArray::UInt32(arr_uint32));
103 let minarr_uint64 = Array::NumericArray(NumericArray::UInt64(arr_uint64));
104 let minarr_float32 = Array::NumericArray(NumericArray::Float32(arr_float32));
105 let minarr_float64 = Array::NumericArray(NumericArray::Float64(arr_float64));
106 let minarr_bool = Array::BooleanArray(arr_bool);
107 let minarr_string32 = Array::TextArray(TextArray::String32(arr_string32));
108 let minarr_categorical32 = Array::TextArray(TextArray::Categorical32(arr_categorical32));
109 #[cfg(feature = "datetime")]
110 let minarr_datetime32 = Array::TemporalArray(TemporalArray::Datetime32(arr_datetime32));
111 #[cfg(feature = "datetime")]
112 let minarr_datetime64 = Array::TemporalArray(TemporalArray::Datetime64(arr_datetime64));
113
114 // Fields
115 #[cfg(feature = "extended_numeric_types")]
116 let field_int8 = Field::new("int8", ArrowType::Int8, false, None);
117 #[cfg(feature = "extended_numeric_types")]
118 let field_int16 = Field::new("int16", ArrowType::Int16, false, None);
119 let field_int32 = Field::new("int32", ArrowType::Int32, false, None);
120 let field_int64 = Field::new("int64", ArrowType::Int64, false, None);
121 #[cfg(feature = "extended_numeric_types")]
122 let field_uint8 = Field::new("uint8", ArrowType::UInt8, false, None);
123 #[cfg(feature = "extended_numeric_types")]
124 let field_uint16 = Field::new("uint16", ArrowType::UInt16, false, None);
125 let field_uint32 = Field::new("uint32", ArrowType::UInt32, false, None);
126 let field_uint64 = Field::new("uint64", ArrowType::UInt64, false, None);
127 let field_float32 = Field::new("float32", ArrowType::Float32, false, None);
128 let field_float64 = Field::new("float64", ArrowType::Float64, false, None);
129 let field_bool = Field::new("bool", ArrowType::Boolean, false, None);
130 let field_string32 = Field::new("string32", ArrowType::String, false, None);
131 let field_categorical32 = Field::new(
132 "categorical32",
133 ArrowType::Dictionary(CategoricalIndexType::UInt32),
134 false,
135 None,
136 );
137 #[cfg(feature = "datetime")]
138 let field_datetime32 = Field::new("dt32", ArrowType::Date32, false, None);
139 #[cfg(feature = "datetime")]
140 let field_datetime64 = Field::new("dt64", ArrowType::Date64, false, None);
141
142 // FieldArrays
143 #[cfg(feature = "extended_numeric_types")]
144 let fa_int8 = FieldArray::new(field_int8, minarr_int8);
145 #[cfg(feature = "extended_numeric_types")]
146 let fa_int16 = FieldArray::new(field_int16, minarr_int16);
147 let fa_int32 = FieldArray::new(field_int32, minarr_int32);
148 let fa_int64 = FieldArray::new(field_int64, minarr_int64);
149 #[cfg(feature = "extended_numeric_types")]
150 let fa_uint8 = FieldArray::new(field_uint8, minarr_uint8);
151 #[cfg(feature = "extended_numeric_types")]
152 let fa_uint16 = FieldArray::new(field_uint16, minarr_uint16);
153 let fa_uint32 = FieldArray::new(field_uint32, minarr_uint32);
154 let fa_uint64 = FieldArray::new(field_uint64, minarr_uint64);
155 let fa_float32 = FieldArray::new(field_float32, minarr_float32);
156 let fa_float64 = FieldArray::new(field_float64, minarr_float64);
157 let fa_bool = FieldArray::new(field_bool, minarr_bool);
158 let fa_string32 = FieldArray::new(field_string32, minarr_string32);
159 let fa_categorical32 = FieldArray::new(field_categorical32, minarr_categorical32);
160 #[cfg(feature = "datetime")]
161 let fa_datetime32 = FieldArray::new(field_datetime32, minarr_datetime32);
162 #[cfg(feature = "datetime")]
163 let fa_datetime64 = FieldArray::new(field_datetime64, minarr_datetime64);
164
165 // Build table
166 let mut cols = Vec::new();
167 #[cfg(feature = "extended_numeric_types")]
168 {
169 cols.push(fa_int8);
170 cols.push(fa_int16);
171 }
172 cols.push(fa_int32);
173 cols.push(fa_int64);
174 #[cfg(feature = "extended_numeric_types")]
175 {
176 cols.push(fa_uint8);
177 cols.push(fa_uint16);
178 }
179 cols.push(fa_uint32);
180 cols.push(fa_uint64);
181 cols.push(fa_float32);
182 cols.push(fa_float64);
183 cols.push(fa_bool);
184 cols.push(fa_string32);
185 cols.push(fa_categorical32);
186 #[cfg(feature = "datetime")]
187 {
188 cols.push(fa_datetime32);
189 cols.push(fa_datetime64);
190 }
191 Table::new("polars_ffi_test".to_string(), Some(cols))
192 }28 pub (crate) fn run_example() {
29 // ---- 1. Build a Minarrow Table with all types ----
30
31 #[cfg(feature = "extended_numeric_types")]
32 let arr_int8 = Arc::new(minarrow::IntegerArray::<i8>::from_slice(&[1, 2, -1])) as Arc<_>;
33 #[cfg(feature = "extended_numeric_types")]
34 let arr_int16 =
35 Arc::new(minarrow::IntegerArray::<i16>::from_slice(&[10, 20, -10])) as Arc<_>;
36 let arr_int32 =
37 Arc::new(minarrow::IntegerArray::<i32>::from_slice(&[100, 200, -100])) as Arc<_>;
38 let arr_int64 =
39 Arc::new(minarrow::IntegerArray::<i64>::from_slice(&[1000, 2000, -1000])) as Arc<_>;
40
41 #[cfg(feature = "extended_numeric_types")]
42 let arr_uint8 = Arc::new(minarrow::IntegerArray::<u8>::from_slice(&[1, 2, 255]))
43 as Arc<minarrow::IntegerArray<u8>>;
44 #[cfg(feature = "extended_numeric_types")]
45 let arr_uint16 = Arc::new(minarrow::IntegerArray::<u16>::from_slice(&[1, 2, 65535]))
46 as Arc<minarrow::IntegerArray<u16>>;
47 let arr_uint32 = Arc::new(minarrow::IntegerArray::<u32>::from_slice(&[1, 2, 4294967295]))
48 as Arc<minarrow::IntegerArray<u32>>;
49 let arr_uint64 =
50 Arc::new(minarrow::IntegerArray::<u64>::from_slice(&[1, 2, 18446744073709551615]))
51 as Arc<minarrow::IntegerArray<u64>>;
52
53 let arr_float32 = Arc::new(minarrow::FloatArray::<f32>::from_slice(&[1.5, -0.5, 0.0]))
54 as Arc<minarrow::FloatArray<f32>>;
55 let arr_float64 = Arc::new(minarrow::FloatArray::<f64>::from_slice(&[1.0, -2.0, 0.0]))
56 as Arc<minarrow::FloatArray<f64>>;
57
58 let arr_bool = Arc::new(minarrow::BooleanArray::<()>::from_slice(&[true, false, true]))
59 as Arc<minarrow::BooleanArray<()>>;
60
61 let arr_string32 = Arc::new(minarrow::StringArray::<u32>::from_slice(&["abc", "def", ""]))
62 as Arc<minarrow::StringArray<u32>>;
63 let arr_categorical32 = Arc::new(minarrow::CategoricalArray::<u32>::from_slices(
64 &[0, 1, 2],
65 &["A".to_string(), "B".to_string(), "C".to_string()]
66 )) as Arc<minarrow::CategoricalArray<u32>>;
67
68 #[cfg(feature = "datetime")]
69 let arr_datetime32 = Arc::new(minarrow::DatetimeArray::<i32> {
70 data: minarrow::Buffer::<i32>::from_slice(&[
71 1_600_000_000 / 86_400,
72 1_600_000_001 / 86_400,
73 1_600_000_002 / 86_400,
74 ]),
75 null_mask: None,
76 time_unit: TimeUnit::Days,
77 });
78 #[cfg(feature = "datetime")]
79 let arr_datetime64 = Arc::new(minarrow::DatetimeArray::<i64> {
80 data: minarrow::Buffer::<i64>::from_slice(&[
81 1_600_000_000_000,
82 1_600_000_000_001,
83 1_600_000_000_002
84 ]),
85 null_mask: None,
86 time_unit: TimeUnit::Milliseconds
87 }) as Arc<_>;
88
89 // ---- 2. Wrap into Array enums ----
90 #[cfg(feature = "extended_numeric_types")]
91 let minarr_int8 = Array::NumericArray(NumericArray::Int8(arr_int8));
92 #[cfg(feature = "extended_numeric_types")]
93 let minarr_int16 = Array::NumericArray(NumericArray::Int16(arr_int16));
94 let minarr_int32 = Array::NumericArray(NumericArray::Int32(arr_int32));
95 let minarr_int64 = Array::NumericArray(NumericArray::Int64(arr_int64));
96 #[cfg(feature = "extended_numeric_types")]
97 let minarr_uint8 = Array::NumericArray(NumericArray::UInt8(arr_uint8));
98 #[cfg(feature = "extended_numeric_types")]
99 let minarr_uint16 = Array::NumericArray(NumericArray::UInt16(arr_uint16));
100 let minarr_uint32 = Array::NumericArray(NumericArray::UInt32(arr_uint32));
101 let minarr_uint64 = Array::NumericArray(NumericArray::UInt64(arr_uint64));
102 let minarr_float32 = Array::NumericArray(NumericArray::Float32(arr_float32));
103 let minarr_float64 = Array::NumericArray(NumericArray::Float64(arr_float64));
104 let minarr_bool = Array::BooleanArray(arr_bool);
105 let minarr_string32 = Array::TextArray(TextArray::String32(arr_string32));
106 let minarr_categorical32 = Array::TextArray(TextArray::Categorical32(arr_categorical32));
107 #[cfg(feature = "datetime")]
108 let minarr_datetime32 = Array::TemporalArray(TemporalArray::Datetime32(arr_datetime32));
109 #[cfg(feature = "datetime")]
110 let minarr_datetime64 = Array::TemporalArray(TemporalArray::Datetime64(arr_datetime64));
111
112 // ---- 3. Build Fields with correct logical types ----
113 #[cfg(feature = "extended_numeric_types")]
114 let field_int8 = Field::new("int8", ArrowType::Int8, false, None);
115 #[cfg(feature = "extended_numeric_types")]
116 let field_int16 = Field::new("int16", ArrowType::Int16, false, None);
117 let field_int32 = Field::new("int32", ArrowType::Int32, false, None);
118 let field_int64 = Field::new("int64", ArrowType::Int64, false, None);
119 #[cfg(feature = "extended_numeric_types")]
120 let field_uint8 = Field::new("uint8", ArrowType::UInt8, false, None);
121 #[cfg(feature = "extended_numeric_types")]
122 let field_uint16 = Field::new("uint16", ArrowType::UInt16, false, None);
123 let field_uint32 = Field::new("uint32", ArrowType::UInt32, false, None);
124 let field_uint64 = Field::new("uint64", ArrowType::UInt64, false, None);
125 let field_float32 = Field::new("float32", ArrowType::Float32, false, None);
126 let field_float64 = Field::new("float64", ArrowType::Float64, false, None);
127 let field_bool = Field::new("bool", ArrowType::Boolean, false, None);
128 let field_string32 = Field::new("string32", ArrowType::String, false, None);
129 let field_categorical32 = Field::new(
130 "categorical32",
131 ArrowType::Dictionary(CategoricalIndexType::UInt32),
132 false,
133 None
134 );
135
136 #[cfg(feature = "datetime")]
137 let field_datetime32 = Field::new("dt32", ArrowType::Date32, false, None);
138 #[cfg(feature = "datetime")]
139 let field_datetime64 = Field::new("dt64", ArrowType::Date64, false, None);
140
141 // ---- 4. Build FieldArrays ----
142 #[cfg(feature = "extended_numeric_types")]
143 let fa_int8 = FieldArray::new(field_int8, minarr_int8);
144 #[cfg(feature = "extended_numeric_types")]
145 let fa_int16 = FieldArray::new(field_int16, minarr_int16);
146 let fa_int32 = FieldArray::new(field_int32, minarr_int32);
147 let fa_int64 = FieldArray::new(field_int64, minarr_int64);
148 #[cfg(feature = "extended_numeric_types")]
149 let fa_uint8 = FieldArray::new(field_uint8, minarr_uint8);
150 #[cfg(feature = "extended_numeric_types")]
151 let fa_uint16 = FieldArray::new(field_uint16, minarr_uint16);
152 let fa_uint32 = FieldArray::new(field_uint32, minarr_uint32);
153 let fa_uint64 = FieldArray::new(field_uint64, minarr_uint64);
154 let fa_float32 = FieldArray::new(field_float32, minarr_float32);
155 let fa_float64 = FieldArray::new(field_float64, minarr_float64);
156 let fa_bool = FieldArray::new(field_bool, minarr_bool);
157 let fa_string32 = FieldArray::new(field_string32, minarr_string32);
158 let fa_categorical32 = FieldArray::new(field_categorical32, minarr_categorical32);
159 #[cfg(feature = "datetime")]
160 let fa_datetime32 = FieldArray::new(field_datetime32, minarr_datetime32);
161 #[cfg(feature = "datetime")]
162 let fa_datetime64 = FieldArray::new(field_datetime64, minarr_datetime64);
163
164 // ---- 5. Build Table ----
165 let mut cols = Vec::new();
166 #[cfg(feature = "extended_numeric_types")]
167 {
168 cols.push(fa_int8);
169 cols.push(fa_int16);
170 }
171 cols.push(fa_int32);
172 cols.push(fa_int64);
173 #[cfg(feature = "extended_numeric_types")]
174 {
175 cols.push(fa_uint8);
176 cols.push(fa_uint16);
177 }
178 cols.push(fa_uint32);
179 cols.push(fa_uint64);
180 cols.push(fa_float32);
181 cols.push(fa_float64);
182 cols.push(fa_bool);
183 cols.push(fa_string32);
184 cols.push(fa_categorical32);
185 #[cfg(feature = "datetime")]
186 {
187 cols.push(fa_datetime32);
188 cols.push(fa_datetime64);
189 }
190 let minarrow_table = Table::new("ffi_test".to_string(), Some(cols));
191
192 // ---- 6. Export each column over FFI, import into Arrow-RS, and roundtrip back to Minarrow ----
193 for (_, col) in minarrow_table.cols.iter().enumerate() {
194 let array_arc = Arc::new(col.array.clone());
195 let schema = Schema::from(vec![(*col.field).clone()]);
196
197 // println!("Minarrow Pre-roundtrip for '{:?}':\n{:#?}", *col.field, array_arc);
198
199 let (c_arr, c_schema) = export_to_c(array_arc.clone(), schema);
200
201 // SAFETY: Arrow-RS expects raw pointers to FFI_ArrowArray/Schema
202 let arr_ptr = c_arr as *mut FFI_ArrowArray;
203 let schema_ptr = c_schema as *mut FFI_ArrowSchema;
204 let arrow_array = unsafe { arr_ptr.read() };
205 let arrow_schema = unsafe { schema_ptr.read() };
206 let array_data = unsafe { arrow_from_ffi(arrow_array, &arrow_schema) }
207 .expect("Arrow FFI import failed");
208 let field_name = &col.field.name;
209 println!("Imported field '{}' as Arrow type {:?}", field_name, array_data.data_type());
210 println!("Arrow-RS values for '{}':", field_name);
211 println!(" {:?}", array_data);
212
213 // Convert ArrayData to ArrayRef
214 let array_ref: ArrayRef = make_array(array_data.clone());
215
216 // Pretty print as a table
217 let arrow_schema =
218 Arc::new(arrow::datatypes::Schema::new(vec![arrow::datatypes::Field::new(
219 field_name,
220 array_ref.data_type().clone(),
221 false
222 )]));
223 let batch = RecordBatch::try_new(arrow_schema, vec![array_ref.clone()]).unwrap();
224 println!("Arrow-RS pretty-print for '{}':", field_name);
225 arrow::util::pretty::print_batches(&[batch]).unwrap();
226
227 // ---- 7. Export Arrow-RS back to Minarrow FFI, roundtrip ----
228 let (ffi_out_arr, ffi_out_schema) =
229 arrow_to_ffi(&array_data).expect("Arrow to FFI failed");
230
231 // Correctly allocate Arrow-RS FFI structs on the heap and cast as raw pointers to your C ABI structs
232 let ffi_out_arr_box = Box::new(ffi_out_arr);
233 let ffi_out_schema_box = Box::new(ffi_out_schema);
234
235 let arr_ptr =
236 Box::into_raw(ffi_out_arr_box) as *const minarrow::ffi::arrow_c_ffi::ArrowArray;
237 let schema_ptr =
238 Box::into_raw(ffi_out_schema_box) as *const minarrow::ffi::arrow_c_ffi::ArrowSchema;
239
240 // Now import back into minarrow using your real FFI import
241 let minarr_back_array: Arc<Array> = unsafe { import_from_c(arr_ptr, schema_ptr) };
242
243 println!("Minarrow array (roundtrip) for '{}':\n{:#?}", field_name, minarr_back_array);
244
245 // ---- 8. Validate roundtrip equality ----
246 assert_eq!(
247 &col.array,
248 minarr_back_array.as_ref(),
249 "Roundtrip array does not match for field {}",
250 field_name
251 );
252 }
253
254 println!("FFI roundtrip test completed for all supported types.");
255 }Sourcepub fn add_col(&mut self, field_array: FieldArray)
pub fn add_col(&mut self, field_array: FieldArray)
Adds a column with a name.
Examples found in repository?
13fn main() {
14 // Inner arrays
15
16 // Numeric
17 let col_i32 = IntArr::<i32>::from_slice(&[1, 2, 3, 4, 5]);
18 let col_u32 = IntArr::<u32>::from_slice(&[100, 200, 300, 400, 500]);
19 let col_i64 = IntArr::<i64>::from_slice(&[10, 20, 30, 40, 50]);
20 let col_u64 = IntArr::<u64>::from_slice(&[101, 201, 301, 401, 501]);
21 let col_f32 = FltArr::<f32>::from_slice(&[1.1, 2.2, 3.3, 4.4, 5.5]);
22 let col_f64 = FltArr::<f64>::from_slice(&[2.2, 3.3, 4.4, 5.5, 6.6]);
23
24 // Boolean with nulls
25 let mut col_bool = BoolArr::from_slice(&[true, false, true, false, true]);
26 col_bool.set_null_mask(Some(Bitmask::from_bools(&[true, true, true, false, true])));
27
28 // String and Dictionary/Categorical
29 let col_str32 = StrArr::<u32>::from_slice(&["red", "blue", "green", "yellow", "purple"]);
30 let col_cat32 = CatArr::<u32>::from_values(
31 ["apple", "banana", "cherry", "banana", "apple"].iter().copied()
32 );
33
34 // Datetime
35 #[cfg(feature = "datetime")]
36 let col_dt32 = DatetimeArray::<i32>::from_slice(
37 &[1000, 2000, 3000, 4000, 5000],
38 Some(TimeUnit::Milliseconds)
39 );
40 #[cfg(feature = "datetime")]
41 let col_dt64 = DatetimeArray::<i64>::from_slice(
42 &[1_000_000_000, 2_000_000_000, 3_000_000_000, 4_000_000_000, 5_000_000_000],
43 Some(TimeUnit::Nanoseconds)
44 );
45
46 // FieldArray (column) construction
47 let fa_i32 = FieldArray::from_inner("int32_col", col_i32);
48 let fa_u32 = FieldArray::from_inner("uint32_col", col_u32);
49 let fa_i64 = FieldArray::from_inner("int64_col", col_i64);
50 let fa_u64 = FieldArray::from_inner("uint64_col", col_u64);
51 let fa_f32 = FieldArray::from_inner("float32_col", col_f32);
52 let fa_f64 = FieldArray::from_inner("float64_col", col_f64);
53 let fa_bool = FieldArray::from_inner("bool_col", col_bool);
54 let fa_str32 = FieldArray::from_inner("utf8_col", col_str32);
55 let fa_cat32 = FieldArray::from_inner("dict32_col", col_cat32);
56 #[cfg(feature = "datetime")]
57 let fa_dt32 = FieldArray::from_inner("datetime32_col", col_dt32);
58 #[cfg(feature = "datetime")]
59 let fa_dt64 = FieldArray::from_inner("datetime64_col", col_dt64);
60
61 // Build Table
62 let mut tbl = Table::new("MyTable".to_string(), None);
63 tbl.add_col(fa_i32);
64 tbl.add_col(fa_u32);
65 tbl.add_col(fa_i64);
66 tbl.add_col(fa_u64);
67 tbl.add_col(fa_f32);
68 tbl.add_col(fa_f64);
69 tbl.add_col(fa_bool);
70 tbl.add_col(fa_str32);
71 tbl.add_col(fa_cat32);
72 #[cfg(feature = "datetime")]
73 tbl.add_col(fa_dt32);
74 #[cfg(feature = "datetime")]
75 tbl.add_col(fa_dt64);
76
77 // Print the table
78 tbl.print();
79}Sourcepub fn col(&self, idx: usize) -> Option<&FieldArray>
pub fn col(&self, idx: usize) -> Option<&FieldArray>
Returns a column by index.
Sourcepub fn col_by_name(&self, name: &str) -> Option<&FieldArray>
pub fn col_by_name(&self, name: &str) -> Option<&FieldArray>
Returns a column by name.
Sourcepub fn remove_col(&mut self, name: &str) -> bool
pub fn remove_col(&mut self, name: &str) -> bool
Removes a column by name.
Sourcepub fn remove_col_at(&mut self, idx: usize) -> bool
pub fn remove_col_at(&mut self, idx: usize) -> bool
Removes a column by index.
Sourcepub fn cols(&self) -> &[FieldArray]
pub fn cols(&self) -> &[FieldArray]
Returns all columns.
Sourcepub fn cols_mut(&mut self) -> &mut [FieldArray]
pub fn cols_mut(&mut self) -> &mut [FieldArray]
Returns mutable reference to all columns.
pub fn iter(&self) -> Iter<'_, FieldArray>
pub fn iter_mut(&mut self) -> IterMut<'_, FieldArray>
pub fn set_name(&mut self, name: impl Into<String>)
Sourcepub fn slice_clone(&self, offset: usize, len: usize) -> Self
pub fn slice_clone(&self, offset: usize, len: usize) -> Self
Returns a new owned Table containing rows [offset, offset+len).
All columns are deeply copied, but only for the affected row(s).
Sourcepub fn slice(&self, offset: usize, len: usize) -> TableV
pub fn slice(&self, offset: usize, len: usize) -> TableV
Returns a zero-copy view over rows [offset, offset+len).
This view borrows from the parent table and does not copy data.
pub fn par_iter(&self) -> Iter<'_, FieldArray>
pub fn par_iter_mut(&mut self) -> IterMut<'_, FieldArray>
Sourcepub fn to_apache_arrow(&self) -> RecordBatch
pub fn to_apache_arrow(&self) -> RecordBatch
Export each column to arrow-rs ArrayRef and build a RecordBatch.
The Arrow schema is derived from the imported array dtypes while preserving the original field names and nullability flags.
Trait Implementations§
Source§impl FromIterator<Table> for SuperTable
impl FromIterator<Table> for SuperTable
Source§impl<'a> IntoIterator for &'a Table
impl<'a> IntoIterator for &'a Table
Source§impl<'a> IntoIterator for &'a mut Table
impl<'a> IntoIterator for &'a mut Table
Source§impl IntoIterator for Table
impl IntoIterator for Table
impl StructuralPartialEq for Table
Auto Trait Implementations§
impl Freeze for Table
impl RefUnwindSafe for Table
impl Send for Table
impl Sync for Table
impl Unpin for Table
impl UnwindSafe for Table
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> CustomValue for T
impl<T> CustomValue for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<I> IntoStreamingIterator for Iwhere
I: IntoIterator,
impl<I> IntoStreamingIterator for Iwhere
I: IntoIterator,
Source§fn into_streaming_iter(self) -> Convert<Self::IntoIter>
fn into_streaming_iter(self) -> Convert<Self::IntoIter>
Source§fn into_streaming_iter_ref<'a, T>(self) -> ConvertRef<'a, Self::IntoIter, T>
fn into_streaming_iter_ref<'a, T>(self) -> ConvertRef<'a, Self::IntoIter, T>
Source§fn into_streaming_iter_mut<'a, T>(self) -> ConvertMut<'a, Self::IntoIter, T>
fn into_streaming_iter_mut<'a, T>(self) -> ConvertMut<'a, Self::IntoIter, T>
Source§impl<T> Key for Twhere
T: Clone,
impl<T> Key for Twhere
T: Clone,
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read moreSource§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.