diff --git a/src/query/ee/tests/it/aggregating_index/index_scan.rs b/src/query/ee/tests/it/aggregating_index/index_scan.rs index 85674a95795fb..61dee3d944735 100644 --- a/src/query/ee/tests/it/aggregating_index/index_scan.rs +++ b/src/query/ee/tests/it/aggregating_index/index_scan.rs @@ -747,47 +747,6 @@ struct TestSuite { /// ``` fn get_test_suites() -> Vec { 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", diff --git a/src/query/service/tests/it/sql/planner/optimizer/agg_index_query_rewrite.rs b/src/query/service/tests/it/sql/planner/optimizer/agg_index_query_rewrite.rs index 34b7747e7c8a5..af02e471d540a 100644 --- a/src/query/service/tests/it/sql/planner/optimizer/agg_index_query_rewrite.rs +++ b/src/query/service/tests/it/sql/planner/optimizer/agg_index_query_rewrite.rs @@ -96,112 +96,6 @@ fn create_table_plan(fixture: &TestFixture, format: &str) -> CreateTablePlan { /// ``` fn get_test_suites() -> Vec { 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", @@ -390,37 +284,6 @@ fn get_test_suites() -> Vec { ], 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", diff --git a/src/query/sql/src/planner/optimizer/aggregate/stats_aggregate.rs b/src/query/sql/src/planner/optimizer/aggregate/stats_aggregate.rs index f4f2bdf12aae1..47b6948e561f3 100644 --- a/src/query/sql/src/planner/optimizer/aggregate/stats_aggregate.rs +++ b/src/query/sql/src/planner/optimizer/aggregate/stats_aggregate.rs @@ -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; @@ -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 { @@ -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()); } } diff --git a/src/query/sql/src/planner/semantic/aggregating_index_visitor.rs b/src/query/sql/src/planner/semantic/aggregating_index_visitor.rs index 06255e50295b2..67b11cc2bba8b 100644 --- a/src/query/sql/src/planner/semantic/aggregating_index_visitor.rs +++ b/src/query/sql/src/planner/semantic/aggregating_index_visitor.rs @@ -28,6 +28,7 @@ use databend_common_ast::ast::TableReference; use databend_common_ast::parser::parse_expr; use databend_common_ast::parser::tokenize_sql; use databend_common_ast::parser::Dialect; +use databend_common_expression::FunctionKind; use databend_common_expression::BLOCK_NAME_COL_NAME; use databend_common_functions::aggregates::AggregateFunctionFactory; use databend_common_functions::BUILTIN_FUNCTIONS; @@ -63,7 +64,7 @@ impl AggregatingIndexRewriter { .. } if !*distinct && SUPPORTED_AGGREGATING_INDEX_FUNCTIONS - .contains(&&*name.name.to_ascii_lowercase().to_lowercase()) + .contains(&name.name.to_ascii_lowercase().to_lowercase().as_str()) && window.is_none() && lambda.is_none() => { @@ -197,47 +198,60 @@ impl AggregatingIndexRewriter { #[derive(Debug, Clone, Default, Visitor)] #[visitor(FunctionCall(enter), SelectStmt(enter), Query(enter))] pub struct AggregatingIndexChecker { + has_agg_function: bool, + has_group_by: bool, + has_selection: bool, not_support: bool, } impl AggregatingIndexChecker { pub fn is_supported(&self) -> bool { - !self.not_support + // Must have at least one of aggregate function, group by, or selection. + // An aggregating index like `select a + 1 from t` are useless and take up extra storage space. + !self.not_support && (self.has_agg_function || self.has_group_by || self.has_selection) } fn enter_function_call(&mut self, func: &FunctionCall) { + if self.not_support { + return; + } let FunctionCall { distinct: _, name, params: _, args: _, - window: _, + window, lambda: _, } = func; - if self.not_support { - return; - } - - // is agg func but not support now. - if AggregateFunctionFactory::instance().contains(&name.name) - && !SUPPORTED_AGGREGATING_INDEX_FUNCTIONS.contains(&&*name.name.to_lowercase()) - { + let name = name.name.to_lowercase(); + let func_name = name.as_str(); + if AggregateFunctionFactory::instance().contains(func_name) { + self.has_agg_function = true; + // is agg func but not support now. + if !SUPPORTED_AGGREGATING_INDEX_FUNCTIONS.contains(&func_name) || window.is_some() { + self.not_support = true; + } + } else if let Some(func_property) = BUILTIN_FUNCTIONS.get_property(func_name) { + // set returning functions and non deterministic functions such as `now()` are not supported. + if func_property.kind == FunctionKind::SRF || func_property.non_deterministic { + self.not_support = true; + } + } else { + // Functions other than aggregate and scalar are not supported, such as window, UDF, etc. self.not_support = true; - return; } - - self.not_support = BUILTIN_FUNCTIONS - .get_property(&name.name) - .map(|p| p.non_deterministic) - .unwrap_or(false); } fn enter_select_stmt(&mut self, stmt: &SelectStmt) { if self.not_support { return; } - if stmt.having.is_some() || stmt.window_list.is_some() || stmt.qualify.is_some() { + if stmt.having.is_some() + || stmt.window_list.is_some() + || stmt.qualify.is_some() + || stmt.top_n.is_some() + { self.not_support = true; return; } @@ -249,12 +263,26 @@ impl AggregatingIndexChecker { return; } } + if stmt.from.len() != 1 { + self.not_support = true; + return; + } + // only support select from one table. + match &stmt.from[0] { + TableReference::Table { .. } => {} + _ => { + self.not_support = true; + return; + } + } for target in &stmt.select_list { - if target.has_window() { + if target.is_star() { self.not_support = true; return; } } + self.has_selection = stmt.selection.is_some(); + self.has_group_by = stmt.group_by.is_some(); } fn enter_query(&mut self, query: &Query) { @@ -288,7 +316,7 @@ impl RefreshAggregatingIndexRewriter { .. } if !*distinct && SUPPORTED_AGGREGATING_INDEX_FUNCTIONS - .contains(&&*name.name.to_ascii_lowercase().to_lowercase()) + .contains(&name.name.to_ascii_lowercase().to_lowercase().as_str()) && window.is_none() => { self.has_agg_function = true; diff --git a/tests/sqllogictests/suites/ee/01_ee_system/01_0000_system_indexes.test b/tests/sqllogictests/suites/ee/01_ee_system/01_0000_system_indexes.test index 88f5982e4be3a..7f3549f053d6d 100644 --- a/tests/sqllogictests/suites/ee/01_ee_system/01_0000_system_indexes.test +++ b/tests/sqllogictests/suites/ee/01_ee_system/01_0000_system_indexes.test @@ -49,7 +49,7 @@ statement ok CREATE AGGREGATING INDEX idx2 AS SELECT b FROM t1 WHERE a < 10 statement ok -CREATE AGGREGATING INDEX idx3 AS SELECT * FROM t2 +CREATE AGGREGATING INDEX idx3 AS SELECT max(a), avg(b) FROM t2 statement ok SHOW INDEXES @@ -59,7 +59,7 @@ SELECT name, type, definition FROM system.indexes ---- idx1 AGGREGATING SELECT b, SUM(a) FROM test_index_db.t1 WHERE b > 3 GROUP BY b idx2 AGGREGATING SELECT b FROM test_index_db.t1 WHERE a < 10 -idx3 AGGREGATING SELECT * FROM test_index_db.t2 +idx3 AGGREGATING SELECT COUNT(), COUNT(b), MAX(a), SUM(b) FROM test_index_db.t2 statement ok DROP AGGREGATING INDEX idx2 @@ -68,7 +68,7 @@ query TTT SELECT name, type, definition FROM system.indexes ---- idx1 AGGREGATING SELECT b, SUM(a) FROM test_index_db.t1 WHERE b > 3 GROUP BY b -idx3 AGGREGATING SELECT * FROM test_index_db.t2 +idx3 AGGREGATING SELECT COUNT(), COUNT(b), MAX(a), SUM(b) FROM test_index_db.t2 statement ok DROP AGGREGATING INDEX idx1 diff --git a/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0000_async_agg_index_base.test b/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0000_async_agg_index_base.test index 2d45787e8f85b..f8a936b20f6bf 100644 --- a/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0000_async_agg_index_base.test +++ b/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0000_async_agg_index_base.test @@ -32,41 +32,14 @@ INSERT INTO t VALUES (1,1,4), (1,2,1), (1,2,4), (2,2,5) # query: eval-scan, index: eval-scan -statement ok +statement error 1601 CREATE ASYNC AGGREGATING INDEX testi AS select c + 1 from t -statement ok -REFRESH AGGREGATING INDEX testi - -query T -select to_string(c + 1) from t ----- -5 -2 -5 -6 - -statement ok -DROP AGGREGATING INDEX testi - # eval-filter-scan, index: eval-scan -statement ok +statement error 1601 CREATE ASYNC AGGREGATING INDEX testi AS select a, b from t -statement ok -REFRESH AGGREGATING INDEX testi - -query T -select a from t where b > 1 ----- -1 -1 -2 - -statement ok -DROP AGGREGATING INDEX testi - # query: eval-agg-eval-scan, index: eval-scan # No available case for index scan. @@ -92,26 +65,9 @@ statement ok DROP AGGREGATING INDEX testi # query: eval-agg-eval-scan, index: eval-filter-scan -statement ok +statement error 1601 CREATE ASYNC AGGREGATING INDEX testi AS select a + 1, b from t -statement ok -REFRESH AGGREGATING INDEX testi - -query I -select sum(a + 1) as s from t group by b order by s ----- -2 -7 - -query I -select sum(a + 1) as s from t ----- -9 - -statement ok -DROP AGGREGATING INDEX testi - # query: eval-agg-eval-filter-scan, index: eval-filter-scan statement ok CREATE ASYNC AGGREGATING INDEX testi AS select a + 1, b from t where b > 1 diff --git a/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0001_agg_index_projected_scan.test b/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0001_agg_index_projected_scan.test index 6f4cbc4078a82..d9e8286a48e69 100644 --- a/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0001_agg_index_projected_scan.test +++ b/tests/sqllogictests/suites/ee/02_ee_aggregating_index/02_0001_agg_index_projected_scan.test @@ -25,6 +25,9 @@ use test_index statement ok DROP AGGREGATING INDEX IF EXISTS testi; +statement ok +DROP AGGREGATING INDEX IF EXISTS testi2; + statement ok CREATE TABLE t (a int, b int, c int) @@ -34,6 +37,32 @@ INSERT INTO t VALUES (1,1,4), (1,2,1), (1,2,4), (2,2,5) statement ok CREATE AGGREGATING INDEX testi AS SELECT b, MAX(a), SUM(a) from t WHERE c > 1 GROUP BY b +statement ok +CREATE AGGREGATING INDEX testi2 AS SELECT MAX(a), MIN(b), AVG(c) from t + +query I +SELECT b from t WHERE c > 1 GROUP BY b ORDER BY b +---- +1 +2 + +query II +SELECT b, SUM(a) from t WHERE c > 1 GROUP BY b ORDER BY b +---- +1 1 +2 3 + +query IIT +SELECT MAX(a), MIN(b), AVG(c) from t +---- +2 1 3.5 + +statement ok +REFRESH AGGREGATING INDEX testi + +statement ok +REFRESH AGGREGATING INDEX testi2 + query I SELECT b from t WHERE c > 1 GROUP BY b ORDER BY b ---- @@ -45,3 +74,8 @@ SELECT b, SUM(a) from t WHERE c > 1 GROUP BY b ORDER BY b ---- 1 1 2 3 + +query IIT +SELECT MAX(a), MIN(b), AVG(c) from t +---- +2 1 3.5 diff --git a/tests/sqllogictests/suites/mode/cluster/explain_v2.test b/tests/sqllogictests/suites/mode/cluster/explain_v2.test index fda4c62dfc762..ef727d846a937 100644 --- a/tests/sqllogictests/suites/mode/cluster/explain_v2.test +++ b/tests/sqllogictests/suites/mode/cluster/explain_v2.test @@ -168,23 +168,27 @@ query T explain select count(1) as c, count(b) as d, max(a) as e from t1 order by c, e, d limit 10; ---- Limit -├── output columns: [count(1) (#2), max(a) (#4), count(b) (#3)] +├── output columns: [count(1) (#2), count(b) (#3), max(a) (#4)] ├── limit: 10 ├── offset: 0 ├── estimated rows: 1.00 └── Sort - ├── output columns: [count(1) (#2), max(a) (#4), count(b) (#3)] + ├── output columns: [count(1) (#2), count(b) (#3), max(a) (#4)] ├── sort keys: [count(1) ASC NULLS LAST, max(a) ASC NULLS LAST, count(b) ASC NULLS LAST] ├── estimated rows: 1.00 └── EvalScalar - ├── output columns: [count(1) (#2), max(a) (#4), count(b) (#3)] - ├── expressions: [99, count(1) (#2)] + ├── output columns: [count(1) (#2), count(b) (#3), max(a) (#4)] + ├── expressions: [99] ├── estimated rows: 1.00 └── EvalScalar - ├── output columns: [count(1) (#2)] - ├── expressions: [100] + ├── output columns: [count(1) (#2), count(b) (#3)] + ├── expressions: [count(1) (#2)] ├── estimated rows: 1.00 - └── DummyTableScan + └── EvalScalar + ├── output columns: [count(1) (#2)] + ├── expressions: [100] + ├── estimated rows: 1.00 + └── DummyTableScan query T explain select (t1.a + 1) as c,(t1.b+1) as d, (t2.a+1) as e from t1 join t2 on t1.a = t2.a order by c, d, e limit 10; diff --git a/tests/sqllogictests/suites/mode/standalone/ee/explain_agg_index.test b/tests/sqllogictests/suites/mode/standalone/ee/explain_agg_index.test index 32ddcfae4009c..12072ef8ec94c 100644 --- a/tests/sqllogictests/suites/mode/standalone/ee/explain_agg_index.test +++ b/tests/sqllogictests/suites/mode/standalone/ee/explain_agg_index.test @@ -242,44 +242,6 @@ SET enable_aggregating_index_scan = 1 statement ok DROP AGGREGATING INDEX idx1 -statement ok -CREATE AGGREGATING INDEX idx1 AS SELECT a + 1 from t1 - -query T -EXPLAIN SELECT avg(a + 1) from t1 ----- -EvalScalar -├── output columns: [sum(a + 1) / if(count(a + 1) = 0, 1, count(a + 1)) (#5)] -├── expressions: [sum(a + 1) (#3) / CAST(if(CAST(count(a + 1) (#4) = 0 AS Boolean NULL), 1, count(a + 1) (#4)) AS UInt64 NULL)] -├── estimated rows: 1.00 -└── AggregateFinal - ├── output columns: [sum(a + 1) (#3), count(a + 1) (#4)] - ├── group by: [] - ├── aggregate functions: [sum(sum_arg_0), count()] - ├── estimated rows: 1.00 - └── AggregatePartial - ├── group by: [] - ├── aggregate functions: [sum(sum_arg_0), count()] - ├── estimated rows: 1.00 - └── EvalScalar - ├── output columns: [sum_arg_0 (#2)] - ├── expressions: [t1.a (#0) + 1] - ├── estimated rows: 0.00 - └── TableScan - ├── table: default.test_index_db.t1 - ├── output columns: [a (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [], limit: NONE] - ├── aggregating index: [SELECT a + 1 FROM test_index_db.t1] - ├── rewritten query: [selection: [index_col_0 (#0)]] - └── estimated rows: 0.00 - -statement ok -DROP AGGREGATING INDEX idx1 - statement ok CREATE AGGREGATING INDEX idx1 AS SELECT avg(a), sum(b) from t1 @@ -704,72 +666,6 @@ AggregateFinal statement ok DROP AGGREGATING INDEX idx1 -statement ok -CREATE AGGREGATING INDEX idx1 AS SELECT a + 1 from t1 - -statement ok -INSERT INTO t1 VALUES (1,1), (1,2), (2,4), (2,5) - -query T -EXPLAIN SELECT avg(a + 1) from t1 ----- -EvalScalar -├── output columns: [sum(a + 1) / if(count(a + 1) = 0, 1, count(a + 1)) (#5)] -├── expressions: [sum(a + 1) (#3) / CAST(if(CAST(count(a + 1) (#4) = 0 AS Boolean NULL), 1, count(a + 1) (#4)) AS UInt64 NULL)] -├── estimated rows: 1.00 -└── AggregateFinal - ├── output columns: [sum(a + 1) (#3), count(a + 1) (#4)] - ├── group by: [] - ├── aggregate functions: [sum(sum_arg_0), count()] - ├── estimated rows: 1.00 - └── AggregatePartial - ├── group by: [] - ├── aggregate functions: [sum(sum_arg_0), count()] - ├── estimated rows: 1.00 - └── EvalScalar - ├── output columns: [sum_arg_0 (#2)] - ├── expressions: [t1.a (#0) + 1] - ├── estimated rows: 4.00 - └── TableScan - ├── table: default.test_index_db.t1 - ├── output columns: [a (#0)] - ├── read rows: 4 - ├── read size: < 1 KiB - ├── partitions total: 1 - ├── partitions scanned: 1 - ├── pruning stats: [segments: , blocks: ] - ├── push downs: [filters: [], limit: NONE] - ├── aggregating index: [SELECT a + 1 FROM test_index_db.t1] - ├── rewritten query: [selection: [index_col_0 (#0)]] - └── estimated rows: 4.00 - -statement ok -truncate table t1 - -query T -EXPLAIN SELECT b, a + 1 as x from t1 order by x ----- -Sort -├── output columns: [t1.b (#1), x (#2)] -├── sort keys: [x ASC NULLS LAST] -├── estimated rows: 0.00 -└── EvalScalar - ├── output columns: [t1.b (#1), x (#2)] - ├── expressions: [t1.a (#0) + 1] - ├── estimated rows: 0.00 - └── TableScan - ├── table: default.test_index_db.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [], limit: NONE] - └── estimated rows: 0.00 - -statement ok -DROP AGGREGATING INDEX idx1 - statement ok USE default diff --git a/tests/sqllogictests/suites/mode/standalone/explain/fold_agg.test b/tests/sqllogictests/suites/mode/standalone/explain/fold_agg.test index 244aac04afb17..6c3844847c3ba 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/fold_agg.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/fold_agg.test @@ -119,14 +119,18 @@ query T explain select count(), max(number) + 3, min(day) from t; ---- EvalScalar -├── output columns: [min(day) (#7), count() (#5), max(number) + 3 (#8)] +├── output columns: [count() (#5), min(day) (#7), max(number) + 3 (#8)] ├── expressions: [max(number) (#6) + 3] ├── estimated rows: 1.00 └── EvalScalar - ├── output columns: [max(number) (#6), min(day) (#7), count() (#5)] - ├── expressions: [1999, '2024-01-01', 3000] + ├── output columns: [count() (#5), max(number) (#6), min(day) (#7)] + ├── expressions: [1999, '2024-01-01'] ├── estimated rows: 1.00 - └── DummyTableScan + └── EvalScalar + ├── output columns: [count() (#5)] + ├── expressions: [3000] + ├── estimated rows: 1.00 + └── DummyTableScan query T explain select count(), max(number) + 4, sum_if(number + 4 , number > 3 ), min(day), max(ts), min(money), 8, min(ts), sum(money) from t; @@ -167,14 +171,18 @@ query T explain select 5, count(), min(number), max(ts), min(money), 4 from t; ---- EvalScalar -├── output columns: [min(number) (#6), max(ts) (#7), min(money) (#8), count() (#5), 5 (#9), 4 (#10)] +├── output columns: [count() (#5), min(number) (#6), max(ts) (#7), min(money) (#8), 5 (#9), 4 (#10)] ├── expressions: [5, 4] ├── estimated rows: 1.00 └── EvalScalar - ├── output columns: [min(number) (#6), max(ts) (#7), min(money) (#8), count() (#5)] - ├── expressions: [0, '2024-01-01 00:33:19.000000', 0.00, 3000] + ├── output columns: [count() (#5), min(number) (#6), max(ts) (#7), min(money) (#8)] + ├── expressions: [0, '2024-01-01 00:33:19.000000', 0.00] ├── estimated rows: 1.00 - └── DummyTableScan + └── EvalScalar + ├── output columns: [count() (#5)] + ├── expressions: [3000] + ├── estimated rows: 1.00 + └── DummyTableScan query T ----