Skip to content

Commit a828a57

Browse files
committed
feat: impl CreateView
1 parent 8a2af1d commit a828a57

File tree

14 files changed

+252
-19
lines changed

14 files changed

+252
-19
lines changed

src/binder/create_view.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use crate::binder::{lower_case_name, lower_ident, Binder};
2+
use crate::catalog::view::View;
3+
use crate::catalog::{ColumnCatalog, ColumnRef};
4+
use crate::errors::DatabaseError;
5+
use crate::expression::{AliasType, ScalarExpression};
6+
use crate::planner::operator::create_view::CreateViewOperator;
7+
use crate::planner::operator::Operator;
8+
use crate::planner::LogicalPlan;
9+
use crate::storage::Transaction;
10+
use itertools::Itertools;
11+
use sqlparser::ast::{Ident, ObjectName, Query};
12+
use std::sync::Arc;
13+
use ulid::Ulid;
14+
15+
impl<'a, 'b, T: Transaction> Binder<'a, 'b, T> {
16+
pub(crate) fn bind_create_view(
17+
&mut self,
18+
or_replace: &bool,
19+
name: &ObjectName,
20+
columns: &[Ident],
21+
query: &Query,
22+
) -> Result<LogicalPlan, DatabaseError> {
23+
let view_name = Arc::new(lower_case_name(name)?);
24+
let mut plan = self.bind_query(query)?;
25+
26+
if !columns.is_empty() {
27+
let mapping_schema = plan.output_schema();
28+
let exprs = columns
29+
.iter()
30+
.enumerate()
31+
.map(|(i, ident)| {
32+
let mapping_column = &mapping_schema[i];
33+
let mut column = ColumnCatalog::new(
34+
lower_ident(ident),
35+
mapping_column.nullable(),
36+
mapping_column.desc().clone(),
37+
);
38+
column.set_ref_table(view_name.clone(), Ulid::new(), true);
39+
40+
ScalarExpression::Alias {
41+
expr: Box::new(ScalarExpression::ColumnRef(mapping_column.clone())),
42+
alias: AliasType::Expr(Box::new(ScalarExpression::ColumnRef(
43+
ColumnRef::from(column),
44+
))),
45+
}
46+
})
47+
.collect_vec();
48+
plan = self.bind_project(plan, exprs)?;
49+
}
50+
51+
Ok(LogicalPlan::new(
52+
Operator::CreateView(CreateViewOperator {
53+
view: View {
54+
name: view_name,
55+
plan: Box::new(plan),
56+
},
57+
or_replace: *or_replace,
58+
}),
59+
vec![],
60+
))
61+
}
62+
}

src/binder/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod analyze;
44
pub mod copy;
55
mod create_index;
66
mod create_table;
7+
mod create_view;
78
mod delete;
89
mod describe;
910
mod distinct;
@@ -329,6 +330,13 @@ impl<'a, 'b, T: Transaction> Binder<'a, 'b, T> {
329330
unique,
330331
..
331332
} => self.bind_create_index(table_name, name, columns, *if_not_exists, *unique)?,
333+
Statement::CreateView {
334+
or_replace,
335+
name,
336+
columns,
337+
query,
338+
..
339+
} => self.bind_create_view(or_replace, name, columns, query)?,
332340
_ => return Err(DatabaseError::UnsupportedStmt(stmt.to_string())),
333341
};
334342
Ok(plan)

src/catalog/view.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
use crate::catalog::TableName;
12
use crate::planner::LogicalPlan;
23
use serde_macros::ReferenceSerialization;
4+
use std::fmt;
5+
use std::fmt::Formatter;
36

47
#[derive(Debug, Clone, Hash, Eq, PartialEq, ReferenceSerialization)]
58
pub struct View {
6-
pub name: String,
7-
pub plan: LogicalPlan,
9+
pub name: TableName,
10+
pub plan: Box<LogicalPlan>,
11+
}
12+
13+
impl fmt::Display for View {
14+
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
15+
write!(f, "View {}: {}", self.name, self.plan.explain(0))?;
16+
17+
Ok(())
18+
}
819
}

src/db.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::binder::{command_type, Binder, BinderContext, CommandType};
2-
use crate::catalog::TableCatalog;
32
use crate::errors::DatabaseError;
43
use crate::execution::{build_write, try_collect};
54
use crate::expression::function::scala::ScalarFunctionImpl;
@@ -89,7 +88,7 @@ pub struct Database<S: Storage> {
8988
table_functions: Arc<TableFunctions>,
9089
mdl: Arc<RwLock<()>>,
9190
pub(crate) meta_cache: Arc<StatisticsMetaCache>,
92-
pub(crate) table_cache: Arc<ShardingLruCache<String, TableCatalog>>,
91+
pub(crate) table_cache: Arc<TableCache>,
9392
}
9493

9594
impl<S: Storage> Database<S> {
@@ -265,7 +264,7 @@ pub struct DBTransaction<'a, S: Storage + 'a> {
265264
table_functions: Arc<TableFunctions>,
266265
_guard: ArcRwLockReadGuard<RawRwLock, ()>,
267266
pub(crate) meta_cache: Arc<StatisticsMetaCache>,
268-
pub(crate) table_cache: Arc<ShardingLruCache<String, TableCatalog>>,
267+
pub(crate) table_cache: Arc<TableCache>,
269268
}
270269

271270
impl<S: Storage> DBTransaction<'_, S> {

src/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,8 @@ pub enum DatabaseError {
150150
UnsupportedStmt(String),
151151
#[error("values length not match, expect {0}, got {1}")]
152152
ValuesLenMismatch(usize, usize),
153+
#[error("the view already exists")]
154+
ViewExists,
155+
#[error("the view not found")]
156+
ViewNotFound,
153157
}

src/execution/ddl/create_view.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::execution::{Executor, WriteExecutor};
2+
use crate::planner::operator::create_view::CreateViewOperator;
3+
use crate::storage::{StatisticsMetaCache, TableCache, Transaction, ViewCache};
4+
use crate::throw;
5+
use crate::types::tuple_builder::TupleBuilder;
6+
use std::sync::Arc;
7+
8+
pub struct CreateView {
9+
op: CreateViewOperator,
10+
view_cache: Arc<ViewCache>,
11+
}
12+
13+
impl From<(CreateViewOperator, Arc<ViewCache>)> for CreateView {
14+
fn from((op, view_cache): (CreateViewOperator, Arc<ViewCache>)) -> Self {
15+
CreateView { op, view_cache }
16+
}
17+
}
18+
19+
impl<'a, T: Transaction + 'a> WriteExecutor<'a, T> for CreateView {
20+
fn execute_mut(
21+
self,
22+
_: (&'a TableCache, &'a StatisticsMetaCache),
23+
transaction: &'a mut T,
24+
) -> Executor<'a> {
25+
Box::new(
26+
#[coroutine]
27+
move || {
28+
let CreateViewOperator { view, or_replace } = self.op;
29+
30+
let result_tuple = TupleBuilder::build_result(format!("{}", view.name));
31+
throw!(transaction.create_view(&self.view_cache, view, or_replace));
32+
33+
yield Ok(result_tuple);
34+
},
35+
)
36+
}
37+
}

src/execution/ddl/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod add_column;
22
pub(crate) mod create_index;
33
pub(crate) mod create_table;
4+
pub(crate) mod create_view;
45
pub mod drop_column;
56
pub(crate) mod drop_table;
67
pub(crate) mod truncate;

src/optimizer/rule/normalization/column_pruning.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ impl ColumnPruning {
150150
// DDL Single Plan
151151
Operator::CreateTable(_)
152152
| Operator::CreateIndex(_)
153+
| Operator::CreateView(_)
153154
| Operator::DropTable(_)
154155
| Operator::Truncate(_)
155156
| Operator::Show

src/optimizer/rule/normalization/compilation_in_advance.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ impl ExpressionRemapper {
104104
| Operator::DropColumn(_)
105105
| Operator::CreateTable(_)
106106
| Operator::CreateIndex(_)
107+
| Operator::CreateView(_)
107108
| Operator::DropTable(_)
108109
| Operator::Truncate(_)
109110
| Operator::CopyFromFile(_)
@@ -205,6 +206,7 @@ impl EvaluatorBind {
205206
| Operator::DropColumn(_)
206207
| Operator::CreateTable(_)
207208
| Operator::CreateIndex(_)
209+
| Operator::CreateView(_)
208210
| Operator::DropTable(_)
209211
| Operator::Truncate(_)
210212
| Operator::CopyFromFile(_)

src/planner/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ impl LogicalPlan {
136136
Operator::CreateIndex(_) => Arc::new(vec![ColumnRef::from(
137137
ColumnCatalog::new_dummy("CREATE INDEX SUCCESS".to_string()),
138138
)]),
139+
Operator::CreateView(_) => Arc::new(vec![ColumnRef::from(
140+
ColumnCatalog::new_dummy("CREATE VIEW SUCCESS".to_string()),
141+
)]),
139142
Operator::DropTable(_) => Arc::new(vec![ColumnRef::from(
140143
ColumnCatalog::new_dummy("DROP TABLE SUCCESS".to_string()),
141144
)]),

0 commit comments

Comments
 (0)