| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| use std::fmt::{self, Display, Formatter}; | |
| use std::sync::Arc; | |
| use datafusion::logical_expr::{ | |
| CreateFunction, CreateFunctionBody, OperateFunctionArg, Volatility, | |
| }; | |
| use pyo3::IntoPyObjectExt; | |
| use pyo3::prelude::*; | |
| use super::PyExpr; | |
| use super::logical_node::LogicalNode; | |
| use crate::common::data_type::PyDataType; | |
| use crate::common::df_schema::PyDFSchema; | |
| use crate::sql::logical::PyLogicalPlan; | |
| #[pyclass( | |
| from_py_object, | |
| frozen, | |
| name = "CreateFunction", | |
| module = "datafusion.expr", | |
| subclass | |
| )] | |
| #[derive(Clone)] | |
| pub struct PyCreateFunction { | |
| create: CreateFunction, | |
| } | |
| impl From<PyCreateFunction> for CreateFunction { | |
| fn from(create: PyCreateFunction) -> Self { | |
| create.create | |
| } | |
| } | |
| impl From<CreateFunction> for PyCreateFunction { | |
| fn from(create: CreateFunction) -> PyCreateFunction { | |
| PyCreateFunction { create } | |
| } | |
| } | |
| impl Display for PyCreateFunction { | |
| fn fmt(&self, f: &mut Formatter) -> fmt::Result { | |
| write!(f, "CreateFunction: name {:?}", self.create.name) | |
| } | |
| } | |
| #[pyclass( | |
| from_py_object, | |
| frozen, | |
| name = "OperateFunctionArg", | |
| module = "datafusion.expr", | |
| subclass | |
| )] | |
| #[derive(Clone)] | |
| pub struct PyOperateFunctionArg { | |
| arg: OperateFunctionArg, | |
| } | |
| #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] | |
| #[pyclass( | |
| from_py_object, | |
| frozen, | |
| eq, | |
| eq_int, | |
| name = "Volatility", | |
| module = "datafusion.expr" | |
| )] | |
| pub enum PyVolatility { | |
| Immutable, | |
| Stable, | |
| Volatile, | |
| } | |
| #[pyclass( | |
| from_py_object, | |
| frozen, | |
| name = "CreateFunctionBody", | |
| module = "datafusion.expr", | |
| subclass | |
| )] | |
| #[derive(Clone)] | |
| pub struct PyCreateFunctionBody { | |
| body: CreateFunctionBody, | |
| } | |
| #[pymethods] | |
| impl PyCreateFunctionBody { | |
| pub fn language(&self) -> Option<String> { | |
| self.body | |
| .language | |
| .as_ref() | |
| .map(|language| language.to_string()) | |
| } | |
| pub fn behavior(&self) -> Option<PyVolatility> { | |
| self.body.behavior.as_ref().map(|behavior| match behavior { | |
| Volatility::Immutable => PyVolatility::Immutable, | |
| Volatility::Stable => PyVolatility::Stable, | |
| Volatility::Volatile => PyVolatility::Volatile, | |
| }) | |
| } | |
| pub fn function_body(&self) -> Option<PyExpr> { | |
| self.body | |
| .function_body | |
| .as_ref() | |
| .map(|function_body| function_body.clone().into()) | |
| } | |
| } | |
| #[pymethods] | |
| impl PyCreateFunction { | |
| #[new] | |
| #[pyo3(signature = (or_replace, temporary, name, params, schema, return_type=None, args=None))] | |
| pub fn new( | |
| or_replace: bool, | |
| temporary: bool, | |
| name: String, | |
| params: PyCreateFunctionBody, | |
| schema: PyDFSchema, | |
| return_type: Option<PyDataType>, | |
| args: Option<Vec<PyOperateFunctionArg>>, | |
| ) -> Self { | |
| PyCreateFunction { | |
| create: CreateFunction { | |
| or_replace, | |
| temporary, | |
| name, | |
| args: args.map(|args| args.into_iter().map(|arg| arg.arg).collect()), | |
| return_type: return_type.map(|return_type| return_type.data_type), | |
| params: params.body, | |
| schema: Arc::new(schema.into()), | |
| }, | |
| } | |
| } | |
| pub fn or_replace(&self) -> bool { | |
| self.create.or_replace | |
| } | |
| pub fn temporary(&self) -> bool { | |
| self.create.temporary | |
| } | |
| pub fn name(&self) -> String { | |
| self.create.name.clone() | |
| } | |
| pub fn params(&self) -> PyCreateFunctionBody { | |
| PyCreateFunctionBody { | |
| body: self.create.params.clone(), | |
| } | |
| } | |
| pub fn schema(&self) -> PyDFSchema { | |
| (*self.create.schema).clone().into() | |
| } | |
| pub fn return_type(&self) -> Option<PyDataType> { | |
| self.create | |
| .return_type | |
| .as_ref() | |
| .map(|return_type| return_type.clone().into()) | |
| } | |
| pub fn args(&self) -> Option<Vec<PyOperateFunctionArg>> { | |
| self.create.args.as_ref().map(|args| { | |
| args.iter() | |
| .map(|arg| PyOperateFunctionArg { arg: arg.clone() }) | |
| .collect() | |
| }) | |
| } | |
| fn __repr__(&self) -> PyResult<String> { | |
| Ok(format!("CreateFunction({self})")) | |
| } | |
| fn __name__(&self) -> PyResult<String> { | |
| Ok("CreateFunction".to_string()) | |
| } | |
| } | |
| impl LogicalNode for PyCreateFunction { | |
| fn inputs(&self) -> Vec<PyLogicalPlan> { | |
| vec![] | |
| } | |
| fn to_variant<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> { | |
| self.clone().into_bound_py_any(py) | |
| } | |
| } |