use arrow::array::{Array, FixedSizeListArray, Float32Array, RecordBatch};
use arrow_schema::DataType;
use crate::error::{JammiError, Result};
use crate::storage::{self, JammiObjectStore};
pub(crate) fn extend_with_fixed_size_list_f32(
batch: &RecordBatch,
table: &str,
column: &str,
out: &mut Vec<Vec<f32>>,
) -> Result<()> {
let col = batch
.column_by_name(column)
.ok_or_else(|| JammiError::Schema {
table: table.to_string(),
column: column.to_string(),
expected: "FixedSizeList<Float32>".to_string(),
actual: "missing".to_string(),
})?;
let list = col
.as_any()
.downcast_ref::<FixedSizeListArray>()
.ok_or_else(|| JammiError::Schema {
table: table.to_string(),
column: column.to_string(),
expected: "FixedSizeList<Float32>".to_string(),
actual: format!("{:?}", col.data_type()),
})?;
if !matches!(list.value_type(), DataType::Float32) {
return Err(JammiError::Schema {
table: table.to_string(),
column: column.to_string(),
expected: "FixedSizeList<Float32>".to_string(),
actual: format!("FixedSizeList<{:?}>", list.value_type()),
});
}
let dim = list.value_length() as usize;
for row in 0..list.len() {
let v = list.value(row);
let floats =
v.as_any()
.downcast_ref::<Float32Array>()
.ok_or_else(|| JammiError::Schema {
table: table.to_string(),
column: column.to_string(),
expected: "FixedSizeList<Float32>".to_string(),
actual: format!("FixedSizeList<{:?}>", v.data_type()),
})?;
let mut row_vec = Vec::with_capacity(dim);
for i in 0..dim {
row_vec.push(floats.value(i));
}
out.push(row_vec);
}
Ok(())
}
pub(crate) async fn read_fixed_size_list_f32_column(
handle: &JammiObjectStore,
table: &str,
column: &str,
) -> Result<Vec<Vec<f32>>> {
let batches = storage::reader::read_all_record_batches(handle).await?;
let mut out = Vec::new();
for batch in batches {
extend_with_fixed_size_list_f32(&batch, table, column, &mut out)?;
}
Ok(out)
}