Skip to content

Commit 872627c

Browse files
authored
feat: refine the rule PushDownFilterWindowTopN in case top n is equal to 0. (#16830)
* top n 0 Signed-off-by: coldWater <forsaken628@gmail.com> * test Signed-off-by: coldWater <forsaken628@gmail.com> * rename Signed-off-by: coldWater <forsaken628@gmail.com> * fix Signed-off-by: coldWater <forsaken628@gmail.com> --------- Signed-off-by: coldWater <forsaken628@gmail.com>
1 parent 80c8cf6 commit 872627c

File tree

4 files changed

+42
-8
lines changed

4 files changed

+42
-8
lines changed

src/query/sql/src/planner/optimizer/rule/factory.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ impl RuleFactory {
9292
}
9393
RuleID::PushDownFilterAggregate => Ok(Box::new(RulePushDownFilterAggregate::new())),
9494
RuleID::PushDownFilterWindow => Ok(Box::new(RulePushDownFilterWindow::new())),
95-
RuleID::PushDownFilterWindowRank => Ok(Box::new(RulePushDownFilterWindowTopN::new())),
95+
RuleID::PushDownFilterWindowTopN => {
96+
Ok(Box::new(RulePushDownFilterWindowTopN::new(ctx.metadata)))
97+
}
9698
RuleID::EliminateFilter => Ok(Box::new(RuleEliminateFilter::new(ctx.metadata))),
9799
RuleID::MergeEvalScalar => Ok(Box::new(RuleMergeEvalScalar::new())),
98100
RuleID::MergeFilter => Ok(Box::new(RuleMergeFilter::new())),

src/query/sql/src/planner/optimizer/rule/rewrite/rule_push_down_filter_window_top_n.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,28 @@ use std::sync::Arc;
1616

1717
use databend_common_exception::Result;
1818
use databend_common_expression::type_check::check_number;
19+
use databend_common_expression::DataField;
20+
use databend_common_expression::DataSchemaRefExt;
1921
use databend_common_expression::FunctionContext;
2022
use databend_common_functions::BUILTIN_FUNCTIONS;
2123

2224
use crate::optimizer::extract::Matcher;
2325
use crate::optimizer::rule::Rule;
2426
use crate::optimizer::rule::TransformResult;
27+
use crate::optimizer::RelExpr;
2528
use crate::optimizer::RuleID;
2629
use crate::optimizer::SExpr;
2730
use crate::plans::ComparisonOp;
31+
use crate::plans::ConstantTableScan;
2832
use crate::plans::Filter;
33+
use crate::plans::Operator;
2934
use crate::plans::RelOp;
35+
use crate::plans::RelOperator;
3036
use crate::plans::ScalarExpr;
3137
use crate::plans::Sort;
3238
use crate::plans::Window;
3339
use crate::plans::WindowFuncType;
40+
use crate::MetadataRef;
3441

3542
/// Input: Filter
3643
/// \
@@ -45,13 +52,15 @@ use crate::plans::WindowFuncType;
4552
/// Sort(top n)
4653
pub struct RulePushDownFilterWindowTopN {
4754
id: RuleID,
55+
metadata: MetadataRef,
4856
matchers: Vec<Matcher>,
4957
}
5058

5159
impl RulePushDownFilterWindowTopN {
52-
pub fn new() -> Self {
60+
pub fn new(metadata: MetadataRef) -> Self {
5361
Self {
54-
id: RuleID::PushDownFilterWindowRank,
62+
id: RuleID::PushDownFilterWindowTopN,
63+
metadata,
5564
matchers: vec![Matcher::MatchOp {
5665
op_type: RelOp::Filter,
5766
children: vec![Matcher::MatchOp {
@@ -93,7 +102,22 @@ impl Rule for RulePushDownFilterWindowTopN {
93102
};
94103

95104
if top_n == 0 {
96-
// TODO
105+
let output_columns = s_expr
106+
.plan()
107+
.derive_relational_prop(&RelExpr::with_s_expr(s_expr))?
108+
.output_columns
109+
.clone();
110+
let metadata = self.metadata.read();
111+
let mut columns = output_columns.iter().copied().collect::<Vec<_>>();
112+
columns.sort();
113+
let fields = columns
114+
.into_iter()
115+
.map(|col| DataField::new(&col.to_string(), metadata.column(col).data_type()))
116+
.collect::<Vec<_>>();
117+
let empty_scan =
118+
ConstantTableScan::new_empty_scan(DataSchemaRefExt::create(fields), output_columns);
119+
let result = SExpr::create_leaf(Arc::new(RelOperator::ConstantTableScan(empty_scan)));
120+
state.add_result(result);
97121
return Ok(());
98122
}
99123

src/query/sql/src/planner/optimizer/rule/rule.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub static DEFAULT_REWRITE_RULES: LazyLock<Vec<RuleID>> = LazyLock::new(|| {
3737
RuleID::PushDownFilterUnion,
3838
RuleID::PushDownFilterAggregate,
3939
RuleID::PushDownFilterWindow,
40-
RuleID::PushDownFilterWindowRank,
40+
RuleID::PushDownFilterWindowTopN,
4141
RuleID::PushDownFilterSort,
4242
RuleID::PushDownFilterEvalScalar,
4343
RuleID::PushDownFilterJoin,
@@ -91,7 +91,7 @@ pub enum RuleID {
9191
PushDownFilterSort,
9292
PushDownFilterProjectSet,
9393
PushDownFilterWindow,
94-
PushDownFilterWindowRank,
94+
PushDownFilterWindowTopN,
9595
PushDownLimit,
9696
PushDownLimitUnion,
9797
PushDownLimitOuterJoin,
@@ -142,7 +142,7 @@ impl Display for RuleID {
142142
RuleID::PushDownSortEvalScalar => write!(f, "PushDownSortEvalScalar"),
143143
RuleID::PushDownLimitWindow => write!(f, "PushDownLimitWindow"),
144144
RuleID::PushDownFilterWindow => write!(f, "PushDownFilterWindow"),
145-
RuleID::PushDownFilterWindowRank => write!(f, "PushDownFilterWindowRank"),
145+
RuleID::PushDownFilterWindowTopN => write!(f, "PushDownFilterWindowTopN"),
146146
RuleID::EliminateEvalScalar => write!(f, "EliminateEvalScalar"),
147147
RuleID::EliminateFilter => write!(f, "EliminateFilter"),
148148
RuleID::EliminateSort => write!(f, "EliminateSort"),

tests/sqllogictests/suites/mode/standalone/explain/window.test

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,17 @@ CompoundBlockOperator(Project) × 1
541541
SyncReadParquetDataTransform × 1
542542
BlockPartitionSource × 1
543543

544+
# top n 0
545+
query T
546+
explain optimized select time, rowkey from (select *, row_number() over(partition by rowkey order by time desc) as rn from table43764_orc) a where rn < 1
547+
----
548+
EvalScalar
549+
├── scalars: [a.rowkey (#0) AS (#0), table43764_orc.rowkey (#0) AS (#0), a.time (#1) AS (#1), table43764_orc.time (#1) AS (#1), table43764_orc.sirc_action (#2) AS (#2), table43764_orc.sirc_operation_count (#3) AS (#3), table43764_orc.akc087 (#4) AS (#4), table43764_orc.aae035 (#5) AS (#5), row_number() OVER ( PARTITION BY rowkey ORDER BY time DESC ) (#6) AS (#6), a.rn (#6) AS (#7)]
550+
└── EmptyResultScan
551+
544552
# same order multi window
545553
query T
546-
explain pipeline select *,lead(number,1, 42) over (order by number), lead(number,2,44) over (order by number), lead(number,3,44) over (order by number) from numbers(5);
554+
explain pipeline select *,lead(number,1, 42) over (order by number), lead(number,2,44) over (order by number), lead(number,3,44) over (order by number) from numbers(5);
547555
----
548556
CompoundBlockOperator(Project) × 1
549557
Transform Window × 1

0 commit comments

Comments
 (0)