Skip to content

Commit

Permalink
add enum-dispatched storage trait draft
Browse files Browse the repository at this point in the history
Signed-off-by: Yuchen Liang <yuchenl3@andrew.cmu.edu>
  • Loading branch information
yliang412 committed Jan 24, 2025
1 parent d13c731 commit e073616
Show file tree
Hide file tree
Showing 12 changed files with 522 additions and 64 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ diesel = { version = "2.2", features = [
"returning_clauses_for_sqlite_3_35",
"chrono",
] }
enum_dispatch = "0.3"
# Using a bundled version of sqlite3-sys to avoid build issues.
libsqlite3-sys = { version = "0.30", features = ["bundled"] }
dotenvy = "0.15"
Expand Down
1 change: 1 addition & 0 deletions optd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ chrono.workspace = true
diesel.workspace = true
diesel_migrations.workspace = true
dotenvy.workspace = true
enum_dispatch.workspace = true
libsqlite3-sys.workspace = true
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::env;

use diesel::prelude::*;
use dotenvy::dotenv;

use optd::storage::{
models::{
common::JoinType,
Expand All @@ -16,55 +15,8 @@ use optd::storage::{
StorageManager,
};

fn main() -> anyhow::Result<()> {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let mut storage = StorageManager::new(&database_url)?;
storage.migration_run()?;
{
use optd::storage::schema::logical_op_kinds::dsl::*;
let kinds = logical_op_kinds
.select(LogicalOpKind::as_select())
.load(&mut storage.conn)?;

println!("logical operator support (n={})", kinds.len());
for kind in kinds {
println!("+ {}", kind.name);
}
}

{
use optd::storage::schema::physical_op_kinds::dsl::*;
let descs = physical_op_kinds
.select(PhysicalOpKind::as_select())
.load(&mut storage.conn)?;

println!("physical operator support (n={})", descs.len());
for desc in descs {
println!("+ {}", desc.name);
}
}

{
use optd::storage::schema::physical_op_kinds::dsl::*;
let descs = physical_op_kinds
.select(PhysicalOpKind::as_select())
.load(&mut storage.conn)?;

println!("physical operator support (n={})", descs.len());
for desc in descs {
println!("+ {}", desc.name);
}
}

// CREATE TABLE t1(v1 INTEGER, v2 TEXT);
// CREATE TABLE t2(v1 INTEGER, v2 TEXT);
// SELECT * from t1 inner join t2 on t1.v1 = t2.v1 where t1.v2 = 'foo';
// - LogicalFilter (on: t1.v2 = 'foo')
// - LogicalJoin (inner, on t1.v1 = t2.v1)
// - LogicalScan (t1)
// - LogicalScan (t2)

#[allow(dead_code)]
pub fn demo(mut storage: StorageManager) -> anyhow::Result<()> {
let logical_scan_id = logical_op_kinds::table
.filter(logical_op_kinds::name.eq("LogicalScan"))
.select(logical_op_kinds::id)
Expand Down Expand Up @@ -278,6 +230,45 @@ fn main() -> anyhow::Result<()> {
// select l.id, l.group_id, l.created_at, desc.name
// from logical_exprs as l, logical_op_kinds as desc
// where l.logical_op_kind_id = desc.id;
Ok(())
}

fn main() -> anyhow::Result<()> {
// CREATE TABLE t1(v1 INTEGER, v2 TEXT);
// CREATE TABLE t2(v1 INTEGER, v2 TEXT);
// SELECT * from t1 inner join t2 on t1.v1 = t2.v1 where t1.v2 = 'foo';
// - LogicalFilter (on: t1.v2 = 'foo')
// - LogicalJoin (inner, on t1.v1 = t2.v1)
// - LogicalScan (t1)
// - LogicalScan (t2)
dotenv().ok();
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let mut storage = StorageManager::new(&database_url)?;
storage.migration_run()?;
{
use optd::storage::schema::logical_op_kinds::dsl::*;
let kinds = logical_op_kinds
.select(LogicalOpKind::as_select())
.load(&mut storage.conn)?;

println!("logical operator support (n={})", kinds.len());
for kind in kinds {
println!("+ {}", kind.name);
}
}

{
use optd::storage::schema::physical_op_kinds::dsl::*;
let descs = physical_op_kinds
.select(PhysicalOpKind::as_select())
.load(&mut storage.conn)?;

println!("physical operator support (n={})", descs.len());
for desc in descs {
println!("+ {}", desc.name);
}
}
// manual_demo(storage)?;
demo(storage)?;
Ok(())
}
163 changes: 163 additions & 0 deletions optd/src/bin/storage_demo_with_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
use diesel::prelude::*;

use dotenvy::dotenv;
use optd::storage::{
models::{
common::JoinType,
logical_expr::{LogicalExpr, LogicalExprStorage},
logical_operators::{LogicalFilter, LogicalJoin, LogicalOpKind, LogicalScan},
physical_operators::PhysicalOpKind,
},
StorageManager,
};

fn demo(mut storage: StorageManager) -> anyhow::Result<()> {
let scan1 = LogicalExpr::Scan(LogicalScan {
table_name: "t1".to_string(),
});

let scan2 = LogicalExpr::Scan(LogicalScan {
table_name: "t2".to_string(),
});

let (scan_1_expr_id, scan_1_group) = storage.add_logical_expr(scan1);
let (scan_2_expr_id, scan_2_group) = storage.add_logical_expr(scan2);

let join = LogicalExpr::Join(LogicalJoin {
join_type: JoinType::Inner,
left: scan_1_group,
right: scan_2_group,
join_cond: "t1.v1 = t2.v1".to_string(),
});

let join_alt = LogicalExpr::Join(LogicalJoin {
join_type: JoinType::Inner,
left: scan_2_group,
right: scan_1_group,
join_cond: "t1.v1 = t2.v1".to_string(),
});

let (join_expr_id, join_group) = storage.add_logical_expr(join);

let join_alt_expr_id = storage.add_logical_expr_to_group(join_alt, join_group);

let filter = LogicalExpr::Filter(LogicalFilter {
child: join_group,
predicate: "t1.v2 = 'foo'".to_string(),
});

let (filter_expr_id, filter_group) = storage.add_logical_expr(filter);

let exprs = storage.get_all_logical_exprs_in_group(filter_group);
assert_eq!(exprs[0].id, filter_expr_id);
assert_eq!(
exprs[0].inner.get_identifiers(&mut storage),
Some((filter_expr_id, filter_group))
);
let child_group = match &exprs[0].inner {
LogicalExpr::Filter(filter) => {
println!("filter: {:?}", filter);
filter.child
}
_ => unreachable!(),
};

let exprs = storage.get_all_logical_exprs_in_group(child_group);
assert_eq!(
exprs[0].inner.get_identifiers(&mut storage),
Some((join_expr_id, join_group))
);
assert_eq!(
exprs[1].inner.get_identifiers(&mut storage),
Some((join_alt_expr_id, join_group))
);

let (left_group, right_group) = match &exprs[0].inner {
LogicalExpr::Join(join) => {
println!("join: {:?}", join);
(join.left, join.right)
}
_ => unreachable!(),
};

let (left_group_alt, right_group_alt) = match &exprs[1].inner {
LogicalExpr::Join(join) => {
println!("join: {:?}", join);
(join.left, join.right)
}
_ => unreachable!(),
};

assert_eq!(left_group, right_group_alt);
assert_eq!(right_group, left_group_alt);

let exprs = storage.get_all_logical_exprs_in_group(left_group);
assert_eq!(exprs[0].id, scan_1_expr_id);
assert_eq!(
exprs[0].inner.get_identifiers(&mut storage),
Some((scan_1_expr_id, scan_1_group))
);
match &exprs[0].inner {
LogicalExpr::Scan(scan) => {
println!("scan: {:?}", scan);
}
_ => unreachable!(),
}

let exprs = storage.get_all_logical_exprs_in_group(right_group);
assert_eq!(exprs[0].id, scan_2_expr_id);
assert_eq!(
exprs[0].inner.get_identifiers(&mut storage),
Some((scan_2_expr_id, scan_2_group))
);
match &exprs[0].inner {
LogicalExpr::Scan(scan) => {
println!("scan: {:?}", scan);
}
_ => unreachable!(),
}

assert_eq!(child_group, join_group);

Ok(())
}

fn main() -> anyhow::Result<()> {
// CREATE TABLE t1(v1 INTEGER, v2 TEXT);
// CREATE TABLE t2(v1 INTEGER, v2 TEXT);
// SELECT * from t1 inner join t2 on t1.v1 = t2.v1 where t1.v2 = 'foo';
// - LogicalFilter (on: t1.v2 = 'foo')
// - LogicalJoin (inner, on t1.v1 = t2.v1)
// - LogicalScan (t1)
// - LogicalScan (t2)
dotenv().ok();
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let mut storage = StorageManager::new(&database_url)?;
storage.migration_run()?;
{
use optd::storage::schema::logical_op_kinds::dsl::*;
let kinds = logical_op_kinds
.select(LogicalOpKind::as_select())
.load(&mut storage.conn)?;

println!("logical operator support (n={})", kinds.len());
for kind in kinds {
println!("+ {}", kind.name);
}
}

{
use optd::storage::schema::physical_op_kinds::dsl::*;
let descs = physical_op_kinds
.select(PhysicalOpKind::as_select())
.load(&mut storage.conn)?;

println!("physical operator support (n={})", descs.len());
for desc in descs {
println!("+ {}", desc.name);
}
}
// manual_demo(storage)?;
demo(storage)?;
Ok(())
}
Loading

0 comments on commit e073616

Please sign in to comment.