Skip to content

Commit d2b564d

Browse files
committed
Add OR ALTER support for CREATE TRIGGER
1 parent cd7b14f commit d2b564d

File tree

5 files changed

+23
-5
lines changed

5 files changed

+23
-5
lines changed

src/ast/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -3665,6 +3665,10 @@ pub enum Statement {
36653665
/// Postgres: <https://www.postgresql.org/docs/current/sql-createtrigger.html>
36663666
/// SQL Server: <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql>
36673667
CreateTrigger {
3668+
/// True if this is a `CREATE OR ALTER TRIGGER` statement
3669+
///
3670+
/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-ver16#arguments)
3671+
or_alter: bool,
36683672
/// The `OR REPLACE` clause is used to re-create the trigger if it already exists.
36693673
///
36703674
/// Example:
@@ -4521,6 +4525,7 @@ impl fmt::Display for Statement {
45214525
}
45224526
Statement::CreateFunction(create_function) => create_function.fmt(f),
45234527
Statement::CreateTrigger {
4528+
or_alter,
45244529
or_replace,
45254530
is_constraint,
45264531
name,
@@ -4538,7 +4543,8 @@ impl fmt::Display for Statement {
45384543
} => {
45394544
write!(
45404545
f,
4541-
"CREATE {or_replace}{is_constraint}TRIGGER {name} ",
4546+
"CREATE {or_alter}{or_replace}{is_constraint}TRIGGER {name} ",
4547+
or_alter = if *or_alter { "OR ALTER " } else { "" },
45424548
or_replace = if *or_replace { "OR REPLACE " } else { "" },
45434549
is_constraint = if *is_constraint { "CONSTRAINT " } else { "" },
45444550
)?;

src/parser/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -4556,9 +4556,9 @@ impl<'a> Parser<'a> {
45564556
} else if self.parse_keyword(Keyword::FUNCTION) {
45574557
self.parse_create_function(or_alter, or_replace, temporary)
45584558
} else if self.parse_keyword(Keyword::TRIGGER) {
4559-
self.parse_create_trigger(or_replace, false)
4559+
self.parse_create_trigger(or_alter, or_replace, false)
45604560
} else if self.parse_keywords(&[Keyword::CONSTRAINT, Keyword::TRIGGER]) {
4561-
self.parse_create_trigger(or_replace, true)
4561+
self.parse_create_trigger(or_alter, or_replace, true)
45624562
} else if self.parse_keyword(Keyword::MACRO) {
45634563
self.parse_create_macro(or_replace, temporary)
45644564
} else if self.parse_keyword(Keyword::SECRET) {
@@ -5256,6 +5256,7 @@ impl<'a> Parser<'a> {
52565256

52575257
pub fn parse_create_trigger(
52585258
&mut self,
5259+
or_alter: bool,
52595260
or_replace: bool,
52605261
is_constraint: bool,
52615262
) -> Result<Statement, ParserError> {
@@ -5265,7 +5266,7 @@ impl<'a> Parser<'a> {
52655266
}
52665267

52675268
if dialect_of!(self is MsSqlDialect) {
5268-
return self.parse_mssql_create_trigger(or_replace, is_constraint);
5269+
return self.parse_mssql_create_trigger(or_alter, or_replace, is_constraint);
52695270
}
52705271

52715272
let name = self.parse_object_name(false)?;
@@ -5309,6 +5310,7 @@ impl<'a> Parser<'a> {
53095310
let exec_body = self.parse_trigger_exec_body()?;
53105311

53115312
Ok(Statement::CreateTrigger {
5313+
or_alter,
53125314
or_replace,
53135315
is_constraint,
53145316
name,
@@ -5331,6 +5333,7 @@ impl<'a> Parser<'a> {
53315333
/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql
53325334
pub fn parse_mssql_create_trigger(
53335335
&mut self,
5336+
or_alter: bool,
53345337
or_replace: bool,
53355338
is_constraint: bool,
53365339
) -> Result<Statement, ParserError> {
@@ -5361,6 +5364,7 @@ impl<'a> Parser<'a> {
53615364
};
53625365

53635366
Ok(Statement::CreateTrigger {
5367+
or_alter,
53645368
or_replace,
53655369
is_constraint,
53665370
name,

tests/sqlparser_mssql.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2128,7 +2128,7 @@ fn parse_mssql_merge_with_output() {
21282128
#[test]
21292129
fn parse_create_trigger() {
21302130
let create_trigger = "\
2131-
CREATE TRIGGER reminder1 \
2131+
CREATE OR ALTER TRIGGER reminder1 \
21322132
ON Sales.Customer \
21332133
AFTER INSERT, UPDATE \
21342134
AS RAISERROR('Notify Customer Relations', 16, 10);\
@@ -2137,6 +2137,7 @@ fn parse_create_trigger() {
21372137
assert_eq!(
21382138
create_stmt,
21392139
Statement::CreateTrigger {
2140+
or_alter: true,
21402141
or_replace: false,
21412142
is_constraint: false,
21422143
name: ObjectName::from(vec![Ident::new("reminder1")]),

tests/sqlparser_mysql.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3521,6 +3521,7 @@ fn parse_create_trigger() {
35213521
assert_eq!(
35223522
create_stmt,
35233523
Statement::CreateTrigger {
3524+
or_alter: false,
35243525
or_replace: false,
35253526
is_constraint: false,
35263527
name: ObjectName::from(vec![Ident::new("emp_stamp")]),

tests/sqlparser_postgres.rs

+6
Original file line numberDiff line numberDiff line change
@@ -5084,6 +5084,7 @@ fn test_escaped_string_literal() {
50845084
fn parse_create_simple_before_insert_trigger() {
50855085
let sql = "CREATE TRIGGER check_insert BEFORE INSERT ON accounts FOR EACH ROW EXECUTE FUNCTION check_account_insert";
50865086
let expected = Statement::CreateTrigger {
5087+
or_alter: false,
50875088
or_replace: false,
50885089
is_constraint: false,
50895090
name: ObjectName::from(vec![Ident::new("check_insert")]),
@@ -5113,6 +5114,7 @@ fn parse_create_simple_before_insert_trigger() {
51135114
fn parse_create_after_update_trigger_with_condition() {
51145115
let sql = "CREATE TRIGGER check_update AFTER UPDATE ON accounts FOR EACH ROW WHEN (NEW.balance > 10000) EXECUTE FUNCTION check_account_update";
51155116
let expected = Statement::CreateTrigger {
5117+
or_alter: false,
51165118
or_replace: false,
51175119
is_constraint: false,
51185120
name: ObjectName::from(vec![Ident::new("check_update")]),
@@ -5149,6 +5151,7 @@ fn parse_create_after_update_trigger_with_condition() {
51495151
fn parse_create_instead_of_delete_trigger() {
51505152
let sql = "CREATE TRIGGER check_delete INSTEAD OF DELETE ON accounts FOR EACH ROW EXECUTE FUNCTION check_account_deletes";
51515153
let expected = Statement::CreateTrigger {
5154+
or_alter: false,
51525155
or_replace: false,
51535156
is_constraint: false,
51545157
name: ObjectName::from(vec![Ident::new("check_delete")]),
@@ -5178,6 +5181,7 @@ fn parse_create_instead_of_delete_trigger() {
51785181
fn parse_create_trigger_with_multiple_events_and_deferrable() {
51795182
let sql = "CREATE CONSTRAINT TRIGGER check_multiple_events BEFORE INSERT OR UPDATE OR DELETE ON accounts DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION check_account_changes";
51805183
let expected = Statement::CreateTrigger {
5184+
or_alter: false,
51815185
or_replace: false,
51825186
is_constraint: true,
51835187
name: ObjectName::from(vec![Ident::new("check_multiple_events")]),
@@ -5215,6 +5219,7 @@ fn parse_create_trigger_with_multiple_events_and_deferrable() {
52155219
fn parse_create_trigger_with_referencing() {
52165220
let sql = "CREATE TRIGGER check_referencing BEFORE INSERT ON accounts REFERENCING NEW TABLE AS new_accounts OLD TABLE AS old_accounts FOR EACH ROW EXECUTE FUNCTION check_account_referencing";
52175221
let expected = Statement::CreateTrigger {
5222+
or_alter: false,
52185223
or_replace: false,
52195224
is_constraint: false,
52205225
name: ObjectName::from(vec![Ident::new("check_referencing")]),
@@ -5528,6 +5533,7 @@ fn parse_trigger_related_functions() {
55285533
assert_eq!(
55295534
create_trigger,
55305535
Statement::CreateTrigger {
5536+
or_alter: false,
55315537
or_replace: false,
55325538
is_constraint: false,
55335539
name: ObjectName::from(vec![Ident::new("emp_stamp")]),

0 commit comments

Comments
 (0)