Moved CreateTrigger and DropTrigger out of Statement enum (#2026)

Co-authored-by: Ifeanyi Ubah <ify1992@yahoo.com>
This commit is contained in:
Luca Cappelletti 2025-09-15 09:26:46 +02:00 committed by GitHub
parent b8539a52af
commit 280f51889f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 270 additions and 244 deletions

View file

@ -20,7 +20,7 @@
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, string::String, vec::Vec};
use core::fmt::{self, Write};
use core::fmt::{self, Display, Write};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
@ -30,14 +30,15 @@ use sqlparser_derive::{Visit, VisitMut};
use crate::ast::value::escape_single_quote_string;
use crate::ast::{
display_comma_separated, display_separated, ArgMode, CommentDef, CreateFunctionBody,
CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, DataType, Expr, FileFormat,
FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier, FunctionParallel,
HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident, InitializeKind,
MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg,
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy, SequenceOptions,
Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag, Value, ValueWithSpan,
WrappedCollection,
display_comma_separated, display_separated, ArgMode, CommentDef, ConditionalStatements,
CreateFunctionBody, CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, DataType,
Expr, FileFormat, FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier,
FunctionParallel, HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident,
InitializeKind, MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens,
OperateFunctionArg, OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy,
SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag,
TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
ValueWithSpan, WrappedCollection,
};
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
use crate::keywords::Keyword;
@ -3176,3 +3177,221 @@ impl Spanned for RenameTableNameKind {
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
/// CREATE TRIGGER
///
/// Examples:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// BEFORE INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
///
/// Postgres: <https://www.postgresql.org/docs/current/sql-createtrigger.html>
/// SQL Server: <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql>
pub struct CreateTrigger {
/// True if this is a `CREATE OR ALTER TRIGGER` statement
///
/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-ver16#arguments)
pub or_alter: bool,
/// The `OR REPLACE` clause is used to re-create the trigger if it already exists.
///
/// Example:
/// ```sql
/// CREATE OR REPLACE TRIGGER trigger_name
/// AFTER INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
pub or_replace: bool,
/// The `CONSTRAINT` keyword is used to create a trigger as a constraint.
pub is_constraint: bool,
/// The name of the trigger to be created.
pub name: ObjectName,
/// Determines whether the function is called before, after, or instead of the event.
///
/// Example of BEFORE:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// BEFORE INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
///
/// Example of AFTER:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// AFTER INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
///
/// Example of INSTEAD OF:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// INSTEAD OF INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
pub period: TriggerPeriod,
/// Whether the trigger period was specified before the target table name.
///
/// ```sql
/// -- period_before_table == true: Postgres, MySQL, and standard SQL
/// CREATE TRIGGER t BEFORE INSERT ON table_name ...;
/// -- period_before_table == false: MSSQL
/// CREATE TRIGGER t ON table_name BEFORE INSERT ...;
/// ```
pub period_before_table: bool,
/// Multiple events can be specified using OR, such as `INSERT`, `UPDATE`, `DELETE`, or `TRUNCATE`.
pub events: Vec<TriggerEvent>,
/// The table on which the trigger is to be created.
pub table_name: ObjectName,
/// The optional referenced table name that can be referenced via
/// the `FROM` keyword.
pub referenced_table_name: Option<ObjectName>,
/// This keyword immediately precedes the declaration of one or two relation names that provide access to the transition relations of the triggering statement.
pub referencing: Vec<TriggerReferencing>,
/// This specifies whether the trigger function should be fired once for
/// every row affected by the trigger event, or just once per SQL statement.
pub trigger_object: TriggerObject,
/// Whether to include the `EACH` term of the `FOR EACH`, as it is optional syntax.
pub include_each: bool,
/// Triggering conditions
pub condition: Option<Expr>,
/// Execute logic block
pub exec_body: Option<TriggerExecBody>,
/// For MSSQL and dialects where statements are preceded by `AS`
pub statements_as: bool,
/// For SQL dialects with statement(s) for a body
pub statements: Option<ConditionalStatements>,
/// The characteristic of the trigger, which include whether the trigger is `DEFERRABLE`, `INITIALLY DEFERRED`, or `INITIALLY IMMEDIATE`,
pub characteristics: Option<ConstraintCharacteristics>,
}
impl Display for CreateTrigger {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let CreateTrigger {
or_alter,
or_replace,
is_constraint,
name,
period_before_table,
period,
events,
table_name,
referenced_table_name,
referencing,
trigger_object,
condition,
include_each,
exec_body,
statements_as,
statements,
characteristics,
} = self;
write!(
f,
"CREATE {or_alter}{or_replace}{is_constraint}TRIGGER {name} ",
or_alter = if *or_alter { "OR ALTER " } else { "" },
or_replace = if *or_replace { "OR REPLACE " } else { "" },
is_constraint = if *is_constraint { "CONSTRAINT " } else { "" },
)?;
if *period_before_table {
write!(f, "{period}")?;
if !events.is_empty() {
write!(f, " {}", display_separated(events, " OR "))?;
}
write!(f, " ON {table_name}")?;
} else {
write!(f, "ON {table_name}")?;
write!(f, " {period}")?;
if !events.is_empty() {
write!(f, " {}", display_separated(events, ", "))?;
}
}
if let Some(referenced_table_name) = referenced_table_name {
write!(f, " FROM {referenced_table_name}")?;
}
if let Some(characteristics) = characteristics {
write!(f, " {characteristics}")?;
}
if !referencing.is_empty() {
write!(f, " REFERENCING {}", display_separated(referencing, " "))?;
}
if *include_each {
write!(f, " FOR EACH {trigger_object}")?;
} else if exec_body.is_some() {
write!(f, " FOR {trigger_object}")?;
}
if let Some(condition) = condition {
write!(f, " WHEN {condition}")?;
}
if let Some(exec_body) = exec_body {
write!(f, " EXECUTE {exec_body}")?;
}
if let Some(statements) = statements {
if *statements_as {
write!(f, " AS")?;
}
write!(f, " {statements}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
/// DROP TRIGGER
///
/// ```sql
/// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
/// ```
///
pub struct DropTrigger {
/// Whether to include the `IF EXISTS` clause.
pub if_exists: bool,
/// The name of the trigger to be dropped.
pub trigger_name: ObjectName,
/// The name of the table from which the trigger is to be dropped.
pub table_name: Option<ObjectName>,
/// `CASCADE` or `RESTRICT`
pub option: Option<ReferentialAction>,
}
impl fmt::Display for DropTrigger {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let DropTrigger {
if_exists,
trigger_name,
table_name,
option,
} = self;
write!(f, "DROP TRIGGER")?;
if *if_exists {
write!(f, " IF EXISTS")?;
}
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}")?;
}
Ok(())
}
}

View file

@ -63,10 +63,10 @@ pub use self::ddl::{
AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
CreateFunction, CreateIndex, CreateTable, Deduplicate, DeferrableInitial, DropBehavior,
GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty,
IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, IndexColumn,
IndexOption, IndexType, KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition,
CreateFunction, CreateIndex, CreateTable, CreateTrigger, Deduplicate, DeferrableInitial,
DropBehavior, DropTrigger, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition,
ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TableConstraint,
TagsColumnOption, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation,
ViewColumnDef,
@ -3914,114 +3914,10 @@ pub enum Statement {
/// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
/// 4. [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
CreateFunction(CreateFunction),
/// CREATE TRIGGER
///
/// Examples:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// BEFORE INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
///
/// Postgres: <https://www.postgresql.org/docs/current/sql-createtrigger.html>
/// SQL Server: <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql>
CreateTrigger {
/// True if this is a `CREATE OR ALTER TRIGGER` statement
///
/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-ver16#arguments)
or_alter: bool,
/// The `OR REPLACE` clause is used to re-create the trigger if it already exists.
///
/// Example:
/// ```sql
/// CREATE OR REPLACE TRIGGER trigger_name
/// AFTER INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
or_replace: bool,
/// The `CONSTRAINT` keyword is used to create a trigger as a constraint.
is_constraint: bool,
/// The name of the trigger to be created.
name: ObjectName,
/// Determines whether the function is called before, after, or instead of the event.
///
/// Example of BEFORE:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// BEFORE INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
///
/// Example of AFTER:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// AFTER INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
///
/// Example of INSTEAD OF:
///
/// ```sql
/// CREATE TRIGGER trigger_name
/// INSTEAD OF INSERT ON table_name
/// FOR EACH ROW
/// EXECUTE FUNCTION trigger_function();
/// ```
period: TriggerPeriod,
/// Whether the trigger period was specified before the target table name.
///
/// ```sql
/// -- period_before_table == true: Postgres, MySQL, and standard SQL
/// CREATE TRIGGER t BEFORE INSERT ON table_name ...;
/// -- period_before_table == false: MSSQL
/// CREATE TRIGGER t ON table_name BEFORE INSERT ...;
/// ```
period_before_table: bool,
/// Multiple events can be specified using OR, such as `INSERT`, `UPDATE`, `DELETE`, or `TRUNCATE`.
events: Vec<TriggerEvent>,
/// The table on which the trigger is to be created.
table_name: ObjectName,
/// The optional referenced table name that can be referenced via
/// the `FROM` keyword.
referenced_table_name: Option<ObjectName>,
/// This keyword immediately precedes the declaration of one or two relation names that provide access to the transition relations of the triggering statement.
referencing: Vec<TriggerReferencing>,
/// This specifies whether the trigger function should be fired once for
/// every row affected by the trigger event, or just once per SQL statement.
trigger_object: TriggerObject,
/// Whether to include the `EACH` term of the `FOR EACH`, as it is optional syntax.
include_each: bool,
/// Triggering conditions
condition: Option<Expr>,
/// Execute logic block
exec_body: Option<TriggerExecBody>,
/// For MSSQL and dialects where statements are preceded by `AS`
statements_as: bool,
/// For SQL dialects with statement(s) for a body
statements: Option<ConditionalStatements>,
/// The characteristic of the trigger, which include whether the trigger is `DEFERRABLE`, `INITIALLY DEFERRED`, or `INITIALLY IMMEDIATE`,
characteristics: Option<ConstraintCharacteristics>,
},
/// DROP TRIGGER
///
/// ```sql
/// DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
/// ```
///
DropTrigger {
if_exists: bool,
trigger_name: ObjectName,
table_name: Option<ObjectName>,
/// `CASCADE` or `RESTRICT`
option: Option<ReferentialAction>,
},
/// CREATE TRIGGER statement. See struct [CreateTrigger] for details.
CreateTrigger(CreateTrigger),
/// DROP TRIGGER statement. See struct [DropTrigger] for details.
DropTrigger(DropTrigger),
/// ```sql
/// CREATE PROCEDURE
/// ```
@ -4984,97 +4880,8 @@ impl fmt::Display for Statement {
}
Statement::CreateFunction(create_function) => create_function.fmt(f),
Statement::CreateDomain(create_domain) => create_domain.fmt(f),
Statement::CreateTrigger {
or_alter,
or_replace,
is_constraint,
name,
period_before_table,
period,
events,
table_name,
referenced_table_name,
referencing,
trigger_object,
condition,
include_each,
exec_body,
statements_as,
statements,
characteristics,
} => {
write!(
f,
"CREATE {or_alter}{or_replace}{is_constraint}TRIGGER {name} ",
or_alter = if *or_alter { "OR ALTER " } else { "" },
or_replace = if *or_replace { "OR REPLACE " } else { "" },
is_constraint = if *is_constraint { "CONSTRAINT " } else { "" },
)?;
if *period_before_table {
write!(f, "{period}")?;
if !events.is_empty() {
write!(f, " {}", display_separated(events, " OR "))?;
}
write!(f, " ON {table_name}")?;
} else {
write!(f, "ON {table_name}")?;
write!(f, " {period}")?;
if !events.is_empty() {
write!(f, " {}", display_separated(events, ", "))?;
}
}
if let Some(referenced_table_name) = referenced_table_name {
write!(f, " FROM {referenced_table_name}")?;
}
if let Some(characteristics) = characteristics {
write!(f, " {characteristics}")?;
}
if !referencing.is_empty() {
write!(f, " REFERENCING {}", display_separated(referencing, " "))?;
}
if *include_each {
write!(f, " FOR EACH {trigger_object}")?;
} else if exec_body.is_some() {
write!(f, " FOR {trigger_object}")?;
}
if let Some(condition) = condition {
write!(f, " WHEN {condition}")?;
}
if let Some(exec_body) = exec_body {
write!(f, " EXECUTE {exec_body}")?;
}
if let Some(statements) = statements {
if *statements_as {
write!(f, " AS")?;
}
write!(f, " {statements}")?;
}
Ok(())
}
Statement::DropTrigger {
if_exists,
trigger_name,
table_name,
option,
} => {
write!(f, "DROP TRIGGER")?;
if *if_exists {
write!(f, " IF EXISTS")?;
}
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}")?;
}
Ok(())
}
Statement::CreateTrigger(create_trigger) => create_trigger.fmt(f),
Statement::DropTrigger(drop_trigger) => drop_trigger.fmt(f),
Statement::CreateProcedure {
name,
or_alter,

View file

@ -17,8 +17,8 @@
use crate::ast::helpers::attached_token::AttachedToken;
use crate::ast::{
BeginEndStatements, ConditionalStatementBlock, ConditionalStatements, GranteesType,
IfStatement, Statement, TriggerObject,
BeginEndStatements, ConditionalStatementBlock, ConditionalStatements, CreateTrigger,
GranteesType, IfStatement, Statement, TriggerObject,
};
use crate::dialect::Dialect;
use crate::keywords::{self, Keyword};
@ -251,7 +251,7 @@ impl MsSqlDialect {
parser.expect_keyword_is(Keyword::AS)?;
let statements = Some(parser.parse_conditional_statements(&[Keyword::END])?);
Ok(Statement::CreateTrigger {
Ok(Statement::CreateTrigger(CreateTrigger {
or_alter,
or_replace: false,
is_constraint: false,
@ -269,7 +269,7 @@ impl MsSqlDialect {
statements_as: true,
statements,
characteristics: None,
})
}))
}
/// Parse a sequence of statements, optionally separated by semicolon.

View file

@ -5564,12 +5564,12 @@ impl<'a> Parser<'a> {
Keyword::RESTRICT => ReferentialAction::Restrict,
_ => unreachable!(),
});
Ok(Statement::DropTrigger {
Ok(Statement::DropTrigger(DropTrigger {
if_exists,
trigger_name,
table_name,
option,
})
}))
}
pub fn parse_create_trigger(
@ -5627,7 +5627,7 @@ impl<'a> Parser<'a> {
statements = Some(self.parse_conditional_statements(&[Keyword::END])?);
}
Ok(Statement::CreateTrigger {
Ok(Statement::CreateTrigger(CreateTrigger {
or_alter,
or_replace,
is_constraint,
@ -5645,7 +5645,7 @@ impl<'a> Parser<'a> {
statements_as: false,
statements,
characteristics,
})
}))
}
pub fn parse_trigger_period(&mut self) -> Result<TriggerPeriod, ParserError> {

View file

@ -2384,7 +2384,7 @@ fn parse_create_trigger() {
let create_stmt = ms().verified_stmt(create_trigger);
assert_eq!(
create_stmt,
Statement::CreateTrigger {
Statement::CreateTrigger(CreateTrigger {
or_alter: true,
or_replace: false,
is_constraint: false,
@ -2417,7 +2417,7 @@ fn parse_create_trigger() {
}],
}),
characteristics: None,
}
})
);
let multi_statement_as_trigger = "\
@ -2476,12 +2476,12 @@ fn parse_drop_trigger() {
let drop_stmt = ms().one_statement_parses_to(sql_drop_trigger, "");
assert_eq!(
drop_stmt,
Statement::DropTrigger {
Statement::DropTrigger(DropTrigger {
if_exists: false,
trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]),
table_name: None,
option: None,
}
})
);
}

View file

@ -3922,7 +3922,7 @@ fn parse_create_trigger() {
let create_stmt = mysql().verified_stmt(sql_create_trigger);
assert_eq!(
create_stmt,
Statement::CreateTrigger {
Statement::CreateTrigger(CreateTrigger {
or_alter: false,
or_replace: false,
is_constraint: false,
@ -3946,7 +3946,7 @@ fn parse_create_trigger() {
statements_as: false,
statements: None,
characteristics: None,
}
})
);
}
@ -3962,12 +3962,12 @@ fn parse_drop_trigger() {
let drop_stmt = mysql().one_statement_parses_to(sql_drop_trigger, "");
assert_eq!(
drop_stmt,
Statement::DropTrigger {
Statement::DropTrigger(DropTrigger {
if_exists: false,
trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]),
table_name: None,
option: None,
}
})
);
}

View file

@ -5671,7 +5671,7 @@ fn parse_create_domain() {
#[test]
fn parse_create_simple_before_insert_trigger() {
let sql = "CREATE TRIGGER check_insert BEFORE INSERT ON accounts FOR EACH ROW EXECUTE FUNCTION check_account_insert";
let expected = Statement::CreateTrigger {
let expected = Statement::CreateTrigger(CreateTrigger {
or_alter: false,
or_replace: false,
is_constraint: false,
@ -5695,7 +5695,7 @@ fn parse_create_simple_before_insert_trigger() {
statements_as: false,
statements: None,
characteristics: None,
};
});
assert_eq!(pg().verified_stmt(sql), expected);
}
@ -5703,7 +5703,7 @@ fn parse_create_simple_before_insert_trigger() {
#[test]
fn parse_create_after_update_trigger_with_condition() {
let sql = "CREATE TRIGGER check_update AFTER UPDATE ON accounts FOR EACH ROW WHEN (NEW.balance > 10000) EXECUTE FUNCTION check_account_update";
let expected = Statement::CreateTrigger {
let expected = Statement::CreateTrigger(CreateTrigger {
or_alter: false,
or_replace: false,
is_constraint: false,
@ -5734,7 +5734,7 @@ fn parse_create_after_update_trigger_with_condition() {
statements_as: false,
statements: None,
characteristics: None,
};
});
assert_eq!(pg().verified_stmt(sql), expected);
}
@ -5742,7 +5742,7 @@ fn parse_create_after_update_trigger_with_condition() {
#[test]
fn parse_create_instead_of_delete_trigger() {
let sql = "CREATE TRIGGER check_delete INSTEAD OF DELETE ON accounts FOR EACH ROW EXECUTE FUNCTION check_account_deletes";
let expected = Statement::CreateTrigger {
let expected = Statement::CreateTrigger(CreateTrigger {
or_alter: false,
or_replace: false,
is_constraint: false,
@ -5766,7 +5766,7 @@ fn parse_create_instead_of_delete_trigger() {
statements_as: false,
statements: None,
characteristics: None,
};
});
assert_eq!(pg().verified_stmt(sql), expected);
}
@ -5774,7 +5774,7 @@ fn parse_create_instead_of_delete_trigger() {
#[test]
fn parse_create_trigger_with_multiple_events_and_deferrable() {
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";
let expected = Statement::CreateTrigger {
let expected = Statement::CreateTrigger(CreateTrigger {
or_alter: false,
or_replace: false,
is_constraint: true,
@ -5806,7 +5806,7 @@ fn parse_create_trigger_with_multiple_events_and_deferrable() {
initially: Some(DeferrableInitial::Deferred),
enforced: None,
}),
};
});
assert_eq!(pg().verified_stmt(sql), expected);
}
@ -5814,7 +5814,7 @@ fn parse_create_trigger_with_multiple_events_and_deferrable() {
#[test]
fn parse_create_trigger_with_referencing() {
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";
let expected = Statement::CreateTrigger {
let expected = Statement::CreateTrigger(CreateTrigger {
or_alter: false,
or_replace: false,
is_constraint: false,
@ -5849,7 +5849,7 @@ fn parse_create_trigger_with_referencing() {
statements_as: false,
statements: None,
characteristics: None,
};
});
assert_eq!(pg().verified_stmt(sql), expected);
}
@ -5901,12 +5901,12 @@ fn parse_drop_trigger() {
);
assert_eq!(
pg().verified_stmt(sql),
Statement::DropTrigger {
Statement::DropTrigger(DropTrigger {
if_exists,
trigger_name: ObjectName::from(vec![Ident::new("check_update")]),
table_name: Some(ObjectName::from(vec![Ident::new("table_name")])),
option
}
})
);
}
}
@ -6130,7 +6130,7 @@ fn parse_trigger_related_functions() {
assert_eq!(
create_trigger,
Statement::CreateTrigger {
Statement::CreateTrigger(CreateTrigger {
or_alter: false,
or_replace: false,
is_constraint: false,
@ -6154,18 +6154,18 @@ fn parse_trigger_related_functions() {
statements_as: false,
statements: None,
characteristics: None
}
})
);
// Check the fourth statement
assert_eq!(
drop_trigger,
Statement::DropTrigger {
Statement::DropTrigger(DropTrigger {
if_exists: false,
trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]),
table_name: Some(ObjectName::from(vec![Ident::new("emp")])),
option: None
}
})
);
}