datafusion_python/expr/
distinct.rs1use std::fmt::{self, Display, Formatter};
19
20use datafusion::logical_expr::Distinct;
21use pyo3::IntoPyObjectExt;
22use pyo3::prelude::*;
23
24use super::logical_node::LogicalNode;
25use crate::sql::logical::PyLogicalPlan;
26
27#[pyclass(
28 from_py_object,
29 frozen,
30 name = "Distinct",
31 module = "datafusion.expr",
32 subclass
33)]
34#[derive(Clone)]
35pub struct PyDistinct {
36 distinct: Distinct,
37}
38
39impl From<PyDistinct> for Distinct {
40 fn from(distinct: PyDistinct) -> Self {
41 distinct.distinct
42 }
43}
44
45impl From<Distinct> for PyDistinct {
46 fn from(distinct: Distinct) -> PyDistinct {
47 PyDistinct { distinct }
48 }
49}
50
51impl Display for PyDistinct {
52 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
53 match &self.distinct {
54 Distinct::All(input) => write!(
55 f,
56 "Distinct ALL
57 \nInput: {input:?}",
58 ),
59 Distinct::On(distinct_on) => {
60 write!(
61 f,
62 "Distinct ON
63 \nInput: {:?}",
64 distinct_on.input,
65 )
66 }
67 }
68 }
69}
70
71#[pymethods]
72impl PyDistinct {
73 fn input(&self) -> PyResult<Vec<PyLogicalPlan>> {
75 Ok(Self::inputs(self))
76 }
77
78 fn __repr__(&self) -> PyResult<String> {
79 Ok(format!("Distinct({self})"))
80 }
81
82 fn __name__(&self) -> PyResult<String> {
83 Ok("Distinct".to_string())
84 }
85}
86
87impl LogicalNode for PyDistinct {
88 fn inputs(&self) -> Vec<PyLogicalPlan> {
89 match &self.distinct {
90 Distinct::All(input) => vec![PyLogicalPlan::from(input.as_ref().clone())],
91 Distinct::On(distinct_on) => {
92 vec![PyLogicalPlan::from(distinct_on.input.as_ref().clone())]
93 }
94 }
95 }
96
97 fn to_variant<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
98 self.clone().into_bound_py_any(py)
99 }
100}