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