Skip to content

Commit b185ac7

Browse files
committed
add a template for startup
Signed-off-by: Runji Wang <[email protected]>
1 parent 281c2e4 commit b185ac7

File tree

5 files changed

+174
-0
lines changed

5 files changed

+174
-0
lines changed

src/agg.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use egg::Language;
2+
3+
use super::*;
4+
5+
#[derive(Debug, PartialEq, Eq)]
6+
pub enum Error {
7+
// #[error("aggregate function calls cannot be nested")]
8+
NestedAgg(String),
9+
// #[error("WHERE clause cannot contain aggregates")]
10+
AggInWhere,
11+
// #[error("GROUP BY clause cannot contain aggregates")]
12+
AggInGroupBy,
13+
// #[error("column {0} must appear in the GROUP BY clause or be used in an aggregate function")]
14+
ColumnNotInAgg(String),
15+
}
16+
17+
/// Converts the SELECT statement into a plan tree.
18+
///
19+
/// The nodes of all clauses have been added to the `egraph`.
20+
/// `from`, `where_`... are the ids of their root node.
21+
pub fn plan_select(
22+
egraph: &mut EGraph,
23+
from: Id,
24+
where_: Id,
25+
having: Id,
26+
groupby: Id,
27+
orderby: Id,
28+
projection: Id,
29+
) -> Result<Id, Error> {
30+
todo!()
31+
}

src/expr.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Expression simplification rules and constant folding.
2+
3+
use egg::rewrite as rw;
4+
5+
use super::*;
6+
7+
/// Returns all rules of expression simplification.
8+
#[rustfmt::skip]
9+
pub fn rules() -> Vec<Rewrite> { vec![
10+
rw!("add-zero"; "(+ ?a 0)" => "?a"),
11+
12+
// TODO: add more rules
13+
]}

src/lib.rs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#![allow(unused)]
2+
3+
use std::hash::Hash;
4+
5+
use egg::{define_language, Analysis, DidMerge, Id};
6+
7+
pub mod agg;
8+
pub mod expr;
9+
pub mod plan;
10+
mod value;
11+
12+
pub use value::*;
13+
14+
pub type RecExpr = egg::RecExpr<Expr>;
15+
pub type EGraph = egg::EGraph<Expr, ExprAnalysis>;
16+
pub type Rewrite = egg::Rewrite<Expr, ExprAnalysis>;
17+
18+
define_language! {
19+
pub enum Expr {
20+
// values
21+
Constant(Value), // null, true, 1, 'hello'
22+
Column(Column), // t.a, b, c
23+
24+
// TODO: add more nodes
25+
}
26+
}
27+
28+
/// The unified analysis for all rules.
29+
#[derive(Default)]
30+
pub struct ExprAnalysis;
31+
32+
/// The analysis data associated with each eclass.
33+
///
34+
/// See [`egg::Analysis`] for how data is being processed.
35+
#[derive(Debug)]
36+
pub struct Data {
37+
// TODO: add analysis data
38+
}
39+
40+
impl Analysis<Expr> for ExprAnalysis {
41+
type Data = Data;
42+
43+
/// Analyze a node and give the result.
44+
fn make(egraph: &EGraph, enode: &Expr) -> Self::Data {
45+
todo!()
46+
}
47+
48+
/// Merge the analysis data with previous one.
49+
fn merge(&mut self, to: &mut Self::Data, from: Self::Data) -> DidMerge {
50+
todo!()
51+
}
52+
53+
/// Modify the graph after analyzing a node.
54+
fn modify(egraph: &mut EGraph, id: Id) {
55+
todo!()
56+
}
57+
}

src/plan.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! Plan optimization rules.
2+
3+
use std::collections::HashSet;
4+
5+
use super::*;
6+
use egg::rewrite as rw;
7+
8+
/// Returns the rules that always improve the plan.
9+
pub fn rules() -> Vec<Rewrite> {
10+
let mut rules = vec![];
11+
rules.extend(projection_pushdown_rules());
12+
rules.extend(join_rules());
13+
// TODO: add rules
14+
rules
15+
}
16+
17+
#[rustfmt::skip]
18+
pub fn join_rules() -> Vec<Rewrite> { vec![
19+
// TODO: add rules
20+
]}
21+
22+
/// Pushdown projections and prune unused columns.
23+
#[rustfmt::skip]
24+
pub fn projection_pushdown_rules() -> Vec<Rewrite> { vec![
25+
// TODO: add rules
26+
]}

src/value.rs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::{fmt::Display, str::FromStr};
2+
3+
/// SQL value.
4+
///
5+
/// # Display and Parse Format
6+
///
7+
/// - Null: `null`
8+
/// - Bool: `false`
9+
/// - Integer: `1`
10+
/// - String: `'string'`
11+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12+
pub enum Value {
13+
Null,
14+
Bool(bool),
15+
Int(i32),
16+
String(String),
17+
}
18+
19+
impl Display for Value {
20+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21+
match self {
22+
Value::Null => write!(f, "null"),
23+
Value::Bool(b) => write!(f, "{b}"),
24+
Value::Int(i) => write!(f, "{i}"),
25+
Value::String(s) => write!(f, "'{s}'"),
26+
}
27+
}
28+
}
29+
30+
impl FromStr for Value {
31+
type Err = String;
32+
33+
fn from_str(s: &str) -> Result<Self, Self::Err> {
34+
if s == "null" {
35+
return Ok(Value::Null);
36+
} else if let Ok(i) = s.parse() {
37+
return Ok(Value::Bool(i));
38+
} else if let Ok(i) = s.parse() {
39+
return Ok(Value::Int(i));
40+
} else if s.starts_with('\'') && s.ends_with('\'') {
41+
return Ok(Value::String(s[1..s.len() - 1].to_string()));
42+
}
43+
Err(s.to_string())
44+
}
45+
}
46+
47+
pub type Column = egg::Symbol;

0 commit comments

Comments
 (0)