Skip to content

Commit

Permalink
fix(query): fix aggregating index conflict with min/max rewrite (data…
Browse files Browse the repository at this point in the history
…bendlabs#17182)

* fix(query): fixed conflicts between aggregate index and min max rewrite

* fix tests

* fix

* fix tests

* fix explain tests

* fix tests

* fix tests

* fix tests

* fix
  • Loading branch information
b41sh authored Jan 7, 2025
1 parent 2c73bdb commit 53ce6b3
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 379 deletions.
41 changes: 0 additions & 41 deletions src/query/ee/tests/it/aggregating_index/index_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,47 +747,6 @@ struct TestSuite {
/// ```
fn get_test_suites() -> Vec<TestSuite> {
vec![
// query: eval-scan, index: eval-scan
TestSuite {
query: "select to_string(c + 1) from t",
index: "select c + 1 from t",
is_index_scan: true,
},
TestSuite {
query: "select c + 1 from t",
index: "select c + 1 from t",
is_index_scan: true,
},
TestSuite {
query: "select a from t",
index: "select a from t",
is_index_scan: true,
},
TestSuite {
query: "select a as z from t",
index: "select a from t",
is_index_scan: true,
},
TestSuite {
query: "select a + 1, to_string(a) from t",
index: "select a from t",
is_index_scan: true,
},
TestSuite {
query: "select a + 1 as z, to_string(a) from t",
index: "select a from t",
is_index_scan: true,
},
TestSuite {
query: "select b from t",
index: "select a, b from t",
is_index_scan: true,
},
TestSuite {
query: "select a from t",
index: "select b, c from t",
is_index_scan: false,
},
// query: eval-filter-scan, index: eval-scan
TestSuite {
query: "select a from t where b > 1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,112 +96,6 @@ fn create_table_plan(fixture: &TestFixture, format: &str) -> CreateTablePlan {
/// ```
fn get_test_suites() -> Vec<TestSuite> {
vec![
// query: eval-scan, index: eval-scan
TestSuite {
query: "select to_string(c + 1) from t",
index: "select c + 1 from t",
is_matched: true,
index_selection: vec!["to_string(index_col_0 (#0))"],
rewritten_predicates: vec![],
},
TestSuite {
query: "select c + 1 from t",
index: "select c + 1 from t",
is_matched: true,
index_selection: vec!["index_col_0 (#0)"],
rewritten_predicates: vec![],
},
TestSuite {
query: "select a from t",
index: "select a from t",
is_matched: true,
index_selection: vec!["index_col_0 (#0)"],
rewritten_predicates: vec![],
},
TestSuite {
query: "select a as z from t",
index: "select a from t",
is_matched: true,
index_selection: vec!["index_col_0 (#0)"],
rewritten_predicates: vec![],
},
TestSuite {
query: "select a + 1, to_string(a) from t",
index: "select a from t",
is_matched: true,
index_selection: vec![
"index_col_0 (#0)",
"plus(index_col_0 (#0), 1)",
"to_string(index_col_0 (#0))",
],
rewritten_predicates: vec![],
},
TestSuite {
query: "select a + 1 as z, to_string(a) from t",
index: "select a from t",
is_matched: true,
index_selection: vec![
"index_col_0 (#0)",
"plus(index_col_0 (#0), 1)",
"to_string(index_col_0 (#0))",
],
rewritten_predicates: vec![],
},
TestSuite {
query: "select b from t",
index: "select a, b from t",
is_matched: true,
index_selection: vec!["index_col_1 (#1)"],
rewritten_predicates: vec![],
},
TestSuite {
query: "select a from t",
index: "select b, c from t",
is_matched: false,
..Default::default()
},
// query: eval-filter-scan, index: eval-scan
TestSuite {
query: "select a from t where b > 1",
index: "select b, c from t",
is_matched: false,
..Default::default()
},
TestSuite {
query: "select a from t where b > 1",
index: "select a, b from t",
is_matched: true,
index_selection: vec!["index_col_0 (#0)"],
rewritten_predicates: vec!["gt(index_col_1 (#1), 1)"],
},
// query: eval-agg-eval-scan, index: eval-scan
TestSuite {
query: "select sum(a) from t group by b",
index: "select a from t",
is_matched: false,
..Default::default()
},
TestSuite {
query: "select avg(a + 1) from t group by b",
index: "select a + 1, b from t",
is_matched: true,
index_selection: vec!["index_col_0 (#0)", "index_col_1 (#1)"],
..Default::default()
},
TestSuite {
query: "select avg(a + 1) from t",
index: "select a + 1, b from t",
is_matched: true,
index_selection: vec!["index_col_1 (#1)"],
..Default::default()
},
// query: eval-agg-eval-filter-scan, index: eval-scan
TestSuite {
query: "select sum(a) from t where a > 1 group by b",
index: "select a from t",
is_matched: false,
..Default::default()
},
// query: eval-scan, index: eval-filter-scan
TestSuite {
query: "select a from t",
Expand Down Expand Up @@ -390,37 +284,6 @@ fn get_test_suites() -> Vec<TestSuite> {
],
rewritten_predicates: vec!["gt(index_col_0 (#0), 1)"],
},
// query: sort-eval-scan, index: eval-scan
TestSuite {
query: "select to_string(c + 1) as s from t order by s",
index: "select c + 1 from t",
is_matched: true,
index_selection: vec!["to_string(index_col_0 (#0))"],
rewritten_predicates: vec![],
},
// query: eval-sort-filter-scan, index: eval-scan
TestSuite {
query: "select a from t where b > 1 order by a",
index: "select a, b from t",
is_matched: true,
index_selection: vec!["index_col_0 (#0)"],
rewritten_predicates: vec!["gt(index_col_1 (#1), 1)"],
},
// query: eval-sort-agg-eval-scan, index: eval-scan
TestSuite {
query: "select avg(a + 1) from t group by b order by b",
index: "select a + 1, b from t",
is_matched: true,
index_selection: vec!["index_col_0 (#0)", "index_col_1 (#1)"],
..Default::default()
},
// query: eval-sort-agg-eval-filter-scan, index: eval-scan
TestSuite {
query: "select sum(a) from t where a > 1 group by b order by b",
index: "select a from t",
is_matched: false,
..Default::default()
},
// query: eval-sort-filter-scan, index: eval-filter-scan
TestSuite {
query: "select a from t where b > 1 order by a",
Expand Down
41 changes: 29 additions & 12 deletions src/query/sql/src/planner/optimizer/aggregate/stats_aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use databend_common_expression::types::DataType;

use crate::optimizer::SExpr;
use crate::plans::Aggregate;
use crate::plans::AggregateFunction;
use crate::plans::BoundColumnRef;
use crate::plans::ConstantExpr;
use crate::plans::DummyTableScan;
use crate::plans::EvalScalar;
Expand All @@ -28,7 +30,9 @@ use crate::plans::RelOp;
use crate::plans::RelOperator;
use crate::plans::ScalarExpr;
use crate::plans::ScalarItem;
use crate::ColumnBindingBuilder;
use crate::MetadataRef;
use crate::Visibility;

// Replace aggregate function with scalar from table's accurate stats function
pub struct RuleStatsAggregateOptimizer {
Expand Down Expand Up @@ -122,27 +126,40 @@ impl RuleStatsAggregateOptimizer {
{
if let Some((col_id, name)) = need_rewrite_agg {
if let Some(stat) = stats.get(col_id) {
if name.eq_ignore_ascii_case("min") && !stat.min.may_be_truncated {
let value_bound = if name.eq_ignore_ascii_case("min") {
&stat.min
} else {
&stat.max
};
if !value_bound.may_be_truncated {
eval_scalar_results.push(ScalarItem {
index: agg.index,
scalar: ScalarExpr::ConstantExpr(ConstantExpr {
value: stat.min.value.clone(),
span: None,
}),
});
continue;
} else if !stat.max.may_be_truncated {
eval_scalar_results.push(ScalarItem {
index: agg.index,
scalar: ScalarExpr::ConstantExpr(ConstantExpr {
value: stat.max.value.clone(),
span: None,
span: agg.scalar.span(),
value: value_bound.value.clone(),
}),
});
continue;
}
}
}

// Add other aggregate functions as derived column,
// this will be used in aggregating index rewrite.
let agg_func = AggregateFunction::try_from(agg.scalar.clone())?;
eval_scalar_results.push(ScalarItem {
index: agg.index,
scalar: ScalarExpr::BoundColumnRef(BoundColumnRef {
span: agg.scalar.span(),
column: ColumnBindingBuilder::new(
agg_func.display_name.clone(),
agg.index,
agg_func.return_type.clone(),
Visibility::Visible,
)
.build(),
}),
});
agg_results.push(agg.clone());
}
}
Expand Down
Loading

0 comments on commit 53ce6b3

Please sign in to comment.