datafusion_ffi/expr/
columnar_value.rs1use abi_stable::StableAbi;
19use datafusion_common::{DataFusionError, ScalarValue};
20use datafusion_expr::ColumnarValue;
21
22use crate::arrow_wrappers::WrappedArray;
23
24#[repr(C)]
27#[derive(Debug, StableAbi)]
28pub enum FFI_ColumnarValue {
29 Array(WrappedArray),
30 Scalar(WrappedArray),
31}
32
33impl TryFrom<ColumnarValue> for FFI_ColumnarValue {
34 type Error = DataFusionError;
35 fn try_from(value: ColumnarValue) -> Result<Self, Self::Error> {
36 Ok(match value {
37 ColumnarValue::Array(v) => {
38 FFI_ColumnarValue::Array(WrappedArray::try_from(&v)?)
39 }
40 ColumnarValue::Scalar(v) => {
41 FFI_ColumnarValue::Scalar(WrappedArray::try_from(&v)?)
42 }
43 })
44 }
45}
46
47impl TryFrom<FFI_ColumnarValue> for ColumnarValue {
48 type Error = DataFusionError;
49 fn try_from(value: FFI_ColumnarValue) -> Result<Self, Self::Error> {
50 Ok(match value {
51 FFI_ColumnarValue::Array(v) => ColumnarValue::Array(v.try_into()?),
52 FFI_ColumnarValue::Scalar(v) => {
53 ColumnarValue::Scalar(ScalarValue::try_from(v)?)
54 }
55 })
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use arrow::array::create_array;
62 use datafusion_common::{DataFusionError, ScalarValue};
63 use datafusion_expr::ColumnarValue;
64
65 use crate::expr::columnar_value::FFI_ColumnarValue;
66
67 #[test]
68 fn ffi_columnar_value_round_trip() -> Result<(), DataFusionError> {
69 let array = create_array!(Int32, [1, 2, 3, 4, 5]);
70
71 for original in [
72 ColumnarValue::Array(array),
73 ColumnarValue::Scalar(ScalarValue::Int32(Some(1))),
74 ] {
75 let ffi_variant = FFI_ColumnarValue::try_from(original.clone())?;
76
77 let returned_value = ColumnarValue::try_from(ffi_variant)?;
78
79 assert_eq!(format!("{returned_value:?}"), format!("{original:?}"));
80 }
81
82 Ok(())
83 }
84}