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"))] #[cfg(not(feature = "std"))]
use alloc::{boxed::Box, string::String, vec::Vec}; use alloc::{boxed::Box, string::String, vec::Vec};
use core::fmt::{self, Write}; use core::fmt::{self, Display, Write};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -30,14 +30,15 @@ use sqlparser_derive::{Visit, VisitMut};
use crate::ast::value::escape_single_quote_string; use crate::ast::value::escape_single_quote_string;
use crate::ast::{ use crate::ast::{
display_comma_separated, display_separated, ArgMode, CommentDef, CreateFunctionBody, display_comma_separated, display_separated, ArgMode, CommentDef, ConditionalStatements,
CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, DataType, Expr, FileFormat, CreateFunctionBody, CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, DataType,
FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier, FunctionParallel, Expr, FileFormat, FunctionBehavior, FunctionCalledOnNull, FunctionDeterminismSpecifier,
HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident, InitializeKind, FunctionParallel, HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, Ident,
MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg, InitializeKind, MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens,
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy, SequenceOptions, OperateFunctionArg, OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy,
Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag, Value, ValueWithSpan, SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag,
WrappedCollection, TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
ValueWithSpan, WrappedCollection,
}; };
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline}; use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
use crate::keywords::Keyword; 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, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain, ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
CreateFunction, CreateIndex, CreateTable, Deduplicate, DeferrableInitial, DropBehavior, CreateFunction, CreateIndex, CreateTable, CreateTrigger, Deduplicate, DeferrableInitial,
GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty, DropBehavior, DropTrigger, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
IndexOption, IndexType, KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition, IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition,
ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TableConstraint, ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TableConstraint,
TagsColumnOption, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation, TagsColumnOption, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation,
ViewColumnDef, 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) /// 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) /// 4. [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
CreateFunction(CreateFunction), CreateFunction(CreateFunction),
/// CREATE TRIGGER /// CREATE TRIGGER statement. See struct [CreateTrigger] for details.
/// CreateTrigger(CreateTrigger),
/// Examples: /// DROP TRIGGER statement. See struct [DropTrigger] for details.
/// DropTrigger(DropTrigger),
/// ```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>,
},
/// ```sql /// ```sql
/// CREATE PROCEDURE /// CREATE PROCEDURE
/// ``` /// ```
@ -4984,97 +4880,8 @@ impl fmt::Display for Statement {
} }
Statement::CreateFunction(create_function) => create_function.fmt(f), Statement::CreateFunction(create_function) => create_function.fmt(f),
Statement::CreateDomain(create_domain) => create_domain.fmt(f), Statement::CreateDomain(create_domain) => create_domain.fmt(f),
Statement::CreateTrigger { Statement::CreateTrigger(create_trigger) => create_trigger.fmt(f),
or_alter, Statement::DropTrigger(drop_trigger) => drop_trigger.fmt(f),
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::CreateProcedure { Statement::CreateProcedure {
name, name,
or_alter, or_alter,

View file

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

View file

@ -5564,12 +5564,12 @@ impl<'a> Parser<'a> {
Keyword::RESTRICT => ReferentialAction::Restrict, Keyword::RESTRICT => ReferentialAction::Restrict,
_ => unreachable!(), _ => unreachable!(),
}); });
Ok(Statement::DropTrigger { Ok(Statement::DropTrigger(DropTrigger {
if_exists, if_exists,
trigger_name, trigger_name,
table_name, table_name,
option, option,
}) }))
} }
pub fn parse_create_trigger( pub fn parse_create_trigger(
@ -5627,7 +5627,7 @@ impl<'a> Parser<'a> {
statements = Some(self.parse_conditional_statements(&[Keyword::END])?); statements = Some(self.parse_conditional_statements(&[Keyword::END])?);
} }
Ok(Statement::CreateTrigger { Ok(Statement::CreateTrigger(CreateTrigger {
or_alter, or_alter,
or_replace, or_replace,
is_constraint, is_constraint,
@ -5645,7 +5645,7 @@ impl<'a> Parser<'a> {
statements_as: false, statements_as: false,
statements, statements,
characteristics, characteristics,
}) }))
} }
pub fn parse_trigger_period(&mut self) -> Result<TriggerPeriod, ParserError> { 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); let create_stmt = ms().verified_stmt(create_trigger);
assert_eq!( assert_eq!(
create_stmt, create_stmt,
Statement::CreateTrigger { Statement::CreateTrigger(CreateTrigger {
or_alter: true, or_alter: true,
or_replace: false, or_replace: false,
is_constraint: false, is_constraint: false,
@ -2417,7 +2417,7 @@ fn parse_create_trigger() {
}], }],
}), }),
characteristics: None, characteristics: None,
} })
); );
let multi_statement_as_trigger = "\ let multi_statement_as_trigger = "\
@ -2476,12 +2476,12 @@ fn parse_drop_trigger() {
let drop_stmt = ms().one_statement_parses_to(sql_drop_trigger, ""); let drop_stmt = ms().one_statement_parses_to(sql_drop_trigger, "");
assert_eq!( assert_eq!(
drop_stmt, drop_stmt,
Statement::DropTrigger { Statement::DropTrigger(DropTrigger {
if_exists: false, if_exists: false,
trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]), trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]),
table_name: None, table_name: None,
option: None, option: None,
} })
); );
} }

View file

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

View file

@ -5671,7 +5671,7 @@ fn parse_create_domain() {
#[test] #[test]
fn parse_create_simple_before_insert_trigger() { 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 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_alter: false,
or_replace: false, or_replace: false,
is_constraint: false, is_constraint: false,
@ -5695,7 +5695,7 @@ fn parse_create_simple_before_insert_trigger() {
statements_as: false, statements_as: false,
statements: None, statements: None,
characteristics: None, characteristics: None,
}; });
assert_eq!(pg().verified_stmt(sql), expected); assert_eq!(pg().verified_stmt(sql), expected);
} }
@ -5703,7 +5703,7 @@ fn parse_create_simple_before_insert_trigger() {
#[test] #[test]
fn parse_create_after_update_trigger_with_condition() { 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 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_alter: false,
or_replace: false, or_replace: false,
is_constraint: false, is_constraint: false,
@ -5734,7 +5734,7 @@ fn parse_create_after_update_trigger_with_condition() {
statements_as: false, statements_as: false,
statements: None, statements: None,
characteristics: None, characteristics: None,
}; });
assert_eq!(pg().verified_stmt(sql), expected); assert_eq!(pg().verified_stmt(sql), expected);
} }
@ -5742,7 +5742,7 @@ fn parse_create_after_update_trigger_with_condition() {
#[test] #[test]
fn parse_create_instead_of_delete_trigger() { 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 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_alter: false,
or_replace: false, or_replace: false,
is_constraint: false, is_constraint: false,
@ -5766,7 +5766,7 @@ fn parse_create_instead_of_delete_trigger() {
statements_as: false, statements_as: false,
statements: None, statements: None,
characteristics: None, characteristics: None,
}; });
assert_eq!(pg().verified_stmt(sql), expected); assert_eq!(pg().verified_stmt(sql), expected);
} }
@ -5774,7 +5774,7 @@ fn parse_create_instead_of_delete_trigger() {
#[test] #[test]
fn parse_create_trigger_with_multiple_events_and_deferrable() { 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 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_alter: false,
or_replace: false, or_replace: false,
is_constraint: true, is_constraint: true,
@ -5806,7 +5806,7 @@ fn parse_create_trigger_with_multiple_events_and_deferrable() {
initially: Some(DeferrableInitial::Deferred), initially: Some(DeferrableInitial::Deferred),
enforced: None, enforced: None,
}), }),
}; });
assert_eq!(pg().verified_stmt(sql), expected); assert_eq!(pg().verified_stmt(sql), expected);
} }
@ -5814,7 +5814,7 @@ fn parse_create_trigger_with_multiple_events_and_deferrable() {
#[test] #[test]
fn parse_create_trigger_with_referencing() { 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 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_alter: false,
or_replace: false, or_replace: false,
is_constraint: false, is_constraint: false,
@ -5849,7 +5849,7 @@ fn parse_create_trigger_with_referencing() {
statements_as: false, statements_as: false,
statements: None, statements: None,
characteristics: None, characteristics: None,
}; });
assert_eq!(pg().verified_stmt(sql), expected); assert_eq!(pg().verified_stmt(sql), expected);
} }
@ -5901,12 +5901,12 @@ fn parse_drop_trigger() {
); );
assert_eq!( assert_eq!(
pg().verified_stmt(sql), pg().verified_stmt(sql),
Statement::DropTrigger { Statement::DropTrigger(DropTrigger {
if_exists, if_exists,
trigger_name: ObjectName::from(vec![Ident::new("check_update")]), trigger_name: ObjectName::from(vec![Ident::new("check_update")]),
table_name: Some(ObjectName::from(vec![Ident::new("table_name")])), table_name: Some(ObjectName::from(vec![Ident::new("table_name")])),
option option
} })
); );
} }
} }
@ -6130,7 +6130,7 @@ fn parse_trigger_related_functions() {
assert_eq!( assert_eq!(
create_trigger, create_trigger,
Statement::CreateTrigger { Statement::CreateTrigger(CreateTrigger {
or_alter: false, or_alter: false,
or_replace: false, or_replace: false,
is_constraint: false, is_constraint: false,
@ -6154,18 +6154,18 @@ fn parse_trigger_related_functions() {
statements_as: false, statements_as: false,
statements: None, statements: None,
characteristics: None characteristics: None
} })
); );
// Check the fourth statement // Check the fourth statement
assert_eq!( assert_eq!(
drop_trigger, drop_trigger,
Statement::DropTrigger { Statement::DropTrigger(DropTrigger {
if_exists: false, if_exists: false,
trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]), trigger_name: ObjectName::from(vec![Ident::new("emp_stamp")]),
table_name: Some(ObjectName::from(vec![Ident::new("emp")])), table_name: Some(ObjectName::from(vec![Ident::new("emp")])),
option: None option: None
} })
); );
} }