Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3029,7 +3029,7 @@ pub struct CreateTrigger {
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
pub period: TriggerPeriod,
pub period: Option<TriggerPeriod>,
/// Whether the trigger period was specified before the target table name.
/// This does not refer to whether the period is BEFORE, AFTER, or INSTEAD OF,
/// but rather the position of the period clause in relation to the table name.
Expand Down Expand Up @@ -3098,14 +3098,18 @@ impl Display for CreateTrigger {
)?;

if *period_before_table {
write!(f, "{period}")?;
if let Some(p) = period {
write!(f, "{p} ")?;
}
if !events.is_empty() {
write!(f, " {}", display_separated(events, " OR "))?;
write!(f, "{} ", display_separated(events, " OR "))?;
}
write!(f, " ON {table_name}")?;
} else {
write!(f, "ON {table_name}")?;
write!(f, " {period}")?;
} else {
write!(f, "ON {table_name} ")?;
if let Some(p) = period {
write!(f, "{p}")?;
}
if !events.is_empty() {
write!(f, " {}", display_separated(events, ", "))?;
}
Expand Down
2 changes: 1 addition & 1 deletion src/dialect/mssql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ impl MsSqlDialect {
or_replace: false,
is_constraint: false,
name,
period,
period: Some(period),
period_before_table: false,
events,
table_name,
Expand Down
2 changes: 1 addition & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5592,7 +5592,7 @@ impl<'a> Parser<'a> {
}

let name = self.parse_object_name(false)?;
let period = self.parse_trigger_period()?;
let period = self.maybe_parse(|parser| parser.parse_trigger_period())?;

let events = self.parse_keyword_separated(Keyword::OR, Parser::parse_trigger_event)?;
self.expect_keyword_is(Keyword::ON)?;
Expand Down
2 changes: 1 addition & 1 deletion tests/sqlparser_mssql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2392,7 +2392,7 @@ fn parse_create_trigger() {
or_replace: false,
is_constraint: false,
name: ObjectName::from(vec![Ident::new("reminder1")]),
period: TriggerPeriod::After,
period: Some(TriggerPeriod::After),
period_before_table: false,
events: vec![TriggerEvent::Insert, TriggerEvent::Update(vec![]),],
table_name: ObjectName::from(vec![Ident::new("Sales"), Ident::new("Customer")]),
Expand Down
2 changes: 1 addition & 1 deletion tests/sqlparser_mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4022,7 +4022,7 @@ fn parse_create_trigger() {
or_replace: false,
is_constraint: false,
name: ObjectName::from(vec![Ident::new("emp_stamp")]),
period: TriggerPeriod::Before,
period: Some(TriggerPeriod::Before),
period_before_table: true,
events: vec![TriggerEvent::Insert],
table_name: ObjectName::from(vec![Ident::new("emp")]),
Expand Down
14 changes: 7 additions & 7 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5640,7 +5640,7 @@ fn parse_create_simple_before_insert_trigger() {
or_replace: false,
is_constraint: false,
name: ObjectName::from(vec![Ident::new("check_insert")]),
period: TriggerPeriod::Before,
period: Some(TriggerPeriod::Before),
period_before_table: true,
events: vec![TriggerEvent::Insert],
table_name: ObjectName::from(vec![Ident::new("accounts")]),
Expand Down Expand Up @@ -5672,7 +5672,7 @@ fn parse_create_after_update_trigger_with_condition() {
or_replace: false,
is_constraint: false,
name: ObjectName::from(vec![Ident::new("check_update")]),
period: TriggerPeriod::After,
period: Some(TriggerPeriod::After),
period_before_table: true,
events: vec![TriggerEvent::Update(vec![])],
table_name: ObjectName::from(vec![Ident::new("accounts")]),
Expand Down Expand Up @@ -5711,7 +5711,7 @@ fn parse_create_instead_of_delete_trigger() {
or_replace: false,
is_constraint: false,
name: ObjectName::from(vec![Ident::new("check_delete")]),
period: TriggerPeriod::InsteadOf,
period: Some(TriggerPeriod::InsteadOf),
period_before_table: true,
events: vec![TriggerEvent::Delete],
table_name: ObjectName::from(vec![Ident::new("accounts")]),
Expand Down Expand Up @@ -5743,7 +5743,7 @@ fn parse_create_trigger_with_multiple_events_and_deferrable() {
or_replace: false,
is_constraint: true,
name: ObjectName::from(vec![Ident::new("check_multiple_events")]),
period: TriggerPeriod::Before,
period: Some(TriggerPeriod::Before),
period_before_table: true,
events: vec![
TriggerEvent::Insert,
Expand Down Expand Up @@ -5783,7 +5783,7 @@ fn parse_create_trigger_with_referencing() {
or_replace: false,
is_constraint: false,
name: ObjectName::from(vec![Ident::new("check_referencing")]),
period: TriggerPeriod::Before,
period: Some(TriggerPeriod::Before),
period_before_table: true,
events: vec![TriggerEvent::Insert],
table_name: ObjectName::from(vec![Ident::new("accounts")]),
Expand Down Expand Up @@ -5830,7 +5830,7 @@ fn parse_create_trigger_invalid_cases() {
),
(
"CREATE TRIGGER check_update TOMORROW UPDATE ON accounts EXECUTE FUNCTION check_account_update",
"Expected: one of FOR or BEFORE or AFTER or INSTEAD, found: TOMORROW"
"Expected: one of INSERT or UPDATE or DELETE or TRUNCATE, found: TOMORROW"
),
(
"CREATE TRIGGER check_update BEFORE SAVE ON accounts EXECUTE FUNCTION check_account_update",
Expand Down Expand Up @@ -6099,7 +6099,7 @@ fn parse_trigger_related_functions() {
or_replace: false,
is_constraint: false,
name: ObjectName::from(vec![Ident::new("emp_stamp")]),
period: TriggerPeriod::Before,
period: Some(TriggerPeriod::Before),
period_before_table: true,
events: vec![TriggerEvent::Insert, TriggerEvent::Update(vec![])],
table_name: ObjectName::from(vec![Ident::new("emp")]),
Expand Down
16 changes: 10 additions & 6 deletions tests/sqlparser_sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ fn test_create_trigger() {
assert!(!or_replace);
assert!(!is_constraint);
assert_eq!(name.to_string(), "trg_inherit_asset_models");
assert_eq!(period, TriggerPeriod::After);
assert_eq!(period, Some(TriggerPeriod::After));
assert!(period_before_table);
assert_eq!(events, vec![TriggerEvent::Insert]);
assert_eq!(table_name.to_string(), "assets");
Expand Down Expand Up @@ -685,7 +685,7 @@ fn test_create_trigger() {
assert!(!or_replace);
assert!(!is_constraint);
assert_eq!(name.to_string(), "log_new_user");
assert_eq!(period, TriggerPeriod::After);
assert_eq!(period, Some(TriggerPeriod::After));
assert!(period_before_table);
assert_eq!(events, vec![TriggerEvent::Insert]);
assert_eq!(table_name.to_string(), "users");
Expand Down Expand Up @@ -725,7 +725,7 @@ fn test_create_trigger() {
assert!(!or_replace);
assert!(!is_constraint);
assert_eq!(name.to_string(), "cleanup_orders");
assert_eq!(period, TriggerPeriod::After);
assert_eq!(period, Some(TriggerPeriod::After));
assert!(period_before_table);
assert_eq!(events, vec![TriggerEvent::Delete]);
assert_eq!(table_name.to_string(), "customers");
Expand Down Expand Up @@ -765,7 +765,7 @@ fn test_create_trigger() {
assert!(!or_replace);
assert!(!is_constraint);
assert_eq!(name.to_string(), "trg_before_update");
assert_eq!(period, TriggerPeriod::Before);
assert_eq!(period, Some(TriggerPeriod::Before));
assert!(period_before_table);
assert_eq!(events, vec![TriggerEvent::Update(Vec::new())]);
assert_eq!(table_name.to_string(), "products");
Expand Down Expand Up @@ -809,7 +809,7 @@ fn test_create_trigger() {
assert!(!or_replace);
assert!(!is_constraint);
assert_eq!(name.to_string(), "trg_instead_of_insert");
assert_eq!(period, TriggerPeriod::InsteadOf);
assert_eq!(period, Some(TriggerPeriod::InsteadOf));
assert!(period_before_table);
assert_eq!(events, vec![TriggerEvent::Insert]);
assert_eq!(table_name.to_string(), "my_view");
Expand Down Expand Up @@ -850,7 +850,7 @@ fn test_create_trigger() {
assert!(!or_replace);
assert!(!is_constraint);
assert_eq!(name.to_string(), "temp_trigger");
assert_eq!(period, TriggerPeriod::After);
assert_eq!(period, Some(TriggerPeriod::After));
assert!(period_before_table);
assert_eq!(events, vec![TriggerEvent::Insert]);
assert_eq!(table_name.to_string(), "temp_table");
Expand All @@ -863,6 +863,10 @@ fn test_create_trigger() {
}
_ => unreachable!("Expected CREATE TRIGGER statement"),
}

// We test a trigger defined without a period (BEFORE/AFTER/INSTEAD OF)
let statement7 = "CREATE TRIGGER trg_inherit_asset_models INSERT ON assets FOR EACH ROW BEGIN INSERT INTO users (name) SELECT pam.name FROM users AS pam; END";
sqlite().verified_stmt(statement7);
}

#[test]
Expand Down