mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-21 23:40:38 +00:00
feat: support syntax parsing of drop trigger (#6371)
* feat: trigger drop * Update Cargo.toml * Update Cargo.lock --------- Co-authored-by: Ning Sun <classicning@gmail.com>
This commit is contained in:
@@ -195,6 +195,14 @@ pub enum Error {
|
||||
location: Location,
|
||||
},
|
||||
|
||||
#[cfg(feature = "enterprise")]
|
||||
#[snafu(display("Invalid trigger name: {}", name))]
|
||||
InvalidTriggerName {
|
||||
name: String,
|
||||
#[snafu(implicit)]
|
||||
location: Location,
|
||||
},
|
||||
|
||||
#[snafu(display("Invalid flow query: {}", reason))]
|
||||
InvalidFlowQuery {
|
||||
reason: String,
|
||||
@@ -445,6 +453,9 @@ impl ErrorExt for Error {
|
||||
| UnsupportedUnaryOp { .. }
|
||||
| ConvertStr { .. } => StatusCode::InvalidArguments,
|
||||
|
||||
#[cfg(feature = "enterprise")]
|
||||
InvalidTriggerName { .. } => StatusCode::InvalidArguments,
|
||||
|
||||
#[cfg(feature = "enterprise")]
|
||||
InvalidTriggerWebhookOption { .. } | NegativeInterval { .. } => {
|
||||
StatusCode::InvalidArguments
|
||||
|
||||
@@ -18,6 +18,8 @@ use sqlparser::tokenizer::Token;
|
||||
|
||||
use crate::error::{self, InvalidFlowNameSnafu, InvalidTableNameSnafu, Result};
|
||||
use crate::parser::{ParserContext, FLOW};
|
||||
#[cfg(feature = "enterprise")]
|
||||
use crate::statements::drop::trigger::DropTrigger;
|
||||
use crate::statements::drop::{DropDatabase, DropFlow, DropTable, DropView};
|
||||
use crate::statements::statement::Statement;
|
||||
|
||||
@@ -29,6 +31,8 @@ impl ParserContext<'_> {
|
||||
Token::Word(w) => match w.keyword {
|
||||
Keyword::TABLE => self.parse_drop_table(),
|
||||
Keyword::VIEW => self.parse_drop_view(),
|
||||
#[cfg(feature = "enterprise")]
|
||||
Keyword::TRIGGER => self.parse_drop_trigger(),
|
||||
Keyword::SCHEMA | Keyword::DATABASE => self.parse_drop_database(),
|
||||
Keyword::NoKeyword => {
|
||||
let uppercase = w.value.to_uppercase();
|
||||
@@ -43,6 +47,31 @@ impl ParserContext<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "enterprise")]
|
||||
fn parse_drop_trigger(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
|
||||
let if_exists = self.parser.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
|
||||
let raw_trigger_ident =
|
||||
self.parse_object_name()
|
||||
.with_context(|_| error::UnexpectedSnafu {
|
||||
expected: "a trigger name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let trigger_ident = Self::canonicalize_object_name(raw_trigger_ident);
|
||||
ensure!(
|
||||
!trigger_ident.0.is_empty(),
|
||||
error::InvalidTriggerNameSnafu {
|
||||
name: trigger_ident.to_string()
|
||||
}
|
||||
);
|
||||
|
||||
Ok(Statement::DropTrigger(DropTrigger::new(
|
||||
trigger_ident,
|
||||
if_exists,
|
||||
)))
|
||||
}
|
||||
|
||||
fn parse_drop_view(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[cfg(feature = "enterprise")]
|
||||
pub mod trigger;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
70
src/sql/src/statements/drop/trigger.rs
Normal file
70
src/sql/src/statements/drop/trigger.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use serde::Serialize;
|
||||
use sqlparser::ast::ObjectName;
|
||||
use sqlparser_derive::{Visit, VisitMut};
|
||||
|
||||
/// `DROP TRIGGER` statement.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
|
||||
pub struct DropTrigger {
|
||||
trigger_name: ObjectName,
|
||||
drop_if_exists: bool,
|
||||
}
|
||||
|
||||
impl DropTrigger {
|
||||
pub fn new(trigger_name: ObjectName, if_exists: bool) -> Self {
|
||||
Self {
|
||||
trigger_name,
|
||||
drop_if_exists: if_exists,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trigger_name(&self) -> &ObjectName {
|
||||
&self.trigger_name
|
||||
}
|
||||
|
||||
pub fn drop_if_exists(&self) -> bool {
|
||||
self.drop_if_exists
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for DropTrigger {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("DROP TRIGGER")?;
|
||||
if self.drop_if_exists() {
|
||||
f.write_str(" IF EXISTS")?;
|
||||
}
|
||||
let trigger_name = self.trigger_name();
|
||||
write!(f, r#" {trigger_name}"#)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sqlparser::ast::Ident;
|
||||
use sqlparser::tokenizer::Span;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_drop_trigger_display() {
|
||||
let ident = Ident {
|
||||
value: "my_trigger".to_string(),
|
||||
quote_style: None,
|
||||
span: Span::empty(),
|
||||
};
|
||||
let trigger_name = ObjectName(vec![ident]);
|
||||
|
||||
let drop_trigger = DropTrigger::new(trigger_name.clone(), true);
|
||||
assert_eq!(
|
||||
drop_trigger.to_string(),
|
||||
"DROP TRIGGER IF EXISTS my_trigger"
|
||||
);
|
||||
|
||||
let drop_trigger_no_if_exists = DropTrigger::new(trigger_name, false);
|
||||
assert_eq!(
|
||||
drop_trigger_no_if_exists.to_string(),
|
||||
"DROP TRIGGER my_trigger"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -72,6 +72,9 @@ pub enum Statement {
|
||||
DropDatabase(DropDatabase),
|
||||
// DROP FLOW
|
||||
DropFlow(DropFlow),
|
||||
// DROP Trigger
|
||||
#[cfg(feature = "enterprise")]
|
||||
DropTrigger(crate::statements::drop::trigger::DropTrigger),
|
||||
// DROP View
|
||||
DropView(DropView),
|
||||
// CREATE DATABASE
|
||||
@@ -158,6 +161,8 @@ impl Display for Statement {
|
||||
#[cfg(feature = "enterprise")]
|
||||
Statement::CreateTrigger(s) => s.fmt(f),
|
||||
Statement::DropFlow(s) => s.fmt(f),
|
||||
#[cfg(feature = "enterprise")]
|
||||
Statement::DropTrigger(s) => s.fmt(f),
|
||||
Statement::DropTable(s) => s.fmt(f),
|
||||
Statement::DropDatabase(s) => s.fmt(f),
|
||||
Statement::DropView(s) => s.fmt(f),
|
||||
|
||||
Reference in New Issue
Block a user