Skip to content

Commit

Permalink
feat: Eliminate Limit Rule (#60)
Browse files Browse the repository at this point in the history
Depends on #58
  • Loading branch information
jurplel authored Feb 13, 2024
1 parent f5e8f10 commit e846c58
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 2 deletions.
5 changes: 3 additions & 2 deletions optd-datafusion-repr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use properties::{
schema::{Catalog, SchemaPropertyBuilder},
};
use rules::{
EliminateFilterRule, EliminateJoinRule, HashJoinRule, JoinAssocRule, JoinCommuteRule,
PhysicalConversionRule, ProjectionPullUpJoin,
EliminateFilterRule, EliminateJoinRule, EliminateLimitRule, HashJoinRule, JoinAssocRule,
JoinCommuteRule, PhysicalConversionRule, ProjectionPullUpJoin,
};

pub use adaptive::PhysicalCollector;
Expand Down Expand Up @@ -52,6 +52,7 @@ impl DatafusionOptimizer {
rules.push(Arc::new(ProjectionPullUpJoin::new()));
rules.push(Arc::new(EliminateJoinRule::new()));
rules.push(Arc::new(EliminateFilterRule::new()));
rules.push(Arc::new(EliminateLimitRule::new()));

let cost_model = AdaptiveCostModel::new(50);
Self {
Expand Down
2 changes: 2 additions & 0 deletions optd-datafusion-repr/src/rules.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// mod filter_join;
mod eliminate_filter;
mod eliminate_limit;
mod joins;
mod macros;
mod physical;

// pub use filter_join::FilterJoinPullUpRule;
pub use eliminate_filter::EliminateFilterRule;
pub use eliminate_limit::EliminateLimitRule;
pub use joins::{
EliminateJoinRule, HashJoinRule, JoinAssocRule, JoinCommuteRule, ProjectionPullUpJoin,
};
Expand Down
49 changes: 49 additions & 0 deletions optd-datafusion-repr/src/rules/eliminate_limit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::collections::HashMap;

use optd_core::rules::{Rule, RuleMatcher};
use optd_core::{optimizer::Optimizer, rel_node::RelNode};

use crate::plan_nodes::{
ConstantExpr, ConstantType, LogicalEmptyRelation, OptRelNode, OptRelNodeTyp,
};

use super::macros::define_rule;

define_rule!(
EliminateLimitRule,
apply_eliminate_limit,
(Limit, child, [skip], [fetch])
);

/// Transformations:
/// - Limit with skip 0 and no fetch -> Eliminate from the tree
/// - Limit with limit 0 -> EmptyRelation
fn apply_eliminate_limit(
_optimizer: &impl Optimizer<OptRelNodeTyp>,
EliminateLimitRulePicks { child, skip, fetch }: EliminateLimitRulePicks,
) -> Vec<RelNode<OptRelNodeTyp>> {
if let OptRelNodeTyp::Constant(ConstantType::UInt64) = skip.typ {
if let OptRelNodeTyp::Constant(ConstantType::UInt64) = fetch.typ {
let skip_val = ConstantExpr::from_rel_node(skip.into())
.unwrap()
.value()
.as_u64();

let fetch_val = ConstantExpr::from_rel_node(fetch.into())
.unwrap()
.value()
.as_u64();

// Bad convention to have u64 max represent None
let fetch_is_none = fetch_val == u64::MAX;

if fetch_is_none && skip_val == 0 {
return vec![child];
} else if fetch_val == 0 {
let node = LogicalEmptyRelation::new(false);
return vec![node.into_rel_node().as_ref().clone()];
}
}
}
vec![]
}
21 changes: 21 additions & 0 deletions optd-sqlplannertest/tests/eliminate_limit.planner.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- (no id or description)
create table t1(t1v1 int, t1v2 int);
create table t2(t2v1 int, t2v3 int);
insert into t1 values (0, 0), (1, 1), (2, 2);
insert into t2 values (0, 200), (1, 201), (2, 202);

/*
3
3
*/

-- Test EliminateLimitRule (with 0 limit clause)
select * from t1 LIMIT 0;

/*
LogicalLimit { skip: 0, fetch: 0 }
└── LogicalProjection { exprs: [ #0, #1 ] }
└── LogicalScan { table: t1 }
PhysicalEmptyRelation { produce_one_row: false }
*/

14 changes: 14 additions & 0 deletions optd-sqlplannertest/tests/eliminate_limit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

- sql: |
create table t1(t1v1 int, t1v2 int);
create table t2(t2v1 int, t2v3 int);
insert into t1 values (0, 0), (1, 1), (2, 2);
insert into t2 values (0, 200), (1, 201), (2, 202);
tasks:
- execute
- sql: |
select * from t1 LIMIT 0;
desc: Test EliminateLimitRule (with 0 limit clause)
tasks:
- explain:logical_optd,physical_optd
- execute

0 comments on commit e846c58

Please sign in to comment.