1use crate::sql::parser::ast::SelectStatement;
2
3pub struct IntoClauseRemover;
22
23impl IntoClauseRemover {
24 pub fn remove_into_clause(statement: SelectStatement) -> SelectStatement {
35 Self::remove_from_statement(statement)
36 }
37
38 fn remove_from_statement(mut statement: SelectStatement) -> SelectStatement {
40 statement.into_table = None;
42
43 if let Some(subquery) = statement.from_subquery.take() {
45 statement.from_subquery = Some(Box::new(Self::remove_from_statement(*subquery)));
46 }
47
48 statement.joins = statement
50 .joins
51 .into_iter()
52 .map(|mut join| {
53 if let crate::sql::parser::ast::TableSource::DerivedTable { query, alias } =
54 join.table
55 {
56 join.table = crate::sql::parser::ast::TableSource::DerivedTable {
57 query: Box::new(Self::remove_from_statement(*query)),
58 alias,
59 };
60 }
61 join
62 })
63 .collect();
64
65 statement.select_items = statement
67 .select_items
68 .into_iter()
69 .map(|item| Self::remove_from_select_item(item))
70 .collect();
71
72 if let Some(mut where_clause) = statement.where_clause.take() {
74 for condition in &mut where_clause.conditions {
75 condition.expr = Self::remove_from_expression(condition.expr.clone());
76 }
77 statement.where_clause = Some(where_clause);
78 }
79
80 statement.set_operations = statement
82 .set_operations
83 .into_iter()
84 .map(|(op, query)| (op, Box::new(Self::remove_from_statement(*query))))
85 .collect();
86
87 statement
88 }
89
90 fn remove_from_select_item(
92 item: crate::sql::parser::ast::SelectItem,
93 ) -> crate::sql::parser::ast::SelectItem {
94 match item {
95 crate::sql::parser::ast::SelectItem::Expression {
96 expr,
97 alias,
98 leading_comments,
99 trailing_comment,
100 } => crate::sql::parser::ast::SelectItem::Expression {
101 expr: Self::remove_from_expression(expr),
102 alias,
103 leading_comments,
104 trailing_comment,
105 },
106 other => other,
107 }
108 }
109
110 fn remove_from_expression(
112 expr: crate::sql::parser::ast::SqlExpression,
113 ) -> crate::sql::parser::ast::SqlExpression {
114 use crate::sql::parser::ast::SqlExpression;
115
116 match expr {
117 SqlExpression::ScalarSubquery { query } => SqlExpression::ScalarSubquery {
118 query: Box::new(Self::remove_from_statement(*query)),
119 },
120 SqlExpression::InSubquery { expr, subquery } => SqlExpression::InSubquery {
121 expr: Box::new(Self::remove_from_expression(*expr)),
122 subquery: Box::new(Self::remove_from_statement(*subquery)),
123 },
124 SqlExpression::NotInSubquery { expr, subquery } => SqlExpression::NotInSubquery {
125 expr: Box::new(Self::remove_from_expression(*expr)),
126 subquery: Box::new(Self::remove_from_statement(*subquery)),
127 },
128 SqlExpression::BinaryOp { left, op, right } => SqlExpression::BinaryOp {
129 left: Box::new(Self::remove_from_expression(*left)),
130 op,
131 right: Box::new(Self::remove_from_expression(*right)),
132 },
133 SqlExpression::FunctionCall {
134 name,
135 args,
136 distinct,
137 } => SqlExpression::FunctionCall {
138 name,
139 args: args
140 .into_iter()
141 .map(|arg| Self::remove_from_expression(arg))
142 .collect(),
143 distinct,
144 },
145 SqlExpression::CaseExpression {
146 when_branches,
147 else_branch,
148 } => SqlExpression::CaseExpression {
149 when_branches: when_branches
150 .into_iter()
151 .map(|branch| crate::sql::parser::ast::WhenBranch {
152 condition: Box::new(Self::remove_from_expression(*branch.condition)),
153 result: Box::new(Self::remove_from_expression(*branch.result)),
154 })
155 .collect(),
156 else_branch: else_branch.map(|e| Box::new(Self::remove_from_expression(*e))),
157 },
158 SqlExpression::SimpleCaseExpression {
159 expr,
160 when_branches,
161 else_branch,
162 } => SqlExpression::SimpleCaseExpression {
163 expr: Box::new(Self::remove_from_expression(*expr)),
164 when_branches: when_branches
165 .into_iter()
166 .map(|branch| crate::sql::parser::ast::SimpleWhenBranch {
167 value: Box::new(Self::remove_from_expression(*branch.value)),
168 result: Box::new(Self::remove_from_expression(*branch.result)),
169 })
170 .collect(),
171 else_branch: else_branch.map(|e| Box::new(Self::remove_from_expression(*e))),
172 },
173 SqlExpression::InList { expr, values } => SqlExpression::InList {
174 expr: Box::new(Self::remove_from_expression(*expr)),
175 values: values
176 .into_iter()
177 .map(|e| Self::remove_from_expression(e))
178 .collect(),
179 },
180 SqlExpression::NotInList { expr, values } => SqlExpression::NotInList {
181 expr: Box::new(Self::remove_from_expression(*expr)),
182 values: values
183 .into_iter()
184 .map(|e| Self::remove_from_expression(e))
185 .collect(),
186 },
187 SqlExpression::Between { expr, lower, upper } => SqlExpression::Between {
188 expr: Box::new(Self::remove_from_expression(*expr)),
189 lower: Box::new(Self::remove_from_expression(*lower)),
190 upper: Box::new(Self::remove_from_expression(*upper)),
191 },
192 SqlExpression::Not { expr } => SqlExpression::Not {
193 expr: Box::new(Self::remove_from_expression(*expr)),
194 },
195 other => other,
197 }
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204 use crate::sql::parser::ast::IntoTable;
205
206 #[test]
207 fn test_remove_simple_into() {
208 let stmt = SelectStatement {
209 distinct: false,
210 columns: vec!["col1".to_string()],
211 select_items: vec![],
212 from_source: None,
213 #[allow(deprecated)]
214 from_table: Some("table1".to_string()),
215 #[allow(deprecated)]
216 from_subquery: None,
217 #[allow(deprecated)]
218 from_function: None,
219 #[allow(deprecated)]
220 from_alias: None,
221 joins: vec![],
222 where_clause: None,
223 order_by: None,
224 group_by: None,
225 having: None,
226 qualify: None,
227 limit: None,
228 offset: None,
229 ctes: vec![],
230 into_table: Some(IntoTable {
231 name: "#temp".to_string(),
232 }),
233 set_operations: vec![],
234 leading_comments: vec![],
235 trailing_comment: None,
236 };
237
238 let result = IntoClauseRemover::remove_into_clause(stmt);
239 assert!(result.into_table.is_none());
240 assert_eq!(result.from_table, Some("table1".to_string()));
241 }
242
243 #[test]
244 fn test_remove_into_from_subquery() {
245 let subquery = SelectStatement {
246 distinct: false,
247 columns: vec![],
248 select_items: vec![],
249 from_source: None,
250 #[allow(deprecated)]
251 from_table: Some("inner_table".to_string()),
252 #[allow(deprecated)]
253 from_subquery: None,
254 #[allow(deprecated)]
255 from_function: None,
256 #[allow(deprecated)]
257 from_alias: None,
258 joins: vec![],
259 where_clause: None,
260 order_by: None,
261 group_by: None,
262 having: None,
263 qualify: None,
264 limit: None,
265 offset: None,
266 ctes: vec![],
267 into_table: Some(IntoTable {
268 name: "#inner_temp".to_string(),
269 }),
270 set_operations: vec![],
271 leading_comments: vec![],
272 trailing_comment: None,
273 };
274
275 let stmt = SelectStatement {
276 distinct: false,
277 columns: vec![],
278 select_items: vec![],
279 from_source: None,
280 #[allow(deprecated)]
281 from_table: None,
282 #[allow(deprecated)]
283 from_subquery: Some(Box::new(subquery)),
284 #[allow(deprecated)]
285 from_function: None,
286 #[allow(deprecated)]
287 from_alias: Some("subq".to_string()),
288 joins: vec![],
289 where_clause: None,
290 order_by: None,
291 group_by: None,
292 having: None,
293 qualify: None,
294 limit: None,
295 offset: None,
296 ctes: vec![],
297 into_table: Some(IntoTable {
298 name: "#outer_temp".to_string(),
299 }),
300 set_operations: vec![],
301 leading_comments: vec![],
302 trailing_comment: None,
303 };
304
305 let result = IntoClauseRemover::remove_into_clause(stmt);
306
307 assert!(result.into_table.is_none());
309 assert!(result.from_subquery.as_ref().unwrap().into_table.is_none());
310 }
311}