|
16 | 16 | // under the License. |
17 | 17 |
|
18 | 18 | use crate::{errors::PyDataFusionResult, expr::PyExpr}; |
19 | | -use datafusion::common::{exec_err, DataFusionError}; |
20 | 19 | use datafusion::logical_expr::conditional_expressions::CaseBuilder; |
21 | 20 | use datafusion::prelude::Expr; |
22 | 21 | use pyo3::prelude::*; |
23 | 22 |
|
| 23 | +// TODO(tsaucer) replace this all with CaseBuilder after it implements Clone |
| 24 | +#[derive(Clone, Debug)] |
24 | 25 | #[pyclass(name = "CaseBuilder", module = "datafusion.expr", subclass, frozen)] |
25 | 26 | pub struct PyCaseBuilder { |
26 | | - case_builder: CaseBuilder, |
| 27 | + expr: Option<Expr>, |
| 28 | + when: Vec<Expr>, |
| 29 | + then: Vec<Expr>, |
27 | 30 | } |
28 | 31 |
|
29 | | -impl From<CaseBuilder> for PyCaseBuilder { |
30 | | - fn from(case_builder: CaseBuilder) -> PyCaseBuilder { |
31 | | - PyCaseBuilder { case_builder } |
| 32 | +#[pymethods] |
| 33 | +impl PyCaseBuilder { |
| 34 | + #[new] |
| 35 | + pub fn new(expr: Option<PyExpr>) -> Self { |
| 36 | + Self { |
| 37 | + expr: expr.map(Into::into), |
| 38 | + when: vec![], |
| 39 | + then: vec![], |
| 40 | + } |
32 | 41 | } |
33 | | -} |
34 | | - |
35 | | -// TODO(tsaucer) upstream make CaseBuilder impl Clone |
36 | | -fn builder_clone(case_builder: &CaseBuilder) -> Result<CaseBuilder, DataFusionError> { |
37 | | - let Expr::Case(case) = case_builder.end()? else { |
38 | | - return exec_err!("CaseBuilder returned an invalid expression"); |
39 | | - }; |
40 | 42 |
|
41 | | - let (when_expr, then_expr) = case |
42 | | - .when_then_expr |
43 | | - .iter() |
44 | | - .map(|(w, t)| (w.as_ref().to_owned(), t.as_ref().to_owned())) |
45 | | - .unzip(); |
| 43 | + pub fn when(&self, when: PyExpr, then: PyExpr) -> PyCaseBuilder { |
| 44 | + println!("when called {self:?}"); |
| 45 | + let mut case_builder = self.clone(); |
| 46 | + case_builder.when.push(when.into()); |
| 47 | + case_builder.then.push(then.into()); |
46 | 48 |
|
47 | | - Ok(CaseBuilder::new( |
48 | | - case.expr, |
49 | | - when_expr, |
50 | | - then_expr, |
51 | | - case.else_expr, |
52 | | - )) |
53 | | -} |
54 | | - |
55 | | -#[pymethods] |
56 | | -impl PyCaseBuilder { |
57 | | - fn when(&self, when: PyExpr, then: PyExpr) -> PyDataFusionResult<PyCaseBuilder> { |
58 | | - let case_builder = builder_clone(&self.case_builder)?.when(when.expr, then.expr); |
59 | | - Ok(PyCaseBuilder { case_builder }) |
| 49 | + case_builder |
60 | 50 | } |
61 | 51 |
|
62 | 52 | fn otherwise(&self, else_expr: PyExpr) -> PyDataFusionResult<PyExpr> { |
63 | | - Ok(builder_clone(&self.case_builder)? |
64 | | - .otherwise(else_expr.expr)? |
65 | | - .into()) |
| 53 | + println!("otherwise called {self:?}"); |
| 54 | + let case_builder = CaseBuilder::new( |
| 55 | + self.expr.clone().map(Box::new), |
| 56 | + self.when.clone(), |
| 57 | + self.then.clone(), |
| 58 | + Some(Box::new(else_expr.into())), |
| 59 | + ); |
| 60 | + |
| 61 | + let expr = case_builder.end()?; |
| 62 | + |
| 63 | + Ok(expr.into()) |
66 | 64 | } |
67 | 65 |
|
68 | 66 | fn end(&self) -> PyDataFusionResult<PyExpr> { |
69 | | - Ok(builder_clone(&self.case_builder)?.end()?.into()) |
| 67 | + println!("end called {self:?}"); |
| 68 | + |
| 69 | + let case_builder = CaseBuilder::new( |
| 70 | + self.expr.clone().map(Box::new), |
| 71 | + self.when.clone(), |
| 72 | + self.then.clone(), |
| 73 | + None, |
| 74 | + ); |
| 75 | + |
| 76 | + let expr = case_builder.end()?; |
| 77 | + |
| 78 | + Ok(expr.into()) |
70 | 79 | } |
71 | 80 | } |
0 commit comments