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, PyObject, 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 let val = value.call_method0("as_py")?;
34
35 let factory = py.import("pyarrow")?.getattr("array")?;
37 let args = PyList::new(py, [val])?;
38 let array = factory.call1((args, typ))?;
39
40 let array = arrow::array::make_array(ArrayData::from_pyarrow_bound(&array)?);
42 let scalar = ScalarValue::try_from_array(&array, 0).map_err(PyDataFusionError::from)?;
43
44 Ok(PyScalarValue(scalar))
45 }
46}
47
48impl<'source> FromPyObject<'source> for PyScalarValue {
49 fn extract_bound(value: &Bound<'source, PyAny>) -> PyResult<Self> {
50 Self::from_pyarrow_bound(value)
51 }
52}
53
54pub fn scalar_to_pyarrow(scalar: &ScalarValue, py: Python) -> PyResult<PyObject> {
55 let array = scalar.to_array().map_err(PyDataFusionError::from)?;
56 let pyarray = array.to_data().to_pyarrow(py)?;
58 let pyscalar = pyarray.call_method1(py, "__getitem__", (0,))?;
59
60 Ok(pyscalar)
61}