databend_common_ast/ast/statements/
procedure.rs1use std::fmt::Display;
16use std::fmt::Formatter;
17
18use derive_visitor::Drive;
19use derive_visitor::DriveMut;
20
21use crate::ast::CreateOption;
22use crate::ast::Expr;
23use crate::ast::Identifier;
24use crate::ast::TypeName;
25use crate::ast::write_comma_separated_list;
26
27#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
28pub struct ExecuteImmediateStmt {
29 pub script: Expr,
30}
31
32impl Display for ExecuteImmediateStmt {
33 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
34 write!(f, "EXECUTE IMMEDIATE {}", self.script)?;
35 Ok(())
36 }
37}
38
39#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
40pub struct ProcedureType {
41 pub name: Option<String>,
42 pub data_type: TypeName,
43}
44
45impl Display for ProcedureType {
46 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
47 if let Some(name) = &self.name {
48 write!(f, "{} {}", name, self.data_type)
49 } else {
50 write!(f, "{}", self.data_type)
51 }
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
56pub enum ProcedureLanguage {
57 SQL,
58}
59
60impl Display for ProcedureLanguage {
61 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
62 match self {
63 ProcedureLanguage::SQL => write!(f, "LANGUAGE SQL "),
64 }
65 }
66}
67
68#[derive(Clone, PartialEq, Drive, DriveMut)]
69pub struct ProcedureIdentity {
70 pub name: String,
71 pub args_type: Vec<TypeName>,
72}
73
74impl std::fmt::Debug for ProcedureIdentity {
75 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
76 f.debug_struct("ProcedureIdentity")
77 .field("name", &self.name)
78 .field(
79 "args_type",
80 &self
81 .args_type
82 .iter()
83 .map(|t| t.to_string())
84 .collect::<Vec<_>>()
85 .join(","),
86 )
87 .finish()
88 }
89}
90
91impl Display for ProcedureIdentity {
92 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
93 write!(
94 f,
95 "{}({})",
96 &self.name,
97 self.args_type
98 .iter()
99 .map(|t| t.to_string())
100 .collect::<Vec<_>>()
101 .join(",")
102 )
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
107pub struct CreateProcedureStmt {
108 pub create_option: CreateOption,
109 pub name: ProcedureIdentity,
110 pub language: ProcedureLanguage,
111 pub args: Option<Vec<ProcedureType>>,
113 pub return_type: Vec<ProcedureType>,
114 pub comment: Option<String>,
115 pub script: String,
116}
117
118impl Display for CreateProcedureStmt {
119 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
124 write!(f, "CREATE")?;
125 if let CreateOption::CreateOrReplace = self.create_option {
126 write!(f, " OR REPLACE")?;
127 }
128 write!(f, " PROCEDURE")?;
129 if let CreateOption::CreateIfNotExists = self.create_option {
130 write!(f, " IF NOT EXISTS")?;
131 }
132 write!(f, " {}", self.name.name)?;
133 if let Some(args) = &self.args {
134 if args.is_empty() {
135 write!(f, "()")?;
136 } else {
137 write!(f, "(")?;
138 write_comma_separated_list(f, args.clone())?;
139 write!(f, ")")?;
140 }
141 } else {
142 write!(f, "()")?;
143 }
144 if self.return_type.len() == 1 {
145 if let Some(name) = &self.return_type[0].name {
146 write!(
147 f,
148 " RETURNS TABLE({} {})",
149 name, self.return_type[0].data_type
150 )?;
151 } else {
152 write!(f, " RETURNS {}", self.return_type[0].data_type)?;
153 }
154 } else {
155 write!(f, " RETURNS TABLE(")?;
156 write_comma_separated_list(f, self.return_type.clone())?;
157 write!(f, ")")?;
158 }
159
160 write!(f, " {}", self.language)?;
161 if let Some(comment) = &self.comment {
162 write!(f, " COMMENT='{}'", comment)?;
163 }
164 write!(f, " AS $$\n{}\n$$", self.script)?;
165 Ok(())
166 }
167}
168
169#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
170pub struct DropProcedureStmt {
171 pub if_exists: bool,
172 pub name: ProcedureIdentity,
173}
174
175impl Display for DropProcedureStmt {
176 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
177 write!(f, "DROP PROCEDURE ")?;
178 if self.if_exists {
179 write!(f, "IF EXISTS ")?;
180 }
181 write!(f, "{}", self.name)?;
182
183 Ok(())
184 }
185}
186#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
187pub struct DescProcedureStmt {
188 pub name: ProcedureIdentity,
189}
190
191impl Display for DescProcedureStmt {
192 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
193 write!(f, "DESCRIBE PROCEDURE {}", self.name)?;
194 Ok(())
195 }
196}
197
198#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
199pub struct CallProcedureStmt {
200 pub name: Identifier,
201 pub args: Vec<Expr>,
202}
203
204impl Display for CallProcedureStmt {
205 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
206 let CallProcedureStmt { name, args } = self;
207 write!(f, "CALL PROCEDURE {}(", name)?;
208 write_comma_separated_list(f, args)?;
209 write!(f, ")")?;
210 Ok(())
211 }
212}