feat: adjust create and drop trigger for mysql dialect (#1734)

diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index afe3e77..5263bfc 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -3256,7 +3256,7 @@
     DropTrigger {
         if_exists: bool,
         trigger_name: ObjectName,
-        table_name: ObjectName,
+        table_name: Option<ObjectName>,
         /// `CASCADE` or `RESTRICT`
         option: Option<ReferentialAction>,
     },
@@ -4062,7 +4062,10 @@
                 if *if_exists {
                     write!(f, " IF EXISTS")?;
                 }
-                write!(f, " {trigger_name} ON {table_name}")?;
+                match &table_name {
+                    Some(table_name) => write!(f, " {trigger_name} ON {table_name}")?,
+                    None => write!(f, " {trigger_name}")?,
+                };
                 if let Some(option) = option {
                     write!(f, " {option}")?;
                 }
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 72e4567..2d64ff3 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -4990,14 +4990,17 @@
     /// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
     /// ```
     pub fn parse_drop_trigger(&mut self) -> Result<Statement, ParserError> {
-        if !dialect_of!(self is PostgreSqlDialect | GenericDialect) {
+        if !dialect_of!(self is PostgreSqlDialect | GenericDialect | MySqlDialect) {
             self.prev_token();
             return self.expected("an object type after DROP", self.peek_token());
         }
         let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
         let trigger_name = self.parse_object_name(false)?;
-        self.expect_keyword_is(Keyword::ON)?;
-        let table_name = self.parse_object_name(false)?;
+        let table_name = if self.parse_keyword(Keyword::ON) {
+            Some(self.parse_object_name(false)?)
+        } else {
+            None
+        };
         let option = self
             .parse_one_of_keywords(&[Keyword::CASCADE, Keyword::RESTRICT])
             .map(|keyword| match keyword {
@@ -5018,7 +5021,7 @@
         or_replace: bool,
         is_constraint: bool,
     ) -> Result<Statement, ParserError> {
-        if !dialect_of!(self is PostgreSqlDialect | GenericDialect) {
+        if !dialect_of!(self is PostgreSqlDialect | GenericDialect | MySqlDialect) {
             self.prev_token();
             return self.expected("an object type after CREATE", self.peek_token());
         }
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index ad2987b..861f782 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -3291,3 +3291,51 @@
         "UPDATE account SET balance = balance WHERE account_id = 5752",
     );
 }
+
+#[test]
+fn parse_create_trigger() {
+    let sql_create_trigger = r#"
+        CREATE TRIGGER emp_stamp BEFORE INSERT ON emp
+            FOR EACH ROW EXECUTE FUNCTION emp_stamp();
+    "#;
+    let create_stmt = mysql().one_statement_parses_to(sql_create_trigger, "");
+    assert_eq!(
+        create_stmt,
+        Statement::CreateTrigger {
+            or_replace: false,
+            is_constraint: false,
+            name: ObjectName::from(vec![Ident::new("emp_stamp")]),
+            period: TriggerPeriod::Before,
+            events: vec![TriggerEvent::Insert],
+            table_name: ObjectName::from(vec![Ident::new("emp")]),
+            referenced_table_name: None,
+            referencing: vec![],
+            trigger_object: TriggerObject::Row,
+            include_each: true,
+            condition: None,
+            exec_body: TriggerExecBody {
+                exec_type: TriggerExecBodyType::Function,
+                func_desc: FunctionDesc {
+                    name: ObjectName::from(vec![Ident::new("emp_stamp")]),
+                    args: None,
+                }
+            },
+            characteristics: None,
+        }
+    );
+}
+
+#[test]
+fn parse_drop_trigger() {
+    let sql_drop_trigger = "DROP TRIGGER emp_stamp;";
+    let drop_stmt = mysql().one_statement_parses_to(sql_drop_trigger, "");
+    assert_eq!(
+        drop_stmt,
+        Statement::DropTrigger {
+            if_exists: false,
+            trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]),
+            table_name: None,
+            option: None,
+        }
+    );
+}
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 2255832..7508218 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -5044,7 +5044,7 @@
                 Statement::DropTrigger {
                     if_exists,
                     trigger_name: ObjectName::from(vec![Ident::new("check_update")]),
-                    table_name: ObjectName::from(vec![Ident::new("table_name")]),
+                    table_name: Some(ObjectName::from(vec![Ident::new("table_name")])),
                     option
                 }
             );
@@ -5297,7 +5297,7 @@
         Statement::DropTrigger {
             if_exists: false,
             trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]),
-            table_name: ObjectName::from(vec![Ident::new("emp")]),
+            table_name: Some(ObjectName::from(vec![Ident::new("emp")])),
             option: None
         }
     );