blob: 8c189a3378a3a59e77ba02f6fde191f57738737b [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//! SQL Abstract Syntax Tree (AST) for triggers.
use super::*;
/// This specifies whether the trigger function should be fired once for every row affected by the trigger event, or just once per SQL statement.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum TriggerObject {
/// The trigger fires once for each row affected by the triggering event
Row,
/// The trigger fires once for the triggering SQL statement
Statement,
}
impl fmt::Display for TriggerObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TriggerObject::Row => write!(f, "ROW"),
TriggerObject::Statement => write!(f, "STATEMENT"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
/// This clause indicates whether the following relation name is for the before-image transition relation or the after-image transition relation
pub enum TriggerReferencingType {
/// The transition relation containing the old rows affected by the triggering statement
OldTable,
/// The transition relation containing the new rows affected by the triggering statement
NewTable,
}
impl fmt::Display for TriggerReferencingType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TriggerReferencingType::OldTable => write!(f, "OLD TABLE"),
TriggerReferencingType::NewTable => write!(f, "NEW TABLE"),
}
}
}
/// This keyword immediately precedes the declaration of one or two relation names that provide access to the transition relations of the triggering statement
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct TriggerReferencing {
/// The referencing type (`OLD TABLE` or `NEW TABLE`).
pub refer_type: TriggerReferencingType,
/// True if the `AS` keyword is present in the referencing clause.
pub is_as: bool,
/// The transition relation name provided by the referencing clause.
pub transition_relation_name: ObjectName,
}
impl fmt::Display for TriggerReferencing {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{refer_type}{is_as} {relation_name}",
refer_type = self.refer_type,
is_as = if self.is_as { " AS" } else { "" },
relation_name = self.transition_relation_name
)
}
}
/// Used to describe trigger events
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum TriggerEvent {
/// Trigger on INSERT event
Insert,
/// Trigger on UPDATE event, with optional list of columns
Update(Vec<Ident>),
/// Trigger on DELETE event
Delete,
/// Trigger on TRUNCATE event
Truncate,
}
impl fmt::Display for TriggerEvent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TriggerEvent::Insert => write!(f, "INSERT"),
TriggerEvent::Update(columns) => {
write!(f, "UPDATE")?;
if !columns.is_empty() {
write!(f, " OF")?;
write!(f, " {}", display_comma_separated(columns))?;
}
Ok(())
}
TriggerEvent::Delete => write!(f, "DELETE"),
TriggerEvent::Truncate => write!(f, "TRUNCATE"),
}
}
}
/// Trigger period
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum TriggerPeriod {
/// The trigger fires once for each row affected by the triggering event
For,
/// The trigger fires once for the triggering SQL statement
After,
/// The trigger fires before the triggering event
Before,
/// The trigger fires instead of the triggering event
InsteadOf,
}
impl fmt::Display for TriggerPeriod {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TriggerPeriod::For => write!(f, "FOR"),
TriggerPeriod::After => write!(f, "AFTER"),
TriggerPeriod::Before => write!(f, "BEFORE"),
TriggerPeriod::InsteadOf => write!(f, "INSTEAD OF"),
}
}
}
/// Types of trigger body execution body.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum TriggerExecBodyType {
/// Execute a function
Function,
/// Execute a procedure
Procedure,
}
impl fmt::Display for TriggerExecBodyType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TriggerExecBodyType::Function => write!(f, "FUNCTION"),
TriggerExecBodyType::Procedure => write!(f, "PROCEDURE"),
}
}
}
/// This keyword immediately precedes the declaration of one or two relation names that provide access to the transition relations of the triggering statement
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct TriggerExecBody {
/// Whether the body is a `FUNCTION` or `PROCEDURE` invocation.
pub exec_type: TriggerExecBodyType,
/// Description of the function/procedure to execute.
pub func_desc: FunctionDesc,
}
impl fmt::Display for TriggerExecBody {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{exec_type} {func_desc}",
exec_type = self.exec_type,
func_desc = self.func_desc
)
}
}