You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by xu...@apache.org on 2025/05/05 04:02:51 UTC
(datafusion) branch main updated: Migrate Optimizer tests to insta, part4 (#15937)
This is an automated email from the ASF dual-hosted git repository.
xudong963 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 6cc49533f9 Migrate Optimizer tests to insta, part4 (#15937)
6cc49533f9 is described below
commit 6cc49533f9c1c60c1737b7139d867b6544caa993
Author: Tommy shu <qs...@gmail.com>
AuthorDate: Mon May 5 00:02:47 2025 -0400
Migrate Optimizer tests to insta, part4 (#15937)
* migrate `assert_eq!` in `optimize_projection/mod.rs` to use snapshot assertions
* migrate `assert_optimized_plan_equal!` in `propagate_empty_relations.rs` to use snapshot assertions
* remove all `assert_optimized_plan_eq`
* migrate `assert_optimized_plan_equal!` in `decorrelate_predicate_subquery.rs` to use snapshot assertions
* Add snapshot assertion macro for optimized plan equality checks
---------
Co-authored-by: Dmitrii Blaginin <dm...@blaginin.me>
---
.../src/decorrelate_predicate_subquery.rs | 1089 ++++++++++----------
.../optimizer/src/optimize_projections/mod.rs | 606 +++++++----
.../optimizer/src/propagate_empty_relation.rs | 22 +-
datafusion/optimizer/src/test/mod.rs | 34 +-
4 files changed, 995 insertions(+), 756 deletions(-)
diff --git a/datafusion/optimizer/src/decorrelate_predicate_subquery.rs b/datafusion/optimizer/src/decorrelate_predicate_subquery.rs
index c18c48251d..a72657bf68 100644
--- a/datafusion/optimizer/src/decorrelate_predicate_subquery.rs
+++ b/datafusion/optimizer/src/decorrelate_predicate_subquery.rs
@@ -427,17 +427,23 @@ mod tests {
use super::*;
use crate::test::*;
+ use crate::assert_optimized_plan_eq_display_indent_snapshot;
use arrow::datatypes::{DataType, Field, Schema};
use datafusion_expr::builder::table_source;
use datafusion_expr::{and, binary_expr, col, lit, not, out_ref_col, table_scan};
- fn assert_optimized_plan_equal(plan: LogicalPlan, expected: &str) -> Result<()> {
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
- plan,
- expected,
- );
- Ok(())
+ macro_rules! assert_optimized_plan_equal {
+ (
+ $plan:expr,
+ @ $expected:literal $(,)?
+ ) => {{
+ let rule: Arc<dyn crate::OptimizerRule + Send + Sync> = Arc::new(DecorrelatePredicateSubquery::new());
+ assert_optimized_plan_eq_display_indent_snapshot!(
+ rule,
+ $plan,
+ @ $expected,
+ )
+ }};
}
fn test_subquery_with_name(name: &str) -> Result<Arc<LogicalPlan>> {
@@ -461,17 +467,21 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.b = __correlated_sq_2.c [a:UInt32, b:UInt32, c:UInt32]\
- \n LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq_1.c [c:UInt32]\
- \n TableScan: sq_1 [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_2 [c:UInt32]\
- \n Projection: sq_2.c [c:UInt32]\
- \n TableScan: sq_2 [a:UInt32, b:UInt32, c:UInt32]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.b = __correlated_sq_2.c [a:UInt32, b:UInt32, c:UInt32]
+ LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq_1.c [c:UInt32]
+ TableScan: sq_1 [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_2 [c:UInt32]
+ Projection: sq_2.c [c:UInt32]
+ TableScan: sq_2 [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test for IN subquery with additional AND filter
@@ -489,15 +499,18 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n Filter: test.a = UInt32(1) AND test.b < UInt32(30) [a:UInt32, b:UInt32, c:UInt32]\
- \n LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq.c [c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ Filter: test.a = UInt32(1) AND test.b < UInt32(30) [a:UInt32, b:UInt32, c:UInt32]
+ LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq.c [c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test for nested IN subqueries
@@ -515,18 +528,21 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.b = __correlated_sq_2.a [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_2 [a:UInt32]\
- \n Projection: sq.a [a:UInt32]\
- \n LeftSemi Join: Filter: sq.a = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq_nested.c [c:UInt32]\
- \n TableScan: sq_nested [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.b = __correlated_sq_2.a [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_2 [a:UInt32]
+ Projection: sq.a [a:UInt32]
+ LeftSemi Join: Filter: sq.a = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq_nested.c [c:UInt32]
+ TableScan: sq_nested [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test multiple correlated subqueries
@@ -551,23 +567,21 @@ mod tests {
.build()?;
debug!("plan to optimize:\n{}", plan.display_indent());
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_2.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
- plan,
- expected,
- );
- Ok(())
+ assert_optimized_plan_equal!(
+ plan,
+ @r###"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_2.o_custkey [c_custkey:Int64, c_name:Utf8]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "###
+ )
}
/// Test recursive correlated subqueries
@@ -601,23 +615,21 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_2.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n LeftSemi Join: Filter: orders.o_orderkey = __correlated_sq_1.l_orderkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n SubqueryAlias: __correlated_sq_1 [l_orderkey:Int64]\
- \n Projection: lineitem.l_orderkey [l_orderkey:Int64]\
- \n TableScan: lineitem [l_orderkey:Int64, l_partkey:Int64, l_suppkey:Int64, l_linenumber:Int32, l_quantity:Float64, l_extendedprice:Float64]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_2.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ LeftSemi Join: Filter: orders.o_orderkey = __correlated_sq_1.l_orderkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ SubqueryAlias: __correlated_sq_1 [l_orderkey:Int64]
+ Projection: lineitem.l_orderkey [l_orderkey:Int64]
+ TableScan: lineitem [l_orderkey:Int64, l_partkey:Int64, l_suppkey:Int64, l_linenumber:Int32, l_quantity:Float64, l_extendedprice:Float64]
+ "
+ )
}
/// Test for correlated IN subquery filter with additional subquery filters
@@ -639,20 +651,18 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n Filter: orders.o_orderkey = Int32(1) [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ Filter: orders.o_orderkey = Int32(1) [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN subquery with no columns in schema
@@ -673,19 +683,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for IN subquery with both columns in schema
@@ -703,20 +711,18 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n Filter: orders.o_custkey = orders.o_custkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ Filter: orders.o_custkey = orders.o_custkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN subquery not equal
@@ -737,19 +743,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey AND customer.c_custkey != __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey AND customer.c_custkey != __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN subquery less than
@@ -770,19 +774,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey AND customer.c_custkey < __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey AND customer.c_custkey < __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN subquery filter with subquery disjunction
@@ -804,20 +806,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey AND (customer.c_custkey = __correlated_sq_1.o_custkey OR __correlated_sq_1.o_orderkey = Int32(1)) [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64, o_orderkey:Int64]\
- \n Projection: orders.o_custkey, orders.o_orderkey [o_custkey:Int64, o_orderkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
-
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey AND (customer.c_custkey = __correlated_sq_1.o_custkey OR __correlated_sq_1.o_orderkey = Int32(1)) [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64, o_orderkey:Int64]
+ Projection: orders.o_custkey, orders.o_orderkey [o_custkey:Int64, o_orderkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN without projection
@@ -861,19 +860,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey + Int32(1) = __correlated_sq_1.o_custkey AND customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey + Int32(1) = __correlated_sq_1.o_custkey AND customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN expressions
@@ -894,19 +891,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.orders.o_custkey + Int32(1) AND customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]\
- \n Projection: orders.o_custkey + Int32(1), orders.o_custkey [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.orders.o_custkey + Int32(1) AND customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]
+ Projection: orders.o_custkey + Int32(1), orders.o_custkey [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN subquery multiple projected columns
@@ -959,20 +954,18 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n Filter: customer.c_custkey = Int32(1) [c_custkey:Int64, c_name:Utf8]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ Filter: customer.c_custkey = Int32(1) [c_custkey:Int64, c_name:Utf8]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated IN subquery filter
@@ -990,19 +983,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.c = __correlated_sq_1.c AND test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]\
- \n Projection: sq.c, sq.a [c:UInt32, a:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.c = __correlated_sq_1.c AND test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]
+ Projection: sq.c, sq.a [c:UInt32, a:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test for single IN subquery filter
@@ -1014,19 +1005,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq.c [c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq.c [c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test for single NOT IN subquery filter
@@ -1038,19 +1027,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftAnti Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq.c [c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftAnti Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq.c [c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1061,19 +1048,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftAnti Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq.c [c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftAnti Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq.c [c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1087,19 +1072,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq.c [c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.c = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq.c [c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1116,19 +1099,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq.c * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [sq.c * UInt32(2):UInt32]\
- \n Projection: sq.c * UInt32(2) [sq.c * UInt32(2):UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq.c * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [sq.c * UInt32(2):UInt32]
+ Projection: sq.c * UInt32(2) [sq.c * UInt32(2):UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1150,20 +1131,18 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq.c * UInt32(2) AND test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [sq.c * UInt32(2):UInt32, a:UInt32]\
- \n Projection: sq.c * UInt32(2), sq.a [sq.c * UInt32(2):UInt32, a:UInt32]\
- \n Filter: sq.a + UInt32(1) = sq.b [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq.c * UInt32(2) AND test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [sq.c * UInt32(2):UInt32, a:UInt32]
+ Projection: sq.c * UInt32(2), sq.a [sq.c * UInt32(2):UInt32, a:UInt32]
+ Filter: sq.a + UInt32(1) = sq.b [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1186,20 +1165,18 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq.c * UInt32(2) AND test.a + test.b = __correlated_sq_1.a + __correlated_sq_1.b [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [sq.c * UInt32(2):UInt32, a:UInt32, b:UInt32]\
- \n Projection: sq.c * UInt32(2), sq.a, sq.b [sq.c * UInt32(2):UInt32, a:UInt32, b:UInt32]\
- \n Filter: sq.a + UInt32(1) = sq.b [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq.c * UInt32(2) AND test.a + test.b = __correlated_sq_1.a + __correlated_sq_1.b [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [sq.c * UInt32(2):UInt32, a:UInt32, b:UInt32]
+ Projection: sq.c * UInt32(2), sq.a, sq.b [sq.c * UInt32(2):UInt32, a:UInt32, b:UInt32]
+ Filter: sq.a + UInt32(1) = sq.b [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1228,24 +1205,22 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n Filter: test.c > UInt32(1) [a:UInt32, b:UInt32, c:UInt32]\
- \n LeftSemi Join: Filter: test.c * UInt32(2) = __correlated_sq_2.sq2.c * UInt32(2) AND test.a > __correlated_sq_2.a [a:UInt32, b:UInt32, c:UInt32]\
- \n LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq1.c * UInt32(2) AND test.a > __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [sq1.c * UInt32(2):UInt32, a:UInt32]\
- \n Projection: sq1.c * UInt32(2), sq1.a [sq1.c * UInt32(2):UInt32, a:UInt32]\
- \n TableScan: sq1 [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_2 [sq2.c * UInt32(2):UInt32, a:UInt32]\
- \n Projection: sq2.c * UInt32(2), sq2.a [sq2.c * UInt32(2):UInt32, a:UInt32]\
- \n TableScan: sq2 [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ Filter: test.c > UInt32(1) [a:UInt32, b:UInt32, c:UInt32]
+ LeftSemi Join: Filter: test.c * UInt32(2) = __correlated_sq_2.sq2.c * UInt32(2) AND test.a > __correlated_sq_2.a [a:UInt32, b:UInt32, c:UInt32]
+ LeftSemi Join: Filter: test.c + UInt32(1) = __correlated_sq_1.sq1.c * UInt32(2) AND test.a > __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [sq1.c * UInt32(2):UInt32, a:UInt32]
+ Projection: sq1.c * UInt32(2), sq1.a [sq1.c * UInt32(2):UInt32, a:UInt32]
+ TableScan: sq1 [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_2 [sq2.c * UInt32(2):UInt32, a:UInt32]
+ Projection: sq2.c * UInt32(2), sq2.a [sq2.c * UInt32(2):UInt32, a:UInt32]
+ TableScan: sq2 [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1263,20 +1238,18 @@ mod tests {
.build()?;
// Subquery and outer query refer to the same table.
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: test.a = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: test.c [c:UInt32]\
- \n Filter: test.a > test.b [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_eq_display_indent(
- Arc::new(DecorrelatePredicateSubquery::new()),
+ assert_optimized_plan_equal!(
plan,
- expected,
- );
- Ok(())
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: test.a = __correlated_sq_1.c [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: test.c [c:UInt32]
+ Filter: test.a > test.b [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test for multiple exists subqueries in the same filter expression
@@ -1297,17 +1270,21 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: __correlated_sq_2.o_custkey = customer.c_custkey [c_custkey:Int64, c_name:Utf8]\
- \n LeftSemi Join: Filter: __correlated_sq_1.o_custkey = customer.c_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: __correlated_sq_2.o_custkey = customer.c_custkey [c_custkey:Int64, c_name:Utf8]
+ LeftSemi Join: Filter: __correlated_sq_1.o_custkey = customer.c_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test recursive correlated subqueries
@@ -1340,17 +1317,21 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: __correlated_sq_2.o_custkey = customer.c_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n LeftSemi Join: Filter: __correlated_sq_1.l_orderkey = orders.o_orderkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n SubqueryAlias: __correlated_sq_1 [l_orderkey:Int64]\
- \n Projection: lineitem.l_orderkey [l_orderkey:Int64]\
- \n TableScan: lineitem [l_orderkey:Int64, l_partkey:Int64, l_suppkey:Int64, l_linenumber:Int32, l_quantity:Float64, l_extendedprice:Float64]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: __correlated_sq_2.o_custkey = customer.c_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_2 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ LeftSemi Join: Filter: __correlated_sq_1.l_orderkey = orders.o_orderkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ SubqueryAlias: __correlated_sq_1 [l_orderkey:Int64]
+ Projection: lineitem.l_orderkey [l_orderkey:Int64]
+ TableScan: lineitem [l_orderkey:Int64, l_partkey:Int64, l_suppkey:Int64, l_linenumber:Int32, l_quantity:Float64, l_extendedprice:Float64]
+ "
+ )
}
/// Test for correlated exists subquery filter with additional subquery filters
@@ -1372,15 +1353,18 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n Filter: orders.o_orderkey = Int32(1) [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ Filter: orders.o_orderkey = Int32(1) [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
#[test]
@@ -1398,14 +1382,17 @@ mod tests {
.build()?;
// Other rule will pushdown `customer.c_custkey = 1`,
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = UInt32(1) [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = UInt32(1) [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for exists subquery with both columns in schema
@@ -1423,14 +1410,18 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: Boolean(true) [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n Filter: orders.o_custkey = orders.o_custkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: Boolean(true) [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ Filter: orders.o_custkey = orders.o_custkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated exists subquery not equal
@@ -1451,14 +1442,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey != __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey != __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated exists subquery less than
@@ -1479,14 +1473,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey < __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey < __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated exists subquery filter with subquery disjunction
@@ -1508,14 +1505,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey OR __correlated_sq_1.o_orderkey = Int32(1) [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64, o_orderkey:Int64]\
- \n Projection: orders.o_custkey, orders.o_orderkey [o_custkey:Int64, o_orderkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey OR __correlated_sq_1.o_orderkey = Int32(1) [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64, o_orderkey:Int64]
+ Projection: orders.o_custkey, orders.o_orderkey [o_custkey:Int64, o_orderkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated exists without projection
@@ -1535,13 +1535,16 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated exists expressions
@@ -1562,14 +1565,17 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]\
- \n Projection: orders.o_custkey + Int32(1), orders.o_custkey [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]
+ Projection: orders.o_custkey + Int32(1), orders.o_custkey [orders.o_custkey + Int32(1):Int64, o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated exists subquery filter with additional filters
@@ -1589,15 +1595,18 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n Filter: customer.c_custkey = Int32(1) [c_custkey:Int64, c_name:Utf8]\
- \n LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ Filter: customer.c_custkey = Int32(1) [c_custkey:Int64, c_name:Utf8]
+ LeftSemi Join: Filter: customer.c_custkey = __correlated_sq_1.o_custkey [c_custkey:Int64, c_name:Utf8]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated exists subquery filter with disjunctions
@@ -1615,16 +1624,19 @@ mod tests {
.project(vec![col("customer.c_custkey")])?
.build()?;
- let expected = "Projection: customer.c_custkey [c_custkey:Int64]\
- \n Filter: __correlated_sq_1.mark OR customer.c_custkey = Int32(1) [c_custkey:Int64, c_name:Utf8, mark:Boolean]\
- \n LeftMark Join: Filter: Boolean(true) [c_custkey:Int64, c_name:Utf8, mark:Boolean]\
- \n TableScan: customer [c_custkey:Int64, c_name:Utf8]\
- \n SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]\
- \n Projection: orders.o_custkey [o_custkey:Int64]\
- \n Filter: customer.c_custkey = orders.o_custkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]\
- \n TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: customer.c_custkey [c_custkey:Int64]
+ Filter: __correlated_sq_1.mark OR customer.c_custkey = Int32(1) [c_custkey:Int64, c_name:Utf8, mark:Boolean]
+ LeftMark Join: Filter: Boolean(true) [c_custkey:Int64, c_name:Utf8, mark:Boolean]
+ TableScan: customer [c_custkey:Int64, c_name:Utf8]
+ SubqueryAlias: __correlated_sq_1 [o_custkey:Int64]
+ Projection: orders.o_custkey [o_custkey:Int64]
+ Filter: customer.c_custkey = orders.o_custkey [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ TableScan: orders [o_orderkey:Int64, o_custkey:Int64, o_orderstatus:Utf8, o_totalprice:Float64;N]
+ "
+ )
}
/// Test for correlated EXISTS subquery filter
@@ -1642,14 +1654,17 @@ mod tests {
.project(vec![col("test.c")])?
.build()?;
- let expected = "Projection: test.c [c:UInt32]\
- \n LeftSemi Join: Filter: test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]\
- \n Projection: sq.c, sq.a [c:UInt32, a:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.c [c:UInt32]
+ LeftSemi Join: Filter: test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]
+ Projection: sq.c, sq.a [c:UInt32, a:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test for single exists subquery filter
@@ -1661,13 +1676,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq.c [c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq.c [c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
/// Test for single NOT exists subquery filter
@@ -1679,13 +1698,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftAnti Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: sq.c [c:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftAnti Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: sq.c [c:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1712,19 +1735,22 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n Filter: test.c > UInt32(1) [a:UInt32, b:UInt32, c:UInt32]\
- \n LeftSemi Join: Filter: test.a = __correlated_sq_2.a [a:UInt32, b:UInt32, c:UInt32]\
- \n LeftSemi Join: Filter: test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]\
- \n Projection: sq1.c, sq1.a [c:UInt32, a:UInt32]\
- \n TableScan: sq1 [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_2 [c:UInt32, a:UInt32]\
- \n Projection: sq2.c, sq2.a [c:UInt32, a:UInt32]\
- \n TableScan: sq2 [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ Filter: test.c > UInt32(1) [a:UInt32, b:UInt32, c:UInt32]
+ LeftSemi Join: Filter: test.a = __correlated_sq_2.a [a:UInt32, b:UInt32, c:UInt32]
+ LeftSemi Join: Filter: test.a = __correlated_sq_1.a [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]
+ Projection: sq1.c, sq1.a [c:UInt32, a:UInt32]
+ TableScan: sq1 [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_2 [c:UInt32, a:UInt32]
+ Projection: sq2.c, sq2.a [c:UInt32, a:UInt32]
+ TableScan: sq2 [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1743,14 +1769,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [UInt32(1):UInt32, a:UInt32]\
- \n Projection: UInt32(1), sq.a [UInt32(1):UInt32, a:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [UInt32(1):UInt32, a:UInt32]
+ Projection: UInt32(1), sq.a [UInt32(1):UInt32, a:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1768,15 +1797,18 @@ mod tests {
.build()?;
// Subquery and outer query refer to the same table.
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32]\
- \n Projection: test.c [c:UInt32]\
- \n Filter: test.a > test.b [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32]
+ Projection: test.c [c:UInt32]
+ Filter: test.a > test.b [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1796,15 +1828,18 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]\
- \n Distinct: [c:UInt32, a:UInt32]\
- \n Projection: sq.c, sq.a [c:UInt32, a:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [c:UInt32, a:UInt32]
+ Distinct: [c:UInt32, a:UInt32]
+ Projection: sq.c, sq.a [c:UInt32, a:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1824,15 +1859,18 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [sq.b + sq.c:UInt32, a:UInt32]\
- \n Distinct: [sq.b + sq.c:UInt32, a:UInt32]\
- \n Projection: sq.b + sq.c, sq.a [sq.b + sq.c:UInt32, a:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [sq.b + sq.c:UInt32, a:UInt32]
+ Distinct: [sq.b + sq.c:UInt32, a:UInt32]
+ Projection: sq.b + sq.c, sq.a [sq.b + sq.c:UInt32, a:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1852,15 +1890,18 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [UInt32(1):UInt32, c:UInt32, a:UInt32]\
- \n Distinct: [UInt32(1):UInt32, c:UInt32, a:UInt32]\
- \n Projection: UInt32(1), sq.c, sq.a [UInt32(1):UInt32, c:UInt32, a:UInt32]\
- \n TableScan: sq [a:UInt32, b:UInt32, c:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: UInt32(1) + __correlated_sq_1.a > test.a * UInt32(2) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [UInt32(1):UInt32, c:UInt32, a:UInt32]
+ Distinct: [UInt32(1):UInt32, c:UInt32, a:UInt32]
+ Projection: UInt32(1), sq.c, sq.a [UInt32(1):UInt32, c:UInt32, a:UInt32]
+ TableScan: sq [a:UInt32, b:UInt32, c:UInt32]
+ "
+ )
}
#[test]
@@ -1884,13 +1925,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [arr:Int32;N]\
- \n Unnest: lists[sq.arr|depth=1] structs[] [arr:Int32;N]\
- \n TableScan: sq [arr:List(Field { name: \"item\", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} });N]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r#"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: Boolean(true) [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [arr:Int32;N]
+ Unnest: lists[sq.arr|depth=1] structs[] [arr:Int32;N]
+ TableScan: sq [arr:List(Field { name: "item", data_type: Int32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} });N]
+ "#
+ )
}
#[test]
@@ -1915,14 +1960,17 @@ mod tests {
.project(vec![col("test.b")])?
.build()?;
- let expected = "Projection: test.b [b:UInt32]\
- \n LeftSemi Join: Filter: __correlated_sq_1.a = test.b [a:UInt32, b:UInt32, c:UInt32]\
- \n TableScan: test [a:UInt32, b:UInt32, c:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [a:UInt32;N]\
- \n Unnest: lists[sq.a|depth=1] structs[] [a:UInt32;N]\
- \n TableScan: sq [a:List(Field { name: \"item\", data_type: UInt32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} });N]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r#"
+ Projection: test.b [b:UInt32]
+ LeftSemi Join: Filter: __correlated_sq_1.a = test.b [a:UInt32, b:UInt32, c:UInt32]
+ TableScan: test [a:UInt32, b:UInt32, c:UInt32]
+ SubqueryAlias: __correlated_sq_1 [a:UInt32;N]
+ Unnest: lists[sq.a|depth=1] structs[] [a:UInt32;N]
+ TableScan: sq [a:List(Field { name: "item", data_type: UInt32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} });N]
+ "#
+ )
}
#[test]
@@ -1946,13 +1994,16 @@ mod tests {
.project(vec![col("\"TEST_A\".\"B\"")])?
.build()?;
- let expected = "Projection: TEST_A.B [B:UInt32]\
- \n LeftSemi Join: Filter: __correlated_sq_1.A = TEST_A.A [A:UInt32, B:UInt32]\
- \n TableScan: TEST_A [A:UInt32, B:UInt32]\
- \n SubqueryAlias: __correlated_sq_1 [Int32(1):Int32, A:UInt32]\
- \n Projection: Int32(1), TEST_B.A [Int32(1):Int32, A:UInt32]\
- \n TableScan: TEST_B [A:UInt32, B:UInt32]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: TEST_A.B [B:UInt32]
+ LeftSemi Join: Filter: __correlated_sq_1.A = TEST_A.A [A:UInt32, B:UInt32]
+ TableScan: TEST_A [A:UInt32, B:UInt32]
+ SubqueryAlias: __correlated_sq_1 [Int32(1):Int32, A:UInt32]
+ Projection: Int32(1), TEST_B.A [Int32(1):Int32, A:UInt32]
+ TableScan: TEST_B [A:UInt32, B:UInt32]
+ "
+ )
}
}
diff --git a/datafusion/optimizer/src/optimize_projections/mod.rs b/datafusion/optimizer/src/optimize_projections/mod.rs
index 4452b2d4ce..a443c4cc81 100644
--- a/datafusion/optimizer/src/optimize_projections/mod.rs
+++ b/datafusion/optimizer/src/optimize_projections/mod.rs
@@ -816,8 +816,8 @@ mod tests {
use crate::optimize_projections::OptimizeProjections;
use crate::optimizer::Optimizer;
use crate::test::{
- assert_fields_eq, assert_optimized_plan_eq, scan_empty, test_table_scan,
- test_table_scan_fields, test_table_scan_with_name,
+ assert_fields_eq, scan_empty, test_table_scan, test_table_scan_fields,
+ test_table_scan_with_name,
};
use crate::{OptimizerContext, OptimizerRule};
use arrow::datatypes::{DataType, Field, Schema};
@@ -835,13 +835,25 @@ mod tests {
not, try_cast, when, BinaryExpr, Expr, Extension, Like, LogicalPlan, Operator,
Projection, UserDefinedLogicalNodeCore, WindowFunctionDefinition,
};
+ use insta::assert_snapshot;
+ use crate::assert_optimized_plan_eq_snapshot;
use datafusion_functions_aggregate::count::count_udaf;
use datafusion_functions_aggregate::expr_fn::{count, max, min};
use datafusion_functions_aggregate::min_max::max_udaf;
- fn assert_optimized_plan_equal(plan: LogicalPlan, expected: &str) -> Result<()> {
- assert_optimized_plan_eq(Arc::new(OptimizeProjections::new()), plan, expected)
+ macro_rules! assert_optimized_plan_equal {
+ (
+ $plan:expr,
+ @ $expected:literal $(,)?
+ ) => {{
+ let rule: Arc<dyn crate::OptimizerRule + Send + Sync> = Arc::new(OptimizeProjections::new());
+ assert_optimized_plan_eq_snapshot!(
+ rule,
+ $plan,
+ @ $expected,
+ )
+ }};
}
#[derive(Debug, Hash, PartialEq, Eq)]
@@ -1030,9 +1042,13 @@ mod tests {
.project(vec![binary_expr(lit(1), Operator::Plus, col("a"))])?
.build()?;
- let expected = "Projection: Int32(1) + test.a\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: Int32(1) + test.a
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1044,9 +1060,13 @@ mod tests {
.project(vec![binary_expr(lit(1), Operator::Plus, col("a"))])?
.build()?;
- let expected = "Projection: Int32(1) + test.a\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: Int32(1) + test.a
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1057,9 +1077,13 @@ mod tests {
.project(vec![col("a").alias("alias")])?
.build()?;
- let expected = "Projection: test.a AS alias\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a AS alias
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1070,9 +1094,13 @@ mod tests {
.project(vec![col("alias2").alias("alias")])?
.build()?;
- let expected = "Projection: test.a AS alias\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a AS alias
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1090,11 +1118,15 @@ mod tests {
.build()
.unwrap();
- let expected = "Aggregate: groupBy=[[]], aggr=[[count(Int32(1))]]\
- \n Projection: \
- \n Aggregate: groupBy=[[]], aggr=[[count(Int32(1))]]\
- \n TableScan: ?table? projection=[]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[]], aggr=[[count(Int32(1))]]
+ Projection:
+ Aggregate: groupBy=[[]], aggr=[[count(Int32(1))]]
+ TableScan: ?table? projection=[]
+ "
+ )
}
#[test]
@@ -1104,9 +1136,13 @@ mod tests {
.project(vec![-col("a")])?
.build()?;
- let expected = "Projection: (- test.a)\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: (- test.a)
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1116,9 +1152,13 @@ mod tests {
.project(vec![col("a").is_null()])?
.build()?;
- let expected = "Projection: test.a IS NULL\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS NULL
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1128,9 +1168,13 @@ mod tests {
.project(vec![col("a").is_not_null()])?
.build()?;
- let expected = "Projection: test.a IS NOT NULL\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS NOT NULL
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1140,9 +1184,13 @@ mod tests {
.project(vec![col("a").is_true()])?
.build()?;
- let expected = "Projection: test.a IS TRUE\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS TRUE
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1152,9 +1200,13 @@ mod tests {
.project(vec![col("a").is_not_true()])?
.build()?;
- let expected = "Projection: test.a IS NOT TRUE\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS NOT TRUE
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1164,9 +1216,13 @@ mod tests {
.project(vec![col("a").is_false()])?
.build()?;
- let expected = "Projection: test.a IS FALSE\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS FALSE
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1176,9 +1232,13 @@ mod tests {
.project(vec![col("a").is_not_false()])?
.build()?;
- let expected = "Projection: test.a IS NOT FALSE\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS NOT FALSE
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1188,9 +1248,13 @@ mod tests {
.project(vec![col("a").is_unknown()])?
.build()?;
- let expected = "Projection: test.a IS UNKNOWN\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS UNKNOWN
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1200,9 +1264,13 @@ mod tests {
.project(vec![col("a").is_not_unknown()])?
.build()?;
- let expected = "Projection: test.a IS NOT UNKNOWN\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a IS NOT UNKNOWN
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1212,9 +1280,13 @@ mod tests {
.project(vec![not(col("a"))])?
.build()?;
- let expected = "Projection: NOT test.a\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: NOT test.a
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1224,9 +1296,13 @@ mod tests {
.project(vec![try_cast(col("a"), DataType::Float64)])?
.build()?;
- let expected = "Projection: TRY_CAST(test.a AS Float64)\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: TRY_CAST(test.a AS Float64)
+ TableScan: test projection=[a]
+ "
+ )
}
#[test]
@@ -1240,9 +1316,13 @@ mod tests {
.project(vec![similar_to_expr])?
.build()?;
- let expected = "Projection: test.a SIMILAR TO Utf8(\"[0-9]\")\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r#"
+ Projection: test.a SIMILAR TO Utf8("[0-9]")
+ TableScan: test projection=[a]
+ "#
+ )
}
#[test]
@@ -1252,9 +1332,13 @@ mod tests {
.project(vec![col("a").between(lit(1), lit(3))])?
.build()?;
- let expected = "Projection: test.a BETWEEN Int32(1) AND Int32(3)\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a BETWEEN Int32(1) AND Int32(3)
+ TableScan: test projection=[a]
+ "
+ )
}
// Test Case expression
@@ -1271,9 +1355,13 @@ mod tests {
])?
.build()?;
- let expected = "Projection: test.a, CASE WHEN test.a = Int32(1) THEN Int32(10) ELSE Int32(0) END AS d\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a, CASE WHEN test.a = Int32(1) THEN Int32(10) ELSE Int32(0) END AS d
+ TableScan: test projection=[a]
+ "
+ )
}
// Test outer projection isn't discarded despite the same schema as inner
@@ -1291,11 +1379,14 @@ mod tests {
])?
.build()?;
- let expected =
- "Projection: a, CASE WHEN a = Int32(1) THEN Int32(10) ELSE d END AS d\
- \n Projection: test.a + Int32(1) AS a, Int32(0) AS d\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: a, CASE WHEN a = Int32(1) THEN Int32(10) ELSE d END AS d
+ Projection: test.a + Int32(1) AS a, Int32(0) AS d
+ TableScan: test projection=[a]
+ "
+ )
}
// Since only column `a` is referred at the output. Scan should only contain projection=[a].
@@ -1313,10 +1404,14 @@ mod tests {
.project(vec![col("a"), lit(0).alias("d")])?
.build()?;
- let expected = "Projection: test.a, Int32(0) AS d\
- \n NoOpUserDefined\
- \n TableScan: test projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a, Int32(0) AS d
+ NoOpUserDefined
+ TableScan: test projection=[a]
+ "
+ )
}
// Only column `a` is referred at the output. However, User defined node itself uses column `b`
@@ -1340,10 +1435,14 @@ mod tests {
.project(vec![col("a"), lit(0).alias("d")])?
.build()?;
- let expected = "Projection: test.a, Int32(0) AS d\
- \n NoOpUserDefined\
- \n TableScan: test projection=[a, b]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a, Int32(0) AS d
+ NoOpUserDefined
+ TableScan: test projection=[a, b]
+ "
+ )
}
// Only column `a` is referred at the output. However, User defined node itself uses expression `b+c`
@@ -1375,10 +1474,14 @@ mod tests {
.project(vec![col("a"), lit(0).alias("d")])?
.build()?;
- let expected = "Projection: test.a, Int32(0) AS d\
- \n NoOpUserDefined\
- \n TableScan: test projection=[a, b, c]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a, Int32(0) AS d
+ NoOpUserDefined
+ TableScan: test projection=[a, b, c]
+ "
+ )
}
// Columns `l.a`, `l.c`, `r.a` is referred at the output.
@@ -1399,11 +1502,15 @@ mod tests {
.project(vec![col("l.a"), col("l.c"), col("r.a"), lit(0).alias("d")])?
.build()?;
- let expected = "Projection: l.a, l.c, r.a, Int32(0) AS d\
- \n UserDefinedCrossJoin\
- \n TableScan: l projection=[a, c]\
- \n TableScan: r projection=[a]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: l.a, l.c, r.a, Int32(0) AS d
+ UserDefinedCrossJoin
+ TableScan: l projection=[a, c]
+ TableScan: r projection=[a]
+ "
+ )
}
#[test]
@@ -1414,10 +1521,13 @@ mod tests {
.aggregate(Vec::<Expr>::new(), vec![max(col("b"))])?
.build()?;
- let expected = "Aggregate: groupBy=[[]], aggr=[[max(test.b)]]\
- \n TableScan: test projection=[b]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[]], aggr=[[max(test.b)]]
+ TableScan: test projection=[b]
+ "
+ )
}
#[test]
@@ -1428,10 +1538,13 @@ mod tests {
.aggregate(vec![col("c")], vec![max(col("b"))])?
.build()?;
- let expected = "Aggregate: groupBy=[[test.c]], aggr=[[max(test.b)]]\
- \n TableScan: test projection=[b, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[test.c]], aggr=[[max(test.b)]]
+ TableScan: test projection=[b, c]
+ "
+ )
}
#[test]
@@ -1443,11 +1556,14 @@ mod tests {
.aggregate(vec![col("c")], vec![max(col("b"))])?
.build()?;
- let expected = "Aggregate: groupBy=[[a.c]], aggr=[[max(a.b)]]\
- \n SubqueryAlias: a\
- \n TableScan: test projection=[b, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[a.c]], aggr=[[max(a.b)]]
+ SubqueryAlias: a
+ TableScan: test projection=[b, c]
+ "
+ )
}
#[test]
@@ -1459,12 +1575,15 @@ mod tests {
.aggregate(Vec::<Expr>::new(), vec![max(col("b"))])?
.build()?;
- let expected = "Aggregate: groupBy=[[]], aggr=[[max(test.b)]]\
- \n Projection: test.b\
- \n Filter: test.c > Int32(1)\
- \n TableScan: test projection=[b, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[]], aggr=[[max(test.b)]]
+ Projection: test.b
+ Filter: test.c > Int32(1)
+ TableScan: test projection=[b, c]
+ "
+ )
}
#[test]
@@ -1485,11 +1604,13 @@ mod tests {
.project([col(Column::new_unqualified("tag.one"))])?
.build()?;
- let expected = "\
- Aggregate: groupBy=[[]], aggr=[[max(m4.tag.one) AS tag.one]]\
- \n TableScan: m4 projection=[tag.one]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[]], aggr=[[max(m4.tag.one) AS tag.one]]
+ TableScan: m4 projection=[tag.one]
+ "
+ )
}
#[test]
@@ -1500,10 +1621,13 @@ mod tests {
.project(vec![col("a"), col("b"), col("c")])?
.project(vec![col("a"), col("c"), col("b")])?
.build()?;
- let expected = "Projection: test.a, test.c, test.b\
- \n TableScan: test projection=[a, b, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a, test.c, test.b
+ TableScan: test projection=[a, b, c]
+ "
+ )
}
#[test]
@@ -1511,9 +1635,10 @@ mod tests {
let schema = Schema::new(test_table_scan_fields());
let plan = table_scan(Some("test"), &schema, Some(vec![1, 0, 2]))?.build()?;
- let expected = "TableScan: test projection=[b, a, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @"TableScan: test projection=[b, a, c]"
+ )
}
#[test]
@@ -1523,10 +1648,13 @@ mod tests {
let plan = table_scan(Some("test"), &schema, Some(vec![1, 0, 2]))?
.project(vec![col("a"), col("b")])?
.build()?;
- let expected = "Projection: test.a, test.b\
- \n TableScan: test projection=[b, a]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a, test.b
+ TableScan: test projection=[b, a]
+ "
+ )
}
#[test]
@@ -1536,10 +1664,13 @@ mod tests {
let plan = LogicalPlanBuilder::from(table_scan)
.project(vec![col("c"), col("b"), col("a")])?
.build()?;
- let expected = "Projection: test.c, test.b, test.a\
- \n TableScan: test projection=[a, b, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.c, test.b, test.a
+ TableScan: test projection=[a, b, c]
+ "
+ )
}
#[test]
@@ -1554,14 +1685,18 @@ mod tests {
.filter(col("a").gt(lit(1)))?
.project(vec![col("a"), col("c"), col("b")])?
.build()?;
- let expected = "Projection: test.a, test.c, test.b\
- \n Filter: test.a > Int32(1)\
- \n Filter: test.b > Int32(1)\
- \n Projection: test.c, test.a, test.b\
- \n Filter: test.c > Int32(1)\
- \n Projection: test.c, test.b, test.a\
- \n TableScan: test projection=[a, b, c]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a, test.c, test.b
+ Filter: test.a > Int32(1)
+ Filter: test.b > Int32(1)
+ Projection: test.c, test.a, test.b
+ Filter: test.c > Int32(1)
+ Projection: test.c, test.b, test.a
+ TableScan: test projection=[a, b, c]
+ "
+ )
}
#[test]
@@ -1576,14 +1711,17 @@ mod tests {
.project(vec![col("a"), col("b"), col("c1")])?
.build()?;
- // make sure projections are pushed down to both table scans
- let expected = "Left Join: test.a = test2.c1\
- \n TableScan: test projection=[a, b]\
- \n TableScan: test2 projection=[c1]";
-
let optimized_plan = optimize(plan)?;
- let formatted_plan = format!("{optimized_plan}");
- assert_eq!(formatted_plan, expected);
+
+ // make sure projections are pushed down to both table scans
+ assert_snapshot!(
+ optimized_plan.clone(),
+ @r"
+ Left Join: test.a = test2.c1
+ TableScan: test projection=[a, b]
+ TableScan: test2 projection=[c1]
+ "
+ );
// make sure schema for join node include both join columns
let optimized_join = optimized_plan;
@@ -1627,15 +1765,18 @@ mod tests {
.project(vec![col("a"), col("b")])?
.build()?;
- // make sure projections are pushed down to both table scans
- let expected = "Projection: test.a, test.b\
- \n Left Join: test.a = test2.c1\
- \n TableScan: test projection=[a, b]\
- \n TableScan: test2 projection=[c1]";
-
let optimized_plan = optimize(plan)?;
- let formatted_plan = format!("{optimized_plan}");
- assert_eq!(formatted_plan, expected);
+
+ // make sure projections are pushed down to both table scans
+ assert_snapshot!(
+ optimized_plan.clone(),
+ @r"
+ Projection: test.a, test.b
+ Left Join: test.a = test2.c1
+ TableScan: test projection=[a, b]
+ TableScan: test2 projection=[c1]
+ "
+ );
// make sure schema for join node include both join columns
let optimized_join = optimized_plan.inputs()[0];
@@ -1677,15 +1818,18 @@ mod tests {
.project(vec![col("a"), col("b")])?
.build()?;
- // make sure projections are pushed down to table scan
- let expected = "Projection: test.a, test.b\
- \n Left Join: Using test.a = test2.a\
- \n TableScan: test projection=[a, b]\
- \n TableScan: test2 projection=[a]";
-
let optimized_plan = optimize(plan)?;
- let formatted_plan = format!("{optimized_plan}");
- assert_eq!(formatted_plan, expected);
+
+ // make sure projections are pushed down to table scan
+ assert_snapshot!(
+ optimized_plan.clone(),
+ @r"
+ Projection: test.a, test.b
+ Left Join: Using test.a = test2.a
+ TableScan: test projection=[a, b]
+ TableScan: test2 projection=[a]
+ "
+ );
// make sure schema for join node include both join columns
let optimized_join = optimized_plan.inputs()[0];
@@ -1717,17 +1861,20 @@ mod tests {
fn cast() -> Result<()> {
let table_scan = test_table_scan()?;
- let projection = LogicalPlanBuilder::from(table_scan)
+ let plan = LogicalPlanBuilder::from(table_scan)
.project(vec![Expr::Cast(Cast::new(
Box::new(col("c")),
DataType::Float64,
))])?
.build()?;
- let expected = "Projection: CAST(test.c AS Float64)\
- \n TableScan: test projection=[c]";
-
- assert_optimized_plan_equal(projection, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: CAST(test.c AS Float64)
+ TableScan: test projection=[c]
+ "
+ )
}
#[test]
@@ -1741,9 +1888,10 @@ mod tests {
assert_fields_eq(&table_scan, vec!["a", "b", "c"]);
assert_fields_eq(&plan, vec!["a", "b"]);
- let expected = "TableScan: test projection=[a, b]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @"TableScan: test projection=[a, b]"
+ )
}
#[test]
@@ -1762,9 +1910,10 @@ mod tests {
assert_fields_eq(&plan, vec!["a", "b"]);
- let expected = "TableScan: test projection=[a, b]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @"TableScan: test projection=[a, b]"
+ )
}
#[test]
@@ -1780,11 +1929,14 @@ mod tests {
assert_fields_eq(&plan, vec!["c", "a"]);
- let expected = "Limit: skip=0, fetch=5\
- \n Projection: test.c, test.a\
- \n TableScan: test projection=[a, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Limit: skip=0, fetch=5
+ Projection: test.c, test.a
+ TableScan: test projection=[a, c]
+ "
+ )
}
#[test]
@@ -1792,8 +1944,10 @@ mod tests {
let table_scan = test_table_scan()?;
let plan = LogicalPlanBuilder::from(table_scan).build()?;
// should expand projection to all columns without projection
- let expected = "TableScan: test projection=[a, b, c]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @"TableScan: test projection=[a, b, c]"
+ )
}
#[test]
@@ -1802,9 +1956,13 @@ mod tests {
let plan = LogicalPlanBuilder::from(table_scan)
.project(vec![lit(1_i64), lit(2_i64)])?
.build()?;
- let expected = "Projection: Int64(1), Int64(2)\
- \n TableScan: test projection=[]";
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: Int64(1), Int64(2)
+ TableScan: test projection=[]
+ "
+ )
}
/// tests that it removes unused columns in projections
@@ -1824,13 +1982,15 @@ mod tests {
assert_fields_eq(&plan, vec!["c", "max(test.a)"]);
let plan = optimize(plan).expect("failed to optimize plan");
- let expected = "\
- Aggregate: groupBy=[[test.c]], aggr=[[max(test.a)]]\
- \n Filter: test.c > Int32(1)\
- \n Projection: test.c, test.a\
- \n TableScan: test projection=[a, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[test.c]], aggr=[[max(test.a)]]
+ Filter: test.c > Int32(1)
+ Projection: test.c, test.a
+ TableScan: test projection=[a, c]
+ "
+ )
}
/// tests that it removes un-needed projections
@@ -1848,11 +2008,13 @@ mod tests {
assert_fields_eq(&plan, vec!["a"]);
- let expected = "\
- Projection: Int32(1) AS a\
- \n TableScan: test projection=[]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: Int32(1) AS a
+ TableScan: test projection=[]
+ "
+ )
}
#[test]
@@ -1877,11 +2039,13 @@ mod tests {
assert_fields_eq(&plan, vec!["a"]);
- let expected = "\
- Projection: Int32(1) AS a\
- \n TableScan: test projection=[], full_filters=[b = Int32(1)]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: Int32(1) AS a
+ TableScan: test projection=[], full_filters=[b = Int32(1)]
+ "
+ )
}
/// tests that optimizing twice yields same plan
@@ -1920,12 +2084,15 @@ mod tests {
assert_fields_eq(&plan, vec!["c", "a", "max(test.b)"]);
- let expected = "Projection: test.c, test.a, max(test.b)\
- \n Filter: test.c > Int32(1)\
- \n Aggregate: groupBy=[[test.a, test.c]], aggr=[[max(test.b)]]\
- \n TableScan: test projection=[a, b, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.c, test.a, max(test.b)
+ Filter: test.c > Int32(1)
+ Aggregate: groupBy=[[test.a, test.c]], aggr=[[max(test.b)]]
+ TableScan: test projection=[a, b, c]
+ "
+ )
}
#[test]
@@ -1942,10 +2109,13 @@ mod tests {
)?
.build()?;
- let expected = "Aggregate: groupBy=[[test.a]], aggr=[[count(test.b), count(test.b) FILTER (WHERE test.c > Int32(42)) AS count2]]\
- \n TableScan: test projection=[a, b, c]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Aggregate: groupBy=[[test.a]], aggr=[[count(test.b), count(test.b) FILTER (WHERE test.c > Int32(42)) AS count2]]
+ TableScan: test projection=[a, b, c]
+ "
+ )
}
#[test]
@@ -1958,11 +2128,14 @@ mod tests {
.project(vec![col("a")])?
.build()?;
- let expected = "Projection: test.a\
- \n Distinct:\
- \n TableScan: test projection=[a, b]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: test.a
+ Distinct:
+ TableScan: test projection=[a, b]
+ "
+ )
}
#[test]
@@ -1990,13 +2163,16 @@ mod tests {
.project(vec![col1, col2])?
.build()?;
- let expected = "Projection: max(test.a) PARTITION BY [test.b] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING, max(test.b) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING\
- \n WindowAggr: windowExpr=[[max(test.b) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING]]\
- \n Projection: test.b, max(test.a) PARTITION BY [test.b] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING\
- \n WindowAggr: windowExpr=[[max(test.a) PARTITION BY [test.b] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING]]\
- \n TableScan: test projection=[a, b]";
-
- assert_optimized_plan_equal(plan, expected)
+ assert_optimized_plan_equal!(
+ plan,
+ @r"
+ Projection: max(test.a) PARTITION BY [test.b] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING, max(test.b) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+ WindowAggr: windowExpr=[[max(test.b) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING]]
+ Projection: test.b, max(test.a) PARTITION BY [test.b] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+ WindowAggr: windowExpr=[[max(test.a) PARTITION BY [test.b] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING]]
+ TableScan: test projection=[a, b]
+ "
+ )
}
fn observe(_plan: &LogicalPlan, _rule: &dyn OptimizerRule) {}
diff --git a/datafusion/optimizer/src/propagate_empty_relation.rs b/datafusion/optimizer/src/propagate_empty_relation.rs
index 344707ae8d..10821f08fb 100644
--- a/datafusion/optimizer/src/propagate_empty_relation.rs
+++ b/datafusion/optimizer/src/propagate_empty_relation.rs
@@ -242,17 +242,28 @@ mod tests {
binary_expr, col, lit, logical_plan::builder::LogicalPlanBuilder, Operator,
};
+ use crate::assert_optimized_plan_eq_snapshot;
use crate::eliminate_filter::EliminateFilter;
use crate::eliminate_nested_union::EliminateNestedUnion;
use crate::test::{
- assert_optimized_plan_eq, assert_optimized_plan_with_rules, test_table_scan,
- test_table_scan_fields, test_table_scan_with_name,
+ assert_optimized_plan_with_rules, test_table_scan, test_table_scan_fields,
+ test_table_scan_with_name,
};
use super::*;
- fn assert_eq(plan: LogicalPlan, expected: &str) -> Result<()> {
- assert_optimized_plan_eq(Arc::new(PropagateEmptyRelation::new()), plan, expected)
+ macro_rules! assert_optimized_plan_equal {
+ (
+ $plan:expr,
+ @ $expected:literal $(,)?
+ ) => {{
+ let rule: Arc<dyn crate::OptimizerRule + Send + Sync> = Arc::new(PropagateEmptyRelation::new());
+ assert_optimized_plan_eq_snapshot!(
+ rule,
+ $plan,
+ @ $expected,
+ )
+ }};
}
fn assert_together_optimized_plan(
@@ -280,8 +291,7 @@ mod tests {
.project(vec![binary_expr(lit(1), Operator::Plus, lit(1))])?
.build()?;
- let expected = "EmptyRelation";
- assert_eq(plan, expected)
+ assert_optimized_plan_equal!(plan, @"EmptyRelation")
}
#[test]
diff --git a/datafusion/optimizer/src/test/mod.rs b/datafusion/optimizer/src/test/mod.rs
index 5927ffea5a..4d89a35fc1 100644
--- a/datafusion/optimizer/src/test/mod.rs
+++ b/datafusion/optimizer/src/test/mod.rs
@@ -165,22 +165,6 @@ pub fn assert_analyzer_check_err(
fn observe(_plan: &LogicalPlan, _rule: &dyn OptimizerRule) {}
-pub fn assert_optimized_plan_eq(
- rule: Arc<dyn OptimizerRule + Send + Sync>,
- plan: LogicalPlan,
- expected: &str,
-) -> Result<()> {
- // Apply the rule once
- let opt_context = OptimizerContext::new().with_max_passes(1);
-
- let optimizer = Optimizer::with_rules(vec![Arc::clone(&rule)]);
- let optimized_plan = optimizer.optimize(plan, &opt_context, observe)?;
- let formatted_plan = format!("{optimized_plan}");
- assert_eq!(formatted_plan, expected);
-
- Ok(())
-}
-
#[macro_export]
macro_rules! assert_optimized_plan_eq_snapshot {
(
@@ -242,6 +226,24 @@ pub fn assert_optimized_plan_eq_display_indent(
assert_eq!(formatted_plan, expected);
}
+#[macro_export]
+macro_rules! assert_optimized_plan_eq_display_indent_snapshot {
+ (
+ $rule:expr,
+ $plan:expr,
+ @ $expected:literal $(,)?
+ ) => {{
+ let optimizer = $crate::Optimizer::with_rules(vec![$rule]);
+ let optimized_plan = optimizer
+ .optimize($plan, &$crate::OptimizerContext::new(), |_, _| {})
+ .expect("failed to optimize plan");
+ let formatted_plan = optimized_plan.display_indent_schema();
+ insta::assert_snapshot!(formatted_plan, @ $expected);
+
+ Ok::<(), datafusion_common::DataFusionError>(())
+ }};
+}
+
pub fn assert_multi_rules_optimized_plan_eq_display_indent(
rules: Vec<Arc<dyn OptimizerRule + Send + Sync>>,
plan: LogicalPlan,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org