forked from apache/datafusion
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
998323a
commit ed678ff
Showing
5 changed files
with
178 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
mod ast; | ||
mod expr; | ||
mod plan; | ||
mod utils; | ||
|
||
pub use expr::expr_to_sql; | ||
pub use plan::plan_to_sql; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use datafusion_common::{ | ||
internal_err, | ||
tree_node::{Transformed, TreeNode}, | ||
Result, | ||
}; | ||
use datafusion_expr::{Aggregate, Expr, LogicalPlan, Projection}; | ||
|
||
/// Recursively searches children of [LogicalPlan] to find an Aggregate node if one exists | ||
/// prior to encountering a Join, TableScan, or subquery node. If an Aggregate node is not found | ||
/// prior to this or at all before reaching the end of the tree, None is returned. | ||
pub(crate) fn find_agg_node_within_select( | ||
plan: &LogicalPlan, | ||
already_projected: bool, | ||
) -> Option<&Aggregate> { | ||
let input = plan.inputs(); | ||
let input = if input.len() > 1 { | ||
return None; | ||
} else { | ||
input.first()? | ||
}; | ||
if let LogicalPlan::Aggregate(agg) = input { | ||
Some(agg) | ||
} else if let LogicalPlan::TableScan(_) = input { | ||
None | ||
} else if let LogicalPlan::Projection(_) = input { | ||
if already_projected { | ||
None | ||
} else { | ||
find_agg_node_within_select(input, true) | ||
} | ||
} else { | ||
find_agg_node_within_select(input, already_projected) | ||
} | ||
} | ||
|
||
/// Recursively identify all Column expressions and transform them into the appropriate | ||
/// aggregate expression contained in agg. | ||
/// | ||
/// For example, if expr contains the column expr "COUNT(*)" it will be transformed | ||
/// into an actual aggregate expression COUNT(*) as identified in the aggregate node. | ||
pub(crate) fn unproject_agg_exprs(expr: &Expr, agg: &Aggregate) -> Result<Expr> { | ||
expr.clone() | ||
.transform(&|sub_expr| { | ||
if let Expr::Column(c) = sub_expr { | ||
// find the column in the agg schmea | ||
if let Ok(n) = agg.schema.index_of_column(&c) { | ||
let unprojected_expr = agg | ||
.group_expr | ||
.iter() | ||
.chain(agg.aggr_expr.iter()) | ||
.nth(n) | ||
.unwrap(); | ||
Ok(Transformed::yes(unprojected_expr.clone())) | ||
} else { | ||
internal_err!( | ||
"Tried to unproject agg expr not found in provided Aggregate!" | ||
) | ||
} | ||
} else { | ||
Ok(Transformed::no(sub_expr)) | ||
} | ||
}) | ||
.map(|e| e.data) | ||
} |
Oops, something went wrong.