Skip to content

Commit

Permalink
feat: add create or replace view support (#14599)
Browse files Browse the repository at this point in the history
  • Loading branch information
lichuang authored Feb 5, 2024
1 parent 3a43077 commit ad86b04
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 20 deletions.
18 changes: 15 additions & 3 deletions src/query/ast/src/ast/format/syntax/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,24 @@ pub(crate) fn pretty_alter_table_action(action: AlterTableAction) -> RcDoc<'stat
}

pub(crate) fn pretty_create_view(stmt: CreateViewStmt) -> RcDoc<'static> {
RcDoc::text("CREATE VIEW")
.append(if stmt.if_not_exists {
RcDoc::space().append(RcDoc::text("IF NOT EXISTS"))
RcDoc::text("CREATE")
.append(if let CreateOption::CreateOrReplace = stmt.create_option {
RcDoc::space().append(RcDoc::text("OR REPLACE"))
} else {
RcDoc::nil()
})
.append(RcDoc::space().append(RcDoc::text("VIEW")))
.append(
if let CreateOption::CreateIfNotExists(if_not_exists) = stmt.create_option {
if if_not_exists {
RcDoc::space().append(RcDoc::text("IF NOT EXISTS"))
} else {
RcDoc::nil()
}
} else {
RcDoc::nil()
},
)
.append(
RcDoc::space()
.append(if let Some(catalog) = stmt.catalog {
Expand Down
16 changes: 12 additions & 4 deletions src/query/ast/src/ast/statements/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@
use std::fmt::Display;
use std::fmt::Formatter;

use databend_common_meta_app::schema::CreateOption;

use crate::ast::write_comma_separated_list;
use crate::ast::write_dot_separated_list;
use crate::ast::Identifier;
use crate::ast::Query;

#[derive(Debug, Clone, PartialEq)]
pub struct CreateViewStmt {
pub if_not_exists: bool,
pub create_option: CreateOption,
pub catalog: Option<Identifier>,
pub database: Option<Identifier>,
pub view: Identifier,
Expand All @@ -32,9 +34,15 @@ pub struct CreateViewStmt {

impl Display for CreateViewStmt {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "CREATE VIEW ")?;
if self.if_not_exists {
write!(f, "IF NOT EXISTS ")?;
write!(f, "CREATE ")?;
if let CreateOption::CreateOrReplace = self.create_option {
write!(f, "OR REPLACE ")?;
}
write!(f, "VIEW ")?;
if let CreateOption::CreateIfNotExists(if_not_exists) = self.create_option {
if if_not_exists {
write!(f, "IF NOT EXISTS ")?;
}
}
write_dot_separated_list(
f,
Expand Down
23 changes: 17 additions & 6 deletions src/query/ast/src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -889,24 +889,35 @@ pub fn statement(i: Input) -> IResult<StatementWithFormat> {
},
);

let create_view = map(
let create_view = map_res(
rule! {
CREATE ~ VIEW ~ ( IF ~ ^NOT ~ ^EXISTS )?
CREATE ~ (OR ~ REPLACE)? ~ VIEW ~ ( IF ~ ^NOT ~ ^EXISTS )?
~ #dot_separated_idents_1_to_3
~ ( "(" ~ #comma_separated_list1(ident) ~ ")" )?
~ AS ~ #query
},
|(_, _, opt_if_not_exists, (catalog, database, view), opt_columns, _, query)| {
Statement::CreateView(CreateViewStmt {
if_not_exists: opt_if_not_exists.is_some(),
|(
_,
opt_or_replace,
_,
opt_if_not_exists,
(catalog, database, view),
opt_columns,
_,
query,
)| {
let create_option =
parse_create_option(opt_or_replace.is_some(), opt_if_not_exists.is_some())?;
Ok(Statement::CreateView(CreateViewStmt {
create_option,
catalog,
database,
view,
columns: opt_columns
.map(|(_, columns, _)| columns)
.unwrap_or_default(),
query: Box::new(query),
})
}))
},
);
let drop_view = map(
Expand Down
1 change: 1 addition & 0 deletions src/query/ast/tests/it/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ fn test_statement() {
r#"alter view v as select number % 3 as a from numbers(1000);"#,
r#"drop view v;"#,
r#"create view v1(c1) as select number % 3 as a from numbers(1000);"#,
r#"create or replace view v1(c1) as select number % 3 as a from numbers(1000);"#,
r#"alter view v1(c2) as select number % 3 as a from numbers(1000);"#,
r#"create stream test2.s1 on table test.t append_only = false;"#,
r#"create stream if not exists test2.s2 on table test.t at (stream => test1.s1) comment = 'this is a stream';"#,
Expand Down
132 changes: 130 additions & 2 deletions src/query/ast/tests/it/testdata/statement.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2083,7 +2083,9 @@ CREATE VIEW v AS SELECT (number % 3) AS a FROM numbers(1000)
---------- AST ------------
CreateView(
CreateViewStmt {
if_not_exists: false,
create_option: CreateIfNotExists(
false,
),
catalog: None,
database: None,
view: Identifier {
Expand Down Expand Up @@ -2335,7 +2337,9 @@ CREATE VIEW v1 (c1) AS SELECT (number % 3) AS a FROM numbers(1000)
---------- AST ------------
CreateView(
CreateViewStmt {
if_not_exists: false,
create_option: CreateIfNotExists(
false,
),
catalog: None,
database: None,
view: Identifier {
Expand Down Expand Up @@ -2452,6 +2456,130 @@ CreateView(
)


---------- Input ----------
create or replace view v1(c1) as select number % 3 as a from numbers(1000);
---------- Output ---------
CREATE OR REPLACE VIEW v1 (c1) AS SELECT (number % 3) AS a FROM numbers(1000)
---------- AST ------------
CreateView(
CreateViewStmt {
create_option: CreateOrReplace,
catalog: None,
database: None,
view: Identifier {
name: "v1",
quote: None,
span: Some(
23..25,
),
},
columns: [
Identifier {
name: "c1",
quote: None,
span: Some(
26..28,
),
},
],
query: Query {
span: Some(
33..74,
),
with: None,
body: Select(
SelectStmt {
span: Some(
33..74,
),
hints: None,
distinct: false,
select_list: [
AliasedExpr {
expr: BinaryOp {
span: Some(
47..48,
),
op: Modulo,
left: ColumnRef {
span: Some(
40..46,
),
database: None,
table: None,
column: Name(
Identifier {
name: "number",
quote: None,
span: Some(
40..46,
),
},
),
},
right: Literal {
span: Some(
49..50,
),
lit: UInt64(
3,
),
},
},
alias: Some(
Identifier {
name: "a",
quote: None,
span: Some(
54..55,
),
},
),
},
],
from: [
TableFunction {
span: Some(
61..74,
),
lateral: false,
name: Identifier {
name: "numbers",
quote: None,
span: Some(
61..68,
),
},
params: [
Literal {
span: Some(
69..73,
),
lit: UInt64(
1000,
),
},
],
named_params: [],
alias: None,
},
],
selection: None,
group_by: None,
having: None,
window_list: None,
qualify: None,
},
),
order_by: [],
limit: [],
offset: None,
ignore_result: false,
},
},
)


---------- Input ----------
alter view v1(c2) as select number % 3 as a from numbers(1000);
---------- Output ---------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use std::sync::Arc;

use databend_common_exception::ErrorCode;
use databend_common_exception::Result;
use databend_common_meta_app::schema::CreateOption;
use databend_common_meta_app::schema::CreateTableReq;
use databend_common_meta_app::schema::TableMeta;
use databend_common_meta_app::schema::TableNameIdent;
Expand Down Expand Up @@ -104,7 +103,7 @@ impl Interpreter for CreateViewInterpreter {
options.insert(QUERY.to_string(), subquery);

let plan = CreateTableReq {
create_option: CreateOption::CreateIfNotExists(self.plan.if_not_exists),
create_option: self.plan.create_option,
name_ident: TableNameIdent {
tenant: self.plan.tenant.clone(),
db_name: self.plan.database.clone(),
Expand Down
4 changes: 2 additions & 2 deletions src/query/sql/src/planner/binder/ddl/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Binder {
stmt: &CreateViewStmt,
) -> Result<Plan> {
let CreateViewStmt {
if_not_exists,
create_option,
catalog,
database,
view,
Expand All @@ -55,7 +55,7 @@ impl Binder {
let subquery = format!("{}", query);

let plan = CreateViewPlan {
if_not_exists: *if_not_exists,
create_option: *create_option,
tenant,
catalog,
database,
Expand Down
4 changes: 3 additions & 1 deletion src/query/sql/src/planner/plans/ddl/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use databend_common_meta_app::schema::CreateOption;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CreateViewPlan {
pub if_not_exists: bool,
pub create_option: CreateOption,
pub tenant: String,
pub catalog: String,
pub database: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,20 @@ create view loop_view2 as select * from loop_view1;

statement error 1025
create view loop_view3 as select * from loop_view2;

statement ok
create view replace_view(a) as select * from numbers(3);

statement error 1005
create or replace view if not exists replace_view(a) as select * from numbers(3);

statement ok
create or replace view replace_view(b) as select * from numbers(1);

query I
select b from replace_view;
----
0

statement ok
drop view if exists replace_view;

0 comments on commit ad86b04

Please sign in to comment.