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:
fys
2025-06-25 02:48:39 +08:00
committed by GitHub
parent 7aa9af5ba6
commit 7953b090c0
14 changed files with 304 additions and 9 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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;

View 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"
);
}
}

View File

@@ -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),