Skip to content
121 changes: 0 additions & 121 deletions datafusion/optimizer/src/eliminate_one_union.rs

This file was deleted.

9 changes: 7 additions & 2 deletions datafusion/optimizer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,17 @@ pub mod eliminate_filter;
pub mod eliminate_group_by_constant;
pub mod eliminate_join;
pub mod eliminate_limit;
pub mod eliminate_nested_union;
pub mod eliminate_one_union;
#[deprecated(since = "52.0.0", note = "Please use OptimizeUnions instead")]
pub mod eliminate_nested_union {
use crate::optimize_unions::OptimizeUnions;
#[deprecated(since = "52.0.0", note = "Please use OptimizeUnions instead")]
pub type EliminateNestedUnion = OptimizeUnions;
}
pub mod eliminate_outer_join;
pub mod extract_equijoin_predicate;
pub mod filter_null_join_keys;
pub mod optimize_projections;
pub mod optimize_unions;
pub mod optimizer;
pub mod propagate_empty_relation;
pub mod push_down_filter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.

//! [`EliminateNestedUnion`]: flattens nested `Union` to a single `Union`
//! [`OptimizeUnions`]: removes `Union` nodes in the logical plan.
use crate::optimizer::ApplyOrder;
use crate::{OptimizerConfig, OptimizerRule};
use datafusion_common::tree_node::Transformed;
Expand All @@ -26,19 +26,21 @@ use itertools::Itertools;
use std::sync::Arc;

#[derive(Default, Debug)]
/// An optimization rule that replaces nested unions with a single union.
pub struct EliminateNestedUnion;
/// An optimization rule that
/// 1. replaces nested unions with a single union.
/// 2. removes unions with a single input.
pub struct OptimizeUnions;

impl EliminateNestedUnion {
impl OptimizeUnions {
#[allow(missing_docs)]
pub fn new() -> Self {
Self {}
}
}

impl OptimizerRule for EliminateNestedUnion {
impl OptimizerRule for OptimizeUnions {
fn name(&self) -> &str {
"eliminate_nested_union"
"optimize_unions"
}

fn apply_order(&self) -> Option<ApplyOrder> {
Expand All @@ -55,6 +57,9 @@ impl OptimizerRule for EliminateNestedUnion {
_config: &dyn OptimizerConfig,
) -> Result<Transformed<LogicalPlan>> {
match plan {
LogicalPlan::Union(Union { mut inputs, .. }) if inputs.len() == 1 => Ok(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding a minor comment here, considering its not exactly related to nested unions?

(Or could rename away from EliminateNestedUnions to something like SimplifyUnions to be all encompassing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Or could rename away from EliminateNestedUnions to something like SimplifyUnions to be all encompassing)

I like this idea -- done in 9041a17

Transformed::yes(Arc::unwrap_or_clone(inputs.pop().unwrap())),
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that's it? Nice find, will be curious if this shows up in planning benchmark

LogicalPlan::Union(Union { inputs, schema }) => {
let inputs = inputs
.into_iter()
Expand Down Expand Up @@ -139,7 +144,7 @@ mod tests {
let analyzed_plan = Analyzer::with_rules(vec![Arc::new(TypeCoercion::new())])
.execute_and_check($plan, &options, |_, _| {})?;
let optimizer_ctx = OptimizerContext::new().with_max_passes(1);
let rules: Vec<Arc<dyn crate::OptimizerRule + Send + Sync>> = vec![Arc::new(EliminateNestedUnion::new())];
let rules: Vec<Arc<dyn crate::OptimizerRule + Send + Sync>> = vec![Arc::new(OptimizeUnions::new())];
assert_optimized_plan_eq_snapshot!(
optimizer_ctx,
rules,
Expand Down Expand Up @@ -420,4 +425,28 @@ mod tests {
TableScan: table_1
")
}

#[test]
fn eliminate_one_union() -> Result<()> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single input unions can't be created easily, so this test looks a little different

let plan = table_scan(Some("table"), &schema(), None)?.build()?;
let schema = Arc::clone(plan.schema());
// note it is not possible to create a single input union via
// LogicalPlanBuilder so create it manually here
let plan = LogicalPlan::Union(Union {
inputs: vec![Arc::new(plan)],
schema,
});

// Note we can't use the same assert_optimized_plan_equal as creating a
// single input union is not possible via LogicalPlanBuilder and other passes
// throw errors / don't handle the schema correctly.
assert_optimized_plan_eq_snapshot!(
OptimizerContext::new().with_max_passes(1),
vec![Arc::new(OptimizeUnions::new())],
plan,
@r"
TableScan: table
"
)
}
}
7 changes: 2 additions & 5 deletions datafusion/optimizer/src/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,11 @@ use crate::eliminate_filter::EliminateFilter;
use crate::eliminate_group_by_constant::EliminateGroupByConstant;
use crate::eliminate_join::EliminateJoin;
use crate::eliminate_limit::EliminateLimit;
use crate::eliminate_nested_union::EliminateNestedUnion;
use crate::eliminate_one_union::EliminateOneUnion;
use crate::eliminate_outer_join::EliminateOuterJoin;
use crate::extract_equijoin_predicate::ExtractEquijoinPredicate;
use crate::filter_null_join_keys::FilterNullJoinKeys;
use crate::optimize_projections::OptimizeProjections;
use crate::optimize_unions::OptimizeUnions;
use crate::plan_signature::LogicalPlanSignature;
use crate::propagate_empty_relation::PropagateEmptyRelation;
use crate::push_down_filter::PushDownFilter;
Expand Down Expand Up @@ -228,7 +227,7 @@ impl Optimizer {
/// Create a new optimizer using the recommended list of rules
pub fn new() -> Self {
let rules: Vec<Arc<dyn OptimizerRule + Sync + Send>> = vec![
Arc::new(EliminateNestedUnion::new()),
Arc::new(OptimizeUnions::new()),
Arc::new(SimplifyExpressions::new()),
Arc::new(ReplaceDistinctWithAggregate::new()),
Arc::new(EliminateJoin::new()),
Expand All @@ -241,8 +240,6 @@ impl Optimizer {
Arc::new(EliminateCrossJoin::new()),
Arc::new(EliminateLimit::new()),
Arc::new(PropagateEmptyRelation::new()),
// Must be after PropagateEmptyRelation
Arc::new(EliminateOneUnion::new()),
Arc::new(FilterNullJoinKeys::default()),
Arc::new(EliminateOuterJoin::new()),
// Filters can't be pushed down past Limits, we should do PushDownFilter after PushDownLimit
Expand Down
4 changes: 2 additions & 2 deletions datafusion/optimizer/src/propagate_empty_relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ mod tests {

use crate::assert_optimized_plan_eq_snapshot;
use crate::eliminate_filter::EliminateFilter;
use crate::eliminate_nested_union::EliminateNestedUnion;
use crate::optimize_unions::OptimizeUnions;
use crate::test::{
assert_optimized_plan_with_rules, test_table_scan, test_table_scan_fields,
test_table_scan_with_name,
Expand Down Expand Up @@ -277,7 +277,7 @@ mod tests {
assert_optimized_plan_with_rules(
vec![
Arc::new(EliminateFilter::new()),
Arc::new(EliminateNestedUnion::new()),
Arc::new(OptimizeUnions::new()),
Arc::new(PropagateEmptyRelation::new()),
],
plan,
Expand Down
4 changes: 2 additions & 2 deletions datafusion/proto/tests/cases/roundtrip_logical_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use datafusion::datasource::listing::{
ListingOptions, ListingTable, ListingTableConfig, ListingTableUrl,
};
use datafusion::execution::options::ArrowReadOptions;
use datafusion::optimizer::eliminate_nested_union::EliminateNestedUnion;
use datafusion::optimizer::optimize_unions::OptimizeUnions;
use datafusion::optimizer::Optimizer;
use datafusion_common::parsers::CompressionTypeVariant;
use datafusion_functions_aggregate::sum::sum_distinct;
Expand Down Expand Up @@ -2744,7 +2744,7 @@ async fn roundtrip_union_query() -> Result<()> {
let logical_round_trip = logical_plan_from_bytes(&bytes, &ctx.task_ctx())?;
// proto deserialization only supports 2-way union, hence this plan has nested unions
// apply the flatten unions optimizer rule to be able to compare
let optimizer = Optimizer::with_rules(vec![Arc::new(EliminateNestedUnion::new())]);
let optimizer = Optimizer::with_rules(vec![Arc::new(OptimizeUnions::new())]);
let unnested = optimizer.optimize(logical_round_trip, &(ctx.state()), |_x, _y| {})?;
assert_eq!(
format!("{}", plan.display_indent_schema()),
Expand Down
12 changes: 4 additions & 8 deletions datafusion/sqllogictest/test_files/explain.slt
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ initial_logical_plan
logical_plan after resolve_grouping_function SAME TEXT AS ABOVE
logical_plan after type_coercion SAME TEXT AS ABOVE
analyzed_logical_plan SAME TEXT AS ABOVE
logical_plan after eliminate_nested_union SAME TEXT AS ABOVE
logical_plan after optimize_unions SAME TEXT AS ABOVE
logical_plan after simplify_expressions SAME TEXT AS ABOVE
logical_plan after replace_distinct_aggregate SAME TEXT AS ABOVE
logical_plan after eliminate_join SAME TEXT AS ABOVE
Expand All @@ -189,7 +189,6 @@ logical_plan after eliminate_filter SAME TEXT AS ABOVE
logical_plan after eliminate_cross_join SAME TEXT AS ABOVE
logical_plan after eliminate_limit SAME TEXT AS ABOVE
logical_plan after propagate_empty_relation SAME TEXT AS ABOVE
logical_plan after eliminate_one_union SAME TEXT AS ABOVE
logical_plan after filter_null_join_keys SAME TEXT AS ABOVE
logical_plan after eliminate_outer_join SAME TEXT AS ABOVE
logical_plan after push_down_limit SAME TEXT AS ABOVE
Expand All @@ -198,7 +197,7 @@ logical_plan after single_distinct_aggregation_to_group_by SAME TEXT AS ABOVE
logical_plan after eliminate_group_by_constant SAME TEXT AS ABOVE
logical_plan after common_sub_expression_eliminate SAME TEXT AS ABOVE
logical_plan after optimize_projections TableScan: simple_explain_test projection=[a, b, c]
logical_plan after eliminate_nested_union SAME TEXT AS ABOVE
logical_plan after optimize_unions SAME TEXT AS ABOVE
logical_plan after simplify_expressions SAME TEXT AS ABOVE
logical_plan after replace_distinct_aggregate SAME TEXT AS ABOVE
logical_plan after eliminate_join SAME TEXT AS ABOVE
Expand All @@ -211,7 +210,6 @@ logical_plan after eliminate_filter SAME TEXT AS ABOVE
logical_plan after eliminate_cross_join SAME TEXT AS ABOVE
logical_plan after eliminate_limit SAME TEXT AS ABOVE
logical_plan after propagate_empty_relation SAME TEXT AS ABOVE
logical_plan after eliminate_one_union SAME TEXT AS ABOVE
logical_plan after filter_null_join_keys SAME TEXT AS ABOVE
logical_plan after eliminate_outer_join SAME TEXT AS ABOVE
logical_plan after push_down_limit SAME TEXT AS ABOVE
Expand Down Expand Up @@ -537,7 +535,7 @@ initial_logical_plan
logical_plan after resolve_grouping_function SAME TEXT AS ABOVE
logical_plan after type_coercion SAME TEXT AS ABOVE
analyzed_logical_plan SAME TEXT AS ABOVE
logical_plan after eliminate_nested_union SAME TEXT AS ABOVE
logical_plan after optimize_unions SAME TEXT AS ABOVE
logical_plan after simplify_expressions SAME TEXT AS ABOVE
logical_plan after replace_distinct_aggregate SAME TEXT AS ABOVE
logical_plan after eliminate_join SAME TEXT AS ABOVE
Expand All @@ -550,7 +548,6 @@ logical_plan after eliminate_filter SAME TEXT AS ABOVE
logical_plan after eliminate_cross_join SAME TEXT AS ABOVE
logical_plan after eliminate_limit SAME TEXT AS ABOVE
logical_plan after propagate_empty_relation SAME TEXT AS ABOVE
logical_plan after eliminate_one_union SAME TEXT AS ABOVE
logical_plan after filter_null_join_keys SAME TEXT AS ABOVE
logical_plan after eliminate_outer_join SAME TEXT AS ABOVE
logical_plan after push_down_limit SAME TEXT AS ABOVE
Expand All @@ -559,7 +556,7 @@ logical_plan after single_distinct_aggregation_to_group_by SAME TEXT AS ABOVE
logical_plan after eliminate_group_by_constant SAME TEXT AS ABOVE
logical_plan after common_sub_expression_eliminate SAME TEXT AS ABOVE
logical_plan after optimize_projections TableScan: simple_explain_test projection=[a, b, c]
logical_plan after eliminate_nested_union SAME TEXT AS ABOVE
logical_plan after optimize_unions SAME TEXT AS ABOVE
logical_plan after simplify_expressions SAME TEXT AS ABOVE
logical_plan after replace_distinct_aggregate SAME TEXT AS ABOVE
logical_plan after eliminate_join SAME TEXT AS ABOVE
Expand All @@ -572,7 +569,6 @@ logical_plan after eliminate_filter SAME TEXT AS ABOVE
logical_plan after eliminate_cross_join SAME TEXT AS ABOVE
logical_plan after eliminate_limit SAME TEXT AS ABOVE
logical_plan after propagate_empty_relation SAME TEXT AS ABOVE
logical_plan after eliminate_one_union SAME TEXT AS ABOVE
logical_plan after filter_null_join_keys SAME TEXT AS ABOVE
logical_plan after eliminate_outer_join SAME TEXT AS ABOVE
logical_plan after push_down_limit SAME TEXT AS ABOVE
Expand Down