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