Skip to content

fix(optimizer): optimize_projections rule bug #12184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion datafusion/optimizer/src/optimize_projections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,26 @@ fn merge_consecutive_projections(proj: Projection) -> Result<Transformed<Project
return Projection::try_new_with_schema(expr, input, schema).map(Transformed::no);
};

// In order to pass the detection of `assert_schema_is_the_same` function, avoid changing
// the plan schema here. e.g.
// Projection: public.test.a -- proj
// Projection: public.test.a AS public.test.a -- prev_projection
// TableScan: public.test
if prev_projection.expr.iter().any(|expr| match expr {
Expr::Alias(Alias {
expr,
name: alias_name,
..
}) => match expr.as_ref() {
Expr::Column(column) => &column.flat_name() == alias_name,
_ => false,
},
_ => false,
}) {
// no change
return Projection::try_new_with_schema(expr, input, schema).map(Transformed::no);
}

// Count usages (referrals) of each projection expression in its input fields:
let mut column_referral_map = HashMap::<&Column, usize>::new();
expr.iter()
Expand Down Expand Up @@ -1019,7 +1039,44 @@ mod tests {

let expected = "Projection: test.a AS alias\
\n TableScan: test projection=[a]";
assert_optimized_plan_equal(plan, expected)
assert_optimized_plan_equal(plan, expected)?;

// SELECT "test.a" FROM (SELECT a AS "test.a" FROM test)
let table_scan = test_table_scan_with_name("test")?;
let plan = LogicalPlanBuilder::from(table_scan)
.project(vec![col("a").alias("test.a")])?
.project(vec![Expr::Column(Column::new_unqualified("test.a"))])?
.build()?;

let expected = "Projection: test.a AS test.a\
\n TableScan: test projection=[a]";
assert_optimized_plan_equal(plan, expected)?;

// SELECT "public.test.a" FROM (SELECT a AS "public.test.a" FROM public.test)
let table_scan = test_table_scan_with_name("public.test")?;
let plan = LogicalPlanBuilder::from(table_scan)
.project(vec![col("a").alias("public.test.a")])?
.project(vec![Expr::Column(Column::new_unqualified("public.test.a"))])?
.build()?;

let expected = "Projection: public.test.a AS public.test.a\
\n TableScan: public.test projection=[a]";
assert_optimized_plan_equal(plan, expected)?;

// SELECT "datafusion.public.test.a" FROM (SELECT a AS "datafusion.public.test.a" FROM datafusion.public.test)
let table_scan = test_table_scan_with_name("datafusion.public.test")?;
let plan = LogicalPlanBuilder::from(table_scan)
.project(vec![col("a").alias("datafusion.public.test.a")])?
.project(vec![Expr::Column(Column::new_unqualified(
"datafusion.public.test.a",
))])?
.build()?;

let expected = "Projection: datafusion.public.test.a AS datafusion.public.test.a\
\n TableScan: datafusion.public.test projection=[a]";
assert_optimized_plan_equal(plan, expected)?;

Ok(())
}

#[test]
Expand Down