trigger.rs - source

sqlparser/ast/

trigger.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! SQL Abstract Syntax Tree (AST) for triggers.
19use super::*;
20
21/// This specifies whether the trigger function should be fired once for every row affected by the trigger event, or just once per SQL statement.
22#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
25pub enum TriggerObject {
26    /// The trigger fires once for each row affected by the triggering event
27    Row,
28    /// The trigger fires once for the triggering SQL statement
29    Statement,
30}
31
32impl fmt::Display for TriggerObject {
33    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34        match self {
35            TriggerObject::Row => write!(f, "ROW"),
36            TriggerObject::Statement => write!(f, "STATEMENT"),
37        }
38    }
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
42#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
43#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
44/// This clause indicates whether the following relation name is for the before-image transition relation or the after-image transition relation
45pub enum TriggerReferencingType {
46    /// The transition relation containing the old rows affected by the triggering statement
47    OldTable,
48    /// The transition relation containing the new rows affected by the triggering statement
49    NewTable,
50}
51
52impl fmt::Display for TriggerReferencingType {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        match self {
55            TriggerReferencingType::OldTable => write!(f, "OLD TABLE"),
56            TriggerReferencingType::NewTable => write!(f, "NEW TABLE"),
57        }
58    }
59}
60
61/// This keyword immediately precedes the declaration of one or two relation names that provide access to the transition relations of the triggering statement
62#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
63#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
64#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
65pub struct TriggerReferencing {
66    /// The referencing type (`OLD TABLE` or `NEW TABLE`).
67    pub refer_type: TriggerReferencingType,
68    /// True if the `AS` keyword is present in the referencing clause.
69    pub is_as: bool,
70    /// The transition relation name provided by the referencing clause.
71    pub transition_relation_name: ObjectName,
72}
73
74impl fmt::Display for TriggerReferencing {
75    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76        write!(
77            f,
78            "{refer_type}{is_as} {relation_name}",
79            refer_type = self.refer_type,
80            is_as = if self.is_as { " AS" } else { "" },
81            relation_name = self.transition_relation_name
82        )
83    }
84}
85
86/// Used to describe trigger events
87#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
88#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
89#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
90pub enum TriggerEvent {
91    /// Trigger on INSERT event
92    Insert,
93    /// Trigger on UPDATE event, with optional list of columns
94    Update(Vec<Ident>),
95    /// Trigger on DELETE event
96    Delete,
97    /// Trigger on TRUNCATE event
98    Truncate,
99}
100
101impl fmt::Display for TriggerEvent {
102    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103        match self {
104            TriggerEvent::Insert => write!(f, "INSERT"),
105            TriggerEvent::Update(columns) => {
106                write!(f, "UPDATE")?;
107                if !columns.is_empty() {
108                    write!(f, " OF")?;
109                    write!(f, " {}", display_comma_separated(columns))?;
110                }
111                Ok(())
112            }
113            TriggerEvent::Delete => write!(f, "DELETE"),
114            TriggerEvent::Truncate => write!(f, "TRUNCATE"),
115        }
116    }
117}
118
119/// Trigger period
120#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
122#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
123pub enum TriggerPeriod {
124    /// The trigger fires once for each row affected by the triggering event
125    For,
126    /// The trigger fires once for the triggering SQL statement
127    After,
128    /// The trigger fires before the triggering event
129    Before,
130    /// The trigger fires instead of the triggering event
131    InsteadOf,
132}
133
134impl fmt::Display for TriggerPeriod {
135    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
136        match self {
137            TriggerPeriod::For => write!(f, "FOR"),
138            TriggerPeriod::After => write!(f, "AFTER"),
139            TriggerPeriod::Before => write!(f, "BEFORE"),
140            TriggerPeriod::InsteadOf => write!(f, "INSTEAD OF"),
141        }
142    }
143}
144
145/// Types of trigger body execution body.
146#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
147#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
148#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
149pub enum TriggerExecBodyType {
150    /// Execute a function
151    Function,
152    /// Execute a procedure
153    Procedure,
154}
155
156impl fmt::Display for TriggerExecBodyType {
157    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
158        match self {
159            TriggerExecBodyType::Function => write!(f, "FUNCTION"),
160            TriggerExecBodyType::Procedure => write!(f, "PROCEDURE"),
161        }
162    }
163}
164/// This keyword immediately precedes the declaration of one or two relation names that provide access to the transition relations of the triggering statement
165#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
166#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
167#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
168pub struct TriggerExecBody {
169    /// Whether the body is a `FUNCTION` or `PROCEDURE` invocation.
170    pub exec_type: TriggerExecBodyType,
171    /// Description of the function/procedure to execute.
172    pub func_desc: FunctionDesc,
173}
174
175impl fmt::Display for TriggerExecBody {
176    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
177        write!(
178            f,
179            "{exec_type} {func_desc}",
180            exec_type = self.exec_type,
181            func_desc = self.func_desc
182        )
183    }
184}