Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 2.3k
Optimize where exists sub-queries into aggregate and join#2813
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
14d807a88f5d7fd2f43c9e34705ec37d29e874a5edee1c7565ea1c288348470cd999c7ccdb98fe7fcb2f9b51e46de8ae118dd2b1634b29086a759ce37a73c21db5c8df3ee70cb08da97f22c0790e0e0c7308b67c0c5ed1ad11d7f96ab6894b281c8c6a08eb17e02545ea3f21950b3549f90d95a9377cdf23b0ffb858b28400a661b170841560a6e58b8c0808File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -108,6 +108,7 @@ mod explain; | ||
| mod idenfifers; | ||
| pub mod information_schema; | ||
| mod partitioned_csv; | ||
| mod subqueries; | ||
| #[cfg(feature = "unicode_expressions")] | ||
| pub mod unicode; | ||
| @@ -483,7 +484,37 @@ fn get_tpch_table_schema(table: &str) -> Schema { | ||
| Field::new("n_comment", DataType::Utf8, false), | ||
| ]), | ||
| _ => unimplemented!(), | ||
| "supplier" => Schema::new(vec![ | ||
ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add missing TPC-H tables to support testing those queries. | ||
| Field::new("s_suppkey", DataType::Int64, false), | ||
| Field::new("s_name", DataType::Utf8, false), | ||
| Field::new("s_address", DataType::Utf8, false), | ||
| Field::new("s_nationkey", DataType::Int64, false), | ||
| Field::new("s_phone", DataType::Utf8, false), | ||
| Field::new("s_acctbal", DataType::Float64, false), | ||
| Field::new("s_comment", DataType::Utf8, false), | ||
| ]), | ||
| "partsupp" => Schema::new(vec![ | ||
| Field::new("ps_partkey", DataType::Int64, false), | ||
| Field::new("ps_suppkey", DataType::Int64, false), | ||
| Field::new("ps_availqty", DataType::Int32, false), | ||
| Field::new("ps_supplycost", DataType::Float64, false), | ||
| Field::new("ps_comment", DataType::Utf8, false), | ||
| ]), | ||
| "part" => Schema::new(vec![ | ||
| Field::new("p_partkey", DataType::Int64, false), | ||
| Field::new("p_name", DataType::Utf8, false), | ||
| Field::new("p_mfgr", DataType::Utf8, false), | ||
| Field::new("p_brand", DataType::Utf8, false), | ||
| Field::new("p_type", DataType::Utf8, false), | ||
| Field::new("p_size", DataType::Int32, false), | ||
| Field::new("p_container", DataType::Utf8, false), | ||
| Field::new("p_retailprice", DataType::Float64, false), | ||
| Field::new("p_comment", DataType::Utf8, false), | ||
| ]), | ||
| _ => unimplemented!("Table: {}", table), | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| use super::*; | ||
| use crate::sql::execute_to_batches; | ||
| use datafusion::assert_batches_eq; | ||
| use datafusion::prelude::SessionContext; | ||
| #[tokio::test] | ||
| async fn tpch_q4_correlated() -> Result<()> { | ||
| let ctx = SessionContext::new(); | ||
| register_tpch_csv(&ctx, "orders").await?; | ||
| register_tpch_csv(&ctx, "lineitem").await?; | ||
| /* | ||
ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Annotate plan with variable names from optimizer code for cross-correlation. | ||
| #orders.o_orderpriority ASC NULLS LAST | ||
| Projection: #orders.o_orderpriority, #COUNT(UInt8(1)) AS order_count | ||
| Aggregate: groupBy=[[#orders.o_orderpriority]], aggr=[[COUNT(UInt8(1))]] | ||
| Filter: EXISTS ( -- plan | ||
| Subquery: Projection: * -- proj | ||
| Filter: #lineitem.l_orderkey = #orders.o_orderkey -- filter | ||
| TableScan: lineitem projection=None -- filter.input | ||
| ) | ||
| TableScan: orders projection=None -- plan.inputs | ||
| */ | ||
| let sql = r#" | ||
| select o_orderpriority, count(*) as order_count | ||
| from orders | ||
| where exists ( | ||
| select * from lineitem where l_orderkey = o_orderkey and l_commitdate < l_receiptdate) | ||
| group by o_orderpriority | ||
| order by o_orderpriority; | ||
| "#; | ||
| // assert plan | ||
| let plan = ctx | ||
| .create_logical_plan(sql) | ||
| .map_err(|e| format!("{:?} at {}", e, "error")) | ||
| .unwrap(); | ||
| let plan = ctx | ||
| .optimize(&plan) | ||
| .map_err(|e| format!("{:?} at {}", e, "error")) | ||
| .unwrap(); | ||
| let actual = format!("{}", plan.display_indent()); | ||
| let expected = r#"Sort: #orders.o_orderpriority ASC NULLS LAST | ||
| Projection: #orders.o_orderpriority, #COUNT(UInt8(1)) AS order_count | ||
| Aggregate: groupBy=[[#orders.o_orderpriority]], aggr=[[COUNT(UInt8(1))]] | ||
| Inner Join: #orders.o_orderkey = #lineitem.l_orderkey | ||
| TableScan: orders projection=[o_orderkey, o_orderpriority] | ||
| Projection: #lineitem.l_orderkey | ||
| Aggregate: groupBy=[[#lineitem.l_orderkey]], aggr=[[]] | ||
| Filter: #lineitem.l_commitdate < #lineitem.l_receiptdate | ||
| TableScan: lineitem projection=[l_orderkey, l_commitdate, l_receiptdate], partial_filters=[#lineitem.l_commitdate < #lineitem.l_receiptdate]"# | ||
| .to_string(); | ||
| assert_eq!(actual, expected); | ||
| // assert data | ||
| let results = execute_to_batches(&ctx, sql).await; | ||
| let expected = vec![ | ||
| "+-----------------+-------------+", | ||
| "| o_orderpriority | order_count |", | ||
| "+-----------------+-------------+", | ||
| "| 1-URGENT | 1 |", | ||
| "| 5-LOW | 1 |", | ||
| "+-----------------+-------------+", | ||
| ]; | ||
| assert_batches_eq!(expected, &results); | ||
| Ok(()) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| p_partkey,p_name,p_mfgr,p_brand,p_type,p_size,p_container,p_retailprice,p_comment | ||
| 1,goldenrod lavender spring chocolate lace,Manufacturer#1,Brand#13,PROMO BURNISHED COPPER,7,JUMBO PKG,901.00,ly. slyly ironi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| ps_partkey,ps_suppkey,ps_availqty,ps_supplycost,ps_comment | ||
| 67310,7311,100,993.49,ven ideas. quickly even packages print. pending multipliers must have to are fluff |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| s_suppkey,s_name,s_address,s_nationkey,s_phone,s_acctbal,s_comment | ||
| 1,Supplier#000000001, N kD4on9OM Ipw3,gf0JBoQDd7tgrzrddZ,17,27-918-335-1736,5755.94,each slyly above the careful |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, this was built upon #2797 . I'll turn this into a draft until that gets merged.