This is an automated email from the ASF dual-hosted git repository.
goldmedal 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 5db274004b Improve TableScan with filters pushdown unparsing (multiple
filters support) (#13131)
5db274004b is described below
commit 5db274004bc4a7d493aba6764a8521694a67cd11
Author: Sergei Grebnov <[email protected]>
AuthorDate: Sun Oct 27 08:33:50 2024 -0700
Improve TableScan with filters pushdown unparsing (multiple filters
support) (#13131)
---
datafusion/sql/src/unparser/ast.rs | 23 ++++++++++++++++++++++-
datafusion/sql/tests/cases/plan_to_sql.rs | 15 +++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/datafusion/sql/src/unparser/ast.rs
b/datafusion/sql/src/unparser/ast.rs
index 71ff712985..2de1ce9125 100644
--- a/datafusion/sql/src/unparser/ast.rs
+++ b/datafusion/sql/src/unparser/ast.rs
@@ -182,7 +182,28 @@ impl SelectBuilder {
self
}
pub fn selection(&mut self, value: Option<ast::Expr>) -> &mut Self {
- self.selection = value;
+ // With filter pushdown optimization, the LogicalPlan can have filters
defined as part of `TableScan` and `Filter` nodes.
+ // To avoid overwriting one of the filters, we combine the existing
filter with the additional filter.
+ // Example:
[...]
+ // | Projection: customer.c_phone AS cntrycode, customer.c_acctbal
[...]
+ // | Filter: CAST(customer.c_acctbal AS Decimal128(38, 6)) >
(<subquery>)
[...]
+ // | Subquery:
+ // | ..
[...]
+ // | TableScan: customer, full_filters=[customer.c_mktsegment =
Utf8("BUILDING")]
+ match (&self.selection, value) {
+ (Some(existing_selection), Some(new_selection)) => {
+ self.selection = Some(ast::Expr::BinaryOp {
+ left: Box::new(existing_selection.clone()),
+ op: ast::BinaryOperator::And,
+ right: Box::new(new_selection),
+ });
+ }
+ (None, Some(new_selection)) => {
+ self.selection = Some(new_selection);
+ }
+ (_, None) => (),
+ }
+
self
}
pub fn group_by(&mut self, value: ast::GroupByExpr) -> &mut Self {
diff --git a/datafusion/sql/tests/cases/plan_to_sql.rs
b/datafusion/sql/tests/cases/plan_to_sql.rs
index 8e25c1c5b1..a58bdf4a31 100644
--- a/datafusion/sql/tests/cases/plan_to_sql.rs
+++ b/datafusion/sql/tests/cases/plan_to_sql.rs
@@ -968,6 +968,21 @@ fn test_table_scan_pushdown() -> Result<()> {
table_scan_with_all.to_string(),
"SELECT t1.id, t1.age FROM t1 WHERE (t1.id > t1.age) LIMIT 10"
);
+
+ let table_scan_with_additional_filter = table_scan_with_filters(
+ Some("t1"),
+ &schema,
+ None,
+ vec![col("id").gt(col("age"))],
+ )?
+ .filter(col("id").eq(lit(5)))?
+ .build()?;
+ let table_scan_with_filter =
plan_to_sql(&table_scan_with_additional_filter)?;
+ assert_eq!(
+ table_scan_with_filter.to_string(),
+ "SELECT * FROM t1 WHERE (t1.id = 5) AND (t1.id > t1.age)"
+ );
+
Ok(())
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]