diff --git a/datafusion/sql/src/expr/binary_op.rs b/datafusion/sql/src/expr/binary_op.rs index 4e9025e02e0c7..c3e7939370e85 100644 --- a/datafusion/sql/src/expr/binary_op.rs +++ b/datafusion/sql/src/expr/binary_op.rs @@ -16,8 +16,10 @@ // under the License. use crate::planner::{ContextProvider, SqlToRel}; -use datafusion_common::{Result, not_impl_err}; +use datafusion_common::{Result, internal_datafusion_err, not_impl_err}; use datafusion_expr::Operator; +use datafusion_expr::expr::ScalarFunction; +use datafusion_expr::{BinaryExpr, Expr}; use sqlparser::ast::BinaryOperator; impl SqlToRel<'_, S> { @@ -72,4 +74,34 @@ impl SqlToRel<'_, S> { _ => not_impl_err!("Unsupported binary operator: {:?}", op), } } + + pub(crate) fn build_binary_expr( + &self, + op: &BinaryOperator, + left: Expr, + right: Expr, + ) -> Result { + if matches!(op, BinaryOperator::PGExp) { + let fun_name = "power"; + let fun = self + .context_provider + .get_function_meta(fun_name) + .ok_or_else(|| { + internal_datafusion_err!( + "Unable to find expected '{fun_name}' function" + ) + })?; + + return Ok(Expr::ScalarFunction(ScalarFunction::new_udf( + fun, + vec![left, right], + ))); + } + + Ok(Expr::BinaryExpr(BinaryExpr::new( + Box::new(left), + self.parse_sql_binary_op(op)?, + Box::new(right), + ))) + } } diff --git a/datafusion/sql/src/expr/mod.rs b/datafusion/sql/src/expr/mod.rs index daf092ecd4cf9..29b75243ea09c 100644 --- a/datafusion/sql/src/expr/mod.rs +++ b/datafusion/sql/src/expr/mod.rs @@ -142,11 +142,7 @@ impl SqlToRel<'_, S> { } let RawBinaryExpr { op, left, right } = binary_expr; - Ok(Expr::BinaryExpr(BinaryExpr::new( - Box::new(left), - self.parse_sql_binary_op(&op)?, - Box::new(right), - ))) + self.build_binary_expr(&op, left, right) } pub fn sql_to_expr_with_alias( diff --git a/datafusion/sqllogictest/test_files/scalar.slt b/datafusion/sqllogictest/test_files/scalar.slt index 89ae30e3c047b..2ac7a9ef364c4 100644 --- a/datafusion/sqllogictest/test_files/scalar.slt +++ b/datafusion/sqllogictest/test_files/scalar.slt @@ -1300,6 +1300,12 @@ NULL -32 statement ok set datafusion.sql_parser.dialect = postgresql; +# postgresql exponentiation uses caret +query R +select 2 ^ 3; +---- +8 + # postgresql bitwise xor with column and scalar query I rowsort select c # 856 from signed_integers;