Skip to content

Commit

Permalink
feat: add docs 01-03 (#19)
Browse files Browse the repository at this point in the history
* simplify executor for 01-03 to 01-05

Signed-off-by: Runji Wang <[email protected]>

* 01-03: refine docs

Signed-off-by: Runji Wang <[email protected]>

Signed-off-by: Runji Wang <[email protected]>
  • Loading branch information
wangrunji0408 authored Sep 19, 2022
1 parent 17bbac1 commit 394cca8
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 246 deletions.
12 changes: 4 additions & 8 deletions code/01-03/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ use std::sync::Arc;

use crate::binder::{BindError, Binder};
use crate::catalog::{CatalogRef, DatabaseCatalog};
use crate::executor::{ExecuteError, ExecutorBuilder};
use crate::executor::{ExecuteError, Executor};
use crate::parser::{parse, ParserError};

/// The database instance.
pub struct Database {
catalog: CatalogRef,
executor_builder: ExecutorBuilder,
}

impl Default for Database {
Expand All @@ -23,24 +22,21 @@ impl Database {
/// Create a new database instance.
pub fn new() -> Self {
let catalog = Arc::new(DatabaseCatalog::new());
Database {
catalog: catalog.clone(),
executor_builder: ExecutorBuilder::new(catalog),
}
Database { catalog }
}

/// Run SQL queries and return the outputs.
pub fn run(&self, sql: &str) -> Result<Vec<String>, Error> {
// parse
let stmts = parse(sql)?;
let mut binder = Binder::new(self.catalog.clone());
let executor = Executor::new(self.catalog.clone());

let mut outputs = vec![];
for stmt in stmts {
let bound_stmt = binder.bind(&stmt)?;
debug!("{:#?}", bound_stmt);
let mut executor = self.executor_builder.build(bound_stmt);
let output = executor.execute()?;
let output = executor.execute(bound_stmt)?;
outputs.push(output);
}
Ok(outputs)
Expand Down
16 changes: 5 additions & 11 deletions code/01-03/src/executor/create.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
use super::*;
use crate::binder::BoundCreateTable;

/// The executor of `CREATE TABLE` statement.
pub struct CreateTableExecutor {
pub stmt: BoundCreateTable,
pub catalog: CatalogRef,
}

impl Executor for CreateTableExecutor {
fn execute(&mut self) -> Result<String, ExecuteError> {
let schema = self.catalog.get_schema(self.stmt.schema_id).unwrap();
let table_id = schema.add_table(&self.stmt.table_name).unwrap();
impl Executor {
pub fn execute_create_table(&self, stmt: BoundCreateTable) -> Result<String, ExecuteError> {
let schema = self.catalog.get_schema(stmt.schema_id).unwrap();
let table_id = schema.add_table(&stmt.table_name).unwrap();
let table = schema.get_table(table_id).unwrap();
for (name, desc) in &self.stmt.columns {
for (name, desc) in &stmt.columns {
table.add_column(name, desc.clone()).unwrap();
}
Ok(String::new())
Expand Down
33 changes: 10 additions & 23 deletions code/01-03/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,26 @@ use crate::catalog::CatalogRef;
mod create;
mod select;

use self::create::*;
use self::select::*;

/// The error type of execution.
#[derive(thiserror::Error, Debug)]
pub enum ExecuteError {}

pub trait Executor {
fn execute(&mut self) -> Result<String, ExecuteError>;
}

/// A type-erased executor object.
pub type BoxedExecutor = Box<dyn Executor>;

/// The builder of executor.
pub struct ExecutorBuilder {
/// Execute the bound AST.
pub struct Executor {
catalog: CatalogRef,
}

impl ExecutorBuilder {
/// Create a new executor builder.
pub fn new(catalog: CatalogRef) -> ExecutorBuilder {
ExecutorBuilder { catalog }
impl Executor {
/// Create a new executor.
pub fn new(catalog: CatalogRef) -> Executor {
Executor { catalog }
}

/// Build executor from a [BoundStatement].
pub fn build(&self, stmt: BoundStatement) -> BoxedExecutor {
/// Execute a bound statement.
pub fn execute(&self, stmt: BoundStatement) -> Result<String, ExecuteError> {
match stmt {
BoundStatement::CreateTable(stmt) => Box::new(CreateTableExecutor {
stmt,
catalog: self.catalog.clone(),
}),
BoundStatement::Select(stmt) => Box::new(SelectExecutor { stmt }),
BoundStatement::CreateTable(stmt) => self.execute_create_table(stmt),
BoundStatement::Select(stmt) => self.execute_select(stmt),
}
}
}
11 changes: 3 additions & 8 deletions code/01-03/src/executor/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@ use super::*;
use crate::binder::BoundSelect;
use crate::parser::Value;

/// The executor of `SELECT` statement.
pub struct SelectExecutor {
pub stmt: BoundSelect,
}

impl Executor for SelectExecutor {
fn execute(&mut self) -> Result<String, ExecuteError> {
impl Executor {
pub fn execute_select(&self, stmt: BoundSelect) -> Result<String, ExecuteError> {
let mut output = String::new();
for v in &self.stmt.values {
for v in &stmt.values {
output += " ";
match v {
Value::SingleQuotedString(s) => output += s,
Expand Down
15 changes: 6 additions & 9 deletions code/01-04/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use std::sync::Arc;
use crate::array::DataChunk;
use crate::binder::{BindError, Binder};
use crate::catalog::{CatalogRef, DatabaseCatalog};
use crate::executor::{ExecuteError, ExecutorBuilder};
use crate::executor::{ExecuteError, Executor};
use crate::parser::{parse, ParserError};
use crate::storage::InMemoryStorage;
use crate::storage::{InMemoryStorage, StorageRef};

/// The database instance.
pub struct Database {
catalog: CatalogRef,
executor_builder: ExecutorBuilder,
storage: StorageRef,
}

impl Default for Database {
Expand All @@ -26,24 +26,21 @@ impl Database {
pub fn new() -> Self {
let catalog = Arc::new(DatabaseCatalog::new());
let storage = Arc::new(InMemoryStorage::new());
Database {
catalog: catalog.clone(),
executor_builder: ExecutorBuilder::new(catalog, storage),
}
Database { catalog, storage }
}

/// Run SQL queries and return the outputs.
pub fn run(&self, sql: &str) -> Result<Vec<DataChunk>, Error> {
// parse
let stmts = parse(sql)?;
let mut binder = Binder::new(self.catalog.clone());
let executor = Executor::new(self.catalog.clone(), self.storage.clone());

let mut outputs = vec![];
for stmt in stmts {
let bound_stmt = binder.bind(&stmt)?;
debug!("{:#?}", bound_stmt);
let mut executor = self.executor_builder.build(bound_stmt);
let output = executor.execute()?;
let output = executor.execute(bound_stmt)?;
outputs.push(output);
}
Ok(outputs)
Expand Down
20 changes: 6 additions & 14 deletions code/01-04/src/executor/create.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
use super::*;
use crate::binder::BoundCreateTable;
use crate::catalog::TableRefId;
use crate::storage::StorageRef;

/// The executor of `CREATE TABLE` statement.
pub struct CreateTableExecutor {
pub stmt: BoundCreateTable,
pub catalog: CatalogRef,
pub storage: StorageRef,
}

impl Executor for CreateTableExecutor {
fn execute(&mut self) -> Result<DataChunk, ExecuteError> {
let schema = self.catalog.get_schema(self.stmt.schema_id).unwrap();
let table_id = schema.add_table(&self.stmt.table_name).unwrap();
impl Executor {
pub fn execute_create_table(&self, stmt: BoundCreateTable) -> Result<DataChunk, ExecuteError> {
let schema = self.catalog.get_schema(stmt.schema_id).unwrap();
let table_id = schema.add_table(&stmt.table_name).unwrap();
let table = schema.get_table(table_id).unwrap();
for (name, desc) in &self.stmt.columns {
for (name, desc) in &stmt.columns {
table.add_column(name, desc.clone()).unwrap();
}
self.storage
.add_table(TableRefId::new(self.stmt.schema_id, table_id))?;
.add_table(TableRefId::new(stmt.schema_id, table_id))?;
Ok(DataChunk::single(1))
}
}
34 changes: 10 additions & 24 deletions code/01-04/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,30 @@ use crate::storage::{StorageError, StorageRef};
mod create;
mod select;

use self::create::*;
use self::select::*;

/// The error type of execution.
#[derive(thiserror::Error, Debug)]
pub enum ExecuteError {
#[error("storage error: {0}")]
Storage(#[from] StorageError),
}

pub trait Executor {
fn execute(&mut self) -> Result<DataChunk, ExecuteError>;
}

/// A type-erased executor object.
pub type BoxedExecutor = Box<dyn Executor>;

/// The builder of executor.
pub struct ExecutorBuilder {
/// Execute the bound AST.
pub struct Executor {
catalog: CatalogRef,
storage: StorageRef,
}

impl ExecutorBuilder {
/// Create a new executor builder.
pub fn new(catalog: CatalogRef, storage: StorageRef) -> ExecutorBuilder {
ExecutorBuilder { catalog, storage }
impl Executor {
/// Create a new executor.
pub fn new(catalog: CatalogRef, storage: StorageRef) -> Executor {
Executor { catalog, storage }
}

/// Build executor from a [BoundStatement].
pub fn build(&self, stmt: BoundStatement) -> BoxedExecutor {
/// Execute a bound statement.
pub fn execute(&self, stmt: BoundStatement) -> Result<DataChunk, ExecuteError> {
match stmt {
BoundStatement::CreateTable(stmt) => Box::new(CreateTableExecutor {
stmt,
catalog: self.catalog.clone(),
storage: self.storage.clone(),
}),
BoundStatement::Select(stmt) => Box::new(SelectExecutor { stmt }),
BoundStatement::CreateTable(stmt) => self.execute_create_table(stmt),
BoundStatement::Select(stmt) => self.execute_select(stmt),
}
}
}
11 changes: 3 additions & 8 deletions code/01-04/src/executor/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@ use super::*;
use crate::array::ArrayImpl;
use crate::binder::BoundSelect;

/// The executor of `SELECT` statement.
pub struct SelectExecutor {
pub stmt: BoundSelect,
}

impl Executor for SelectExecutor {
fn execute(&mut self) -> Result<DataChunk, ExecuteError> {
let chunk = self.stmt.values.iter().map(ArrayImpl::from).collect();
impl Executor {
pub fn execute_select(&self, stmt: BoundSelect) -> Result<DataChunk, ExecuteError> {
let chunk = stmt.values.iter().map(ArrayImpl::from).collect();
Ok(chunk)
}
}
15 changes: 6 additions & 9 deletions code/01-05/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use std::sync::Arc;
use crate::array::DataChunk;
use crate::binder::{BindError, Binder};
use crate::catalog::{CatalogRef, DatabaseCatalog};
use crate::executor::{ExecuteError, ExecutorBuilder};
use crate::executor::{ExecuteError, Executor};
use crate::parser::{parse, ParserError};
use crate::storage::InMemoryStorage;
use crate::storage::{InMemoryStorage, StorageRef};

/// The database instance.
pub struct Database {
catalog: CatalogRef,
executor_builder: ExecutorBuilder,
storage: StorageRef,
}

impl Default for Database {
Expand All @@ -26,24 +26,21 @@ impl Database {
pub fn new() -> Self {
let catalog = Arc::new(DatabaseCatalog::new());
let storage = Arc::new(InMemoryStorage::new());
Database {
catalog: catalog.clone(),
executor_builder: ExecutorBuilder::new(catalog, storage),
}
Database { catalog, storage }
}

/// Run SQL queries and return the outputs.
pub fn run(&self, sql: &str) -> Result<Vec<DataChunk>, Error> {
// parse
let stmts = parse(sql)?;
let mut binder = Binder::new(self.catalog.clone());
let executor = Executor::new(self.catalog.clone(), self.storage.clone());

let mut outputs = vec![];
for stmt in stmts {
let bound_stmt = binder.bind(&stmt)?;
debug!("{:#?}", bound_stmt);
let mut executor = self.executor_builder.build(bound_stmt);
let output = executor.execute()?;
let output = executor.execute(bound_stmt)?;
outputs.push(output);
}
Ok(outputs)
Expand Down
20 changes: 6 additions & 14 deletions code/01-05/src/executor/create.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
use super::*;
use crate::binder::BoundCreateTable;
use crate::catalog::TableRefId;
use crate::storage::StorageRef;

/// The executor of `CREATE TABLE` statement.
pub struct CreateTableExecutor {
pub stmt: BoundCreateTable,
pub catalog: CatalogRef,
pub storage: StorageRef,
}

impl Executor for CreateTableExecutor {
fn execute(&mut self) -> Result<DataChunk, ExecuteError> {
let schema = self.catalog.get_schema(self.stmt.schema_id).unwrap();
let table_id = schema.add_table(&self.stmt.table_name).unwrap();
impl Executor {
pub fn execute_create_table(&self, stmt: BoundCreateTable) -> Result<DataChunk, ExecuteError> {
let schema = self.catalog.get_schema(stmt.schema_id).unwrap();
let table_id = schema.add_table(&stmt.table_name).unwrap();
let table = schema.get_table(table_id).unwrap();
for (name, desc) in &self.stmt.columns {
for (name, desc) in &stmt.columns {
table.add_column(name, desc.clone()).unwrap();
}
self.storage
.add_table(TableRefId::new(self.stmt.schema_id, table_id))?;
.add_table(TableRefId::new(stmt.schema_id, table_id))?;
Ok(DataChunk::single(1))
}
}
Loading

0 comments on commit 394cca8

Please sign in to comment.