Skip to content

Commit

Permalink
Refactor 2 part
Browse files Browse the repository at this point in the history
  • Loading branch information
PakhomovAlexander committed Dec 13, 2024
1 parent 32ce0f5 commit 6489a0a
Show file tree
Hide file tree
Showing 14 changed files with 1,353 additions and 1,319 deletions.
454 changes: 454 additions & 0 deletions db/src/analyzer/analyzer.rs

Large diffs are not rendered by default.

582 changes: 4 additions & 578 deletions db/src/analyzer/mod.rs

Large diffs are not rendered by default.

127 changes: 127 additions & 0 deletions db/src/analyzer/tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use std::fmt::Display;

use crate::types::ColType;

//#[allow(clippy::unused)]
#[allow(dead_code)]
#[derive(Debug, PartialEq, Clone)]
pub enum Operator {
Projec(ProjectInfo),
Filter(FilterInfo),
Read(ReadInfo),
Join(JoinInfo),
Group(GroupInfo),
Sort(SortInfo),
Limit(LimitInfo),
Distinct(DistinctInfo),

Add(InfixOpInfo),
Sub(InfixOpInfo),
Mul(InfixOpInfo),
Div(InfixOpInfo),
Eq(InfixOpInfo),
Neq(InfixOpInfo),
Lt(InfixOpInfo),
Lte(InfixOpInfo),
Gt(InfixOpInfo),
Gte(InfixOpInfo),
And(InfixOpInfo),
Or(InfixOpInfo),
Not,
In,
Like,
IsNull,
IsNotNull,
Exists,
NotExists,
Between,
Case,
Cast,

Const(Constant),
Col(Column),

CreateTable(CreateTableInfo),
}

#[derive(Debug, PartialEq, Clone)]
pub struct ProjectInfo {
pub columns: Vec<Column>,
}

#[derive(Debug, PartialEq, Clone)]
pub struct Column {
pub column_name: String,
}

#[derive(Debug, PartialEq, Clone)]
pub struct ColumnDefinition {
pub column_name: String,
pub column_type: ColType,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Constant {
Num(i32),
Str(String),
}

#[derive(Debug, PartialEq, Clone)]
pub struct Table {
pub table_name: String,
}

#[derive(Debug, PartialEq, Clone)]
pub struct FilterInfo {
pub node: Box<LogicalNode>,
}

#[derive(Debug, PartialEq, Clone)]
pub struct InfixOpInfo {
pub left: Box<LogicalNode>,
pub right: Box<LogicalNode>,
}

#[derive(Debug, PartialEq, Clone)]
pub struct ReadInfo {
pub table: Table,
}

#[derive(Debug, PartialEq, Clone)]
pub struct JoinInfo {}

#[derive(Debug, PartialEq, Clone)]
pub struct GroupInfo {}

#[derive(Debug, PartialEq, Clone)]
pub struct SortInfo {}

#[derive(Debug, PartialEq, Clone)]
pub struct LimitInfo {}

#[derive(Debug, PartialEq, Clone)]
pub struct DistinctInfo {}

#[derive(Debug, PartialEq, Clone)]
pub struct CreateTableInfo {
pub table_name: String,
pub columns: Vec<ColumnDefinition>,
}

#[derive(Debug, PartialEq, Clone)]
pub struct LogicalNode {
pub op: Operator,
pub children: Vec<LogicalNode>,
}

#[derive(Debug, PartialEq, Clone)]
pub struct LogicalPlan {
pub root: LogicalNode,
}

impl Display for LogicalPlan {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let _ = f.write_str("NOT IMPLEMENTED YET");
Ok(())
}
}
238 changes: 238 additions & 0 deletions db/src/catalog/catalog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
use std::collections::HashMap;

use super::types::{ColumnId, ColumnSchema, DataType, TableId, TableSchema};

pub struct Catalog {
store: MemoryCatalogStore,
}

impl Catalog {
pub fn mem() -> Catalog {
Catalog {
store: MemoryCatalogStore::new(),
}
}

pub fn register_table(&mut self, table: &TableSchema) -> Result<(), ()> {
self.store.put(table)?;
Ok(())
}

pub fn get_table(&self, table_id: &TableId) -> Option<TableSchema> {
self.store.get(table_id)
}

pub fn drop_table(&mut self, table_id: &TableId) -> Result<(), ()> {
self.store.delete(table_id)?;
Ok(())
}
}

trait CatalogStore {
fn get(&self, id: &TableId) -> Option<TableSchema>;

fn put(&mut self, table: &TableSchema) -> Result<(), ()>;

fn delete(&mut self, id: &TableId) -> Result<(), ()>;
}

#[derive(Clone)]
struct MemoryCatalogStore {
tables: HashMap<TableId, TableSchema>,
}

impl MemoryCatalogStore {
fn new() -> MemoryCatalogStore {
MemoryCatalogStore {
tables: HashMap::new(),
}
}
}

impl CatalogStore for MemoryCatalogStore {
fn get(&self, id: &TableId) -> Option<TableSchema> {
self.tables.get(id).cloned()
}

fn put(&mut self, table: &TableSchema) -> Result<(), ()> {
if self.tables.contains_key(&table.id) {
return Err(());
}

self.tables.insert(table.id.clone(), table.clone());
Ok(())
}

fn delete(&mut self, id: &TableId) -> Result<(), ()> {
match self.tables.remove(id) {
None => Err(()),
Some(_) => Ok(()),
}
}
}

pub struct TableSchemaBuilder {
schema_name: String,
id: Option<TableId>,
columns: Vec<ColumnSchema>,
}

impl TableSchemaBuilder {
pub fn public() -> TableSchemaBuilder {
TableSchemaBuilder {
schema_name: "public".to_string(),
id: None,
columns: Vec::new(),
}
}

pub fn table(&mut self, table_name: &str) -> &mut Self {
self.id = Some(TableId::new(&self.schema_name, table_name));
self
}

pub fn col(&mut self, col_name: &str, data_type: DataType) -> &mut Self {
self.columns.push(ColumnSchema::new(
&ColumnId::new(self.id.as_ref().unwrap(), col_name),
data_type,
));

self
}

pub fn build(&self) -> TableSchema {
TableSchema::new(self.id.as_ref().unwrap(), self.columns.clone())
}
}

#[cfg(test)]
mod tests {
use crate::catalog::types::DataType;

use super::*;

fn samle_schema() -> TableSchema {
TableSchema::new(
&TableId::public("table1"),
vec![
ColumnSchema::new(
&ColumnId::new(&TableId::public("table1"), "col1"),
DataType::Int,
),
ColumnSchema::new(
&ColumnId::new(&TableId::public("table1"), "col2"),
DataType::String,
),
],
)
}

#[test]
fn register_table() {
let mut catalog = Catalog::mem();

let table = samle_schema();

let register_result = catalog.register_table(&table);
assert_eq!(register_result, Ok(()));

assert_eq!(catalog.get_table(&table.id), Some(table));
}

#[test]
fn drop_table() {
let mut catalog = Catalog::mem();

let table = samle_schema();
let register_result = catalog.register_table(&table);
assert_eq!(register_result, Ok(()));

let drop_result = catalog.drop_table(&table.id);
assert_eq!(drop_result, Ok(()));

assert_eq!(catalog.get_table(&table.id), None);
}

#[test]
fn register_twice() {
let mut catalog = Catalog::mem();

let table = samle_schema();
let register_result = catalog.register_table(&table);
assert_eq!(register_result, Ok(()));

let register_result = catalog.register_table(&table);
assert_eq!(register_result, Err(()));
}

#[test]
fn drop_twice() {
let mut catalog = Catalog::mem();

let table = samle_schema();
let register_result = catalog.register_table(&table);
assert_eq!(register_result, Ok(()));

let drop_result = catalog.drop_table(&table.id);
assert_eq!(drop_result, Ok(()));

let drop_result = catalog.drop_table(&table.id);
assert_eq!(drop_result, Err(()));
}

#[test]
fn table_id() {
let table_id = TableId::new("schema1", "table1");
assert_eq!(table_id.get_table_name(), "table1");
assert_eq!(table_id.get_schema_name(), "schema1");
assert_eq!(table_id.to_fqn(), "schema1.table1");

let table_id = TableId::public("table1");
assert_eq!(table_id.get_table_name(), "table1");
assert_eq!(table_id.get_schema_name(), "public");
assert_eq!(table_id.to_fqn(), "public.table1");

let table_id = TableId::from_fqn("schema1.table1");
assert_eq!(table_id.get_table_name(), "table1");
assert_eq!(table_id.get_schema_name(), "schema1");
}

#[test]
fn column_id() {
let table_id = TableId::public("table1");
let column_id = ColumnId::new(&table_id, "col1");
assert_eq!(column_id.get_column_name(), "col1");
assert_eq!(column_id.get_table_id(), table_id);
assert_eq!(column_id.to_fqn(), "public.table1.col1");

let column_id = ColumnId::from_fqn("public.table1.col1");
assert_eq!(column_id.get_column_name(), "col1");
assert_eq!(column_id.get_table_id(), table_id);
}

#[test]
fn builder() {
let table = TableSchemaBuilder::public()
.table("table1")
.col("col1", DataType::Int)
.col("col2", DataType::String)
.build();

assert_eq!(
table,
TableSchema::new(
&TableId::public("table1"),
vec![
ColumnSchema::new(
&ColumnId::new(&TableId::public("table1"), "col1"),
DataType::Int,
),
ColumnSchema::new(
&ColumnId::new(&TableId::public("table1"), "col2"),
DataType::String,
),
],
)
);
}
}
Loading

0 comments on commit 6489a0a

Please sign in to comment.