datafusion_python/
pyarrow_util.rs1use arrow::array::{Array, ArrayData};
21use arrow::pyarrow::{FromPyArrow, ToPyArrow};
22use datafusion::scalar::ScalarValue;
23use pyo3::types::{PyAnyMethods, PyList};
24use pyo3::{Bound, FromPyObject, PyAny, PyResult, Python};
25
26use crate::common::data_type::PyScalarValue;
27use crate::errors::PyDataFusionError;
28
29impl FromPyArrow for PyScalarValue {
30 fn from_pyarrow_bound(value: &Bound<'_, PyAny>) -> PyResult<Self> {
31 let py = value.py();
32 let typ = value.getattr("type")?;
33
34 let factory = py.import("pyarrow")?.getattr("array")?;
36 let args = PyList::new(py, [value])?;
37 let array = factory.call1((args, typ))?;
38
39 let array = arrow::array::make_array(ArrayData::from_pyarrow_bound(&array)?);
41 let scalar = ScalarValue::try_from_array(&array, 0).map_err(PyDataFusionError::from)?;
42
43 Ok(PyScalarValue(scalar))
44 }
45}
46
47impl<'source> FromPyObject<'source> for PyScalarValue {
48 fn extract_bound(value: &Bound<'source, PyAny>) -> PyResult<Self> {
49 Self::from_pyarrow_bound(value)
50 }
51}
52
53pub fn scalar_to_pyarrow<'py>(
54 scalar: &ScalarValue,
55 py: Python<'py>,
56) -> PyResult<Bound<'py, PyAny>> {
57 let array = scalar.to_array().map_err(PyDataFusionError::from)?;
58 let pyarray = array.to_data().to_pyarrow(py)?;
60 let pyscalar = pyarray.call_method1("__getitem__", (0,))?;
61
62 Ok(pyscalar)
63}