Skip to content

Commit

Permalink
feat: impl CreateView
Browse files Browse the repository at this point in the history
  • Loading branch information
KKould committed Nov 1, 2024
1 parent 8a2af1d commit a828a57
Show file tree
Hide file tree
Showing 14 changed files with 252 additions and 19 deletions.
62 changes: 62 additions & 0 deletions src/binder/create_view.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::binder::{lower_case_name, lower_ident, Binder};
use crate::catalog::view::View;
use crate::catalog::{ColumnCatalog, ColumnRef};
use crate::errors::DatabaseError;
use crate::expression::{AliasType, ScalarExpression};
use crate::planner::operator::create_view::CreateViewOperator;
use crate::planner::operator::Operator;
use crate::planner::LogicalPlan;
use crate::storage::Transaction;
use itertools::Itertools;
use sqlparser::ast::{Ident, ObjectName, Query};
use std::sync::Arc;
use ulid::Ulid;

impl<'a, 'b, T: Transaction> Binder<'a, 'b, T> {
pub(crate) fn bind_create_view(
&mut self,
or_replace: &bool,
name: &ObjectName,
columns: &[Ident],
query: &Query,
) -> Result<LogicalPlan, DatabaseError> {
let view_name = Arc::new(lower_case_name(name)?);
let mut plan = self.bind_query(query)?;

if !columns.is_empty() {
let mapping_schema = plan.output_schema();
let exprs = columns
.iter()
.enumerate()
.map(|(i, ident)| {
let mapping_column = &mapping_schema[i];
let mut column = ColumnCatalog::new(
lower_ident(ident),
mapping_column.nullable(),
mapping_column.desc().clone(),
);
column.set_ref_table(view_name.clone(), Ulid::new(), true);

ScalarExpression::Alias {
expr: Box::new(ScalarExpression::ColumnRef(mapping_column.clone())),
alias: AliasType::Expr(Box::new(ScalarExpression::ColumnRef(
ColumnRef::from(column),
))),
}
})
.collect_vec();
plan = self.bind_project(plan, exprs)?;
}

Ok(LogicalPlan::new(
Operator::CreateView(CreateViewOperator {
view: View {
name: view_name,
plan: Box::new(plan),
},
or_replace: *or_replace,
}),
vec![],
))
}
}
8 changes: 8 additions & 0 deletions src/binder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod analyze;
pub mod copy;
mod create_index;
mod create_table;
mod create_view;
mod delete;
mod describe;
mod distinct;
Expand Down Expand Up @@ -329,6 +330,13 @@ impl<'a, 'b, T: Transaction> Binder<'a, 'b, T> {
unique,
..
} => self.bind_create_index(table_name, name, columns, *if_not_exists, *unique)?,
Statement::CreateView {
or_replace,
name,
columns,
query,
..
} => self.bind_create_view(or_replace, name, columns, query)?,
_ => return Err(DatabaseError::UnsupportedStmt(stmt.to_string())),
};
Ok(plan)
Expand Down
15 changes: 13 additions & 2 deletions src/catalog/view.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
use crate::catalog::TableName;
use crate::planner::LogicalPlan;
use serde_macros::ReferenceSerialization;
use std::fmt;
use std::fmt::Formatter;

#[derive(Debug, Clone, Hash, Eq, PartialEq, ReferenceSerialization)]
pub struct View {
pub name: String,
pub plan: LogicalPlan,
pub name: TableName,
pub plan: Box<LogicalPlan>,
}

impl fmt::Display for View {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "View {}: {}", self.name, self.plan.explain(0))?;

Ok(())
}
}
5 changes: 2 additions & 3 deletions src/db.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::binder::{command_type, Binder, BinderContext, CommandType};
use crate::catalog::TableCatalog;
use crate::errors::DatabaseError;
use crate::execution::{build_write, try_collect};
use crate::expression::function::scala::ScalarFunctionImpl;
Expand Down Expand Up @@ -89,7 +88,7 @@ pub struct Database<S: Storage> {
table_functions: Arc<TableFunctions>,
mdl: Arc<RwLock<()>>,
pub(crate) meta_cache: Arc<StatisticsMetaCache>,
pub(crate) table_cache: Arc<ShardingLruCache<String, TableCatalog>>,
pub(crate) table_cache: Arc<TableCache>,
}

impl<S: Storage> Database<S> {
Expand Down Expand Up @@ -265,7 +264,7 @@ pub struct DBTransaction<'a, S: Storage + 'a> {
table_functions: Arc<TableFunctions>,
_guard: ArcRwLockReadGuard<RawRwLock, ()>,
pub(crate) meta_cache: Arc<StatisticsMetaCache>,
pub(crate) table_cache: Arc<ShardingLruCache<String, TableCatalog>>,
pub(crate) table_cache: Arc<TableCache>,
}

impl<S: Storage> DBTransaction<'_, S> {
Expand Down
4 changes: 4 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,8 @@ pub enum DatabaseError {
UnsupportedStmt(String),
#[error("values length not match, expect {0}, got {1}")]
ValuesLenMismatch(usize, usize),
#[error("the view already exists")]
ViewExists,
#[error("the view not found")]
ViewNotFound,
}
37 changes: 37 additions & 0 deletions src/execution/ddl/create_view.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::execution::{Executor, WriteExecutor};
use crate::planner::operator::create_view::CreateViewOperator;
use crate::storage::{StatisticsMetaCache, TableCache, Transaction, ViewCache};
use crate::throw;
use crate::types::tuple_builder::TupleBuilder;
use std::sync::Arc;

pub struct CreateView {
op: CreateViewOperator,
view_cache: Arc<ViewCache>,
}

impl From<(CreateViewOperator, Arc<ViewCache>)> for CreateView {
fn from((op, view_cache): (CreateViewOperator, Arc<ViewCache>)) -> Self {
CreateView { op, view_cache }
}
}

impl<'a, T: Transaction + 'a> WriteExecutor<'a, T> for CreateView {
fn execute_mut(
self,
_: (&'a TableCache, &'a StatisticsMetaCache),
transaction: &'a mut T,
) -> Executor<'a> {
Box::new(
#[coroutine]
move || {
let CreateViewOperator { view, or_replace } = self.op;

let result_tuple = TupleBuilder::build_result(format!("{}", view.name));
throw!(transaction.create_view(&self.view_cache, view, or_replace));

yield Ok(result_tuple);
},
)
}
}
1 change: 1 addition & 0 deletions src/execution/ddl/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod add_column;
pub(crate) mod create_index;
pub(crate) mod create_table;
pub(crate) mod create_view;
pub mod drop_column;
pub(crate) mod drop_table;
pub(crate) mod truncate;
1 change: 1 addition & 0 deletions src/optimizer/rule/normalization/column_pruning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ impl ColumnPruning {
// DDL Single Plan
Operator::CreateTable(_)
| Operator::CreateIndex(_)
| Operator::CreateView(_)
| Operator::DropTable(_)
| Operator::Truncate(_)
| Operator::Show
Expand Down
2 changes: 2 additions & 0 deletions src/optimizer/rule/normalization/compilation_in_advance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ impl ExpressionRemapper {
| Operator::DropColumn(_)
| Operator::CreateTable(_)
| Operator::CreateIndex(_)
| Operator::CreateView(_)
| Operator::DropTable(_)
| Operator::Truncate(_)
| Operator::CopyFromFile(_)
Expand Down Expand Up @@ -205,6 +206,7 @@ impl EvaluatorBind {
| Operator::DropColumn(_)
| Operator::CreateTable(_)
| Operator::CreateIndex(_)
| Operator::CreateView(_)
| Operator::DropTable(_)
| Operator::Truncate(_)
| Operator::CopyFromFile(_)
Expand Down
3 changes: 3 additions & 0 deletions src/planner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ impl LogicalPlan {
Operator::CreateIndex(_) => Arc::new(vec![ColumnRef::from(
ColumnCatalog::new_dummy("CREATE INDEX SUCCESS".to_string()),
)]),
Operator::CreateView(_) => Arc::new(vec![ColumnRef::from(
ColumnCatalog::new_dummy("CREATE VIEW SUCCESS".to_string()),
)]),
Operator::DropTable(_) => Arc::new(vec![ColumnRef::from(
ColumnCatalog::new_dummy("DROP TABLE SUCCESS".to_string()),
)]),
Expand Down
22 changes: 22 additions & 0 deletions src/planner/operator/create_view.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::catalog::view::View;
use serde_macros::ReferenceSerialization;
use std::fmt;
use std::fmt::Formatter;

#[derive(Debug, PartialEq, Eq, Clone, Hash, ReferenceSerialization)]
pub struct CreateViewOperator {
pub view: View,
pub or_replace: bool,
}

impl fmt::Display for CreateViewOperator {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"Create View as {}, Or Replace: {}",
self.view, self.or_replace
)?;

Ok(())
}
}
6 changes: 6 additions & 0 deletions src/planner/operator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod copy_from_file;
pub mod copy_to_file;
pub mod create_index;
pub mod create_table;
pub mod create_view;
pub mod delete;
pub mod describe;
pub mod drop_table;
Expand Down Expand Up @@ -34,6 +35,7 @@ use crate::planner::operator::copy_from_file::CopyFromFileOperator;
use crate::planner::operator::copy_to_file::CopyToFileOperator;
use crate::planner::operator::create_index::CreateIndexOperator;
use crate::planner::operator::create_table::CreateTableOperator;
use crate::planner::operator::create_view::CreateViewOperator;
use crate::planner::operator::delete::DeleteOperator;
use crate::planner::operator::describe::DescribeOperator;
use crate::planner::operator::drop_table::DropTableOperator;
Expand Down Expand Up @@ -77,6 +79,7 @@ pub enum Operator {
DropColumn(DropColumnOperator),
CreateTable(CreateTableOperator),
CreateIndex(CreateIndexOperator),
CreateView(CreateViewOperator),
DropTable(DropTableOperator),
Truncate(TruncateOperator),
// Copy
Expand Down Expand Up @@ -164,6 +167,7 @@ impl Operator {
| Operator::DropColumn(_)
| Operator::CreateTable(_)
| Operator::CreateIndex(_)
| Operator::CreateView(_)
| Operator::DropTable(_)
| Operator::Truncate(_)
| Operator::CopyFromFile(_)
Expand Down Expand Up @@ -240,6 +244,7 @@ impl Operator {
| Operator::DropColumn(_)
| Operator::CreateTable(_)
| Operator::CreateIndex(_)
| Operator::CreateView(_)
| Operator::DropTable(_)
| Operator::Truncate(_)
| Operator::CopyFromFile(_)
Expand Down Expand Up @@ -272,6 +277,7 @@ impl fmt::Display for Operator {
Operator::DropColumn(op) => write!(f, "{}", op),
Operator::CreateTable(op) => write!(f, "{}", op),
Operator::CreateIndex(op) => write!(f, "{}", op),
Operator::CreateView(op) => write!(f, "{}", op),
Operator::DropTable(op) => write!(f, "{}", op),
Operator::Truncate(op) => write!(f, "{}", op),
Operator::CopyFromFile(op) => write!(f, "{}", op),
Expand Down
Loading

0 comments on commit a828a57

Please sign in to comment.