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