use reifydb_core::value::column::data::ColumnData;
use reifydb_type::{error::TypeError, fragment::LazyFragment, value::r#type::Type};
use super::cast_column_data;
use crate::{Result, expression::context::EvalContext};
pub fn from_any(
ctx: &EvalContext,
data: &ColumnData,
target: Type,
lazy_fragment: impl LazyFragment + Clone,
) -> Result<ColumnData> {
let any_container = match data {
ColumnData::Any(container) => container,
_ => {
return Err(TypeError::UnsupportedCast {
from: data.get_type(),
to: target,
fragment: lazy_fragment.fragment(),
}
.into());
}
};
if any_container.is_empty() {
return Ok(ColumnData::with_capacity(target.clone(), 0));
}
let mut temp_results = Vec::with_capacity(any_container.len());
for i in 0..any_container.len() {
if !any_container.is_defined(i) {
temp_results.push(None);
continue;
}
let value = &*any_container.data()[i];
let single_column = ColumnData::from(value.clone());
match cast_column_data(ctx, &single_column, target.clone(), lazy_fragment.clone()) {
Ok(result) => temp_results.push(Some(result)),
Err(e) => {
return Err(e);
}
}
}
let mut result = ColumnData::with_capacity(target, any_container.len());
for temp_result in temp_results {
match temp_result {
None => {
result.push_none();
}
Some(casted_column) => {
match &casted_column {
ColumnData::Bool(c) => {
if c.is_defined(0) {
result.push::<bool>(c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Int1(c) => {
if c.is_defined(0) {
result.push::<i8>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Int2(c) => {
if c.is_defined(0) {
result.push::<i16>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Int4(c) => {
if c.is_defined(0) {
result.push::<i32>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Int8(c) => {
if c.is_defined(0) {
result.push::<i64>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Int16(c) => {
if c.is_defined(0) {
result.push::<i128>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Uint1(c) => {
if c.is_defined(0) {
result.push::<u8>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Uint2(c) => {
if c.is_defined(0) {
result.push::<u16>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Uint4(c) => {
if c.is_defined(0) {
result.push::<u32>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Uint8(c) => {
if c.is_defined(0) {
result.push::<u64>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Uint16(c) => {
if c.is_defined(0) {
result.push::<u128>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Float4(c) => {
if c.is_defined(0) {
result.push::<f32>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Float8(c) => {
if c.is_defined(0) {
result.push::<f64>(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Utf8 {
container: c,
..
} => {
if c.is_defined(0) {
result.push::<String>(c.get(0).unwrap().clone());
} else {
result.push_none();
}
}
ColumnData::Blob {
container: c,
..
} => {
if c.is_defined(0) {
result.push(c.get(0).unwrap().clone());
} else {
result.push_none();
}
}
ColumnData::Date(c) => {
if c.is_defined(0) {
result.push(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::DateTime(c) => {
if c.is_defined(0) {
result.push(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Time(c) => {
if c.is_defined(0) {
result.push(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Duration(c) => {
if c.is_defined(0) {
result.push(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::IdentityId(c) => {
if c.is_defined(0) {
result.push(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Uuid4(c) => {
if c.is_defined(0) {
result.push(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Uuid7(c) => {
if c.is_defined(0) {
result.push(*c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Int {
container: c,
..
} => {
if c.is_defined(0) {
result.push(c.get(0).unwrap().clone());
} else {
result.push_none();
}
}
ColumnData::Uint {
container: c,
..
} => {
if c.is_defined(0) {
result.push(c.get(0).unwrap().clone());
} else {
result.push_none();
}
}
ColumnData::Decimal {
container: c,
..
} => {
if c.is_defined(0) {
result.push(c.get(0).unwrap().clone());
} else {
result.push_none();
}
}
ColumnData::DictionaryId(c) => {
if c.is_defined(0) {
result.push(c.get(0).unwrap());
} else {
result.push_none();
}
}
ColumnData::Any(_) => {
unreachable!("Casting from Any should not produce Any")
}
ColumnData::Option {
..
} => {
let value = casted_column.get_value(0);
result.push_value(value);
}
}
}
}
}
Ok(result)
}