Skip to content
This repository was archived by the owner on Jan 7, 2025. It is now read-only.

Commit e846c58

Browse files
authored
feat: Eliminate Limit Rule (#60)
Depends on #58
1 parent f5e8f10 commit e846c58

File tree

5 files changed

+89
-2
lines changed

5 files changed

+89
-2
lines changed

optd-datafusion-repr/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use properties::{
1111
schema::{Catalog, SchemaPropertyBuilder},
1212
};
1313
use rules::{
14-
EliminateFilterRule, EliminateJoinRule, HashJoinRule, JoinAssocRule, JoinCommuteRule,
15-
PhysicalConversionRule, ProjectionPullUpJoin,
14+
EliminateFilterRule, EliminateJoinRule, EliminateLimitRule, HashJoinRule, JoinAssocRule,
15+
JoinCommuteRule, PhysicalConversionRule, ProjectionPullUpJoin,
1616
};
1717

1818
pub use adaptive::PhysicalCollector;
@@ -52,6 +52,7 @@ impl DatafusionOptimizer {
5252
rules.push(Arc::new(ProjectionPullUpJoin::new()));
5353
rules.push(Arc::new(EliminateJoinRule::new()));
5454
rules.push(Arc::new(EliminateFilterRule::new()));
55+
rules.push(Arc::new(EliminateLimitRule::new()));
5556

5657
let cost_model = AdaptiveCostModel::new(50);
5758
Self {

optd-datafusion-repr/src/rules.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// mod filter_join;
22
mod eliminate_filter;
3+
mod eliminate_limit;
34
mod joins;
45
mod macros;
56
mod physical;
67

78
// pub use filter_join::FilterJoinPullUpRule;
89
pub use eliminate_filter::EliminateFilterRule;
10+
pub use eliminate_limit::EliminateLimitRule;
911
pub use joins::{
1012
EliminateJoinRule, HashJoinRule, JoinAssocRule, JoinCommuteRule, ProjectionPullUpJoin,
1113
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::collections::HashMap;
2+
3+
use optd_core::rules::{Rule, RuleMatcher};
4+
use optd_core::{optimizer::Optimizer, rel_node::RelNode};
5+
6+
use crate::plan_nodes::{
7+
ConstantExpr, ConstantType, LogicalEmptyRelation, OptRelNode, OptRelNodeTyp,
8+
};
9+
10+
use super::macros::define_rule;
11+
12+
define_rule!(
13+
EliminateLimitRule,
14+
apply_eliminate_limit,
15+
(Limit, child, [skip], [fetch])
16+
);
17+
18+
/// Transformations:
19+
/// - Limit with skip 0 and no fetch -> Eliminate from the tree
20+
/// - Limit with limit 0 -> EmptyRelation
21+
fn apply_eliminate_limit(
22+
_optimizer: &impl Optimizer<OptRelNodeTyp>,
23+
EliminateLimitRulePicks { child, skip, fetch }: EliminateLimitRulePicks,
24+
) -> Vec<RelNode<OptRelNodeTyp>> {
25+
if let OptRelNodeTyp::Constant(ConstantType::UInt64) = skip.typ {
26+
if let OptRelNodeTyp::Constant(ConstantType::UInt64) = fetch.typ {
27+
let skip_val = ConstantExpr::from_rel_node(skip.into())
28+
.unwrap()
29+
.value()
30+
.as_u64();
31+
32+
let fetch_val = ConstantExpr::from_rel_node(fetch.into())
33+
.unwrap()
34+
.value()
35+
.as_u64();
36+
37+
// Bad convention to have u64 max represent None
38+
let fetch_is_none = fetch_val == u64::MAX;
39+
40+
if fetch_is_none && skip_val == 0 {
41+
return vec![child];
42+
} else if fetch_val == 0 {
43+
let node = LogicalEmptyRelation::new(false);
44+
return vec![node.into_rel_node().as_ref().clone()];
45+
}
46+
}
47+
}
48+
vec![]
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-- (no id or description)
2+
create table t1(t1v1 int, t1v2 int);
3+
create table t2(t2v1 int, t2v3 int);
4+
insert into t1 values (0, 0), (1, 1), (2, 2);
5+
insert into t2 values (0, 200), (1, 201), (2, 202);
6+
7+
/*
8+
3
9+
3
10+
*/
11+
12+
-- Test EliminateLimitRule (with 0 limit clause)
13+
select * from t1 LIMIT 0;
14+
15+
/*
16+
LogicalLimit { skip: 0, fetch: 0 }
17+
└── LogicalProjection { exprs: [ #0, #1 ] }
18+
└── LogicalScan { table: t1 }
19+
PhysicalEmptyRelation { produce_one_row: false }
20+
*/
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
- sql: |
3+
create table t1(t1v1 int, t1v2 int);
4+
create table t2(t2v1 int, t2v3 int);
5+
insert into t1 values (0, 0), (1, 1), (2, 2);
6+
insert into t2 values (0, 200), (1, 201), (2, 202);
7+
tasks:
8+
- execute
9+
- sql: |
10+
select * from t1 LIMIT 0;
11+
desc: Test EliminateLimitRule (with 0 limit clause)
12+
tasks:
13+
- explain:logical_optd,physical_optd
14+
- execute

0 commit comments

Comments
 (0)