mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-06-01 12:50:40 +00:00
feat: impl drop view (#4231)
* feat: impl drop view * fix: metric name * fix: comments * test: add DropViewProcedure test * test: drop view meets a table * test: update sqlness tests by drop view * feat: apply suggestion from AI * chore: apply suggestion Co-authored-by: Jeremyhi <jiachun_feng@proton.me> * chore: apply suggestion Co-authored-by: Jeremyhi <jiachun_feng@proton.me> * chore: apply suggestion Co-authored-by: Jeremyhi <jiachun_feng@proton.me> * fix: TYPE_NAME for DropFlowProcedure --------- Co-authored-by: Jeremyhi <jiachun_feng@proton.me>
This commit is contained in:
@@ -16,9 +16,9 @@ use snafu::{ensure, ResultExt};
|
||||
use sqlparser::dialect::keywords::Keyword;
|
||||
use sqlparser::tokenizer::Token;
|
||||
|
||||
use crate::error::{self, InvalidTableNameSnafu, Result};
|
||||
use crate::error::{self, InvalidFlowNameSnafu, InvalidTableNameSnafu, Result};
|
||||
use crate::parser::{ParserContext, FLOW};
|
||||
use crate::statements::drop::{DropDatabase, DropFlow, DropTable};
|
||||
use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
|
||||
use crate::statements::statement::Statement;
|
||||
|
||||
/// DROP statement parser implementation
|
||||
@@ -28,6 +28,7 @@ impl<'a> ParserContext<'a> {
|
||||
match self.parser.peek_token().token {
|
||||
Token::Word(w) => match w.keyword {
|
||||
Keyword::TABLE => self.parse_drop_table(),
|
||||
Keyword::VIEW => self.parse_drop_view(),
|
||||
Keyword::SCHEMA | Keyword::DATABASE => self.parse_drop_database(),
|
||||
Keyword::NoKeyword => {
|
||||
let uppercase = w.value.to_uppercase();
|
||||
@@ -42,6 +43,31 @@ impl<'a> ParserContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_drop_view(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
|
||||
let if_exists = self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
|
||||
let raw_view_ident = self
|
||||
.parse_object_name()
|
||||
.with_context(|_| error::UnexpectedSnafu {
|
||||
sql: self.sql,
|
||||
expected: "a view name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let view_ident = Self::canonicalize_object_name(raw_view_ident);
|
||||
ensure!(
|
||||
!view_ident.0.is_empty(),
|
||||
InvalidTableNameSnafu {
|
||||
name: view_ident.to_string()
|
||||
}
|
||||
);
|
||||
|
||||
Ok(Statement::DropView(DropView {
|
||||
view_name: view_ident,
|
||||
drop_if_exists: if_exists,
|
||||
}))
|
||||
}
|
||||
|
||||
fn parse_drop_flow(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
|
||||
@@ -56,7 +82,7 @@ impl<'a> ParserContext<'a> {
|
||||
let flow_ident = Self::canonicalize_object_name(raw_flow_ident);
|
||||
ensure!(
|
||||
!flow_ident.0.is_empty(),
|
||||
InvalidTableNameSnafu {
|
||||
InvalidFlowNameSnafu {
|
||||
name: flow_ident.to_string()
|
||||
}
|
||||
);
|
||||
@@ -263,4 +289,53 @@ mod tests {
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_drop_view() {
|
||||
let sql = "DROP VIEW foo";
|
||||
let result =
|
||||
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
|
||||
let mut stmts: Vec<Statement> = result.unwrap();
|
||||
let stmt = stmts.pop().unwrap();
|
||||
assert_eq!(
|
||||
stmt,
|
||||
Statement::DropView(DropView {
|
||||
view_name: ObjectName(vec![Ident::new("foo")]),
|
||||
drop_if_exists: false,
|
||||
})
|
||||
);
|
||||
assert_eq!(sql, stmt.to_string());
|
||||
|
||||
let sql = "DROP VIEW greptime.public.foo";
|
||||
let result =
|
||||
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
|
||||
let mut stmts: Vec<Statement> = result.unwrap();
|
||||
let stmt = stmts.pop().unwrap();
|
||||
assert_eq!(
|
||||
stmt,
|
||||
Statement::DropView(DropView {
|
||||
view_name: ObjectName(vec![
|
||||
Ident::new("greptime"),
|
||||
Ident::new("public"),
|
||||
Ident::new("foo")
|
||||
]),
|
||||
drop_if_exists: false,
|
||||
})
|
||||
);
|
||||
assert_eq!(sql, stmt.to_string());
|
||||
|
||||
let sql = "DROP VIEW IF EXISTS foo";
|
||||
let result =
|
||||
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
|
||||
let mut stmts: Vec<Statement> = result.unwrap();
|
||||
let stmt = stmts.pop().unwrap();
|
||||
assert_eq!(
|
||||
stmt,
|
||||
Statement::DropView(DropView {
|
||||
view_name: ObjectName(vec![Ident::new("foo")]),
|
||||
drop_if_exists: true,
|
||||
})
|
||||
);
|
||||
assert_eq!(sql, stmt.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,30 @@ impl Display for DropFlow {
|
||||
}
|
||||
}
|
||||
|
||||
/// `DROP VIEW` statement.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
|
||||
pub struct DropView {
|
||||
// The view name
|
||||
pub view_name: ObjectName,
|
||||
// drop view if exists
|
||||
pub drop_if_exists: bool,
|
||||
}
|
||||
|
||||
impl Display for DropView {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"DROP VIEW{} {}",
|
||||
if self.drop_if_exists {
|
||||
" IF EXISTS"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
self.view_name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::assert_matches::assert_matches;
|
||||
|
||||
@@ -25,7 +25,7 @@ use crate::statements::create::{
|
||||
};
|
||||
use crate::statements::delete::Delete;
|
||||
use crate::statements::describe::DescribeTable;
|
||||
use crate::statements::drop::{DropDatabase, DropFlow, DropTable};
|
||||
use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
|
||||
use crate::statements::explain::Explain;
|
||||
use crate::statements::insert::Insert;
|
||||
use crate::statements::query::Query;
|
||||
@@ -55,14 +55,16 @@ pub enum Statement {
|
||||
CreateTableLike(CreateTableLike),
|
||||
// CREATE FLOW
|
||||
CreateFlow(CreateFlow),
|
||||
// DROP FLOW
|
||||
DropFlow(DropFlow),
|
||||
// CREATE VIEW ... AS
|
||||
CreateView(CreateView),
|
||||
// DROP TABLE
|
||||
DropTable(DropTable),
|
||||
// DROP DATABASE
|
||||
DropDatabase(DropDatabase),
|
||||
// DROP FLOW
|
||||
DropFlow(DropFlow),
|
||||
// DROP View
|
||||
DropView(DropView),
|
||||
// CREATE DATABASE
|
||||
CreateDatabase(CreateDatabase),
|
||||
/// ALTER TABLE
|
||||
@@ -119,6 +121,7 @@ impl Display for Statement {
|
||||
Statement::DropFlow(s) => s.fmt(f),
|
||||
Statement::DropTable(s) => s.fmt(f),
|
||||
Statement::DropDatabase(s) => s.fmt(f),
|
||||
Statement::DropView(s) => s.fmt(f),
|
||||
Statement::CreateDatabase(s) => s.fmt(f),
|
||||
Statement::Alter(s) => s.fmt(f),
|
||||
Statement::ShowDatabases(s) => s.fmt(f),
|
||||
|
||||
Reference in New Issue
Block a user