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