This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new e2b335ce01 Use // for unparsing DuckDB division operator (#13509)
e2b335ce01 is described below
commit e2b335ce019f0b158be5cb2b13292b475ac6a981
Author: Qianqian <[email protected]>
AuthorDate: Sat Nov 30 04:41:40 2024 -0800
Use // for unparsing DuckDB division operator (#13509)
* Use // as DuckDB division operator
* Fix clippy error
---
datafusion/sql/src/unparser/dialect.rs | 27 ++++++++++++++++++++++++++-
datafusion/sql/src/unparser/expr.rs | 28 +++++++++++++++++++++++++++-
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/datafusion/sql/src/unparser/dialect.rs
b/datafusion/sql/src/unparser/dialect.rs
index 57c89f74f5..e979d8fd4e 100644
--- a/datafusion/sql/src/unparser/dialect.rs
+++ b/datafusion/sql/src/unparser/dialect.rs
@@ -21,7 +21,7 @@ use arrow_schema::TimeUnit;
use datafusion_expr::Expr;
use regex::Regex;
use sqlparser::{
- ast::{self, Function, Ident, ObjectName, TimezoneInfo},
+ ast::{self, BinaryOperator, Function, Ident, ObjectName, TimezoneInfo},
keywords::ALL_KEYWORDS,
};
@@ -131,6 +131,13 @@ pub trait Dialect: Send + Sync {
false
}
+ /// The division operator for the dialect
+ /// Most dialect uses ` BinaryOperator::Divide` (/)
+ /// But DuckDB dialect uses `BinaryOperator::DuckIntegerDivide` (//)
+ fn division_operator(&self) -> BinaryOperator {
+ BinaryOperator::Divide
+ }
+
/// Allows the dialect to override scalar function unparsing if the
dialect has specific rules.
/// Returns None if the default unparsing should be used, or
Some(ast::Expr) if there is
/// a custom implementation for the function.
@@ -298,6 +305,10 @@ impl Dialect for DuckDBDialect {
CharacterLengthStyle::Length
}
+ fn division_operator(&self) -> BinaryOperator {
+ BinaryOperator::DuckIntegerDivide
+ }
+
fn scalar_function_to_sql_overrides(
&self,
unparser: &Unparser,
@@ -435,6 +446,7 @@ pub struct CustomDialect {
date32_cast_dtype: ast::DataType,
supports_column_alias_in_table_alias: bool,
requires_derived_table_alias: bool,
+ division_operator: BinaryOperator,
full_qualified_col: bool,
}
@@ -460,6 +472,7 @@ impl Default for CustomDialect {
date32_cast_dtype: ast::DataType::Date,
supports_column_alias_in_table_alias: true,
requires_derived_table_alias: false,
+ division_operator: BinaryOperator::Divide,
full_qualified_col: false,
}
}
@@ -562,6 +575,10 @@ impl Dialect for CustomDialect {
self.requires_derived_table_alias
}
+ fn division_operator(&self) -> BinaryOperator {
+ self.division_operator.clone()
+ }
+
fn full_qualified_col(&self) -> bool {
self.full_qualified_col
}
@@ -598,6 +615,7 @@ pub struct CustomDialectBuilder {
date32_cast_dtype: ast::DataType,
supports_column_alias_in_table_alias: bool,
requires_derived_table_alias: bool,
+ division_operator: BinaryOperator,
full_qualified_col: bool,
}
@@ -629,6 +647,7 @@ impl CustomDialectBuilder {
date32_cast_dtype: ast::DataType::Date,
supports_column_alias_in_table_alias: true,
requires_derived_table_alias: false,
+ division_operator: BinaryOperator::Divide,
full_qualified_col: false,
}
}
@@ -652,6 +671,7 @@ impl CustomDialectBuilder {
supports_column_alias_in_table_alias: self
.supports_column_alias_in_table_alias,
requires_derived_table_alias: self.requires_derived_table_alias,
+ division_operator: self.division_operator,
full_qualified_col: self.full_qualified_col,
}
}
@@ -770,6 +790,11 @@ impl CustomDialectBuilder {
self
}
+ pub fn with_division_operator(mut self, division_operator: BinaryOperator)
-> Self {
+ self.division_operator = division_operator;
+ self
+ }
+
/// Customize the dialect to allow full qualified column names
pub fn with_full_qualified_col(mut self, full_qualified_col: bool) -> Self
{
self.full_qualified_col = full_qualified_col;
diff --git a/datafusion/sql/src/unparser/expr.rs
b/datafusion/sql/src/unparser/expr.rs
index 7024636045..48dfc425ee 100644
--- a/datafusion/sql/src/unparser/expr.rs
+++ b/datafusion/sql/src/unparser/expr.rs
@@ -882,7 +882,7 @@ impl Unparser<'_> {
Operator::Plus => Ok(BinaryOperator::Plus),
Operator::Minus => Ok(BinaryOperator::Minus),
Operator::Multiply => Ok(BinaryOperator::Multiply),
- Operator::Divide => Ok(BinaryOperator::Divide),
+ Operator::Divide => Ok(self.dialect.division_operator()),
Operator::Modulo => Ok(BinaryOperator::Modulo),
Operator::And => Ok(BinaryOperator::And),
Operator::Or => Ok(BinaryOperator::Or),
@@ -2584,6 +2584,32 @@ mod tests {
Ok(())
}
+ #[test]
+ fn custom_dialect_division_operator() -> Result<()> {
+ let default_dialect = CustomDialectBuilder::new().build();
+ let duckdb_dialect = CustomDialectBuilder::new()
+ .with_division_operator(BinaryOperator::DuckIntegerDivide)
+ .build();
+
+ for (dialect, expected) in
+ [(default_dialect, "(a / b)"), (duckdb_dialect, "(a // b)")]
+ {
+ let unparser = Unparser::new(&dialect);
+ let expr = Expr::BinaryExpr(BinaryExpr {
+ left: Box::new(col("a")),
+ op: Operator::Divide,
+ right: Box::new(col("b")),
+ });
+ let ast = unparser.expr_to_sql(&expr)?;
+
+ let actual = format!("{}", ast);
+ let expected = expected.to_string();
+
+ assert_eq!(actual, expected);
+ }
+ Ok(())
+ }
+
#[test]
fn test_cast_value_to_dict_expr() {
let tests = [(
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]