1use crate::dialects::transform_recursive;
10use crate::dialects::{Dialect, DialectType};
11use crate::error::{Error, Result};
12use crate::expressions::{
13 Alias, BinaryOp, BooleanLiteral, Cast, DataType, Exists, Expression, From, Function,
14 Identifier, Join, JoinKind, Lateral, LateralView, Literal, NamedArgSeparator, NamedArgument,
15 Over, Select, StructField, Subquery, Tuple, UnaryFunc, UnnestFunc, Where, WindowFunction, With,
16 WithinGroup,
17};
18use std::cell::RefCell;
19
20pub fn preprocess<F>(expr: Expression, transforms: &[F]) -> Result<Expression>
29where
30 F: Fn(Expression) -> Result<Expression>,
31{
32 let mut result = expr;
33 for transform in transforms {
34 result = transform(result)?;
35 }
36 Ok(result)
37}
38
39const MAX_TSQL_GROUPING_SETS: usize = 4096;
40
41pub(crate) fn normalize_grouping_sets_for_tsql(expr: Expression) -> Result<Expression> {
45 transform_recursive(expr, &|expr| {
46 let Expression::Select(mut select) = expr else {
47 return Ok(expr);
48 };
49
50 if let Some(group_by) = select.group_by.as_mut() {
51 group_by.expressions = std::mem::take(&mut group_by.expressions)
52 .into_iter()
53 .map(normalize_tsql_grouping_element)
54 .collect();
55 }
56
57 Ok(Expression::Select(select))
58 })
59}
60
61fn normalize_tsql_grouping_element(expression: Expression) -> Expression {
62 match expression {
63 Expression::Function(mut function)
64 if !function.quoted && function.name.eq_ignore_ascii_case("GROUPING SETS") =>
65 {
66 function.args = normalize_tsql_grouping_sets(std::mem::take(&mut function.args));
67 Expression::Function(function)
68 }
69 Expression::GroupingSets(mut grouping_sets) => {
70 grouping_sets.expressions =
71 normalize_tsql_grouping_sets(std::mem::take(&mut grouping_sets.expressions));
72 Expression::GroupingSets(grouping_sets)
73 }
74 Expression::Function(mut function)
75 if !function.quoted
76 && (function.name.eq_ignore_ascii_case("ROLLUP")
77 || function.name.eq_ignore_ascii_case("CUBE")) =>
78 {
79 function.args = std::mem::take(&mut function.args)
80 .into_iter()
81 .map(normalize_tsql_grouping_unit)
82 .collect();
83 Expression::Function(function)
84 }
85 Expression::Rollup(mut rollup) => {
86 rollup.expressions = std::mem::take(&mut rollup.expressions)
87 .into_iter()
88 .map(normalize_tsql_grouping_unit)
89 .collect();
90 Expression::Rollup(rollup)
91 }
92 Expression::Cube(mut cube) => {
93 cube.expressions = std::mem::take(&mut cube.expressions)
94 .into_iter()
95 .map(normalize_tsql_grouping_unit)
96 .collect();
97 Expression::Cube(cube)
98 }
99 other => other,
100 }
101}
102
103fn normalize_tsql_grouping_sets(expressions: Vec<Expression>) -> Vec<Expression> {
104 let mut normalized = Vec::new();
105
106 for expression in expressions {
107 match expression {
108 Expression::Function(mut function)
109 if !function.quoted && function.name.eq_ignore_ascii_case("GROUPING SETS") =>
110 {
111 normalized.extend(normalize_tsql_grouping_sets(std::mem::take(
112 &mut function.args,
113 )));
114 }
115 Expression::GroupingSets(mut grouping_sets) => {
116 normalized.extend(normalize_tsql_grouping_sets(std::mem::take(
117 &mut grouping_sets.expressions,
118 )));
119 }
120 other => normalized.push(normalize_tsql_grouping_unit(
121 normalize_tsql_grouping_element(other),
122 )),
123 }
124 }
125
126 normalized
127}
128
129fn normalize_tsql_grouping_unit(expression: Expression) -> Expression {
130 let Expression::Tuple(tuple) = expression else {
131 return expression;
132 };
133
134 let mut expressions = Vec::new();
135 for expression in tuple.expressions {
136 append_tsql_grouping_unit(expression, &mut expressions);
137 }
138
139 Expression::Tuple(Box::new(Tuple { expressions }))
140}
141
142fn append_tsql_grouping_unit(expression: Expression, expressions: &mut Vec<Expression>) {
143 match expression {
144 Expression::Tuple(tuple) => {
145 for expression in tuple.expressions {
146 append_tsql_grouping_unit(expression, expressions);
147 }
148 }
149 Expression::Paren(paren) => append_tsql_grouping_unit(paren.this, expressions),
150 other => {
151 if !expressions.contains(&other) {
152 expressions.push(other);
153 }
154 }
155 }
156}
157
158pub fn expand_distinct_grouping_sets_for_tsql(
161 expr: Expression,
162 target: DialectType,
163) -> Result<Expression> {
164 transform_recursive(expr, &|expr| {
165 let Expression::Select(mut select) = expr else {
166 return Ok(expr);
167 };
168
169 let Some(group_by) = select.group_by.as_mut() else {
170 return Ok(Expression::Select(select));
171 };
172 if group_by.all != Some(false) {
173 return Ok(Expression::Select(select));
174 }
175
176 let mut product = vec![Vec::new()];
177 let mut has_advanced_grouping = false;
178
179 for element in &group_by.expressions {
180 let alternatives = match expand_grouping_element(element, target)? {
181 Some(alternatives) => {
182 has_advanced_grouping = true;
183 alternatives
184 }
185 None => vec![vec![element.clone()]],
186 };
187
188 let expanded_len = product
189 .len()
190 .checked_mul(alternatives.len())
191 .filter(|len| *len <= MAX_TSQL_GROUPING_SETS)
192 .ok_or_else(|| grouping_set_expansion_error(target))?;
193 let mut next = Vec::with_capacity(expanded_len);
194
195 for left in &product {
196 for right in &alternatives {
197 let mut combined = left.clone();
198 for expression in right {
199 if !combined.contains(expression) {
200 combined.push(expression.clone());
201 }
202 }
203 next.push(combined);
204 }
205 }
206 product = next;
207 }
208
209 if !has_advanced_grouping {
210 return Ok(Expression::Select(select));
211 }
212
213 let mut distinct_sets = Vec::with_capacity(product.len());
214 for grouping_set in product {
215 if !distinct_sets.contains(&grouping_set) {
216 distinct_sets.push(grouping_set);
217 }
218 }
219
220 let sets = distinct_sets
221 .into_iter()
222 .map(|expressions| Expression::Tuple(Box::new(Tuple { expressions })))
223 .collect();
224 group_by.all = None;
225 group_by.expressions = vec![Expression::Function(Box::new(Function::new(
226 "GROUPING SETS".to_string(),
227 sets,
228 )))];
229
230 Ok(Expression::Select(select))
231 })
232}
233
234fn expand_grouping_element(
235 expression: &Expression,
236 target: DialectType,
237) -> Result<Option<Vec<Vec<Expression>>>> {
238 match expression {
239 Expression::Function(function) if function.name.eq_ignore_ascii_case("ROLLUP") => {
240 Ok(Some(expand_rollup(&function.args)))
241 }
242 Expression::Function(function) if function.name.eq_ignore_ascii_case("CUBE") => {
243 Ok(Some(expand_cube(&function.args, target)?))
244 }
245 Expression::Function(function) if function.name.eq_ignore_ascii_case("GROUPING SETS") => {
246 Ok(Some(expand_explicit_grouping_sets(&function.args, target)?))
247 }
248 Expression::Rollup(rollup) => Ok(Some(expand_rollup(&rollup.expressions))),
249 Expression::Cube(cube) => Ok(Some(expand_cube(&cube.expressions, target)?)),
250 Expression::GroupingSets(grouping_sets) => Ok(Some(expand_explicit_grouping_sets(
251 &grouping_sets.expressions,
252 target,
253 )?)),
254 _ => Ok(None),
255 }
256}
257
258fn expand_rollup(elements: &[Expression]) -> Vec<Vec<Expression>> {
259 (0..=elements.len())
260 .rev()
261 .map(|end| flatten_grouping_units(&elements[..end]))
262 .collect()
263}
264
265fn expand_cube(elements: &[Expression], target: DialectType) -> Result<Vec<Vec<Expression>>> {
266 let set_count = 1usize
267 .checked_shl(elements.len() as u32)
268 .filter(|count| *count <= MAX_TSQL_GROUPING_SETS)
269 .ok_or_else(|| grouping_set_expansion_error(target))?;
270
271 Ok((0..set_count)
272 .rev()
273 .map(|mask| {
274 let selected = elements
275 .iter()
276 .enumerate()
277 .filter_map(|(index, element)| {
278 let bit = elements.len() - index - 1;
279 (mask & (1usize << bit) != 0).then_some(element)
280 })
281 .cloned()
282 .collect::<Vec<_>>();
283 flatten_grouping_units(&selected)
284 })
285 .collect())
286}
287
288fn expand_explicit_grouping_sets(
289 elements: &[Expression],
290 target: DialectType,
291) -> Result<Vec<Vec<Expression>>> {
292 let mut sets = Vec::new();
293 for element in elements {
294 if let Some(nested) = expand_grouping_element(element, target)? {
295 sets.extend(nested);
296 } else {
297 sets.push(flatten_grouping_unit(element));
298 }
299 if sets.len() > MAX_TSQL_GROUPING_SETS {
300 return Err(grouping_set_expansion_error(target));
301 }
302 }
303 Ok(sets)
304}
305
306fn flatten_grouping_units(elements: &[Expression]) -> Vec<Expression> {
307 elements.iter().flat_map(flatten_grouping_unit).collect()
308}
309
310fn flatten_grouping_unit(expression: &Expression) -> Vec<Expression> {
311 match expression {
312 Expression::Tuple(tuple) => tuple.expressions.clone(),
313 Expression::Paren(paren) => flatten_grouping_unit(&paren.this),
314 _ => vec![expression.clone()],
315 }
316}
317
318fn grouping_set_expansion_error(target: DialectType) -> Error {
319 Error::unsupported(
320 format!("GROUP BY DISTINCT expansion beyond {MAX_TSQL_GROUPING_SETS} grouping sets"),
321 target.to_string(),
322 )
323}
324
325pub fn grouped_percentiles_to_tsql_windows(expr: Expression) -> Result<Expression> {
333 transform_recursive(expr, &grouped_percentiles_to_tsql_windows_inner)
334}
335
336fn grouped_percentiles_to_tsql_windows_inner(expr: Expression) -> Result<Expression> {
337 let Expression::Select(select) = expr else {
338 return Ok(expr);
339 };
340
341 rewrite_grouped_percentile_select(*select).map(|select| Expression::Select(Box::new(select)))
342}
343
344fn rewrite_grouped_percentile_select(select: Select) -> Result<Select> {
345 let Some(group_by) = &select.group_by else {
346 return Ok(select);
347 };
348
349 if select.having.is_some()
350 || group_by.all.is_some()
351 || group_by.totals
352 || group_by.expressions.is_empty()
353 || group_by.expressions.iter().any(is_complex_grouping_expr)
354 {
355 return Ok(select);
356 }
357
358 let partition_by = group_by.expressions.clone();
359 let mut changed = false;
360 let mut rewritten_expressions = Vec::with_capacity(select.expressions.len());
361
362 for expression in &select.expressions {
363 if is_group_projection(expression, &partition_by) {
364 rewritten_expressions.push(expression.clone());
365 continue;
366 }
367
368 let Some(rewritten) = rewrite_grouped_percentile_projection(expression, &partition_by)
369 else {
370 return Ok(select);
371 };
372
373 changed = true;
374 rewritten_expressions.push(rewritten);
375 }
376
377 if !changed {
378 return Ok(select);
379 }
380
381 let mut rewritten = select;
382 rewritten.expressions = rewritten_expressions;
383 rewritten.group_by = None;
384 rewritten.distinct = true;
385 Ok(rewritten)
386}
387
388fn is_complex_grouping_expr(expr: &Expression) -> bool {
389 matches!(
390 expr,
391 Expression::Cube(_) | Expression::Rollup(_) | Expression::GroupingSets(_)
392 ) || matches!(expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("GROUPING SETS"))
393}
394
395fn is_group_projection(expr: &Expression, group_by: &[Expression]) -> bool {
396 let inner = match expr {
397 Expression::Alias(alias) => &alias.this,
398 other => other,
399 };
400
401 group_by.iter().any(|group_expr| inner == group_expr)
402}
403
404fn rewrite_grouped_percentile_projection(
405 expr: &Expression,
406 partition_by: &[Expression],
407) -> Option<Expression> {
408 match expr {
409 Expression::Alias(alias) => {
410 let rewritten = rewrite_grouped_percentile_expr(&alias.this, partition_by)?;
411 let mut alias = alias.as_ref().clone();
412 alias.this = rewritten;
413 Some(Expression::Alias(Box::new(alias)))
414 }
415 other => rewrite_grouped_percentile_expr(other, partition_by),
416 }
417}
418
419fn rewrite_grouped_percentile_expr(
420 expr: &Expression,
421 partition_by: &[Expression],
422) -> Option<Expression> {
423 let Expression::WithinGroup(within_group) = expr else {
424 return None;
425 };
426
427 if !is_percentile_ordered_set(&within_group.this) || within_group.order_by.len() != 1 {
428 return None;
429 }
430
431 let mut order_by = within_group.order_by.clone();
432 order_by[0].nulls_first = None;
436
437 Some(Expression::WindowFunction(Box::new(WindowFunction {
438 this: Expression::WithinGroup(Box::new(WithinGroup {
439 this: within_group.this.clone(),
440 order_by,
441 })),
442 over: Over {
443 window_name: None,
444 partition_by: partition_by.to_vec(),
445 order_by: Vec::new(),
446 frame: None,
447 alias: None,
448 },
449 keep: None,
450 inferred_type: None,
451 })))
452}
453
454fn is_percentile_ordered_set(expr: &Expression) -> bool {
455 match expr {
456 Expression::Function(function) => is_percentile_name(&function.name),
457 Expression::AggregateFunction(function) => is_percentile_name(&function.name),
458 Expression::PercentileCont(_) | Expression::PercentileDisc(_) => true,
459 _ => false,
460 }
461}
462
463fn is_percentile_name(name: &str) -> bool {
464 name.eq_ignore_ascii_case("PERCENTILE_CONT") || name.eq_ignore_ascii_case("PERCENTILE_DISC")
465}
466
467pub fn unnest_to_explode(expr: Expression) -> Result<Expression> {
471 match expr {
472 Expression::Unnest(unnest) => {
473 Ok(Expression::Explode(Box::new(UnaryFunc::new(unnest.this))))
474 }
475 _ => Ok(expr),
476 }
477}
478
479pub fn unnest_to_explode_select(expr: Expression) -> Result<Expression> {
489 transform_recursive(expr, &unnest_to_explode_select_inner)
490}
491
492fn make_udtf_expr(unnest: &UnnestFunc) -> Expression {
495 let has_multi_expr = !unnest.expressions.is_empty();
496 if has_multi_expr {
497 let mut all_args = vec![unnest.this.clone()];
499 all_args.extend(unnest.expressions.iter().cloned());
500 let arrays_zip =
501 Expression::Function(Box::new(Function::new("ARRAYS_ZIP".to_string(), all_args)));
502 Expression::Function(Box::new(Function::new(
503 "INLINE".to_string(),
504 vec![arrays_zip],
505 )))
506 } else {
507 Expression::Explode(Box::new(UnaryFunc::new(unnest.this.clone())))
509 }
510}
511
512fn unnest_to_explode_select_inner(expr: Expression) -> Result<Expression> {
513 let Expression::Select(mut select) = expr else {
514 return Ok(expr);
515 };
516
517 if let Some(ref mut from) = select.from {
519 if from.expressions.len() >= 1 {
520 let mut new_from_exprs = Vec::new();
521 let mut new_lateral_views = Vec::new();
522 let first_is_unnest = is_unnest_expr(&from.expressions[0]);
523
524 for (idx, from_item) in from.expressions.drain(..).enumerate() {
525 if idx == 0 && first_is_unnest {
526 let replaced = replace_from_unnest(from_item);
529 new_from_exprs.push(replaced);
530 } else if idx > 0 && is_unnest_expr(&from_item) {
531 let (alias_name, column_aliases, unnest_func) = extract_unnest_info(from_item);
533 let udtf = make_udtf_expr(&unnest_func);
534 new_lateral_views.push(LateralView {
535 this: udtf,
536 table_alias: alias_name,
537 column_aliases,
538 outer: false,
539 });
540 } else {
541 new_from_exprs.push(from_item);
542 }
543 }
544
545 from.expressions = new_from_exprs;
546 select.lateral_views.extend(new_lateral_views);
548 }
549 }
550
551 let mut remaining_joins = Vec::new();
553 for join in select.joins.drain(..) {
554 if matches!(join.kind, JoinKind::Cross | JoinKind::Inner) {
555 let (is_unnest, is_lateral) = check_join_unnest(&join.this);
556 if is_unnest {
557 let (lateral_alias, lateral_col_aliases, join_expr) = if is_lateral {
559 if let Expression::Lateral(lat) = join.this {
560 let alias = lat.alias.map(|s| Identifier::new(&s));
562 let col_aliases: Vec<Identifier> = lat
563 .column_aliases
564 .iter()
565 .map(|s| Identifier::new(s))
566 .collect();
567 (alias, col_aliases, *lat.this)
568 } else {
569 (None, Vec::new(), join.this)
570 }
571 } else {
572 (None, Vec::new(), join.this)
573 };
574
575 let (alias_name, column_aliases, unnest_func) = extract_unnest_info(join_expr);
576
577 let final_alias = lateral_alias.or(alias_name);
579 let final_col_aliases = if !lateral_col_aliases.is_empty() {
580 lateral_col_aliases
581 } else {
582 column_aliases
583 };
584
585 let table_alias = final_alias.or_else(|| Some(Identifier::new("unnest")));
587 let col_aliases = if final_col_aliases.is_empty() {
588 vec![Identifier::new("unnest")]
589 } else {
590 final_col_aliases
591 };
592
593 let udtf = make_udtf_expr(&unnest_func);
594 select.lateral_views.push(LateralView {
595 this: udtf,
596 table_alias,
597 column_aliases: col_aliases,
598 outer: false,
599 });
600 } else {
601 remaining_joins.push(join);
602 }
603 } else {
604 remaining_joins.push(join);
605 }
606 }
607 select.joins = remaining_joins;
608
609 Ok(Expression::Select(select))
610}
611
612fn is_unnest_expr(expr: &Expression) -> bool {
614 match expr {
615 Expression::Unnest(_) => true,
616 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
617 _ => false,
618 }
619}
620
621fn check_join_unnest(expr: &Expression) -> (bool, bool) {
623 match expr {
624 Expression::Unnest(_) => (true, false),
625 Expression::Alias(a) => {
626 if matches!(a.this, Expression::Unnest(_)) {
627 (true, false)
628 } else {
629 (false, false)
630 }
631 }
632 Expression::Lateral(lat) => match &*lat.this {
633 Expression::Unnest(_) => (true, true),
634 Expression::Alias(a) => {
635 if matches!(a.this, Expression::Unnest(_)) {
636 (true, true)
637 } else {
638 (false, true)
639 }
640 }
641 _ => (false, true),
642 },
643 _ => (false, false),
644 }
645}
646
647fn replace_from_unnest(from_item: Expression) -> Expression {
649 match from_item {
650 Expression::Alias(mut a) => {
651 if let Expression::Unnest(unnest) = a.this {
652 a.this = make_udtf_expr(&unnest);
653 }
654 Expression::Alias(a)
655 }
656 Expression::Unnest(unnest) => make_udtf_expr(&unnest),
657 other => other,
658 }
659}
660
661fn extract_unnest_info(expr: Expression) -> (Option<Identifier>, Vec<Identifier>, UnnestFunc) {
663 match expr {
664 Expression::Alias(a) => {
665 if let Expression::Unnest(unnest) = a.this {
666 (Some(a.alias), a.column_aliases, *unnest)
667 } else {
668 (
670 Some(a.alias),
671 a.column_aliases,
672 UnnestFunc {
673 this: a.this,
674 expressions: Vec::new(),
675 with_ordinality: false,
676 alias: None,
677 offset_alias: None,
678 inferred_type: None,
679 },
680 )
681 }
682 }
683 Expression::Unnest(unnest) => {
684 let alias = unnest.alias.clone();
685 (alias, Vec::new(), *unnest)
686 }
687 _ => (
688 None,
689 Vec::new(),
690 UnnestFunc {
691 this: expr,
692 expressions: Vec::new(),
693 with_ordinality: false,
694 alias: None,
695 offset_alias: None,
696 inferred_type: None,
697 },
698 ),
699 }
700}
701
702pub fn explode_to_unnest(expr: Expression) -> Result<Expression> {
704 match expr {
705 Expression::Explode(explode) => Ok(Expression::Unnest(Box::new(UnnestFunc {
706 this: explode.this,
707 expressions: Vec::new(),
708 with_ordinality: false,
709 alias: None,
710 offset_alias: None,
711 inferred_type: None,
712 }))),
713 _ => Ok(expr),
714 }
715}
716
717pub fn replace_bool_with_int(expr: Expression) -> Result<Expression> {
721 match expr {
722 Expression::Boolean(b) => {
723 let value = if b.value { "1" } else { "0" };
724 Ok(Expression::Literal(Box::new(Literal::Number(
725 value.to_string(),
726 ))))
727 }
728 _ => Ok(expr),
729 }
730}
731
732pub fn replace_int_with_bool(expr: Expression) -> Result<Expression> {
736 match expr {
737 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(n) if n == "1" || n == "0") =>
738 {
739 let Literal::Number(n) = lit.as_ref() else {
740 unreachable!()
741 };
742 Ok(Expression::Boolean(BooleanLiteral { value: n == "1" }))
743 }
744 _ => Ok(expr),
745 }
746}
747
748pub fn remove_precision_parameterized_types(expr: Expression) -> Result<Expression> {
753 Ok(strip_type_params_recursive(expr))
754}
755
756fn strip_type_params_recursive(expr: Expression) -> Expression {
758 match expr {
759 Expression::Cast(mut cast) => {
761 cast.to = strip_data_type_params(cast.to);
762 cast.this = strip_type_params_recursive(cast.this);
764 Expression::Cast(cast)
765 }
766 Expression::TryCast(mut try_cast) => {
768 try_cast.to = strip_data_type_params(try_cast.to);
769 try_cast.this = strip_type_params_recursive(try_cast.this);
770 Expression::TryCast(try_cast)
771 }
772 Expression::SafeCast(mut safe_cast) => {
774 safe_cast.to = strip_data_type_params(safe_cast.to);
775 safe_cast.this = strip_type_params_recursive(safe_cast.this);
776 Expression::SafeCast(safe_cast)
777 }
778 _ => expr,
781 }
782}
783
784fn strip_data_type_params(dt: DataType) -> DataType {
786 match dt {
787 DataType::Decimal { .. } => DataType::Decimal {
789 precision: None,
790 scale: None,
791 },
792 DataType::TinyInt { .. } => DataType::TinyInt { length: None },
793 DataType::SmallInt { .. } => DataType::SmallInt { length: None },
794 DataType::Int { .. } => DataType::Int {
795 length: None,
796 integer_spelling: false,
797 },
798 DataType::BigInt { .. } => DataType::BigInt { length: None },
799
800 DataType::Char { .. } => DataType::Char { length: None },
802 DataType::VarChar { .. } => DataType::VarChar {
803 length: None,
804 parenthesized_length: false,
805 },
806
807 DataType::Binary { .. } => DataType::Binary { length: None },
809 DataType::VarBinary { .. } => DataType::VarBinary { length: None },
810
811 DataType::Bit { .. } => DataType::Bit { length: None },
813 DataType::VarBit { .. } => DataType::VarBit { length: None },
814
815 DataType::Time { .. } => DataType::Time {
817 precision: None,
818 timezone: false,
819 },
820 DataType::Timestamp { timezone, .. } => DataType::Timestamp {
821 precision: None,
822 timezone,
823 },
824
825 DataType::Array {
827 element_type,
828 dimension,
829 } => DataType::Array {
830 element_type: Box::new(strip_data_type_params(*element_type)),
831 dimension,
832 },
833
834 DataType::Map {
836 key_type,
837 value_type,
838 } => DataType::Map {
839 key_type: Box::new(strip_data_type_params(*key_type)),
840 value_type: Box::new(strip_data_type_params(*value_type)),
841 },
842
843 DataType::Struct { fields, nested } => DataType::Struct {
845 fields: fields
846 .into_iter()
847 .map(|f| {
848 StructField::with_options(
849 f.name,
850 strip_data_type_params(f.data_type),
851 f.options,
852 )
853 })
854 .collect(),
855 nested,
856 },
857
858 DataType::Vector { element_type, .. } => DataType::Vector {
860 element_type: element_type.map(|et| Box::new(strip_data_type_params(*et))),
861 dimension: None,
862 },
863
864 DataType::Object { fields, modifier } => DataType::Object {
866 fields: fields
867 .into_iter()
868 .map(|(name, ty, not_null)| (name, strip_data_type_params(ty), not_null))
869 .collect(),
870 modifier,
871 },
872
873 other => other,
875 }
876}
877
878pub fn eliminate_qualify(expr: Expression) -> Result<Expression> {
893 match expr {
894 Expression::Select(mut select) => {
895 if let Some(qualify) = select.qualify.take() {
896 let qualify_filter = qualify.this;
903 let window_alias_name = "_w".to_string();
904 let window_alias_ident = Identifier::new(window_alias_name.clone());
905
906 let (window_expr, outer_where) =
909 extract_window_from_condition(qualify_filter.clone(), &window_alias_ident);
910
911 if let Some(win_expr) = window_expr {
912 let window_alias_expr =
914 Expression::Alias(Box::new(crate::expressions::Alias {
915 this: win_expr,
916 alias: window_alias_ident.clone(),
917 column_aliases: vec![],
918 alias_explicit_as: false,
919 alias_keyword: None,
920 pre_alias_comments: vec![],
921 trailing_comments: vec![],
922 inferred_type: None,
923 }));
924
925 let outer_exprs: Vec<Expression> = select
929 .expressions
930 .iter()
931 .map(|expr| {
932 if let Expression::Alias(a) = expr {
933 Expression::Column(Box::new(crate::expressions::Column {
935 name: a.alias.clone(),
936 table: None,
937 join_mark: false,
938 trailing_comments: vec![],
939 span: None,
940 inferred_type: None,
941 }))
942 } else {
943 expr.clone()
944 }
945 })
946 .collect();
947 select.expressions.push(window_alias_expr);
948
949 let inner_select = Expression::Select(select);
951 let subquery = Subquery {
952 this: inner_select,
953 alias: Some(Identifier::new("_t".to_string())),
954 column_aliases: vec![],
955 alias_explicit_as: false,
956 alias_keyword: None,
957 order_by: None,
958 limit: None,
959 offset: None,
960 distribute_by: None,
961 sort_by: None,
962 cluster_by: None,
963 lateral: false,
964 modifiers_inside: false,
965 trailing_comments: vec![],
966 inferred_type: None,
967 };
968
969 let outer_select = Select {
971 expressions: outer_exprs,
972 from: Some(From {
973 expressions: vec![Expression::Subquery(Box::new(subquery))],
974 }),
975 where_clause: Some(Where { this: outer_where }),
976 ..Select::new()
977 };
978
979 return Ok(Expression::Select(Box::new(outer_select)));
980 } else {
981 let qualify_alias = Expression::Alias(Box::new(crate::expressions::Alias {
983 this: qualify_filter.clone(),
984 alias: window_alias_ident.clone(),
985 column_aliases: vec![],
986 alias_explicit_as: false,
987 alias_keyword: None,
988 pre_alias_comments: vec![],
989 trailing_comments: vec![],
990 inferred_type: None,
991 }));
992
993 let original_exprs = select.expressions.clone();
994 select.expressions.push(qualify_alias);
995
996 let inner_select = Expression::Select(select);
997 let subquery = Subquery {
998 this: inner_select,
999 alias: Some(Identifier::new("_t".to_string())),
1000 column_aliases: vec![],
1001 alias_explicit_as: false,
1002 alias_keyword: None,
1003 order_by: None,
1004 limit: None,
1005 offset: None,
1006 distribute_by: None,
1007 sort_by: None,
1008 cluster_by: None,
1009 lateral: false,
1010 modifiers_inside: false,
1011 trailing_comments: vec![],
1012 inferred_type: None,
1013 };
1014
1015 let outer_select = Select {
1016 expressions: original_exprs,
1017 from: Some(From {
1018 expressions: vec![Expression::Subquery(Box::new(subquery))],
1019 }),
1020 where_clause: Some(Where {
1021 this: Expression::Column(Box::new(crate::expressions::Column {
1022 name: window_alias_ident,
1023 table: None,
1024 join_mark: false,
1025 trailing_comments: vec![],
1026 span: None,
1027 inferred_type: None,
1028 })),
1029 }),
1030 ..Select::new()
1031 };
1032
1033 return Ok(Expression::Select(Box::new(outer_select)));
1034 }
1035 }
1036 Ok(Expression::Select(select))
1037 }
1038 other => Ok(other),
1039 }
1040}
1041
1042fn extract_window_from_condition(
1046 condition: Expression,
1047 alias: &Identifier,
1048) -> (Option<Expression>, Expression) {
1049 let alias_col = Expression::Column(Box::new(crate::expressions::Column {
1050 name: alias.clone(),
1051 table: None,
1052 join_mark: false,
1053 trailing_comments: vec![],
1054 span: None,
1055 inferred_type: None,
1056 }));
1057
1058 match condition {
1060 Expression::Eq(ref op) => {
1062 if is_window_expr(&op.left) {
1063 (
1064 Some(op.left.clone()),
1065 Expression::Eq(Box::new(BinaryOp {
1066 left: alias_col,
1067 right: op.right.clone(),
1068 ..(**op).clone()
1069 })),
1070 )
1071 } else if is_window_expr(&op.right) {
1072 (
1073 Some(op.right.clone()),
1074 Expression::Eq(Box::new(BinaryOp {
1075 left: op.left.clone(),
1076 right: alias_col,
1077 ..(**op).clone()
1078 })),
1079 )
1080 } else {
1081 (None, condition)
1082 }
1083 }
1084 Expression::Neq(ref op) => {
1085 if is_window_expr(&op.left) {
1086 (
1087 Some(op.left.clone()),
1088 Expression::Neq(Box::new(BinaryOp {
1089 left: alias_col,
1090 right: op.right.clone(),
1091 ..(**op).clone()
1092 })),
1093 )
1094 } else if is_window_expr(&op.right) {
1095 (
1096 Some(op.right.clone()),
1097 Expression::Neq(Box::new(BinaryOp {
1098 left: op.left.clone(),
1099 right: alias_col,
1100 ..(**op).clone()
1101 })),
1102 )
1103 } else {
1104 (None, condition)
1105 }
1106 }
1107 Expression::Lt(ref op) => {
1108 if is_window_expr(&op.left) {
1109 (
1110 Some(op.left.clone()),
1111 Expression::Lt(Box::new(BinaryOp {
1112 left: alias_col,
1113 right: op.right.clone(),
1114 ..(**op).clone()
1115 })),
1116 )
1117 } else if is_window_expr(&op.right) {
1118 (
1119 Some(op.right.clone()),
1120 Expression::Lt(Box::new(BinaryOp {
1121 left: op.left.clone(),
1122 right: alias_col,
1123 ..(**op).clone()
1124 })),
1125 )
1126 } else {
1127 (None, condition)
1128 }
1129 }
1130 Expression::Lte(ref op) => {
1131 if is_window_expr(&op.left) {
1132 (
1133 Some(op.left.clone()),
1134 Expression::Lte(Box::new(BinaryOp {
1135 left: alias_col,
1136 right: op.right.clone(),
1137 ..(**op).clone()
1138 })),
1139 )
1140 } else if is_window_expr(&op.right) {
1141 (
1142 Some(op.right.clone()),
1143 Expression::Lte(Box::new(BinaryOp {
1144 left: op.left.clone(),
1145 right: alias_col,
1146 ..(**op).clone()
1147 })),
1148 )
1149 } else {
1150 (None, condition)
1151 }
1152 }
1153 Expression::Gt(ref op) => {
1154 if is_window_expr(&op.left) {
1155 (
1156 Some(op.left.clone()),
1157 Expression::Gt(Box::new(BinaryOp {
1158 left: alias_col,
1159 right: op.right.clone(),
1160 ..(**op).clone()
1161 })),
1162 )
1163 } else if is_window_expr(&op.right) {
1164 (
1165 Some(op.right.clone()),
1166 Expression::Gt(Box::new(BinaryOp {
1167 left: op.left.clone(),
1168 right: alias_col,
1169 ..(**op).clone()
1170 })),
1171 )
1172 } else {
1173 (None, condition)
1174 }
1175 }
1176 Expression::Gte(ref op) => {
1177 if is_window_expr(&op.left) {
1178 (
1179 Some(op.left.clone()),
1180 Expression::Gte(Box::new(BinaryOp {
1181 left: alias_col,
1182 right: op.right.clone(),
1183 ..(**op).clone()
1184 })),
1185 )
1186 } else if is_window_expr(&op.right) {
1187 (
1188 Some(op.right.clone()),
1189 Expression::Gte(Box::new(BinaryOp {
1190 left: op.left.clone(),
1191 right: alias_col,
1192 ..(**op).clone()
1193 })),
1194 )
1195 } else {
1196 (None, condition)
1197 }
1198 }
1199 _ if is_window_expr(&condition) => (Some(condition), alias_col),
1201 _ => (None, condition),
1203 }
1204}
1205
1206fn is_window_expr(expr: &Expression) -> bool {
1208 matches!(expr, Expression::Window(_) | Expression::WindowFunction(_))
1209}
1210
1211pub fn eliminate_distinct_on(expr: Expression) -> Result<Expression> {
1230 eliminate_distinct_on_for_dialect(expr, None, None)
1231}
1232
1233pub fn strip_cte_materialization(expr: Expression) -> Result<Expression> {
1236 transform_recursive(expr, &strip_cte_materialization_single)
1237}
1238
1239fn strip_cte_materialization_single(expr: Expression) -> Result<Expression> {
1240 Ok(match expr {
1241 Expression::Select(mut select) => {
1242 strip_with_cte_materialization(&mut select.with);
1243 Expression::Select(select)
1244 }
1245 Expression::Union(mut union) => {
1246 strip_with_cte_materialization(&mut union.with);
1247 Expression::Union(union)
1248 }
1249 Expression::Intersect(mut intersect) => {
1250 strip_with_cte_materialization(&mut intersect.with);
1251 Expression::Intersect(intersect)
1252 }
1253 Expression::Except(mut except) => {
1254 strip_with_cte_materialization(&mut except.with);
1255 Expression::Except(except)
1256 }
1257 Expression::Pivot(mut pivot) => {
1258 strip_with_cte_materialization(&mut pivot.with);
1259 Expression::Pivot(pivot)
1260 }
1261 Expression::Insert(mut insert) => {
1262 strip_with_cte_materialization(&mut insert.with);
1263 Expression::Insert(insert)
1264 }
1265 Expression::Update(mut update) => {
1266 strip_with_cte_materialization(&mut update.with);
1267 Expression::Update(update)
1268 }
1269 Expression::Delete(mut delete) => {
1270 strip_with_cte_materialization(&mut delete.with);
1271 Expression::Delete(delete)
1272 }
1273 Expression::CreateTable(mut create_table) => {
1274 strip_with_cte_materialization(&mut create_table.with_cte);
1275 Expression::CreateTable(create_table)
1276 }
1277 Expression::With(mut with) => {
1278 strip_cte_materialization_in_with(&mut with);
1279 Expression::With(with)
1280 }
1281 Expression::Cte(mut cte) => {
1282 cte.materialized = None;
1283 Expression::Cte(cte)
1284 }
1285 _ => expr,
1286 })
1287}
1288
1289fn strip_with_cte_materialization(with: &mut Option<With>) {
1290 if let Some(with) = with {
1291 strip_cte_materialization_in_with(with);
1292 }
1293}
1294
1295fn strip_cte_materialization_in_with(with: &mut With) {
1296 for cte in &mut with.ctes {
1297 cte.materialized = None;
1298 }
1299}
1300
1301#[derive(Clone, Copy)]
1302enum DistinctOnNullsMode {
1303 None,
1304 NullsFirst,
1305 CaseExpr,
1306}
1307
1308pub fn eliminate_distinct_on_for_dialect(
1313 expr: Expression,
1314 target: Option<DialectType>,
1315 source: Option<DialectType>,
1316) -> Result<Expression> {
1317 if matches!(
1319 target,
1320 Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB)
1321 ) {
1322 return Ok(expr);
1323 }
1324
1325 let nulls_mode = match target {
1330 Some(DialectType::MySQL)
1331 | Some(DialectType::SingleStore)
1332 | Some(DialectType::TSQL)
1333 | Some(DialectType::Fabric) => DistinctOnNullsMode::CaseExpr,
1334 Some(DialectType::Oracle) | Some(DialectType::Redshift) | Some(DialectType::Snowflake) => {
1335 DistinctOnNullsMode::None
1336 }
1337 Some(DialectType::StarRocks) => {
1338 if matches!(source, Some(DialectType::Redshift)) {
1339 DistinctOnNullsMode::CaseExpr
1340 } else {
1341 DistinctOnNullsMode::None
1342 }
1343 }
1344 _ => DistinctOnNullsMode::NullsFirst,
1346 };
1347
1348 transform_recursive(expr, &|expr| eliminate_distinct_on_select(expr, nulls_mode))
1349}
1350
1351fn eliminate_distinct_on_select(
1352 expr: Expression,
1353 nulls_mode: DistinctOnNullsMode,
1354) -> Result<Expression> {
1355 use crate::expressions::Case;
1356
1357 match expr {
1358 Expression::Select(mut select) => {
1359 if let Some(distinct_cols) = select.distinct_on.take() {
1360 if !distinct_cols.is_empty() {
1361 let row_number_alias = Identifier::new("_row_number".to_string());
1363
1364 let order_exprs = if let Some(ref order_by) = select.order_by {
1366 let mut exprs = order_by.expressions.clone();
1367 match nulls_mode {
1369 DistinctOnNullsMode::NullsFirst => {
1370 for ord in &mut exprs {
1371 if ord.desc && ord.nulls_first.is_none() {
1372 ord.nulls_first = Some(true);
1373 }
1374 }
1375 }
1376 DistinctOnNullsMode::CaseExpr => {
1377 let mut new_exprs = Vec::new();
1380 for ord in &exprs {
1381 if ord.desc && ord.nulls_first.is_none() {
1382 let null_check = Expression::Case(Box::new(Case {
1384 operand: None,
1385 whens: vec![(
1386 Expression::IsNull(Box::new(
1387 crate::expressions::IsNull {
1388 this: ord.this.clone(),
1389 not: false,
1390 postfix_form: false,
1391 },
1392 )),
1393 Expression::Literal(Box::new(Literal::Number(
1394 "1".to_string(),
1395 ))),
1396 )],
1397 else_: Some(Expression::Literal(Box::new(
1398 Literal::Number("0".to_string()),
1399 ))),
1400 comments: Vec::new(),
1401 inferred_type: None,
1402 }));
1403 new_exprs.push(crate::expressions::Ordered {
1404 this: null_check,
1405 desc: true,
1406 nulls_first: None,
1407 explicit_asc: false,
1408 with_fill: None,
1409 });
1410 }
1411 new_exprs.push(ord.clone());
1412 }
1413 exprs = new_exprs;
1414 }
1415 DistinctOnNullsMode::None => {}
1416 }
1417 exprs
1418 } else {
1419 distinct_cols
1420 .iter()
1421 .map(|e| crate::expressions::Ordered {
1422 this: e.clone(),
1423 desc: false,
1424 nulls_first: None,
1425 explicit_asc: false,
1426 with_fill: None,
1427 })
1428 .collect()
1429 };
1430
1431 let row_number_func =
1433 Expression::WindowFunction(Box::new(crate::expressions::WindowFunction {
1434 this: Expression::RowNumber(crate::expressions::RowNumber),
1435 over: Over {
1436 partition_by: distinct_cols,
1437 order_by: order_exprs,
1438 frame: None,
1439 window_name: None,
1440 alias: None,
1441 },
1442 keep: None,
1443 inferred_type: None,
1444 }));
1445
1446 let mut inner_aliased_exprs = Vec::new();
1450 let mut outer_select_exprs = Vec::new();
1451 for orig_expr in &select.expressions {
1452 match orig_expr {
1453 Expression::Alias(alias) => {
1454 inner_aliased_exprs.push(orig_expr.clone());
1456 outer_select_exprs.push(Expression::Column(Box::new(
1457 crate::expressions::Column {
1458 name: alias.alias.clone(),
1459 table: None,
1460 join_mark: false,
1461 trailing_comments: vec![],
1462 span: None,
1463 inferred_type: None,
1464 },
1465 )));
1466 }
1467 Expression::Column(col) => {
1468 inner_aliased_exprs.push(Expression::Alias(Box::new(
1470 crate::expressions::Alias {
1471 this: orig_expr.clone(),
1472 alias: col.name.clone(),
1473 column_aliases: vec![],
1474 alias_explicit_as: false,
1475 alias_keyword: None,
1476 pre_alias_comments: vec![],
1477 trailing_comments: vec![],
1478 inferred_type: None,
1479 },
1480 )));
1481 outer_select_exprs.push(Expression::Column(Box::new(
1482 crate::expressions::Column {
1483 name: col.name.clone(),
1484 table: None,
1485 join_mark: false,
1486 trailing_comments: vec![],
1487 span: None,
1488 inferred_type: None,
1489 },
1490 )));
1491 }
1492 _ => {
1493 inner_aliased_exprs.push(orig_expr.clone());
1495 outer_select_exprs.push(orig_expr.clone());
1496 }
1497 }
1498 }
1499
1500 let row_number_alias_expr =
1502 Expression::Alias(Box::new(crate::expressions::Alias {
1503 this: row_number_func,
1504 alias: row_number_alias.clone(),
1505 column_aliases: vec![],
1506 alias_explicit_as: false,
1507 alias_keyword: None,
1508 pre_alias_comments: vec![],
1509 trailing_comments: vec![],
1510 inferred_type: None,
1511 }));
1512 inner_aliased_exprs.push(row_number_alias_expr);
1513
1514 select.expressions = inner_aliased_exprs;
1516
1517 let _inner_order_by = select.order_by.take();
1519
1520 select.distinct = false;
1522
1523 let inner_select = Expression::Select(select);
1525 let subquery = Subquery {
1526 this: inner_select,
1527 alias: Some(Identifier::new("_t".to_string())),
1528 column_aliases: vec![],
1529 alias_explicit_as: false,
1530 alias_keyword: None,
1531 order_by: None,
1532 limit: None,
1533 offset: None,
1534 distribute_by: None,
1535 sort_by: None,
1536 cluster_by: None,
1537 lateral: false,
1538 modifiers_inside: false,
1539 trailing_comments: vec![],
1540 inferred_type: None,
1541 };
1542
1543 let outer_select = Select {
1546 expressions: outer_select_exprs,
1547 from: Some(From {
1548 expressions: vec![Expression::Subquery(Box::new(subquery))],
1549 }),
1550 where_clause: Some(Where {
1551 this: Expression::Eq(Box::new(BinaryOp {
1552 left: Expression::Column(Box::new(crate::expressions::Column {
1553 name: row_number_alias,
1554 table: None,
1555 join_mark: false,
1556 trailing_comments: vec![],
1557 span: None,
1558 inferred_type: None,
1559 })),
1560 right: Expression::Literal(Box::new(Literal::Number(
1561 "1".to_string(),
1562 ))),
1563 left_comments: vec![],
1564 operator_comments: vec![],
1565 trailing_comments: vec![],
1566 inferred_type: None,
1567 })),
1568 }),
1569 ..Select::new()
1570 };
1571
1572 return Ok(Expression::Select(Box::new(outer_select)));
1573 }
1574 }
1575 Ok(Expression::Select(select))
1576 }
1577 other => Ok(other),
1578 }
1579}
1580
1581pub fn eliminate_semi_and_anti_joins(expr: Expression) -> Result<Expression> {
1589 match expr {
1590 Expression::Select(mut select) => {
1591 let mut new_joins = Vec::new();
1592 let mut extra_where_conditions = Vec::new();
1593
1594 for join in select.joins.drain(..) {
1595 match join.kind {
1596 JoinKind::Semi | JoinKind::LeftSemi => {
1597 if let Some(on_condition) = join.on {
1598 let subquery_select = Select {
1600 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1601 "1".to_string(),
1602 )))],
1603 from: Some(From {
1604 expressions: vec![join.this],
1605 }),
1606 where_clause: Some(Where { this: on_condition }),
1607 ..Select::new()
1608 };
1609
1610 let exists = Expression::Exists(Box::new(Exists {
1611 this: Expression::Subquery(Box::new(Subquery {
1612 this: Expression::Select(Box::new(subquery_select)),
1613 alias: None,
1614 column_aliases: vec![],
1615 alias_explicit_as: false,
1616 alias_keyword: None,
1617 order_by: None,
1618 limit: None,
1619 offset: None,
1620 distribute_by: None,
1621 sort_by: None,
1622 cluster_by: None,
1623 lateral: false,
1624 modifiers_inside: false,
1625 trailing_comments: vec![],
1626 inferred_type: None,
1627 })),
1628 not: false,
1629 }));
1630
1631 extra_where_conditions.push(exists);
1632 }
1633 }
1634 JoinKind::Anti | JoinKind::LeftAnti => {
1635 if let Some(on_condition) = join.on {
1636 let subquery_select = Select {
1638 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1639 "1".to_string(),
1640 )))],
1641 from: Some(From {
1642 expressions: vec![join.this],
1643 }),
1644 where_clause: Some(Where { this: on_condition }),
1645 ..Select::new()
1646 };
1647
1648 let not_exists = Expression::Exists(Box::new(Exists {
1650 this: Expression::Subquery(Box::new(Subquery {
1651 this: Expression::Select(Box::new(subquery_select)),
1652 alias: None,
1653 column_aliases: vec![],
1654 alias_explicit_as: false,
1655 alias_keyword: None,
1656 order_by: None,
1657 limit: None,
1658 offset: None,
1659 distribute_by: None,
1660 sort_by: None,
1661 cluster_by: None,
1662 lateral: false,
1663 modifiers_inside: false,
1664 trailing_comments: vec![],
1665 inferred_type: None,
1666 })),
1667 not: true,
1668 }));
1669
1670 extra_where_conditions.push(not_exists);
1671 }
1672 }
1673 _ => {
1674 new_joins.push(join);
1676 }
1677 }
1678 }
1679
1680 select.joins = new_joins;
1681
1682 if !extra_where_conditions.is_empty() {
1684 let combined = extra_where_conditions
1685 .into_iter()
1686 .reduce(|acc, cond| {
1687 Expression::And(Box::new(BinaryOp {
1688 left: acc,
1689 right: cond,
1690 left_comments: vec![],
1691 operator_comments: vec![],
1692 trailing_comments: vec![],
1693 inferred_type: None,
1694 }))
1695 })
1696 .unwrap();
1697
1698 select.where_clause = match select.where_clause {
1699 Some(Where { this: existing }) => Some(Where {
1700 this: Expression::And(Box::new(BinaryOp {
1701 left: existing,
1702 right: combined,
1703 left_comments: vec![],
1704 operator_comments: vec![],
1705 trailing_comments: vec![],
1706 inferred_type: None,
1707 })),
1708 }),
1709 None => Some(Where { this: combined }),
1710 };
1711 }
1712
1713 Ok(Expression::Select(select))
1714 }
1715 other => Ok(other),
1716 }
1717}
1718
1719pub fn eliminate_full_outer_join(expr: Expression) -> Result<Expression> {
1737 match expr {
1738 Expression::Select(mut select) => {
1739 let full_outer_join_idx = select.joins.iter().position(|j| j.kind == JoinKind::Full);
1741
1742 if let Some(idx) = full_outer_join_idx {
1743 let full_join_count = select
1745 .joins
1746 .iter()
1747 .filter(|j| j.kind == JoinKind::Full)
1748 .count();
1749 if full_join_count != 1 {
1750 return Ok(Expression::Select(select));
1751 }
1752
1753 let mut right_select = select.clone();
1755
1756 let full_join = &select.joins[idx];
1758 let join_condition = full_join.on.clone();
1759
1760 select.joins[idx].kind = JoinKind::Left;
1762
1763 right_select.joins[idx].kind = JoinKind::Right;
1765
1766 if let (Some(ref from), Some(ref join_cond)) = (&select.from, &join_condition) {
1768 if !from.expressions.is_empty() {
1769 let anti_subquery = Expression::Select(Box::new(Select {
1770 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1771 "1".to_string(),
1772 )))],
1773 from: Some(from.clone()),
1774 where_clause: Some(Where {
1775 this: join_cond.clone(),
1776 }),
1777 ..Select::new()
1778 }));
1779
1780 let not_exists = Expression::Not(Box::new(crate::expressions::UnaryOp {
1781 inferred_type: None,
1782 this: Expression::Exists(Box::new(Exists {
1783 this: Expression::Subquery(Box::new(Subquery {
1784 this: anti_subquery,
1785 alias: None,
1786 column_aliases: vec![],
1787 alias_explicit_as: false,
1788 alias_keyword: None,
1789 order_by: None,
1790 limit: None,
1791 offset: None,
1792 distribute_by: None,
1793 sort_by: None,
1794 cluster_by: None,
1795 lateral: false,
1796 modifiers_inside: false,
1797 trailing_comments: vec![],
1798 inferred_type: None,
1799 })),
1800 not: false,
1801 })),
1802 }));
1803
1804 right_select.where_clause = Some(Where {
1806 this: match right_select.where_clause {
1807 Some(w) => Expression::And(Box::new(BinaryOp {
1808 left: w.this,
1809 right: not_exists,
1810 left_comments: vec![],
1811 operator_comments: vec![],
1812 trailing_comments: vec![],
1813 inferred_type: None,
1814 })),
1815 None => not_exists,
1816 },
1817 });
1818 }
1819 }
1820
1821 right_select.with = None;
1823
1824 let order_by = select.order_by.take();
1826
1827 let union = crate::expressions::Union {
1829 left: Expression::Select(select),
1830 right: Expression::Select(right_select),
1831 all: true, distinct: false,
1833 with: None,
1834 order_by,
1835 limit: None,
1836 offset: None,
1837 distribute_by: None,
1838 sort_by: None,
1839 cluster_by: None,
1840 by_name: false,
1841 side: None,
1842 kind: None,
1843 corresponding: false,
1844 strict: false,
1845 on_columns: Vec::new(),
1846 };
1847
1848 return Ok(Expression::Union(Box::new(union)));
1849 }
1850
1851 Ok(Expression::Select(select))
1852 }
1853 other => Ok(other),
1854 }
1855}
1856
1857pub fn move_ctes_to_top_level(expr: Expression) -> Result<Expression> {
1870 match expr {
1871 Expression::Select(mut select) => {
1872 let mut collected_ctes: Vec<crate::expressions::Cte> = Vec::new();
1874 let mut has_recursive = false;
1875
1876 collect_nested_ctes(
1877 &Expression::Select(select.clone()),
1878 &mut collected_ctes,
1879 &mut has_recursive,
1880 true,
1881 );
1882
1883 let mut cte_body_collected: Vec<(String, Vec<crate::expressions::Cte>)> = Vec::new();
1886 if let Some(ref with) = select.with {
1887 for cte in &with.ctes {
1888 let mut body_ctes: Vec<crate::expressions::Cte> = Vec::new();
1889 collect_ctes_from_cte_body(&cte.this, &mut body_ctes, &mut has_recursive);
1890 if !body_ctes.is_empty() {
1891 cte_body_collected.push((cte.alias.name.clone(), body_ctes));
1892 }
1893 }
1894 }
1895
1896 let has_subquery_ctes = !collected_ctes.is_empty();
1897 let has_body_ctes = !cte_body_collected.is_empty();
1898
1899 if has_subquery_ctes || has_body_ctes {
1900 strip_nested_with_clauses(&mut select, true);
1902
1903 if has_body_ctes {
1905 if let Some(ref mut with) = select.with {
1906 for cte in with.ctes.iter_mut() {
1907 strip_with_from_cte_body(&mut cte.this);
1908 }
1909 }
1910 }
1911
1912 let top_with = select.with.get_or_insert_with(|| crate::expressions::With {
1913 ctes: Vec::new(),
1914 recursive: false,
1915 leading_comments: vec![],
1916 search: None,
1917 });
1918
1919 if has_recursive {
1920 top_with.recursive = true;
1921 }
1922
1923 if has_body_ctes {
1925 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
1926 for mut cte in top_with.ctes.drain(..) {
1927 if let Some(pos) = cte_body_collected
1929 .iter()
1930 .position(|(name, _)| *name == cte.alias.name)
1931 {
1932 let (_, mut nested) = cte_body_collected.remove(pos);
1933 for nested_cte in nested.iter_mut() {
1935 strip_with_from_cte_body(&mut nested_cte.this);
1936 }
1937 new_ctes.extend(nested);
1938 }
1939 strip_with_from_cte_body(&mut cte.this);
1941 new_ctes.push(cte);
1942 }
1943 top_with.ctes = new_ctes;
1944 }
1945
1946 top_with.ctes.extend(collected_ctes);
1948 }
1949
1950 Ok(Expression::Select(select))
1951 }
1952 other => Ok(other),
1953 }
1954}
1955
1956fn collect_ctes_from_cte_body(
1958 expr: &Expression,
1959 collected: &mut Vec<crate::expressions::Cte>,
1960 has_recursive: &mut bool,
1961) {
1962 if let Expression::Select(select) = expr {
1963 if let Some(ref with) = select.with {
1964 if with.recursive {
1965 *has_recursive = true;
1966 }
1967 for cte in &with.ctes {
1968 collect_ctes_from_cte_body(&cte.this, collected, has_recursive);
1970 collected.push(cte.clone());
1972 }
1973 }
1974 }
1975}
1976
1977fn strip_with_from_cte_body(expr: &mut Expression) {
1979 if let Expression::Select(ref mut select) = expr {
1980 select.with = None;
1981 }
1982}
1983
1984fn strip_nested_with_clauses(select: &mut Select, _is_top_level: bool) {
1986 if let Some(ref mut from) = select.from {
1988 for expr in from.expressions.iter_mut() {
1989 strip_with_from_expr(expr);
1990 }
1991 }
1992 for join in select.joins.iter_mut() {
1994 strip_with_from_expr(&mut join.this);
1995 }
1996 for expr in select.expressions.iter_mut() {
1998 strip_with_from_expr(expr);
1999 }
2000 if let Some(ref mut w) = select.where_clause {
2002 strip_with_from_expr(&mut w.this);
2003 }
2004}
2005
2006fn strip_with_from_expr(expr: &mut Expression) {
2007 match expr {
2008 Expression::Subquery(ref mut subquery) => {
2009 strip_with_from_inner_query(&mut subquery.this);
2010 }
2011 Expression::Alias(ref mut alias) => {
2012 strip_with_from_expr(&mut alias.this);
2013 }
2014 Expression::Select(ref mut select) => {
2015 select.with = None;
2017 strip_nested_with_clauses(select, false);
2019 }
2020 _ => {}
2021 }
2022}
2023
2024fn strip_with_from_inner_query(expr: &mut Expression) {
2025 if let Expression::Select(ref mut select) = expr {
2026 select.with = None;
2027 strip_nested_with_clauses(select, false);
2028 }
2029}
2030
2031fn collect_nested_ctes(
2033 expr: &Expression,
2034 collected: &mut Vec<crate::expressions::Cte>,
2035 has_recursive: &mut bool,
2036 is_top_level: bool,
2037) {
2038 match expr {
2039 Expression::Select(select) => {
2040 if !is_top_level {
2042 if let Some(ref with) = select.with {
2043 if with.recursive {
2044 *has_recursive = true;
2045 }
2046 collected.extend(with.ctes.clone());
2047 }
2048 }
2049
2050 if let Some(ref from) = select.from {
2052 for expr in &from.expressions {
2053 collect_nested_ctes(expr, collected, has_recursive, false);
2054 }
2055 }
2056
2057 for join in &select.joins {
2059 collect_nested_ctes(&join.this, collected, has_recursive, false);
2060 }
2061
2062 for sel_expr in &select.expressions {
2064 collect_nested_ctes(sel_expr, collected, has_recursive, false);
2065 }
2066
2067 if let Some(ref where_clause) = select.where_clause {
2069 collect_nested_ctes(&where_clause.this, collected, has_recursive, false);
2070 }
2071 }
2072 Expression::Subquery(subquery) => {
2073 collect_nested_ctes(&subquery.this, collected, has_recursive, false);
2075 }
2076 Expression::Alias(alias) => {
2077 collect_nested_ctes(&alias.this, collected, has_recursive, false);
2078 }
2079 _ => {}
2081 }
2082}
2083
2084pub fn eliminate_window_clause(expr: Expression) -> Result<Expression> {
2100 match expr {
2101 Expression::Select(mut select) => {
2102 if let Some(named_windows) = select.windows.take() {
2103 let window_map: std::collections::HashMap<String, &Over> = named_windows
2105 .iter()
2106 .map(|nw| (nw.name.name.to_lowercase(), &nw.spec))
2107 .collect();
2108
2109 select.expressions = select
2111 .expressions
2112 .into_iter()
2113 .map(|e| inline_window_refs(e, &window_map))
2114 .collect();
2115 }
2116 Ok(Expression::Select(select))
2117 }
2118 other => Ok(other),
2119 }
2120}
2121
2122fn inline_window_refs(
2124 expr: Expression,
2125 window_map: &std::collections::HashMap<String, &Over>,
2126) -> Expression {
2127 match expr {
2128 Expression::WindowFunction(mut wf) => {
2129 if let Some(ref name) = wf.over.window_name {
2131 let key = name.name.to_lowercase();
2132 if let Some(named_spec) = window_map.get(&key) {
2133 if wf.over.partition_by.is_empty() && !named_spec.partition_by.is_empty() {
2135 wf.over.partition_by = named_spec.partition_by.clone();
2136 }
2137 if wf.over.order_by.is_empty() && !named_spec.order_by.is_empty() {
2138 wf.over.order_by = named_spec.order_by.clone();
2139 }
2140 if wf.over.frame.is_none() && named_spec.frame.is_some() {
2141 wf.over.frame = named_spec.frame.clone();
2142 }
2143 wf.over.window_name = None;
2145 }
2146 }
2147 Expression::WindowFunction(wf)
2148 }
2149 Expression::Alias(mut alias) => {
2150 alias.this = inline_window_refs(alias.this, window_map);
2152 Expression::Alias(alias)
2153 }
2154 other => other,
2157 }
2158}
2159
2160pub fn eliminate_join_marks(expr: Expression) -> Result<Expression> {
2174 match expr {
2175 Expression::Select(mut select) => {
2176 let has_join_marks = select
2178 .where_clause
2179 .as_ref()
2180 .map_or(false, |w| contains_join_mark(&w.this));
2181
2182 if !has_join_marks {
2183 return Ok(Expression::Select(select));
2184 }
2185
2186 let from_tables: Vec<String> = select
2188 .from
2189 .as_ref()
2190 .map(|f| {
2191 f.expressions
2192 .iter()
2193 .filter_map(|e| get_table_name(e))
2194 .collect()
2195 })
2196 .unwrap_or_default();
2197
2198 let mut join_conditions: std::collections::HashMap<String, Vec<Expression>> =
2200 std::collections::HashMap::new();
2201 let mut remaining_conditions: Vec<Expression> = Vec::new();
2202
2203 if let Some(ref where_clause) = select.where_clause {
2204 extract_join_mark_conditions(
2205 &where_clause.this,
2206 &mut join_conditions,
2207 &mut remaining_conditions,
2208 );
2209 }
2210
2211 let mut new_joins = select.joins.clone();
2213 for (table_name, conditions) in join_conditions {
2214 let table_in_from = from_tables.contains(&table_name);
2216
2217 if table_in_from && !conditions.is_empty() {
2218 let combined_condition = conditions.into_iter().reduce(|a, b| {
2220 Expression::And(Box::new(BinaryOp {
2221 left: a,
2222 right: b,
2223 left_comments: vec![],
2224 operator_comments: vec![],
2225 trailing_comments: vec![],
2226 inferred_type: None,
2227 }))
2228 });
2229
2230 if let Some(ref mut from) = select.from {
2232 if let Some(pos) = from
2233 .expressions
2234 .iter()
2235 .position(|e| get_table_name(e).map_or(false, |n| n == table_name))
2236 {
2237 if from.expressions.len() > 1 {
2238 let join_table = from.expressions.remove(pos);
2239 new_joins.push(crate::expressions::Join {
2240 this: join_table,
2241 kind: JoinKind::Left,
2242 on: combined_condition,
2243 using: vec![],
2244 use_inner_keyword: false,
2245 use_outer_keyword: true,
2246 deferred_condition: false,
2247 join_hint: None,
2248 match_condition: None,
2249 pivots: Vec::new(),
2250 comments: Vec::new(),
2251 nesting_group: 0,
2252 directed: false,
2253 });
2254 }
2255 }
2256 }
2257 }
2258 }
2259
2260 select.joins = new_joins;
2261
2262 if remaining_conditions.is_empty() {
2264 select.where_clause = None;
2265 } else {
2266 let combined = remaining_conditions.into_iter().reduce(|a, b| {
2267 Expression::And(Box::new(BinaryOp {
2268 left: a,
2269 right: b,
2270 left_comments: vec![],
2271 operator_comments: vec![],
2272 trailing_comments: vec![],
2273 inferred_type: None,
2274 }))
2275 });
2276 select.where_clause = combined.map(|c| Where { this: c });
2277 }
2278
2279 clear_join_marks(&mut Expression::Select(select.clone()));
2281
2282 Ok(Expression::Select(select))
2283 }
2284 other => Ok(other),
2285 }
2286}
2287
2288fn contains_join_mark(expr: &Expression) -> bool {
2290 match expr {
2291 Expression::Column(col) => col.join_mark,
2292 Expression::And(op) | Expression::Or(op) => {
2293 contains_join_mark(&op.left) || contains_join_mark(&op.right)
2294 }
2295 Expression::Eq(op)
2296 | Expression::Neq(op)
2297 | Expression::Lt(op)
2298 | Expression::Lte(op)
2299 | Expression::Gt(op)
2300 | Expression::Gte(op) => contains_join_mark(&op.left) || contains_join_mark(&op.right),
2301 Expression::Not(op) => contains_join_mark(&op.this),
2302 _ => false,
2303 }
2304}
2305
2306fn get_table_name(expr: &Expression) -> Option<String> {
2308 match expr {
2309 Expression::Table(t) => Some(t.name.name.clone()),
2310 Expression::Alias(a) => Some(a.alias.name.clone()),
2311 _ => None,
2312 }
2313}
2314
2315fn extract_join_mark_conditions(
2317 expr: &Expression,
2318 join_conditions: &mut std::collections::HashMap<String, Vec<Expression>>,
2319 remaining: &mut Vec<Expression>,
2320) {
2321 match expr {
2322 Expression::And(op) => {
2323 extract_join_mark_conditions(&op.left, join_conditions, remaining);
2324 extract_join_mark_conditions(&op.right, join_conditions, remaining);
2325 }
2326 _ => {
2327 if let Some(table) = get_join_mark_table(expr) {
2328 join_conditions
2329 .entry(table)
2330 .or_insert_with(Vec::new)
2331 .push(expr.clone());
2332 } else {
2333 remaining.push(expr.clone());
2334 }
2335 }
2336 }
2337}
2338
2339fn get_join_mark_table(expr: &Expression) -> Option<String> {
2341 match expr {
2342 Expression::Eq(op)
2343 | Expression::Neq(op)
2344 | Expression::Lt(op)
2345 | Expression::Lte(op)
2346 | Expression::Gt(op)
2347 | Expression::Gte(op) => {
2348 if let Expression::Column(col) = &op.left {
2350 if col.join_mark {
2351 return col.table.as_ref().map(|t| t.name.clone());
2352 }
2353 }
2354 if let Expression::Column(col) = &op.right {
2355 if col.join_mark {
2356 return col.table.as_ref().map(|t| t.name.clone());
2357 }
2358 }
2359 None
2360 }
2361 _ => None,
2362 }
2363}
2364
2365fn clear_join_marks(expr: &mut Expression) {
2367 match expr {
2368 Expression::Column(col) => col.join_mark = false,
2369 Expression::Select(select) => {
2370 if let Some(ref mut w) = select.where_clause {
2371 clear_join_marks(&mut w.this);
2372 }
2373 for sel_expr in &mut select.expressions {
2374 clear_join_marks(sel_expr);
2375 }
2376 }
2377 Expression::And(op) | Expression::Or(op) => {
2378 clear_join_marks(&mut op.left);
2379 clear_join_marks(&mut op.right);
2380 }
2381 Expression::Eq(op)
2382 | Expression::Neq(op)
2383 | Expression::Lt(op)
2384 | Expression::Lte(op)
2385 | Expression::Gt(op)
2386 | Expression::Gte(op) => {
2387 clear_join_marks(&mut op.left);
2388 clear_join_marks(&mut op.right);
2389 }
2390 _ => {}
2391 }
2392}
2393
2394pub fn add_recursive_cte_column_names(expr: Expression) -> Result<Expression> {
2401 match expr {
2402 Expression::Select(mut select) => {
2403 if let Some(ref mut with) = select.with {
2404 if with.recursive {
2405 let mut counter = 0;
2406 for cte in &mut with.ctes {
2407 if cte.columns.is_empty() {
2408 if let Expression::Select(ref cte_select) = cte.this {
2410 let names: Vec<Identifier> = cte_select
2411 .expressions
2412 .iter()
2413 .map(|e| match e {
2414 Expression::Alias(a) => a.alias.clone(),
2415 Expression::Column(c) => c.name.clone(),
2416 _ => {
2417 counter += 1;
2418 Identifier::new(format!("_c_{}", counter))
2419 }
2420 })
2421 .collect();
2422 cte.columns = names;
2423 }
2424 }
2425 }
2426 }
2427 }
2428 Ok(Expression::Select(select))
2429 }
2430 other => Ok(other),
2431 }
2432}
2433
2434pub fn epoch_cast_to_ts(expr: Expression) -> Result<Expression> {
2441 match expr {
2442 Expression::Cast(mut cast) => {
2443 if let Expression::Literal(ref lit) = cast.this {
2444 if let Literal::String(ref s) = lit.as_ref() {
2445 if s.to_lowercase() == "epoch" {
2446 if is_temporal_type(&cast.to) {
2447 cast.this = Expression::Literal(Box::new(Literal::String(
2448 "1970-01-01 00:00:00".to_string(),
2449 )));
2450 }
2451 }
2452 }
2453 }
2454 Ok(Expression::Cast(cast))
2455 }
2456 Expression::TryCast(mut try_cast) => {
2457 if let Expression::Literal(ref lit) = try_cast.this {
2458 if let Literal::String(ref s) = lit.as_ref() {
2459 if s.to_lowercase() == "epoch" {
2460 if is_temporal_type(&try_cast.to) {
2461 try_cast.this = Expression::Literal(Box::new(Literal::String(
2462 "1970-01-01 00:00:00".to_string(),
2463 )));
2464 }
2465 }
2466 }
2467 }
2468 Ok(Expression::TryCast(try_cast))
2469 }
2470 other => Ok(other),
2471 }
2472}
2473
2474fn is_temporal_type(dt: &DataType) -> bool {
2476 matches!(
2477 dt,
2478 DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. }
2479 )
2480}
2481
2482pub fn ensure_bools(expr: Expression) -> Result<Expression> {
2507 let expr = ensure_bools_in_value_context(expr);
2508
2509 Ok(match expr {
2510 Expression::And(_) | Expression::Or(_) | Expression::Not(_) => ensure_bool_condition(expr),
2512 other => other,
2513 })
2514}
2515
2516fn ensure_bools_in_value_context(expr: Expression) -> Expression {
2520 match expr {
2521 Expression::Case(mut case) => {
2522 let is_simple_case = case.operand.is_some();
2523 if let Some(operand) = case.operand.take() {
2524 case.operand = Some(ensure_bools_in_value_context(operand));
2525 }
2526 case.whens = case
2527 .whens
2528 .into_iter()
2529 .map(|(condition, result)| {
2530 let new_condition = if is_simple_case {
2531 ensure_bools_in_value_context(condition)
2532 } else {
2533 ensure_bool_condition(ensure_bools_in_value_context(condition))
2534 };
2535 let new_result = ensure_bools_in_value_context(result);
2536 (new_condition, new_result)
2537 })
2538 .collect();
2539 if let Some(else_expr) = case.else_ {
2540 case.else_ = Some(ensure_bools_in_value_context(else_expr));
2541 }
2542 Expression::Case(Box::new(*case))
2543 }
2544 Expression::Select(select) => Expression::Select(Box::new(ensure_bools_in_select(*select))),
2545 Expression::Subquery(mut subquery) => {
2546 subquery.this = ensure_bools_in_value_context(subquery.this);
2547 Expression::Subquery(subquery)
2548 }
2549 Expression::JoinedTable(mut joined_table) => {
2550 joined_table.left = ensure_bools_in_value_context(joined_table.left);
2551 joined_table.joins = joined_table
2552 .joins
2553 .into_iter()
2554 .map(ensure_bools_in_join)
2555 .collect();
2556 joined_table.lateral_views = joined_table
2557 .lateral_views
2558 .into_iter()
2559 .map(|mut lateral_view| {
2560 lateral_view.this = ensure_bools_in_value_context(lateral_view.this);
2561 lateral_view
2562 })
2563 .collect();
2564 Expression::JoinedTable(joined_table)
2565 }
2566 Expression::Union(mut union) => {
2567 let left = std::mem::replace(&mut union.left, Expression::null());
2568 let right = std::mem::replace(&mut union.right, Expression::null());
2569 union.left = ensure_bools_in_value_context(left);
2570 union.right = ensure_bools_in_value_context(right);
2571 if let Some(with) = union.with.take() {
2572 union.with = Some(ensure_bools_in_with(with));
2573 }
2574 Expression::Union(union)
2575 }
2576 Expression::Intersect(mut intersect) => {
2577 let left = std::mem::replace(&mut intersect.left, Expression::null());
2578 let right = std::mem::replace(&mut intersect.right, Expression::null());
2579 intersect.left = ensure_bools_in_value_context(left);
2580 intersect.right = ensure_bools_in_value_context(right);
2581 if let Some(with) = intersect.with.take() {
2582 intersect.with = Some(ensure_bools_in_with(with));
2583 }
2584 Expression::Intersect(intersect)
2585 }
2586 Expression::Except(mut except) => {
2587 let left = std::mem::replace(&mut except.left, Expression::null());
2588 let right = std::mem::replace(&mut except.right, Expression::null());
2589 except.left = ensure_bools_in_value_context(left);
2590 except.right = ensure_bools_in_value_context(right);
2591 if let Some(with) = except.with.take() {
2592 except.with = Some(ensure_bools_in_with(with));
2593 }
2594 Expression::Except(except)
2595 }
2596 Expression::Alias(mut alias) => {
2597 alias.this = ensure_bools_in_value_context(alias.this);
2598 Expression::Alias(alias)
2599 }
2600 Expression::Paren(mut paren) => {
2601 paren.this = ensure_bools_in_value_context(paren.this);
2602 Expression::Paren(paren)
2603 }
2604 other => other,
2605 }
2606}
2607
2608fn ensure_bools_in_select(mut select: Select) -> Select {
2609 select.expressions = select
2610 .expressions
2611 .into_iter()
2612 .map(ensure_bools_in_value_context)
2613 .collect();
2614
2615 if let Some(from) = select.from.take() {
2616 select.from = Some(crate::expressions::From {
2617 expressions: from
2618 .expressions
2619 .into_iter()
2620 .map(ensure_bools_in_value_context)
2621 .collect(),
2622 });
2623 }
2624
2625 select.joins = select.joins.into_iter().map(ensure_bools_in_join).collect();
2626
2627 if let Some(mut where_clause) = select.where_clause.take() {
2628 where_clause.this = ensure_bool_condition(ensure_bools_in_value_context(where_clause.this));
2629 select.where_clause = Some(where_clause);
2630 }
2631
2632 if let Some(mut having) = select.having.take() {
2633 having.this = ensure_bool_condition(ensure_bools_in_value_context(having.this));
2634 select.having = Some(having);
2635 }
2636
2637 if let Some(with) = select.with.take() {
2638 select.with = Some(ensure_bools_in_with(with));
2639 }
2640
2641 select
2642}
2643
2644fn ensure_bools_in_join(mut join: Join) -> Join {
2645 join.this = ensure_bools_in_value_context(join.this);
2646
2647 if let Some(on) = join.on.take() {
2648 join.on = Some(ensure_bool_condition(ensure_bools_in_value_context(on)));
2649 }
2650
2651 if let Some(match_condition) = join.match_condition.take() {
2652 join.match_condition = Some(ensure_bool_condition(ensure_bools_in_value_context(
2653 match_condition,
2654 )));
2655 }
2656
2657 join.pivots = join
2658 .pivots
2659 .into_iter()
2660 .map(ensure_bools_in_value_context)
2661 .collect();
2662
2663 join
2664}
2665
2666fn ensure_bools_in_with(mut with: With) -> With {
2667 with.ctes = with
2668 .ctes
2669 .into_iter()
2670 .map(|mut cte| {
2671 cte.this = ensure_bools_in_value_context(cte.this);
2672 cte
2673 })
2674 .collect();
2675 with
2676}
2677
2678fn is_boolean_expression(expr: &Expression) -> bool {
2681 matches!(
2682 expr,
2683 Expression::Eq(_)
2684 | Expression::Neq(_)
2685 | Expression::Lt(_)
2686 | Expression::Lte(_)
2687 | Expression::Gt(_)
2688 | Expression::Gte(_)
2689 | Expression::Is(_)
2690 | Expression::IsNull(_)
2691 | Expression::IsTrue(_)
2692 | Expression::IsFalse(_)
2693 | Expression::Like(_)
2694 | Expression::ILike(_)
2695 | Expression::StartsWith(_)
2696 | Expression::SimilarTo(_)
2697 | Expression::Glob(_)
2698 | Expression::RegexpLike(_)
2699 | Expression::In(_)
2700 | Expression::Between(_)
2701 | Expression::Exists(_)
2702 | Expression::And(_)
2703 | Expression::Or(_)
2704 | Expression::Not(_)
2705 | Expression::Any(_)
2706 | Expression::All(_)
2707 | Expression::NullSafeEq(_)
2708 | Expression::NullSafeNeq(_)
2709 | Expression::EqualNull(_)
2710 )
2711}
2712
2713fn wrap_neq_zero(expr: Expression) -> Expression {
2715 Expression::Neq(Box::new(BinaryOp {
2716 left: expr,
2717 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
2718 left_comments: vec![],
2719 operator_comments: vec![],
2720 trailing_comments: vec![],
2721 inferred_type: None,
2722 }))
2723}
2724
2725pub(crate) fn ensure_bool_condition(expr: Expression) -> Expression {
2731 match expr {
2732 Expression::And(op) => {
2734 let new_op = BinaryOp {
2735 left: ensure_bool_condition(op.left.clone()),
2736 right: ensure_bool_condition(op.right.clone()),
2737 left_comments: op.left_comments.clone(),
2738 operator_comments: op.operator_comments.clone(),
2739 trailing_comments: op.trailing_comments.clone(),
2740 inferred_type: None,
2741 };
2742 Expression::And(Box::new(new_op))
2743 }
2744 Expression::Or(op) => {
2745 let new_op = BinaryOp {
2746 left: ensure_bool_condition(op.left.clone()),
2747 right: ensure_bool_condition(op.right.clone()),
2748 left_comments: op.left_comments.clone(),
2749 operator_comments: op.operator_comments.clone(),
2750 trailing_comments: op.trailing_comments.clone(),
2751 inferred_type: None,
2752 };
2753 Expression::Or(Box::new(new_op))
2754 }
2755 Expression::Not(op) => Expression::Not(Box::new(crate::expressions::UnaryOp {
2757 this: ensure_bool_condition(op.this.clone()),
2758 inferred_type: None,
2759 })),
2760 Expression::Paren(paren) => Expression::Paren(Box::new(crate::expressions::Paren {
2762 this: ensure_bool_condition(paren.this.clone()),
2763 trailing_comments: paren.trailing_comments.clone(),
2764 })),
2765 Expression::Boolean(BooleanLiteral { value: true }) => {
2767 Expression::Paren(Box::new(crate::expressions::Paren {
2768 this: Expression::Eq(Box::new(BinaryOp {
2769 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2770 right: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2771 left_comments: vec![],
2772 operator_comments: vec![],
2773 trailing_comments: vec![],
2774 inferred_type: None,
2775 })),
2776 trailing_comments: vec![],
2777 }))
2778 }
2779 Expression::Boolean(BooleanLiteral { value: false }) => {
2780 Expression::Paren(Box::new(crate::expressions::Paren {
2781 this: Expression::Eq(Box::new(BinaryOp {
2782 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2783 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
2784 left_comments: vec![],
2785 operator_comments: vec![],
2786 trailing_comments: vec![],
2787 inferred_type: None,
2788 })),
2789 trailing_comments: vec![],
2790 }))
2791 }
2792 ref e if is_boolean_expression(e) => expr,
2794 _ => wrap_neq_zero(expr),
2797 }
2798}
2799
2800pub fn unqualify_columns(expr: Expression) -> Result<Expression> {
2806 Ok(unqualify_columns_recursive(expr))
2807}
2808
2809fn unqualify_columns_recursive(expr: Expression) -> Expression {
2811 match expr {
2812 Expression::Column(mut col) => {
2813 col.table = None;
2814 Expression::Column(col)
2815 }
2816 Expression::Select(mut select) => {
2817 select.expressions = select
2818 .expressions
2819 .into_iter()
2820 .map(unqualify_columns_recursive)
2821 .collect();
2822 if let Some(ref mut where_clause) = select.where_clause {
2823 where_clause.this = unqualify_columns_recursive(where_clause.this.clone());
2824 }
2825 if let Some(ref mut having) = select.having {
2826 having.this = unqualify_columns_recursive(having.this.clone());
2827 }
2828 if let Some(ref mut group_by) = select.group_by {
2829 group_by.expressions = group_by
2830 .expressions
2831 .iter()
2832 .cloned()
2833 .map(unqualify_columns_recursive)
2834 .collect();
2835 }
2836 if let Some(ref mut order_by) = select.order_by {
2837 order_by.expressions = order_by
2838 .expressions
2839 .iter()
2840 .map(|o| crate::expressions::Ordered {
2841 this: unqualify_columns_recursive(o.this.clone()),
2842 desc: o.desc,
2843 nulls_first: o.nulls_first,
2844 explicit_asc: o.explicit_asc,
2845 with_fill: o.with_fill.clone(),
2846 })
2847 .collect();
2848 }
2849 for join in &mut select.joins {
2850 if let Some(ref mut on) = join.on {
2851 *on = unqualify_columns_recursive(on.clone());
2852 }
2853 }
2854 Expression::Select(select)
2855 }
2856 Expression::Alias(mut alias) => {
2857 alias.this = unqualify_columns_recursive(alias.this);
2858 Expression::Alias(alias)
2859 }
2860 Expression::And(op) => Expression::And(Box::new(unqualify_binary_op(*op))),
2862 Expression::Or(op) => Expression::Or(Box::new(unqualify_binary_op(*op))),
2863 Expression::Eq(op) => Expression::Eq(Box::new(unqualify_binary_op(*op))),
2864 Expression::Neq(op) => Expression::Neq(Box::new(unqualify_binary_op(*op))),
2865 Expression::Lt(op) => Expression::Lt(Box::new(unqualify_binary_op(*op))),
2866 Expression::Lte(op) => Expression::Lte(Box::new(unqualify_binary_op(*op))),
2867 Expression::Gt(op) => Expression::Gt(Box::new(unqualify_binary_op(*op))),
2868 Expression::Gte(op) => Expression::Gte(Box::new(unqualify_binary_op(*op))),
2869 Expression::Add(op) => Expression::Add(Box::new(unqualify_binary_op(*op))),
2870 Expression::Sub(op) => Expression::Sub(Box::new(unqualify_binary_op(*op))),
2871 Expression::Mul(op) => Expression::Mul(Box::new(unqualify_binary_op(*op))),
2872 Expression::Div(op) => Expression::Div(Box::new(unqualify_binary_op(*op))),
2873 Expression::Function(mut func) => {
2875 func.args = func
2876 .args
2877 .into_iter()
2878 .map(unqualify_columns_recursive)
2879 .collect();
2880 Expression::Function(func)
2881 }
2882 Expression::AggregateFunction(mut func) => {
2883 func.args = func
2884 .args
2885 .into_iter()
2886 .map(unqualify_columns_recursive)
2887 .collect();
2888 Expression::AggregateFunction(func)
2889 }
2890 Expression::Case(mut case) => {
2891 case.whens = case
2892 .whens
2893 .into_iter()
2894 .map(|(cond, result)| {
2895 (
2896 unqualify_columns_recursive(cond),
2897 unqualify_columns_recursive(result),
2898 )
2899 })
2900 .collect();
2901 if let Some(else_expr) = case.else_ {
2902 case.else_ = Some(unqualify_columns_recursive(else_expr));
2903 }
2904 Expression::Case(case)
2905 }
2906 other => other,
2908 }
2909}
2910
2911fn unqualify_binary_op(mut op: BinaryOp) -> BinaryOp {
2913 op.left = unqualify_columns_recursive(op.left);
2914 op.right = unqualify_columns_recursive(op.right);
2915 op
2916}
2917
2918pub fn unnest_generate_date_array_using_recursive_cte(expr: Expression) -> Result<Expression> {
2938 match expr {
2939 Expression::Select(mut select) => {
2940 let mut cte_count = 0;
2941 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
2942
2943 if let Some(ref mut with) = select.with {
2945 for cte in &mut with.ctes {
2946 process_expression_for_gda(&mut cte.this, &mut cte_count, &mut new_ctes);
2947 }
2948 }
2949
2950 if let Some(ref mut from) = select.from {
2952 for table_expr in &mut from.expressions {
2953 if let Some((cte, replacement)) =
2954 try_convert_generate_date_array(table_expr, &mut cte_count)
2955 {
2956 new_ctes.push(cte);
2957 *table_expr = replacement;
2958 }
2959 }
2960 }
2961
2962 for join in &mut select.joins {
2964 if let Some((cte, replacement)) =
2965 try_convert_generate_date_array(&join.this, &mut cte_count)
2966 {
2967 new_ctes.push(cte);
2968 join.this = replacement;
2969 }
2970 }
2971
2972 if !new_ctes.is_empty() {
2974 let with_clause = select.with.get_or_insert_with(|| crate::expressions::With {
2975 ctes: Vec::new(),
2976 recursive: true, leading_comments: vec![],
2978 search: None,
2979 });
2980 with_clause.recursive = true;
2981
2982 let mut all_ctes = new_ctes;
2984 all_ctes.append(&mut with_clause.ctes);
2985 with_clause.ctes = all_ctes;
2986 }
2987
2988 Ok(Expression::Select(select))
2989 }
2990 other => Ok(other),
2991 }
2992}
2993
2994fn process_expression_for_gda(
2997 expr: &mut Expression,
2998 cte_count: &mut usize,
2999 new_ctes: &mut Vec<crate::expressions::Cte>,
3000) {
3001 match expr {
3002 Expression::Select(ref mut select) => {
3003 if let Some(ref mut from) = select.from {
3005 for table_expr in &mut from.expressions {
3006 if let Some((cte, replacement)) =
3007 try_convert_generate_date_array(table_expr, cte_count)
3008 {
3009 new_ctes.push(cte);
3010 *table_expr = replacement;
3011 }
3012 }
3013 }
3014 for join in &mut select.joins {
3016 if let Some((cte, replacement)) =
3017 try_convert_generate_date_array(&join.this, cte_count)
3018 {
3019 new_ctes.push(cte);
3020 join.this = replacement;
3021 }
3022 }
3023 }
3024 Expression::Union(ref mut u) => {
3025 process_expression_for_gda(&mut u.left, cte_count, new_ctes);
3026 process_expression_for_gda(&mut u.right, cte_count, new_ctes);
3027 }
3028 Expression::Subquery(ref mut sq) => {
3029 process_expression_for_gda(&mut sq.this, cte_count, new_ctes);
3030 }
3031 _ => {}
3032 }
3033}
3034
3035fn try_convert_generate_date_array(
3038 expr: &Expression,
3039 cte_count: &mut usize,
3040) -> Option<(crate::expressions::Cte, Expression)> {
3041 try_convert_generate_date_array_with_name(expr, cte_count, None)
3042}
3043
3044fn try_convert_generate_date_array_with_name(
3045 expr: &Expression,
3046 cte_count: &mut usize,
3047 column_name_override: Option<&str>,
3048) -> Option<(crate::expressions::Cte, Expression)> {
3049 fn extract_gda_args(
3051 inner: &Expression,
3052 ) -> Option<(&Expression, &Expression, Option<&Expression>)> {
3053 match inner {
3054 Expression::GenerateDateArray(gda) => {
3055 let start = gda.start.as_ref()?;
3056 let end = gda.end.as_ref()?;
3057 let step = gda.step.as_deref();
3058 Some((start, end, step))
3059 }
3060 Expression::GenerateSeries(gs) => {
3061 let start = gs.start.as_deref()?;
3062 let end = gs.end.as_deref()?;
3063 let step = gs.step.as_deref();
3064 Some((start, end, step))
3065 }
3066 Expression::Function(f) if f.name.eq_ignore_ascii_case("GENERATE_DATE_ARRAY") => {
3067 if f.args.len() >= 2 {
3068 let start = &f.args[0];
3069 let end = &f.args[1];
3070 let step = f.args.get(2);
3071 Some((start, end, step))
3072 } else {
3073 None
3074 }
3075 }
3076 _ => None,
3077 }
3078 }
3079
3080 if let Expression::Unnest(unnest) = expr {
3082 if let Some((start, end, step_opt)) = extract_gda_args(&unnest.this) {
3083 let start = start;
3084 let end = end;
3085 let step: Option<&Expression> = step_opt;
3086
3087 let cte_name = if *cte_count == 0 {
3089 "_generated_dates".to_string()
3090 } else {
3091 format!("_generated_dates_{}", cte_count)
3092 };
3093 *cte_count += 1;
3094
3095 let column_name =
3096 Identifier::new(column_name_override.unwrap_or("date_value").to_string());
3097
3098 let cast_to_date = |expr: &Expression| -> Expression {
3100 match expr {
3101 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
3102 if let Expression::Literal(lit) = expr {
3104 if let Literal::Date(d) = lit.as_ref() {
3105 Expression::Cast(Box::new(Cast {
3106 this: Expression::Literal(Box::new(Literal::String(d.clone()))),
3107 to: DataType::Date,
3108 trailing_comments: vec![],
3109 double_colon_syntax: false,
3110 format: None,
3111 default: None,
3112 inferred_type: None,
3113 }))
3114 } else {
3115 expr.clone()
3116 }
3117 } else {
3118 unreachable!()
3119 }
3120 }
3121 Expression::Cast(c) if matches!(c.to, DataType::Date) => expr.clone(),
3122 _ => Expression::Cast(Box::new(Cast {
3123 this: expr.clone(),
3124 to: DataType::Date,
3125 trailing_comments: vec![],
3126 double_colon_syntax: false,
3127 format: None,
3128 default: None,
3129 inferred_type: None,
3130 })),
3131 }
3132 };
3133
3134 let base_select = Select {
3136 expressions: vec![Expression::Alias(Box::new(crate::expressions::Alias {
3137 this: cast_to_date(start),
3138 alias: column_name.clone(),
3139 column_aliases: vec![],
3140 alias_explicit_as: false,
3141 alias_keyword: None,
3142 pre_alias_comments: vec![],
3143 trailing_comments: vec![],
3144 inferred_type: None,
3145 }))],
3146 ..Select::new()
3147 };
3148
3149 let normalize_interval = |expr: &Expression| -> Expression {
3151 if let Expression::Interval(ref iv) = expr {
3152 let mut iv_clone = iv.as_ref().clone();
3153 if let Some(Expression::Literal(ref lit)) = iv_clone.this {
3154 if let Literal::String(ref s) = lit.as_ref() {
3155 if s.parse::<f64>().is_ok() {
3157 iv_clone.this =
3158 Some(Expression::Literal(Box::new(Literal::Number(s.clone()))));
3159 }
3160 }
3161 }
3162 Expression::Interval(Box::new(iv_clone))
3163 } else {
3164 expr.clone()
3165 }
3166 };
3167
3168 let normalized_step = step.map(|s| normalize_interval(s)).unwrap_or_else(|| {
3171 Expression::Interval(Box::new(crate::expressions::Interval {
3172 this: Some(Expression::Literal(Box::new(Literal::Number(
3173 "1".to_string(),
3174 )))),
3175 unit: Some(crate::expressions::IntervalUnitSpec::Simple {
3176 unit: crate::expressions::IntervalUnit::Day,
3177 use_plural: false,
3178 }),
3179 }))
3180 });
3181
3182 let (add_unit, add_count) = extract_interval_unit_and_count(&normalized_step);
3184
3185 let date_add_expr = Expression::DateAdd(Box::new(crate::expressions::DateAddFunc {
3186 this: Expression::Column(Box::new(crate::expressions::Column {
3187 name: column_name.clone(),
3188 table: None,
3189 join_mark: false,
3190 trailing_comments: vec![],
3191 span: None,
3192 inferred_type: None,
3193 })),
3194 interval: add_count,
3195 unit: add_unit,
3196 }));
3197
3198 let cast_date_add = Expression::Cast(Box::new(Cast {
3199 this: date_add_expr.clone(),
3200 to: DataType::Date,
3201 trailing_comments: vec![],
3202 double_colon_syntax: false,
3203 format: None,
3204 default: None,
3205 inferred_type: None,
3206 }));
3207
3208 let recursive_select = Select {
3209 expressions: vec![cast_date_add.clone()],
3210 from: Some(From {
3211 expressions: vec![Expression::Table(Box::new(
3212 crate::expressions::TableRef::new(&cte_name),
3213 ))],
3214 }),
3215 where_clause: Some(Where {
3216 this: Expression::Lte(Box::new(BinaryOp {
3217 left: cast_date_add,
3218 right: cast_to_date(end),
3219 left_comments: vec![],
3220 operator_comments: vec![],
3221 trailing_comments: vec![],
3222 inferred_type: None,
3223 })),
3224 }),
3225 ..Select::new()
3226 };
3227
3228 let union = crate::expressions::Union {
3230 left: Expression::Select(Box::new(base_select)),
3231 right: Expression::Select(Box::new(recursive_select)),
3232 all: true, distinct: false,
3234 with: None,
3235 order_by: None,
3236 limit: None,
3237 offset: None,
3238 distribute_by: None,
3239 sort_by: None,
3240 cluster_by: None,
3241 by_name: false,
3242 side: None,
3243 kind: None,
3244 corresponding: false,
3245 strict: false,
3246 on_columns: Vec::new(),
3247 };
3248
3249 let cte = crate::expressions::Cte {
3251 this: Expression::Union(Box::new(union)),
3252 alias: Identifier::new(cte_name.clone()),
3253 columns: vec![column_name.clone()],
3254 materialized: None,
3255 key_expressions: Vec::new(),
3256 alias_first: true,
3257 comments: Vec::new(),
3258 };
3259
3260 let replacement_select = Select {
3262 expressions: vec![Expression::Column(Box::new(crate::expressions::Column {
3263 name: column_name,
3264 table: None,
3265 join_mark: false,
3266 trailing_comments: vec![],
3267 span: None,
3268 inferred_type: None,
3269 }))],
3270 from: Some(From {
3271 expressions: vec![Expression::Table(Box::new(
3272 crate::expressions::TableRef::new(&cte_name),
3273 ))],
3274 }),
3275 ..Select::new()
3276 };
3277
3278 let replacement = Expression::Subquery(Box::new(Subquery {
3279 this: Expression::Select(Box::new(replacement_select)),
3280 alias: Some(Identifier::new(cte_name)),
3281 column_aliases: vec![],
3282 alias_explicit_as: false,
3283 alias_keyword: None,
3284 order_by: None,
3285 limit: None,
3286 offset: None,
3287 distribute_by: None,
3288 sort_by: None,
3289 cluster_by: None,
3290 lateral: false,
3291 modifiers_inside: false,
3292 trailing_comments: vec![],
3293 inferred_type: None,
3294 }));
3295
3296 return Some((cte, replacement));
3297 }
3298 }
3299
3300 if let Expression::Alias(alias) = expr {
3302 let col_name = alias.column_aliases.first().map(|id| id.name.as_str());
3304 if let Some((cte, replacement)) =
3305 try_convert_generate_date_array_with_name(&alias.this, cte_count, col_name)
3306 {
3307 if col_name.is_some() {
3310 return Some((cte, replacement));
3311 }
3312 let new_alias = Expression::Alias(Box::new(crate::expressions::Alias {
3313 this: replacement,
3314 alias: alias.alias.clone(),
3315 column_aliases: alias.column_aliases.clone(),
3316 alias_explicit_as: false,
3317 alias_keyword: None,
3318 pre_alias_comments: alias.pre_alias_comments.clone(),
3319 trailing_comments: alias.trailing_comments.clone(),
3320 inferred_type: None,
3321 }));
3322 return Some((cte, new_alias));
3323 }
3324 }
3325
3326 None
3327}
3328
3329fn extract_interval_unit_and_count(
3334 expr: &Expression,
3335) -> (crate::expressions::IntervalUnit, Expression) {
3336 use crate::expressions::{IntervalUnit, IntervalUnitSpec, Literal};
3337
3338 if let Expression::Interval(ref iv) = expr {
3339 if let Some(ref unit_spec) = iv.unit {
3341 if let IntervalUnitSpec::Simple { unit, .. } = unit_spec {
3342 let count = match &iv.this {
3343 Some(e) => e.clone(),
3344 None => Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3345 };
3346 return (unit.clone(), count);
3347 }
3348 }
3349
3350 if let Some(ref val_expr) = iv.this {
3352 match val_expr {
3353 Expression::Literal(lit)
3354 if matches!(lit.as_ref(), Literal::String(_) | Literal::Number(_)) =>
3355 {
3356 let s = match lit.as_ref() {
3357 Literal::String(s) | Literal::Number(s) => s,
3358 _ => unreachable!(),
3359 };
3360 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
3362 if parts.len() == 2 {
3363 let count_str = parts[0].trim();
3364 let unit_str = parts[1].trim().to_uppercase();
3365 let unit = match unit_str.as_str() {
3366 "YEAR" | "YEARS" => IntervalUnit::Year,
3367 "QUARTER" | "QUARTERS" => IntervalUnit::Quarter,
3368 "MONTH" | "MONTHS" => IntervalUnit::Month,
3369 "WEEK" | "WEEKS" => IntervalUnit::Week,
3370 "DAY" | "DAYS" => IntervalUnit::Day,
3371 "HOUR" | "HOURS" => IntervalUnit::Hour,
3372 "MINUTE" | "MINUTES" => IntervalUnit::Minute,
3373 "SECOND" | "SECONDS" => IntervalUnit::Second,
3374 "MILLISECOND" | "MILLISECONDS" => IntervalUnit::Millisecond,
3375 "MICROSECOND" | "MICROSECONDS" => IntervalUnit::Microsecond,
3376 _ => IntervalUnit::Day,
3377 };
3378 return (
3379 unit,
3380 Expression::Literal(Box::new(Literal::Number(count_str.to_string()))),
3381 );
3382 }
3383 if s.parse::<f64>().is_ok() {
3385 return (
3386 IntervalUnit::Day,
3387 Expression::Literal(Box::new(Literal::Number(s.clone()))),
3388 );
3389 }
3390 }
3391 _ => {}
3392 }
3393 }
3394
3395 (
3397 IntervalUnit::Day,
3398 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3399 )
3400 } else {
3401 (
3402 IntervalUnit::Day,
3403 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3404 )
3405 }
3406}
3407
3408pub fn no_ilike_sql(expr: Expression) -> Result<Expression> {
3421 match expr {
3422 Expression::ILike(ilike) => {
3423 let lower_left = Expression::Function(Box::new(crate::expressions::Function {
3425 name: "LOWER".to_string(),
3426 args: vec![ilike.left],
3427 distinct: false,
3428 trailing_comments: vec![],
3429 use_bracket_syntax: false,
3430 no_parens: false,
3431 quoted: false,
3432 span: None,
3433 inferred_type: None,
3434 }));
3435
3436 let lower_right = Expression::Function(Box::new(crate::expressions::Function {
3437 name: "LOWER".to_string(),
3438 args: vec![ilike.right],
3439 distinct: false,
3440 trailing_comments: vec![],
3441 use_bracket_syntax: false,
3442 no_parens: false,
3443 quoted: false,
3444 span: None,
3445 inferred_type: None,
3446 }));
3447
3448 Ok(Expression::Like(Box::new(crate::expressions::LikeOp {
3449 left: lower_left,
3450 right: lower_right,
3451 escape: ilike.escape,
3452 quantifier: ilike.quantifier,
3453 inferred_type: None,
3454 })))
3455 }
3456 other => Ok(other),
3457 }
3458}
3459
3460pub fn no_trycast_sql(expr: Expression) -> Result<Expression> {
3468 match expr {
3469 Expression::TryCast(try_cast) => Ok(Expression::Cast(try_cast)),
3470 other => Ok(other),
3471 }
3472}
3473
3474pub fn no_safe_cast_sql(expr: Expression) -> Result<Expression> {
3479 match expr {
3480 Expression::SafeCast(safe_cast) => Ok(Expression::Cast(safe_cast)),
3481 other => Ok(other),
3482 }
3483}
3484
3485pub fn no_comment_column_constraint(expr: Expression) -> Result<Expression> {
3492 Ok(expr)
3494}
3495
3496pub fn unnest_generate_series(expr: Expression) -> Result<Expression> {
3510 match expr {
3513 Expression::Table(ref table) => {
3514 if table.name.name.to_uppercase() == "GENERATE_SERIES" {
3517 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3519 this: expr.clone(),
3520 expressions: Vec::new(),
3521 with_ordinality: false,
3522 alias: None,
3523 offset_alias: None,
3524 inferred_type: None,
3525 }));
3526
3527 return Ok(Expression::Alias(Box::new(crate::expressions::Alias {
3529 this: unnest,
3530 alias: Identifier::new("_u".to_string()),
3531 column_aliases: vec![],
3532 alias_explicit_as: false,
3533 alias_keyword: None,
3534 pre_alias_comments: vec![],
3535 trailing_comments: vec![],
3536 inferred_type: None,
3537 })));
3538 }
3539 Ok(expr)
3540 }
3541 Expression::GenerateSeries(gs) => {
3542 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3544 this: Expression::GenerateSeries(gs),
3545 expressions: Vec::new(),
3546 with_ordinality: false,
3547 alias: None,
3548 offset_alias: None,
3549 inferred_type: None,
3550 }));
3551 Ok(unnest)
3552 }
3553 other => Ok(other),
3554 }
3555}
3556
3557pub fn unwrap_unnest_generate_series_for_postgres(expr: Expression) -> Result<Expression> {
3568 use crate::dialects::transform_recursive;
3569 transform_recursive(expr, &unwrap_unnest_generate_series_single)
3570}
3571
3572fn unwrap_unnest_generate_series_single(expr: Expression) -> Result<Expression> {
3573 use crate::expressions::*;
3574 match expr {
3576 Expression::Select(mut select) => {
3577 if let Some(ref mut from) = select.from {
3579 for table_expr in &mut from.expressions {
3580 if let Some(replacement) = try_unwrap_unnest_gen_series(table_expr) {
3581 *table_expr = replacement;
3582 }
3583 }
3584 }
3585 for join in &mut select.joins {
3587 if let Some(replacement) = try_unwrap_unnest_gen_series(&join.this) {
3588 join.this = replacement;
3589 }
3590 }
3591 Ok(Expression::Select(select))
3592 }
3593 other => Ok(other),
3594 }
3595}
3596
3597fn try_unwrap_unnest_gen_series(expr: &Expression) -> Option<Expression> {
3600 use crate::expressions::*;
3601
3602 let gen_series = match expr {
3604 Expression::Unnest(unnest) => {
3605 if let Expression::GenerateSeries(ref gs) = unnest.this {
3606 Some(gs.as_ref().clone())
3607 } else {
3608 None
3609 }
3610 }
3611 Expression::Alias(alias) => {
3612 if let Expression::Unnest(ref unnest) = alias.this {
3613 if let Expression::GenerateSeries(ref gs) = unnest.this {
3614 Some(gs.as_ref().clone())
3615 } else {
3616 None
3617 }
3618 } else {
3619 None
3620 }
3621 }
3622 _ => None,
3623 };
3624
3625 let gs = gen_series?;
3626
3627 let value_col = Expression::boxed_column(Column {
3629 name: Identifier::new("value".to_string()),
3630 table: None,
3631 join_mark: false,
3632 trailing_comments: vec![],
3633 span: None,
3634 inferred_type: None,
3635 });
3636
3637 let cast_value = Expression::Cast(Box::new(Cast {
3638 this: value_col,
3639 to: DataType::Date,
3640 trailing_comments: vec![],
3641 double_colon_syntax: false,
3642 format: None,
3643 default: None,
3644 inferred_type: None,
3645 }));
3646
3647 let gen_series_expr = Expression::GenerateSeries(Box::new(gs));
3648
3649 let gen_series_aliased = Expression::Alias(Box::new(Alias {
3651 this: gen_series_expr,
3652 alias: Identifier::new("_t".to_string()),
3653 column_aliases: vec![Identifier::new("value".to_string())],
3654 alias_explicit_as: false,
3655 alias_keyword: None,
3656 pre_alias_comments: vec![],
3657 trailing_comments: vec![],
3658 inferred_type: None,
3659 }));
3660
3661 let mut inner_select = Select::new();
3662 inner_select.expressions = vec![cast_value];
3663 inner_select.from = Some(From {
3664 expressions: vec![gen_series_aliased],
3665 });
3666
3667 let inner_select_expr = Expression::Select(Box::new(inner_select));
3668
3669 let subquery = Expression::Subquery(Box::new(Subquery {
3670 this: inner_select_expr,
3671 alias: None,
3672 column_aliases: vec![],
3673 alias_explicit_as: false,
3674 alias_keyword: None,
3675 order_by: None,
3676 limit: None,
3677 offset: None,
3678 distribute_by: None,
3679 sort_by: None,
3680 cluster_by: None,
3681 lateral: false,
3682 modifiers_inside: false,
3683 trailing_comments: vec![],
3684 inferred_type: None,
3685 }));
3686
3687 Some(Expression::Alias(Box::new(Alias {
3689 this: subquery,
3690 alias: Identifier::new("_unnested_generate_series".to_string()),
3691 column_aliases: vec![],
3692 alias_explicit_as: false,
3693 alias_keyword: None,
3694 pre_alias_comments: vec![],
3695 trailing_comments: vec![],
3696 inferred_type: None,
3697 })))
3698}
3699
3700pub fn expand_between_in_delete(expr: Expression) -> Result<Expression> {
3708 match expr {
3709 Expression::Delete(mut delete) => {
3710 if let Some(ref mut where_clause) = delete.where_clause {
3712 where_clause.this = expand_between_recursive(where_clause.this.clone());
3713 }
3714 Ok(Expression::Delete(delete))
3715 }
3716 other => Ok(other),
3717 }
3718}
3719
3720fn expand_between_recursive(expr: Expression) -> Expression {
3722 match expr {
3723 Expression::Between(between) => {
3726 let this = expand_between_recursive(between.this.clone());
3727 let low = expand_between_recursive(between.low);
3728 let high = expand_between_recursive(between.high);
3729
3730 if between.not {
3731 Expression::Or(Box::new(BinaryOp::new(
3733 Expression::Lt(Box::new(BinaryOp::new(this.clone(), low))),
3734 Expression::Gt(Box::new(BinaryOp::new(this, high))),
3735 )))
3736 } else {
3737 Expression::And(Box::new(BinaryOp::new(
3739 Expression::Gte(Box::new(BinaryOp::new(this.clone(), low))),
3740 Expression::Lte(Box::new(BinaryOp::new(this, high))),
3741 )))
3742 }
3743 }
3744
3745 Expression::And(mut op) => {
3747 op.left = expand_between_recursive(op.left);
3748 op.right = expand_between_recursive(op.right);
3749 Expression::And(op)
3750 }
3751 Expression::Or(mut op) => {
3752 op.left = expand_between_recursive(op.left);
3753 op.right = expand_between_recursive(op.right);
3754 Expression::Or(op)
3755 }
3756 Expression::Not(mut op) => {
3757 op.this = expand_between_recursive(op.this);
3758 Expression::Not(op)
3759 }
3760
3761 Expression::Paren(mut paren) => {
3763 paren.this = expand_between_recursive(paren.this);
3764 Expression::Paren(paren)
3765 }
3766
3767 other => other,
3769 }
3770}
3771
3772pub fn pushdown_cte_column_names(expr: Expression) -> Result<Expression> {
3781 match expr {
3782 Expression::Select(mut select) => {
3783 if let Some(ref mut with) = select.with {
3784 for cte in &mut with.ctes {
3785 if !cte.columns.is_empty() {
3786 let is_star = matches!(&cte.this, Expression::Select(s) if
3788 s.expressions.len() == 1 && matches!(&s.expressions[0], Expression::Star(_)));
3789
3790 if is_star {
3791 cte.columns.clear();
3793 continue;
3794 }
3795
3796 let column_names: Vec<Identifier> = cte.columns.drain(..).collect();
3798
3799 if let Expression::Select(ref mut inner_select) = cte.this {
3801 let new_exprs: Vec<Expression> = inner_select
3802 .expressions
3803 .drain(..)
3804 .zip(
3805 column_names
3806 .into_iter()
3807 .chain(std::iter::repeat_with(|| Identifier::new(""))),
3808 )
3809 .map(|(expr, col_name)| {
3810 if col_name.name.is_empty() {
3811 return expr;
3812 }
3813 match expr {
3815 Expression::Alias(mut a) => {
3816 a.alias = col_name;
3817 Expression::Alias(a)
3818 }
3819 other => {
3820 Expression::Alias(Box::new(crate::expressions::Alias {
3821 this: other,
3822 alias: col_name,
3823 column_aliases: Vec::new(),
3824 alias_explicit_as: false,
3825 alias_keyword: None,
3826 pre_alias_comments: Vec::new(),
3827 trailing_comments: Vec::new(),
3828 inferred_type: None,
3829 }))
3830 }
3831 }
3832 })
3833 .collect();
3834 inner_select.expressions = new_exprs;
3835 }
3836 }
3837 }
3838 }
3839 Ok(Expression::Select(select))
3840 }
3841 other => Ok(other),
3842 }
3843}
3844
3845pub fn simplify_nested_paren_values(expr: Expression) -> Result<Expression> {
3849 match expr {
3850 Expression::Select(mut select) => {
3851 if let Some(ref mut from) = select.from {
3852 for from_item in from.expressions.iter_mut() {
3853 simplify_paren_values_in_from(from_item);
3854 }
3855 }
3856 Ok(Expression::Select(select))
3857 }
3858 other => Ok(other),
3859 }
3860}
3861
3862fn simplify_paren_values_in_from(expr: &mut Expression) {
3863 let replacement = match expr {
3865 Expression::Subquery(ref subquery) => {
3867 if let Expression::Paren(ref paren) = subquery.this {
3868 if matches!(&paren.this, Expression::Values(_)) {
3869 let mut new_sub = subquery.as_ref().clone();
3870 new_sub.this = paren.this.clone();
3871 Some(Expression::Subquery(Box::new(new_sub)))
3872 } else {
3873 None
3874 }
3875 } else {
3876 None
3877 }
3878 }
3879 Expression::Paren(ref outer_paren) => {
3882 if let Expression::Subquery(ref subquery) = outer_paren.this {
3883 if matches!(&subquery.this, Expression::Values(_)) {
3885 Some(outer_paren.this.clone())
3886 }
3887 else if let Expression::Paren(ref paren) = subquery.this {
3889 if matches!(&paren.this, Expression::Values(_)) {
3890 let mut new_sub = subquery.as_ref().clone();
3891 new_sub.this = paren.this.clone();
3892 Some(Expression::Subquery(Box::new(new_sub)))
3893 } else {
3894 None
3895 }
3896 } else {
3897 None
3898 }
3899 } else if let Expression::Paren(ref inner_paren) = outer_paren.this {
3900 if matches!(&inner_paren.this, Expression::Values(_)) {
3901 Some(outer_paren.this.clone())
3902 } else {
3903 None
3904 }
3905 } else {
3906 None
3907 }
3908 }
3909 _ => None,
3910 };
3911 if let Some(new_expr) = replacement {
3912 *expr = new_expr;
3913 }
3914}
3915
3916pub fn add_auto_table_alias(expr: Expression) -> Result<Expression> {
3920 match expr {
3921 Expression::Select(mut select) => {
3922 if let Some(ref mut from) = select.from {
3924 let mut counter = 0usize;
3925 for from_item in from.expressions.iter_mut() {
3926 add_auto_alias_to_from_item(from_item, &mut counter);
3927 }
3928 }
3929 Ok(Expression::Select(select))
3930 }
3931 other => Ok(other),
3932 }
3933}
3934
3935fn add_auto_alias_to_from_item(expr: &mut Expression, counter: &mut usize) {
3936 use crate::expressions::Identifier;
3937
3938 match expr {
3939 Expression::Alias(ref mut alias) => {
3940 if alias.alias.name.is_empty() && !alias.column_aliases.is_empty() {
3942 alias.alias = Identifier::new(format!("_t{}", counter));
3943 *counter += 1;
3944 }
3945 }
3946 _ => {}
3947 }
3948}
3949
3950pub fn propagate_struct_field_names(expr: Expression) -> Result<Expression> {
3960 use crate::dialects::transform_recursive;
3961 transform_recursive(expr, &propagate_struct_names_in_expr)
3962}
3963
3964fn propagate_struct_names_in_expr(expr: Expression) -> Result<Expression> {
3965 use crate::expressions::{Alias, ArrayConstructor, Function, Identifier};
3966
3967 fn propagate_in_elements(elements: &[Expression]) -> Option<Vec<Expression>> {
3969 if elements.len() <= 1 {
3970 return None;
3971 }
3972 if let Some(Expression::Function(ref first_struct)) = elements.first() {
3974 if first_struct.name.eq_ignore_ascii_case("STRUCT") {
3975 let field_names: Vec<Option<String>> = first_struct
3977 .args
3978 .iter()
3979 .map(|arg| {
3980 if let Expression::Alias(a) = arg {
3981 Some(a.alias.name.clone())
3982 } else {
3983 None
3984 }
3985 })
3986 .collect();
3987
3988 if field_names.iter().any(|n| n.is_some()) {
3990 let mut new_elements = Vec::with_capacity(elements.len());
3991 new_elements.push(elements[0].clone());
3992
3993 for elem in &elements[1..] {
3994 if let Expression::Function(ref s) = elem {
3995 if s.name.eq_ignore_ascii_case("STRUCT")
3996 && s.args.len() == field_names.len()
3997 {
3998 let all_unnamed =
4000 s.args.iter().all(|a| !matches!(a, Expression::Alias(_)));
4001 if all_unnamed {
4002 let new_args: Vec<Expression> = s
4004 .args
4005 .iter()
4006 .zip(field_names.iter())
4007 .map(|(val, name)| {
4008 if let Some(n) = name {
4009 Expression::Alias(Box::new(Alias::new(
4010 val.clone(),
4011 Identifier::new(n.clone()),
4012 )))
4013 } else {
4014 val.clone()
4015 }
4016 })
4017 .collect();
4018 new_elements.push(Expression::Function(Box::new(
4019 Function::new("STRUCT".to_string(), new_args),
4020 )));
4021 continue;
4022 }
4023 }
4024 }
4025 new_elements.push(elem.clone());
4026 }
4027
4028 return Some(new_elements);
4029 }
4030 }
4031 }
4032 None
4033 }
4034
4035 if let Expression::Array(ref arr) = expr {
4037 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
4038 return Ok(Expression::Array(Box::new(crate::expressions::Array {
4039 expressions: new_elements,
4040 })));
4041 }
4042 }
4043
4044 if let Expression::ArrayFunc(ref arr) = expr {
4046 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
4047 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
4048 expressions: new_elements,
4049 bracket_notation: arr.bracket_notation,
4050 use_list_keyword: arr.use_list_keyword,
4051 })));
4052 }
4053 }
4054
4055 Ok(expr)
4056}
4057
4058pub fn unnest_alias_to_column_alias(expr: Expression) -> Result<Expression> {
4061 use crate::dialects::transform_recursive;
4062 transform_recursive(expr, &unnest_alias_transform_single_select)
4063}
4064
4065pub fn unnest_from_to_cross_join(expr: Expression) -> Result<Expression> {
4068 use crate::dialects::transform_recursive;
4069 transform_recursive(expr, &unnest_from_to_cross_join_single_select)
4070}
4071
4072fn unnest_from_to_cross_join_single_select(expr: Expression) -> Result<Expression> {
4073 if let Expression::Select(mut select) = expr {
4074 if let Some(ref mut from) = select.from {
4075 if from.expressions.len() > 1 {
4076 let mut new_from_exprs = Vec::new();
4077 let mut new_cross_joins = Vec::new();
4078
4079 for (idx, from_item) in from.expressions.drain(..).enumerate() {
4080 if idx == 0 {
4081 new_from_exprs.push(from_item);
4082 } else {
4083 let is_unnest = match &from_item {
4084 Expression::Unnest(_) => true,
4085 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
4086 _ => false,
4087 };
4088
4089 if is_unnest {
4090 new_cross_joins.push(crate::expressions::Join {
4091 this: from_item,
4092 on: None,
4093 using: Vec::new(),
4094 kind: JoinKind::Cross,
4095 use_inner_keyword: false,
4096 use_outer_keyword: false,
4097 deferred_condition: false,
4098 join_hint: None,
4099 match_condition: None,
4100 pivots: Vec::new(),
4101 comments: Vec::new(),
4102 nesting_group: 0,
4103 directed: false,
4104 });
4105 } else {
4106 new_from_exprs.push(from_item);
4107 }
4108 }
4109 }
4110
4111 from.expressions = new_from_exprs;
4112 new_cross_joins.append(&mut select.joins);
4113 select.joins = new_cross_joins;
4114 }
4115 }
4116
4117 Ok(Expression::Select(select))
4118 } else {
4119 Ok(expr)
4120 }
4121}
4122
4123pub fn wrap_unnest_join_aliases(expr: Expression) -> Result<Expression> {
4127 use crate::dialects::transform_recursive;
4128 transform_recursive(expr, &wrap_unnest_join_aliases_single)
4129}
4130
4131fn wrap_unnest_join_aliases_single(expr: Expression) -> Result<Expression> {
4132 if let Expression::Select(mut select) = expr {
4133 for join in &mut select.joins {
4135 wrap_unnest_alias_in_join_item(&mut join.this);
4136 }
4137 Ok(Expression::Select(select))
4138 } else {
4139 Ok(expr)
4140 }
4141}
4142
4143fn wrap_unnest_alias_in_join_item(expr: &mut Expression) {
4145 use crate::expressions::Identifier;
4146 if let Expression::Alias(alias) = expr {
4147 let is_unnest = match &alias.this {
4149 Expression::Function(f) => f.name.eq_ignore_ascii_case("UNNEST"),
4150 _ => false,
4151 };
4152
4153 if is_unnest && alias.column_aliases.is_empty() {
4154 let original_alias_name = alias.alias.name.clone();
4156 alias.alias = Identifier {
4157 name: "_u".to_string(),
4158 quoted: false,
4159 trailing_comments: Vec::new(),
4160 span: None,
4161 };
4162 alias.column_aliases = vec![Identifier {
4163 name: original_alias_name,
4164 quoted: false,
4165 trailing_comments: Vec::new(),
4166 span: None,
4167 }];
4168 }
4169 }
4170}
4171
4172fn unnest_alias_transform_single_select(expr: Expression) -> Result<Expression> {
4173 if let Expression::Select(mut select) = expr {
4174 let mut counter = 0usize;
4175
4176 if let Some(ref mut from) = select.from {
4178 for from_item in from.expressions.iter_mut() {
4180 convert_unnest_alias_in_from(from_item, &mut counter);
4181 }
4182
4183 if from.expressions.len() > 1 {
4185 let mut new_from_exprs = Vec::new();
4186 let mut new_cross_joins = Vec::new();
4187
4188 for (idx, from_item) in from.expressions.drain(..).enumerate() {
4189 if idx == 0 {
4190 new_from_exprs.push(from_item);
4192 } else {
4193 let is_unnest = match &from_item {
4195 Expression::Unnest(_) => true,
4196 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
4197 _ => false,
4198 };
4199
4200 if is_unnest {
4201 new_cross_joins.push(crate::expressions::Join {
4203 this: from_item,
4204 on: None,
4205 using: Vec::new(),
4206 kind: JoinKind::Cross,
4207 use_inner_keyword: false,
4208 use_outer_keyword: false,
4209 deferred_condition: false,
4210 join_hint: None,
4211 match_condition: None,
4212 pivots: Vec::new(),
4213 comments: Vec::new(),
4214 nesting_group: 0,
4215 directed: false,
4216 });
4217 } else {
4218 new_from_exprs.push(from_item);
4220 }
4221 }
4222 }
4223
4224 from.expressions = new_from_exprs;
4225 new_cross_joins.append(&mut select.joins);
4227 select.joins = new_cross_joins;
4228 }
4229 }
4230
4231 for join in select.joins.iter_mut() {
4233 convert_unnest_alias_in_from(&mut join.this, &mut counter);
4234 }
4235
4236 Ok(Expression::Select(select))
4237 } else {
4238 Ok(expr)
4239 }
4240}
4241
4242fn convert_unnest_alias_in_from(expr: &mut Expression, counter: &mut usize) {
4243 use crate::expressions::Identifier;
4244
4245 if let Expression::Alias(ref mut alias) = expr {
4246 let is_unnest = matches!(&alias.this, Expression::Unnest(_))
4248 || matches!(&alias.this, Expression::Function(f) if f.name.eq_ignore_ascii_case("EXPLODE"));
4249
4250 if is_unnest && alias.column_aliases.is_empty() {
4251 let col_alias = alias.alias.clone();
4253 alias.column_aliases = vec![col_alias];
4254 alias.alias = Identifier::new(format!("_t{}", counter));
4255 *counter += 1;
4256 }
4257 }
4258}
4259
4260pub fn expand_posexplode_duckdb(expr: Expression) -> Result<Expression> {
4267 use crate::expressions::{Alias, Function};
4268
4269 match expr {
4270 Expression::Select(mut select) => {
4271 let mut new_expressions = Vec::new();
4273 let mut changed = false;
4274
4275 for sel_expr in select.expressions.drain(..) {
4276 if let Expression::Alias(ref alias_box) = sel_expr {
4278 if let Expression::Function(ref func) = alias_box.this {
4279 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4280 let arg = func.args[0].clone();
4281 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
4283 (
4284 alias_box.column_aliases[0].name.clone(),
4285 alias_box.column_aliases[1].name.clone(),
4286 )
4287 } else if !alias_box.alias.is_empty() {
4288 ("pos".to_string(), alias_box.alias.name.clone())
4290 } else {
4291 ("pos".to_string(), "col".to_string())
4292 };
4293
4294 let gen_subscripts = Expression::Function(Box::new(Function::new(
4296 "GENERATE_SUBSCRIPTS".to_string(),
4297 vec![
4298 arg.clone(),
4299 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4300 ],
4301 )));
4302 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4303 gen_subscripts,
4304 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4305 )));
4306 let pos_alias = Expression::Alias(Box::new(Alias {
4307 this: sub_one,
4308 alias: Identifier::new(pos_name),
4309 column_aliases: Vec::new(),
4310 alias_explicit_as: false,
4311 alias_keyword: None,
4312 pre_alias_comments: Vec::new(),
4313 trailing_comments: Vec::new(),
4314 inferred_type: None,
4315 }));
4316
4317 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4319 this: arg,
4320 expressions: Vec::new(),
4321 with_ordinality: false,
4322 alias: None,
4323 offset_alias: None,
4324 inferred_type: None,
4325 }));
4326 let col_alias = Expression::Alias(Box::new(Alias {
4327 this: unnest,
4328 alias: Identifier::new(col_name),
4329 column_aliases: Vec::new(),
4330 alias_explicit_as: false,
4331 alias_keyword: None,
4332 pre_alias_comments: Vec::new(),
4333 trailing_comments: Vec::new(),
4334 inferred_type: None,
4335 }));
4336
4337 new_expressions.push(pos_alias);
4338 new_expressions.push(col_alias);
4339 changed = true;
4340 continue;
4341 }
4342 }
4343 }
4344
4345 if let Expression::Function(ref func) = sel_expr {
4347 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4348 let arg = func.args[0].clone();
4349 let pos_name = "pos";
4350 let col_name = "col";
4351
4352 let gen_subscripts = Expression::Function(Box::new(Function::new(
4354 "GENERATE_SUBSCRIPTS".to_string(),
4355 vec![
4356 arg.clone(),
4357 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4358 ],
4359 )));
4360 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4361 gen_subscripts,
4362 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4363 )));
4364 let pos_alias = Expression::Alias(Box::new(Alias {
4365 this: sub_one,
4366 alias: Identifier::new(pos_name),
4367 column_aliases: Vec::new(),
4368 alias_explicit_as: false,
4369 alias_keyword: None,
4370 pre_alias_comments: Vec::new(),
4371 trailing_comments: Vec::new(),
4372 inferred_type: None,
4373 }));
4374
4375 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4377 this: arg,
4378 expressions: Vec::new(),
4379 with_ordinality: false,
4380 alias: None,
4381 offset_alias: None,
4382 inferred_type: None,
4383 }));
4384 let col_alias = Expression::Alias(Box::new(Alias {
4385 this: unnest,
4386 alias: Identifier::new(col_name),
4387 column_aliases: Vec::new(),
4388 alias_explicit_as: false,
4389 alias_keyword: None,
4390 pre_alias_comments: Vec::new(),
4391 trailing_comments: Vec::new(),
4392 inferred_type: None,
4393 }));
4394
4395 new_expressions.push(pos_alias);
4396 new_expressions.push(col_alias);
4397 changed = true;
4398 continue;
4399 }
4400 }
4401
4402 new_expressions.push(sel_expr);
4404 }
4405
4406 if changed {
4407 select.expressions = new_expressions;
4408 } else {
4409 select.expressions = new_expressions;
4410 }
4411
4412 if let Some(ref mut from) = select.from {
4415 expand_posexplode_in_from_duckdb(from)?;
4416 }
4417
4418 Ok(Expression::Select(select))
4419 }
4420 other => Ok(other),
4421 }
4422}
4423
4424fn expand_posexplode_in_from_duckdb(from: &mut From) -> Result<()> {
4426 use crate::expressions::{Alias, Function};
4427
4428 let mut new_expressions = Vec::new();
4429 let mut _changed = false;
4430
4431 for table_expr in from.expressions.drain(..) {
4432 if let Expression::Alias(ref alias_box) = table_expr {
4434 if let Expression::Function(ref func) = alias_box.this {
4435 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4436 let arg = func.args[0].clone();
4437 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
4438 (
4439 alias_box.column_aliases[0].name.clone(),
4440 alias_box.column_aliases[1].name.clone(),
4441 )
4442 } else {
4443 ("pos".to_string(), "col".to_string())
4444 };
4445
4446 let gen_subscripts = Expression::Function(Box::new(Function::new(
4448 "GENERATE_SUBSCRIPTS".to_string(),
4449 vec![
4450 arg.clone(),
4451 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4452 ],
4453 )));
4454 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4455 gen_subscripts,
4456 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4457 )));
4458 let pos_alias = Expression::Alias(Box::new(Alias {
4459 this: sub_one,
4460 alias: Identifier::new(&pos_name),
4461 column_aliases: Vec::new(),
4462 alias_explicit_as: false,
4463 alias_keyword: None,
4464 pre_alias_comments: Vec::new(),
4465 trailing_comments: Vec::new(),
4466 inferred_type: None,
4467 }));
4468 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4469 this: arg,
4470 expressions: Vec::new(),
4471 with_ordinality: false,
4472 alias: None,
4473 offset_alias: None,
4474 inferred_type: None,
4475 }));
4476 let col_alias = Expression::Alias(Box::new(Alias {
4477 this: unnest,
4478 alias: Identifier::new(&col_name),
4479 column_aliases: Vec::new(),
4480 alias_explicit_as: false,
4481 alias_keyword: None,
4482 pre_alias_comments: Vec::new(),
4483 trailing_comments: Vec::new(),
4484 inferred_type: None,
4485 }));
4486
4487 let mut inner_select = Select::new();
4488 inner_select.expressions = vec![pos_alias, col_alias];
4489
4490 let subquery = Expression::Subquery(Box::new(Subquery {
4491 this: Expression::Select(Box::new(inner_select)),
4492 alias: None,
4493 column_aliases: Vec::new(),
4494 alias_explicit_as: false,
4495 alias_keyword: None,
4496 order_by: None,
4497 limit: None,
4498 offset: None,
4499 distribute_by: None,
4500 sort_by: None,
4501 cluster_by: None,
4502 lateral: false,
4503 modifiers_inside: false,
4504 trailing_comments: Vec::new(),
4505 inferred_type: None,
4506 }));
4507 new_expressions.push(subquery);
4508 _changed = true;
4509 continue;
4510 }
4511 }
4512 }
4513
4514 if let Expression::Function(ref func) = table_expr {
4516 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4517 let arg = func.args[0].clone();
4518
4519 let gen_subscripts = Expression::Function(Box::new(Function::new(
4521 "GENERATE_SUBSCRIPTS".to_string(),
4522 vec![
4523 arg.clone(),
4524 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4525 ],
4526 )));
4527 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4528 gen_subscripts,
4529 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4530 )));
4531 let pos_alias = Expression::Alias(Box::new(Alias {
4532 this: sub_one,
4533 alias: Identifier::new("pos"),
4534 column_aliases: Vec::new(),
4535 alias_explicit_as: false,
4536 alias_keyword: None,
4537 pre_alias_comments: Vec::new(),
4538 trailing_comments: Vec::new(),
4539 inferred_type: None,
4540 }));
4541 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4542 this: arg,
4543 expressions: Vec::new(),
4544 with_ordinality: false,
4545 alias: None,
4546 offset_alias: None,
4547 inferred_type: None,
4548 }));
4549 let col_alias = Expression::Alias(Box::new(Alias {
4550 this: unnest,
4551 alias: Identifier::new("col"),
4552 column_aliases: Vec::new(),
4553 alias_explicit_as: false,
4554 alias_keyword: None,
4555 pre_alias_comments: Vec::new(),
4556 trailing_comments: Vec::new(),
4557 inferred_type: None,
4558 }));
4559
4560 let mut inner_select = Select::new();
4561 inner_select.expressions = vec![pos_alias, col_alias];
4562
4563 let subquery = Expression::Subquery(Box::new(Subquery {
4564 this: Expression::Select(Box::new(inner_select)),
4565 alias: None,
4566 column_aliases: Vec::new(),
4567 alias_explicit_as: false,
4568 alias_keyword: None,
4569 order_by: None,
4570 limit: None,
4571 offset: None,
4572 distribute_by: None,
4573 sort_by: None,
4574 cluster_by: None,
4575 lateral: false,
4576 modifiers_inside: false,
4577 trailing_comments: Vec::new(),
4578 inferred_type: None,
4579 }));
4580 new_expressions.push(subquery);
4581 _changed = true;
4582 continue;
4583 }
4584 }
4585
4586 new_expressions.push(table_expr);
4587 }
4588
4589 from.expressions = new_expressions;
4590 Ok(())
4591}
4592
4593pub fn explode_projection_to_unnest(expr: Expression, target: DialectType) -> Result<Expression> {
4608 match expr {
4609 Expression::Select(select) => explode_projection_to_unnest_impl(*select, target),
4610 other => Ok(other),
4611 }
4612}
4613
4614pub fn snowflake_flatten_projection_to_unnest(expr: Expression) -> Result<Expression> {
4624 match expr {
4625 Expression::Select(select) => snowflake_flatten_projection_to_unnest_impl(*select),
4626 other => Ok(other),
4627 }
4628}
4629
4630fn snowflake_flatten_projection_to_unnest_impl(mut select: Select) -> Result<Expression> {
4631 let mut flattened_inputs: Vec<Expression> = Vec::new();
4632 let mut new_selects: Vec<Expression> = Vec::with_capacity(select.expressions.len());
4633
4634 for sel_expr in select.expressions.into_iter() {
4635 let found_input: RefCell<Option<Expression>> = RefCell::new(None);
4636
4637 let rewritten = transform_recursive(sel_expr, &|e| {
4638 if let Expression::Lateral(lat) = e {
4639 if let Some(input_expr) = extract_flatten_input(&lat) {
4640 if found_input.borrow().is_none() {
4641 *found_input.borrow_mut() = Some(input_expr);
4642 }
4643 return Ok(Expression::Lateral(Box::new(rewrite_flatten_lateral(*lat))));
4644 }
4645 return Ok(Expression::Lateral(lat));
4646 }
4647 Ok(e)
4648 })?;
4649
4650 if let Some(input) = found_input.into_inner() {
4651 flattened_inputs.push(input);
4652 }
4653 new_selects.push(rewritten);
4654 }
4655
4656 if flattened_inputs.is_empty() {
4657 select.expressions = new_selects;
4658 return Ok(Expression::Select(Box::new(select)));
4659 }
4660
4661 select.expressions = new_selects;
4662
4663 for (idx, input_expr) in flattened_inputs.into_iter().enumerate() {
4664 let is_first = idx == 0;
4666 let series_alias = if is_first {
4667 "pos".to_string()
4668 } else {
4669 format!("pos_{}", idx + 1)
4670 };
4671 let series_source_alias = if is_first {
4672 "_u".to_string()
4673 } else {
4674 format!("_u_{}", idx * 2 + 1)
4675 };
4676 let unnest_source_alias = if is_first {
4677 "_u_2".to_string()
4678 } else {
4679 format!("_u_{}", idx * 2 + 2)
4680 };
4681 let pos2_alias = if is_first {
4682 "pos_2".to_string()
4683 } else {
4684 format!("{}_2", series_alias)
4685 };
4686 let entity_alias = if is_first {
4687 "entity".to_string()
4688 } else {
4689 format!("entity_{}", idx + 1)
4690 };
4691
4692 let array_size_call = Expression::Function(Box::new(Function::new(
4693 "ARRAY_SIZE".to_string(),
4694 vec![Expression::NamedArgument(Box::new(NamedArgument {
4695 name: Identifier::new("INPUT"),
4696 value: input_expr.clone(),
4697 separator: NamedArgSeparator::DArrow,
4698 }))],
4699 )));
4700
4701 let greatest = Expression::Function(Box::new(Function::new(
4702 "GREATEST".to_string(),
4703 vec![array_size_call.clone()],
4704 )));
4705
4706 let series_end = Expression::Add(Box::new(BinaryOp::new(
4707 Expression::Paren(Box::new(crate::expressions::Paren {
4708 this: Expression::Sub(Box::new(BinaryOp::new(
4709 greatest,
4710 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4711 ))),
4712 trailing_comments: Vec::new(),
4713 })),
4714 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4715 )));
4716
4717 let series_range = Expression::Function(Box::new(Function::new(
4718 "ARRAY_GENERATE_RANGE".to_string(),
4719 vec![
4720 Expression::Literal(Box::new(Literal::Number("0".to_string()))),
4721 series_end,
4722 ],
4723 )));
4724
4725 let series_flatten = Expression::Function(Box::new(Function::new(
4726 "FLATTEN".to_string(),
4727 vec![Expression::NamedArgument(Box::new(NamedArgument {
4728 name: Identifier::new("INPUT"),
4729 value: series_range,
4730 separator: NamedArgSeparator::DArrow,
4731 }))],
4732 )));
4733
4734 let series_table = Expression::Function(Box::new(Function::new(
4735 "TABLE".to_string(),
4736 vec![series_flatten],
4737 )));
4738
4739 let series_alias_expr = Expression::Alias(Box::new(Alias {
4740 this: series_table,
4741 alias: Identifier::new(series_source_alias.clone()),
4742 column_aliases: vec![
4743 Identifier::new("seq"),
4744 Identifier::new("key"),
4745 Identifier::new("path"),
4746 Identifier::new("index"),
4747 Identifier::new(series_alias.clone()),
4748 Identifier::new("this"),
4749 ],
4750 alias_explicit_as: false,
4751 alias_keyword: None,
4752 pre_alias_comments: Vec::new(),
4753 trailing_comments: Vec::new(),
4754 inferred_type: None,
4755 }));
4756
4757 select.joins.push(Join {
4758 this: series_alias_expr,
4759 on: None,
4760 using: Vec::new(),
4761 kind: JoinKind::Cross,
4762 use_inner_keyword: false,
4763 use_outer_keyword: false,
4764 deferred_condition: false,
4765 join_hint: None,
4766 match_condition: None,
4767 pivots: Vec::new(),
4768 comments: Vec::new(),
4769 nesting_group: 0,
4770 directed: false,
4771 });
4772
4773 let entity_flatten = Expression::Function(Box::new(Function::new(
4774 "FLATTEN".to_string(),
4775 vec![Expression::NamedArgument(Box::new(NamedArgument {
4776 name: Identifier::new("INPUT"),
4777 value: input_expr.clone(),
4778 separator: NamedArgSeparator::DArrow,
4779 }))],
4780 )));
4781
4782 let entity_table = Expression::Function(Box::new(Function::new(
4783 "TABLE".to_string(),
4784 vec![entity_flatten],
4785 )));
4786
4787 let entity_alias_expr = Expression::Alias(Box::new(Alias {
4788 this: entity_table,
4789 alias: Identifier::new(unnest_source_alias.clone()),
4790 column_aliases: vec![
4791 Identifier::new("seq"),
4792 Identifier::new("key"),
4793 Identifier::new("path"),
4794 Identifier::new(pos2_alias.clone()),
4795 Identifier::new(entity_alias.clone()),
4796 Identifier::new("this"),
4797 ],
4798 alias_explicit_as: false,
4799 alias_keyword: None,
4800 pre_alias_comments: Vec::new(),
4801 trailing_comments: Vec::new(),
4802 inferred_type: None,
4803 }));
4804
4805 select.joins.push(Join {
4806 this: entity_alias_expr,
4807 on: None,
4808 using: Vec::new(),
4809 kind: JoinKind::Cross,
4810 use_inner_keyword: false,
4811 use_outer_keyword: false,
4812 deferred_condition: false,
4813 join_hint: None,
4814 match_condition: None,
4815 pivots: Vec::new(),
4816 comments: Vec::new(),
4817 nesting_group: 0,
4818 directed: false,
4819 });
4820
4821 let pos_col =
4822 Expression::qualified_column(series_source_alias.clone(), series_alias.clone());
4823 let pos2_col =
4824 Expression::qualified_column(unnest_source_alias.clone(), pos2_alias.clone());
4825
4826 let eq = Expression::Eq(Box::new(BinaryOp::new(pos_col.clone(), pos2_col.clone())));
4827 let size_minus_1 = Expression::Paren(Box::new(crate::expressions::Paren {
4828 this: Expression::Sub(Box::new(BinaryOp::new(
4829 array_size_call,
4830 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4831 ))),
4832 trailing_comments: Vec::new(),
4833 }));
4834 let gt = Expression::Gt(Box::new(BinaryOp::new(pos_col, size_minus_1.clone())));
4835 let pos2_eq_size = Expression::Eq(Box::new(BinaryOp::new(pos2_col, size_minus_1)));
4836 let and_cond = Expression::And(Box::new(BinaryOp::new(gt, pos2_eq_size)));
4837 let or_cond = Expression::Or(Box::new(BinaryOp::new(
4838 eq,
4839 Expression::Paren(Box::new(crate::expressions::Paren {
4840 this: and_cond,
4841 trailing_comments: Vec::new(),
4842 })),
4843 )));
4844
4845 select.where_clause = Some(match select.where_clause.take() {
4846 Some(existing) => Where {
4847 this: Expression::And(Box::new(BinaryOp::new(existing.this, or_cond))),
4848 },
4849 None => Where { this: or_cond },
4850 });
4851 }
4852
4853 Ok(Expression::Select(Box::new(select)))
4854}
4855
4856fn extract_flatten_input(lat: &Lateral) -> Option<Expression> {
4857 let Expression::Function(f) = lat.this.as_ref() else {
4858 return None;
4859 };
4860 if !f.name.eq_ignore_ascii_case("FLATTEN") {
4861 return None;
4862 }
4863
4864 for arg in &f.args {
4865 if let Expression::NamedArgument(na) = arg {
4866 if na.name.name.eq_ignore_ascii_case("INPUT") {
4867 return Some(na.value.clone());
4868 }
4869 }
4870 }
4871 f.args.first().cloned()
4872}
4873
4874fn rewrite_flatten_lateral(mut lat: Lateral) -> Lateral {
4875 let cond = Expression::Eq(Box::new(BinaryOp::new(
4876 Expression::qualified_column("_u", "pos"),
4877 Expression::qualified_column("_u_2", "pos_2"),
4878 )));
4879 let true_expr = Expression::qualified_column("_u_2", "entity");
4880 let iff_expr = Expression::Function(Box::new(Function::new(
4881 "IFF".to_string(),
4882 vec![cond, true_expr, Expression::Null(crate::expressions::Null)],
4883 )));
4884
4885 lat.this = Box::new(iff_expr);
4886 if lat.column_aliases.is_empty() {
4887 lat.column_aliases = vec![
4888 "SEQ".to_string(),
4889 "KEY".to_string(),
4890 "PATH".to_string(),
4891 "INDEX".to_string(),
4892 "VALUE".to_string(),
4893 "THIS".to_string(),
4894 ];
4895 }
4896 lat
4897}
4898
4899struct ExplodeInfo {
4901 arg_sql: String,
4903 explode_alias: String,
4905 pos_alias: String,
4907 unnest_source_alias: String,
4909}
4910
4911fn explode_projection_to_unnest_impl(select: Select, target: DialectType) -> Result<Expression> {
4912 let is_presto = matches!(
4913 target,
4914 DialectType::Presto | DialectType::Trino | DialectType::Athena
4915 );
4916 let is_bigquery = matches!(target, DialectType::BigQuery);
4917
4918 if !is_presto && !is_bigquery {
4919 return Ok(Expression::Select(Box::new(select)));
4920 }
4921
4922 let has_explode = select.expressions.iter().any(|e| expr_contains_explode(e));
4924 if !has_explode {
4925 return Ok(Expression::Select(Box::new(select)));
4926 }
4927
4928 let mut taken_select_names = std::collections::HashSet::new();
4930 let mut taken_source_names = std::collections::HashSet::new();
4931
4932 for sel in &select.expressions {
4934 if let Some(name) = get_output_name(sel) {
4935 taken_select_names.insert(name);
4936 }
4937 }
4938
4939 for sel in &select.expressions {
4941 let explode_expr = find_explode_in_expr(sel);
4942 if let Some(arg) = explode_expr {
4943 if let Some(name) = get_output_name(&arg) {
4944 taken_select_names.insert(name);
4945 }
4946 }
4947 }
4948
4949 if let Some(ref from) = select.from {
4951 for from_expr in &from.expressions {
4952 collect_source_names(from_expr, &mut taken_source_names);
4953 }
4954 }
4955 for join in &select.joins {
4957 collect_source_names(&join.this, &mut taken_source_names);
4958 }
4959
4960 let series_alias = new_name(&mut taken_select_names, "pos");
4962
4963 let series_source_alias = new_name(&mut taken_source_names, "_u");
4965
4966 let target_dialect = Dialect::get(target);
4968
4969 let mut explode_infos: Vec<ExplodeInfo> = Vec::new();
4971 let mut new_projections: Vec<String> = Vec::new();
4972
4973 for (_idx, sel_expr) in select.expressions.iter().enumerate() {
4974 let explode_data = extract_explode_data(sel_expr);
4975
4976 if let Some((is_posexplode, arg_expr, explicit_alias, explicit_pos_alias)) = explode_data {
4977 let arg_sql = target_dialect
4979 .generate(&arg_expr)
4980 .unwrap_or_else(|_| "NULL".to_string());
4981
4982 let unnest_source_alias = new_name(&mut taken_source_names, "_u");
4983
4984 let explode_alias = if let Some(ref ea) = explicit_alias {
4985 taken_select_names.remove(ea.as_str());
4988 let name = new_name(&mut taken_select_names, ea);
4990 name
4991 } else {
4992 new_name(&mut taken_select_names, "col")
4993 };
4994
4995 let pos_alias = if let Some(ref pa) = explicit_pos_alias {
4996 taken_select_names.remove(pa.as_str());
4998 let name = new_name(&mut taken_select_names, pa);
4999 name
5000 } else {
5001 new_name(&mut taken_select_names, "pos")
5002 };
5003
5004 if is_presto {
5006 let if_col = format!(
5008 "IF({}.{} = {}.{}, {}.{}) AS {}",
5009 series_source_alias,
5010 series_alias,
5011 unnest_source_alias,
5012 pos_alias,
5013 unnest_source_alias,
5014 explode_alias,
5015 explode_alias
5016 );
5017 new_projections.push(if_col);
5018
5019 if is_posexplode {
5021 let if_pos = format!(
5022 "IF({}.{} = {}.{}, {}.{}) AS {}",
5023 series_source_alias,
5024 series_alias,
5025 unnest_source_alias,
5026 pos_alias,
5027 unnest_source_alias,
5028 pos_alias,
5029 pos_alias
5030 );
5031 new_projections.push(if_pos);
5032 }
5033 } else {
5034 let if_col = format!(
5036 "IF({} = {}, {}, NULL) AS {}",
5037 series_alias, pos_alias, explode_alias, explode_alias
5038 );
5039 new_projections.push(if_col);
5040
5041 if is_posexplode {
5043 let if_pos = format!(
5044 "IF({} = {}, {}, NULL) AS {}",
5045 series_alias, pos_alias, pos_alias, pos_alias
5046 );
5047 new_projections.push(if_pos);
5048 }
5049 }
5050
5051 explode_infos.push(ExplodeInfo {
5052 arg_sql,
5053 explode_alias,
5054 pos_alias,
5055 unnest_source_alias,
5056 });
5057 } else {
5058 let sel_sql = target_dialect
5060 .generate(sel_expr)
5061 .unwrap_or_else(|_| "*".to_string());
5062 new_projections.push(sel_sql);
5063 }
5064 }
5065
5066 if explode_infos.is_empty() {
5067 return Ok(Expression::Select(Box::new(select)));
5068 }
5069
5070 let mut from_parts: Vec<String> = Vec::new();
5072
5073 if let Some(ref from) = select.from {
5075 for from_expr in &from.expressions {
5076 let from_sql = target_dialect.generate(from_expr).unwrap_or_default();
5077 from_parts.push(from_sql);
5078 }
5079 }
5080
5081 let size_exprs: Vec<String> = explode_infos
5083 .iter()
5084 .map(|info| {
5085 if is_presto {
5086 format!("CARDINALITY({})", info.arg_sql)
5087 } else {
5088 format!("ARRAY_LENGTH({})", info.arg_sql)
5089 }
5090 })
5091 .collect();
5092
5093 let greatest_arg = if size_exprs.len() == 1 {
5094 size_exprs[0].clone()
5095 } else {
5096 format!("GREATEST({})", size_exprs.join(", "))
5097 };
5098
5099 let series_sql = if is_presto {
5102 if size_exprs.len() == 1 {
5104 format!(
5105 "UNNEST(SEQUENCE(1, GREATEST({}))) AS {}({})",
5106 greatest_arg, series_source_alias, series_alias
5107 )
5108 } else {
5109 format!(
5111 "UNNEST(SEQUENCE(1, {})) AS {}({})",
5112 greatest_arg, series_source_alias, series_alias
5113 )
5114 }
5115 } else {
5116 if size_exprs.len() == 1 {
5118 format!(
5119 "UNNEST(GENERATE_ARRAY(0, GREATEST({}) - 1)) AS {}",
5120 greatest_arg, series_alias
5121 )
5122 } else {
5123 format!(
5125 "UNNEST(GENERATE_ARRAY(0, {} - 1)) AS {}",
5126 greatest_arg, series_alias
5127 )
5128 }
5129 };
5130
5131 let mut cross_joins: Vec<String> = Vec::new();
5135
5136 for info in &explode_infos {
5137 cross_joins.push(format!(
5139 "CROSS JOIN UNNEST({}) WITH ORDINALITY AS {}({}, {})",
5140 info.arg_sql, info.unnest_source_alias, info.explode_alias, info.pos_alias
5141 ));
5142 }
5143
5144 let mut where_conditions: Vec<String> = Vec::new();
5146
5147 for info in &explode_infos {
5148 let size_expr = if is_presto {
5149 format!("CARDINALITY({})", info.arg_sql)
5150 } else {
5151 format!("ARRAY_LENGTH({})", info.arg_sql)
5152 };
5153
5154 let cond = if is_presto {
5155 format!(
5156 "{series_src}.{series_al} = {unnest_src}.{pos_al} OR ({series_src}.{series_al} > {size} AND {unnest_src}.{pos_al} = {size})",
5157 series_src = series_source_alias,
5158 series_al = series_alias,
5159 unnest_src = info.unnest_source_alias,
5160 pos_al = info.pos_alias,
5161 size = size_expr
5162 )
5163 } else {
5164 format!(
5165 "{series_al} = {pos_al} OR ({series_al} > ({size} - 1) AND {pos_al} = ({size} - 1))",
5166 series_al = series_alias,
5167 pos_al = info.pos_alias,
5168 size = size_expr
5169 )
5170 };
5171
5172 where_conditions.push(cond);
5173 }
5174
5175 let where_sql = if where_conditions.len() == 1 {
5177 where_conditions[0].clone()
5178 } else {
5179 where_conditions
5180 .iter()
5181 .map(|c| format!("({})", c))
5182 .collect::<Vec<_>>()
5183 .join(" AND ")
5184 };
5185
5186 let select_part = new_projections.join(", ");
5188
5189 let from_and_joins = if from_parts.is_empty() {
5191 format!("FROM {} {}", series_sql, cross_joins.join(" "))
5193 } else {
5194 format!(
5195 "FROM {} {} {}",
5196 from_parts.join(", "),
5197 format!("CROSS JOIN {}", series_sql),
5198 cross_joins.join(" ")
5199 )
5200 };
5201
5202 let full_sql = format!(
5203 "SELECT {} {} WHERE {}",
5204 select_part, from_and_joins, where_sql
5205 );
5206
5207 let generic_dialect = Dialect::get(DialectType::Generic);
5210 let parsed = generic_dialect.parse(&full_sql);
5211 match parsed {
5212 Ok(mut stmts) if !stmts.is_empty() => {
5213 let mut result = stmts.remove(0);
5214
5215 if is_bigquery {
5219 convert_unnest_presto_to_bigquery(&mut result);
5220 }
5221
5222 Ok(result)
5223 }
5224 _ => {
5225 Ok(Expression::Select(Box::new(select)))
5227 }
5228 }
5229}
5230
5231fn convert_unnest_presto_to_bigquery(expr: &mut Expression) {
5235 match expr {
5236 Expression::Select(ref mut select) => {
5237 if let Some(ref mut from) = select.from {
5239 for from_item in from.expressions.iter_mut() {
5240 convert_unnest_presto_to_bigquery(from_item);
5241 }
5242 }
5243 for join in select.joins.iter_mut() {
5245 convert_unnest_presto_to_bigquery(&mut join.this);
5246 }
5247 }
5248 Expression::Alias(ref alias) => {
5249 if let Expression::Unnest(ref unnest) = alias.this {
5251 if unnest.with_ordinality && alias.column_aliases.len() >= 2 {
5252 let col_alias = alias.column_aliases[0].clone();
5253 let pos_alias = alias.column_aliases[1].clone();
5254 let mut new_unnest = unnest.as_ref().clone();
5255 new_unnest.alias = Some(col_alias);
5256 new_unnest.offset_alias = Some(pos_alias);
5257 *expr = Expression::Unnest(Box::new(new_unnest));
5259 }
5260 }
5261 }
5262 _ => {}
5263 }
5264}
5265
5266fn new_name(names: &mut std::collections::HashSet<String>, base: &str) -> String {
5269 if !names.contains(base) {
5270 names.insert(base.to_string());
5271 return base.to_string();
5272 }
5273 let mut i = 2;
5274 loop {
5275 let candidate = format!("{}_{}", base, i);
5276 if !names.contains(&candidate) {
5277 names.insert(candidate.clone());
5278 return candidate;
5279 }
5280 i += 1;
5281 }
5282}
5283
5284fn expr_contains_explode(expr: &Expression) -> bool {
5286 match expr {
5287 Expression::Explode(_) => true,
5288 Expression::ExplodeOuter(_) => true,
5289 Expression::Function(f) => {
5290 let name = f.name.to_uppercase();
5291 name == "POSEXPLODE" || name == "POSEXPLODE_OUTER"
5292 }
5293 Expression::Alias(a) => expr_contains_explode(&a.this),
5294 _ => false,
5295 }
5296}
5297
5298fn find_explode_in_expr(expr: &Expression) -> Option<Expression> {
5300 match expr {
5301 Expression::Explode(uf) => Some(uf.this.clone()),
5302 Expression::ExplodeOuter(uf) => Some(uf.this.clone()),
5303 Expression::Function(f) => {
5304 let name = f.name.to_uppercase();
5305 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5306 Some(f.args[0].clone())
5307 } else {
5308 None
5309 }
5310 }
5311 Expression::Alias(a) => find_explode_in_expr(&a.this),
5312 _ => None,
5313 }
5314}
5315
5316fn extract_explode_data(
5319 expr: &Expression,
5320) -> Option<(bool, Expression, Option<String>, Option<String>)> {
5321 match expr {
5322 Expression::Explode(uf) => Some((false, uf.this.clone(), None, None)),
5324 Expression::ExplodeOuter(uf) => Some((false, uf.this.clone(), None, None)),
5325 Expression::Function(f) => {
5327 let name = f.name.to_uppercase();
5328 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5329 Some((true, f.args[0].clone(), None, None))
5330 } else {
5331 None
5332 }
5333 }
5334 Expression::Alias(a) => {
5336 match &a.this {
5337 Expression::Explode(uf) => {
5338 let alias = if !a.alias.is_empty() {
5339 Some(a.alias.name.clone())
5340 } else {
5341 None
5342 };
5343 Some((false, uf.this.clone(), alias, None))
5344 }
5345 Expression::ExplodeOuter(uf) => {
5346 let alias = if !a.alias.is_empty() {
5347 Some(a.alias.name.clone())
5348 } else {
5349 None
5350 };
5351 Some((false, uf.this.clone(), alias, None))
5352 }
5353 Expression::Function(f) => {
5354 let name = f.name.to_uppercase();
5355 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5356 if a.column_aliases.len() == 2 {
5358 let pos_alias = a.column_aliases[0].name.clone();
5359 let col_alias = a.column_aliases[1].name.clone();
5360 Some((true, f.args[0].clone(), Some(col_alias), Some(pos_alias)))
5361 } else if !a.alias.is_empty() {
5362 Some((true, f.args[0].clone(), Some(a.alias.name.clone()), None))
5364 } else {
5365 Some((true, f.args[0].clone(), None, None))
5366 }
5367 } else {
5368 None
5369 }
5370 }
5371 _ => None,
5372 }
5373 }
5374 _ => None,
5375 }
5376}
5377
5378fn get_output_name(expr: &Expression) -> Option<String> {
5380 match expr {
5381 Expression::Alias(a) => {
5382 if !a.alias.is_empty() {
5383 Some(a.alias.name.clone())
5384 } else {
5385 None
5386 }
5387 }
5388 Expression::Column(c) => Some(c.name.name.clone()),
5389 Expression::Identifier(id) => Some(id.name.clone()),
5390 _ => None,
5391 }
5392}
5393
5394fn collect_source_names(expr: &Expression, names: &mut std::collections::HashSet<String>) {
5396 match expr {
5397 Expression::Alias(a) => {
5398 if !a.alias.is_empty() {
5399 names.insert(a.alias.name.clone());
5400 }
5401 }
5402 Expression::Subquery(s) => {
5403 if let Some(ref alias) = s.alias {
5404 names.insert(alias.name.clone());
5405 }
5406 }
5407 Expression::Table(t) => {
5408 if let Some(ref alias) = t.alias {
5409 names.insert(alias.name.clone());
5410 } else {
5411 names.insert(t.name.name.clone());
5412 }
5413 }
5414 Expression::Column(c) => {
5415 names.insert(c.name.name.clone());
5416 }
5417 Expression::Identifier(id) => {
5418 names.insert(id.name.clone());
5419 }
5420 _ => {}
5421 }
5422}
5423
5424pub fn strip_unnest_column_refs(expr: Expression) -> Result<Expression> {
5427 use crate::dialects::transform_recursive;
5428 transform_recursive(expr, &strip_unnest_column_refs_single)
5429}
5430
5431fn strip_unnest_column_refs_single(expr: Expression) -> Result<Expression> {
5432 if let Expression::Select(mut select) = expr {
5433 for join in select.joins.iter_mut() {
5435 strip_unnest_from_expr(&mut join.this);
5436 }
5437 if let Some(ref mut from) = select.from {
5439 for from_item in from.expressions.iter_mut() {
5440 strip_unnest_from_expr(from_item);
5441 }
5442 }
5443 Ok(Expression::Select(select))
5444 } else {
5445 Ok(expr)
5446 }
5447}
5448
5449fn strip_unnest_from_expr(expr: &mut Expression) {
5452 if let Expression::Alias(ref mut alias) = expr {
5453 if let Expression::Unnest(ref unnest) = alias.this {
5454 let is_column_ref = matches!(&unnest.this, Expression::Column(_) | Expression::Dot(_));
5455 if is_column_ref {
5456 let inner = unnest.this.clone();
5458 alias.this = inner;
5459 }
5460 }
5461 }
5462}
5463
5464pub fn wrap_duckdb_unnest_struct(expr: Expression) -> Result<Expression> {
5467 use crate::dialects::transform_recursive;
5468 transform_recursive(expr, &wrap_duckdb_unnest_struct_single)
5469}
5470
5471fn wrap_duckdb_unnest_struct_single(expr: Expression) -> Result<Expression> {
5472 if let Expression::Select(mut select) = expr {
5473 if let Some(ref mut from) = select.from {
5475 for from_item in from.expressions.iter_mut() {
5476 try_wrap_unnest_in_subquery(from_item);
5477 }
5478 }
5479
5480 for join in select.joins.iter_mut() {
5482 try_wrap_unnest_in_subquery(&mut join.this);
5483 }
5484
5485 Ok(Expression::Select(select))
5486 } else {
5487 Ok(expr)
5488 }
5489}
5490
5491fn is_struct_array_unnest_arg(expr: &Expression) -> bool {
5493 match expr {
5494 Expression::Array(arr) => arr
5496 .expressions
5497 .iter()
5498 .any(|e| matches!(e, Expression::Struct(_))),
5499 Expression::ArrayFunc(arr) => arr
5500 .expressions
5501 .iter()
5502 .any(|e| matches!(e, Expression::Struct(_))),
5503 Expression::Cast(c) => {
5505 matches!(&c.to, DataType::Array { element_type, .. } if matches!(**element_type, DataType::Struct { .. }))
5506 }
5507 _ => false,
5508 }
5509}
5510
5511fn try_wrap_unnest_in_subquery(expr: &mut Expression) {
5514 if let Expression::Alias(ref alias) = expr {
5516 if let Expression::Unnest(ref unnest) = alias.this {
5517 if is_struct_array_unnest_arg(&unnest.this) {
5518 let unnest_clone = (**unnest).clone();
5519 let alias_name = alias.alias.clone();
5520 let new_expr = make_unnest_subquery(unnest_clone, Some(alias_name));
5521 *expr = new_expr;
5522 return;
5523 }
5524 }
5525 }
5526
5527 if let Expression::Unnest(ref unnest) = expr {
5529 if is_struct_array_unnest_arg(&unnest.this) {
5530 let unnest_clone = (**unnest).clone();
5531 let new_expr = make_unnest_subquery(unnest_clone, None);
5532 *expr = new_expr;
5533 }
5534 }
5535}
5536
5537fn make_unnest_subquery(unnest: UnnestFunc, alias: Option<Identifier>) -> Expression {
5539 let max_depth_arg = Expression::NamedArgument(Box::new(NamedArgument {
5541 name: Identifier::new("max_depth".to_string()),
5542 value: Expression::Literal(Box::new(Literal::Number("2".to_string()))),
5543 separator: NamedArgSeparator::DArrow,
5544 }));
5545
5546 let mut unnest_args = vec![unnest.this];
5547 unnest_args.extend(unnest.expressions);
5548 unnest_args.push(max_depth_arg);
5549
5550 let unnest_func =
5551 Expression::Function(Box::new(Function::new("UNNEST".to_string(), unnest_args)));
5552
5553 let mut inner_select = Select::new();
5555 inner_select.expressions = vec![unnest_func];
5556 let inner_select = Expression::Select(Box::new(inner_select));
5557
5558 let subquery = Subquery {
5560 this: inner_select,
5561 alias,
5562 column_aliases: Vec::new(),
5563 alias_explicit_as: false,
5564 alias_keyword: None,
5565 order_by: None,
5566 limit: None,
5567 offset: None,
5568 distribute_by: None,
5569 sort_by: None,
5570 cluster_by: None,
5571 lateral: false,
5572 modifiers_inside: false,
5573 trailing_comments: Vec::new(),
5574 inferred_type: None,
5575 };
5576
5577 Expression::Subquery(Box::new(subquery))
5578}
5579
5580pub fn no_limit_order_by_union(expr: Expression) -> Result<Expression> {
5592 use crate::expressions::{Limit as LimitClause, Offset as OffsetClause, OrderBy, Star};
5593
5594 match expr {
5595 Expression::Union(mut u) => {
5596 if u.order_by.is_none() && u.limit.is_none() && u.offset.is_none() {
5599 if let Expression::Select(ref mut right_select) = u.right {
5601 if right_select.order_by.is_some()
5602 || right_select.limit.is_some()
5603 || right_select.offset.is_some()
5604 {
5605 u.order_by = right_select.order_by.take();
5607 u.limit = right_select.limit.take().map(|l| Box::new(l.this));
5608 u.offset = right_select.offset.take().map(|o| Box::new(o.this));
5609 }
5610 }
5611 }
5612
5613 let has_order_or_limit =
5614 u.order_by.is_some() || u.limit.is_some() || u.offset.is_some();
5615 if has_order_or_limit {
5616 let order_by: Option<OrderBy> = u.order_by.take();
5618 let union_limit: Option<Box<Expression>> = u.limit.take();
5619 let union_offset: Option<Box<Expression>> = u.offset.take();
5620
5621 let select_limit: Option<LimitClause> = union_limit.map(|l| LimitClause {
5623 this: *l,
5624 percent: false,
5625 comments: Vec::new(),
5626 });
5627
5628 let select_offset: Option<OffsetClause> = union_offset.map(|o| OffsetClause {
5630 this: *o,
5631 rows: None,
5632 });
5633
5634 let subquery = Subquery {
5636 this: Expression::Union(u),
5637 alias: Some(Identifier::new("_l_0")),
5638 column_aliases: Vec::new(),
5639 alias_explicit_as: true,
5640 alias_keyword: None,
5641 lateral: false,
5642 modifiers_inside: false,
5643 order_by: None,
5644 limit: None,
5645 offset: None,
5646 distribute_by: None,
5647 sort_by: None,
5648 cluster_by: None,
5649 trailing_comments: Vec::new(),
5650 inferred_type: None,
5651 };
5652
5653 let mut select = Select::default();
5655 select.expressions = vec![Expression::Star(Star {
5656 table: None,
5657 except: None,
5658 replace: None,
5659 rename: None,
5660 trailing_comments: Vec::new(),
5661 span: None,
5662 })];
5663 select.from = Some(From {
5664 expressions: vec![Expression::Subquery(Box::new(subquery))],
5665 });
5666 select.order_by = order_by;
5667 select.limit = select_limit;
5668 select.offset = select_offset;
5669
5670 Ok(Expression::Select(Box::new(select)))
5671 } else {
5672 Ok(Expression::Union(u))
5673 }
5674 }
5675 _ => Ok(expr),
5676 }
5677}
5678
5679pub fn expand_like_any(expr: Expression) -> Result<Expression> {
5687 use crate::expressions::{BinaryOp, LikeOp, Paren};
5688
5689 const LIKE_ALL_MARKER: &str = "__LIKE_ALL_EXPANSION__";
5692
5693 fn unwrap_parens(e: &Expression) -> &Expression {
5694 match e {
5695 Expression::Paren(p) => unwrap_parens(&p.this),
5696 _ => e,
5697 }
5698 }
5699
5700 fn extract_tuple_values(e: &Expression) -> Option<Vec<Expression>> {
5701 let inner = unwrap_parens(e);
5702 match inner {
5703 Expression::Tuple(t) => Some(t.expressions.clone()),
5704 _ if !matches!(e, Expression::Tuple(_)) => Some(vec![inner.clone()]),
5706 _ => None,
5707 }
5708 }
5709
5710 fn expand_like_quantifier(
5712 op: &LikeOp,
5713 values: Vec<Expression>,
5714 is_ilike: bool,
5715 combiner: fn(Expression, Expression) -> Expression,
5716 wrap_marker: bool,
5717 ) -> Expression {
5718 let num_values = values.len();
5719 let mut result: Option<Expression> = None;
5720 for val in values {
5721 let like = if is_ilike {
5722 Expression::ILike(Box::new(LikeOp {
5723 left: op.left.clone(),
5724 right: val,
5725 escape: op.escape.clone(),
5726 quantifier: None,
5727 inferred_type: None,
5728 }))
5729 } else {
5730 Expression::Like(Box::new(LikeOp {
5731 left: op.left.clone(),
5732 right: val,
5733 escape: op.escape.clone(),
5734 quantifier: None,
5735 inferred_type: None,
5736 }))
5737 };
5738 result = Some(match result {
5739 None => like,
5740 Some(prev) => combiner(prev, like),
5741 });
5742 }
5743 let expanded = result.unwrap_or_else(|| unreachable!("values is non-empty"));
5744 if wrap_marker && num_values > 1 {
5748 Expression::Paren(Box::new(Paren {
5749 this: expanded,
5750 trailing_comments: vec![LIKE_ALL_MARKER.to_string()],
5751 }))
5752 } else {
5753 expanded
5754 }
5755 }
5756
5757 fn or_combiner(a: Expression, b: Expression) -> Expression {
5758 Expression::Or(Box::new(BinaryOp::new(a, b)))
5759 }
5760
5761 fn and_combiner(a: Expression, b: Expression) -> Expression {
5762 Expression::And(Box::new(BinaryOp::new(a, b)))
5763 }
5764
5765 fn is_like_all_marker(p: &Paren) -> bool {
5766 p.trailing_comments.len() == 1 && p.trailing_comments[0] == LIKE_ALL_MARKER
5767 }
5768
5769 let result = transform_recursive(expr, &|e| {
5777 match e {
5778 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ANY") => {
5780 if let Some(values) = extract_tuple_values(&op.right) {
5781 if values.is_empty() {
5782 return Ok(e);
5783 }
5784 Ok(expand_like_quantifier(
5785 op,
5786 values,
5787 false,
5788 or_combiner,
5789 false,
5790 ))
5791 } else {
5792 Ok(e)
5793 }
5794 }
5795 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ALL") => {
5797 if let Some(values) = extract_tuple_values(&op.right) {
5798 if values.is_empty() {
5799 return Ok(e);
5800 }
5801 Ok(expand_like_quantifier(
5802 op,
5803 values,
5804 false,
5805 and_combiner,
5806 true,
5807 ))
5808 } else {
5809 Ok(e)
5810 }
5811 }
5812 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ANY") => {
5814 if let Some(values) = extract_tuple_values(&op.right) {
5815 if values.is_empty() {
5816 return Ok(e);
5817 }
5818 Ok(expand_like_quantifier(op, values, true, or_combiner, false))
5819 } else {
5820 Ok(e)
5821 }
5822 }
5823 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ALL") => {
5825 if let Some(values) = extract_tuple_values(&op.right) {
5826 if values.is_empty() {
5827 return Ok(e);
5828 }
5829 Ok(expand_like_quantifier(op, values, true, and_combiner, true))
5830 } else {
5831 Ok(e)
5832 }
5833 }
5834 Expression::And(mut op) => {
5839 if matches!(&op.left, Expression::Or(_)) {
5840 op.left = Expression::Paren(Box::new(Paren {
5841 this: op.left,
5842 trailing_comments: vec![],
5843 }));
5844 }
5845 if matches!(&op.right, Expression::Or(_)) {
5846 op.right = Expression::Paren(Box::new(Paren {
5847 this: op.right,
5848 trailing_comments: vec![],
5849 }));
5850 }
5851 Ok(Expression::And(op))
5852 }
5853 Expression::Or(mut op) => {
5856 if let Expression::Paren(ref mut p) = op.left {
5857 if is_like_all_marker(p) {
5858 p.trailing_comments.clear();
5859 }
5860 }
5861 if let Expression::Paren(ref mut p) = op.right {
5862 if is_like_all_marker(p) {
5863 p.trailing_comments.clear();
5864 }
5865 }
5866 Ok(Expression::Or(op))
5867 }
5868 _ => Ok(e),
5869 }
5870 })?;
5871
5872 transform_recursive(result, &|e| {
5876 if let Expression::Paren(p) = &e {
5877 if is_like_all_marker(p) {
5878 let Expression::Paren(p) = e else {
5879 unreachable!()
5880 };
5881 return Ok(p.this);
5882 }
5883 }
5884 Ok(e)
5885 })
5886}
5887
5888pub fn qualify_derived_table_outputs(expr: Expression) -> Result<Expression> {
5896 use crate::expressions::Alias;
5897
5898 fn add_self_aliases_to_select(select: &mut Select) {
5899 let new_expressions: Vec<Expression> = select
5900 .expressions
5901 .iter()
5902 .map(|e| {
5903 match e {
5904 Expression::Column(col) => {
5906 let alias_name = col.name.clone();
5907 Expression::Alias(Box::new(Alias {
5908 this: e.clone(),
5909 alias: alias_name,
5910 column_aliases: Vec::new(),
5911 alias_explicit_as: false,
5912 alias_keyword: None,
5913 pre_alias_comments: Vec::new(),
5914 trailing_comments: Vec::new(),
5915 inferred_type: None,
5916 }))
5917 }
5918 _ => e.clone(),
5920 }
5921 })
5922 .collect();
5923 select.expressions = new_expressions;
5924 }
5925
5926 fn walk_and_qualify(expr: &mut Expression) {
5927 match expr {
5928 Expression::Select(ref mut select) => {
5929 if let Some(ref mut from) = select.from {
5931 for e in from.expressions.iter_mut() {
5932 qualify_subquery_expr(e);
5933 walk_and_qualify(e);
5934 }
5935 }
5936 for join in select.joins.iter_mut() {
5938 qualify_subquery_expr(&mut join.this);
5939 walk_and_qualify(&mut join.this);
5940 }
5941 for e in select.expressions.iter_mut() {
5943 walk_and_qualify(e);
5944 }
5945 if let Some(ref mut w) = select.where_clause {
5947 walk_and_qualify(&mut w.this);
5948 }
5949 }
5950 Expression::Subquery(ref mut subquery) => {
5951 walk_and_qualify(&mut subquery.this);
5952 }
5953 Expression::Union(ref mut u) => {
5954 walk_and_qualify(&mut u.left);
5955 walk_and_qualify(&mut u.right);
5956 }
5957 Expression::Intersect(ref mut i) => {
5958 walk_and_qualify(&mut i.left);
5959 walk_and_qualify(&mut i.right);
5960 }
5961 Expression::Except(ref mut e) => {
5962 walk_and_qualify(&mut e.left);
5963 walk_and_qualify(&mut e.right);
5964 }
5965 Expression::Cte(ref mut cte) => {
5966 walk_and_qualify(&mut cte.this);
5967 }
5968 _ => {}
5969 }
5970 }
5971
5972 fn qualify_subquery_expr(expr: &mut Expression) {
5973 match expr {
5974 Expression::Subquery(ref mut subquery) => {
5975 if subquery.alias.is_some() && subquery.column_aliases.is_empty() {
5977 if let Expression::Select(ref mut inner_select) = subquery.this {
5978 let has_star = inner_select
5980 .expressions
5981 .iter()
5982 .any(|e| matches!(e, Expression::Star(_)));
5983 if !has_star {
5984 add_self_aliases_to_select(inner_select);
5985 }
5986 }
5987 }
5988 walk_and_qualify(&mut subquery.this);
5990 }
5991 Expression::Alias(ref mut alias) => {
5992 qualify_subquery_expr(&mut alias.this);
5993 }
5994 _ => {}
5995 }
5996 }
5997
5998 let mut result = expr;
5999 walk_and_qualify(&mut result);
6000
6001 if let Expression::Select(ref mut select) = result {
6003 if let Some(ref mut with) = select.with {
6004 for cte in with.ctes.iter_mut() {
6005 if cte.columns.is_empty() {
6007 walk_and_qualify(&mut cte.this);
6009 }
6010 }
6011 }
6012 }
6013
6014 Ok(result)
6015}
6016
6017#[cfg(test)]
6018mod tests {
6019 use super::*;
6020 use crate::dialects::{Dialect, DialectType};
6021 use crate::expressions::Column;
6022
6023 fn gen(expr: &Expression) -> String {
6024 let dialect = Dialect::get(DialectType::Generic);
6025 dialect.generate(expr).unwrap()
6026 }
6027
6028 #[test]
6029 fn test_preprocess() {
6030 let expr = Expression::Boolean(BooleanLiteral { value: true });
6031 let result = preprocess(expr, &[replace_bool_with_int]).unwrap();
6032 assert!(
6033 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
6034 );
6035 }
6036
6037 #[test]
6038 fn test_preprocess_chain() {
6039 let expr = Expression::Boolean(BooleanLiteral { value: true });
6041 let transforms: Vec<fn(Expression) -> Result<Expression>> =
6043 vec![replace_bool_with_int, replace_int_with_bool];
6044 let result = preprocess(expr, &transforms).unwrap();
6045 if let Expression::Boolean(b) = result {
6048 assert!(b.value);
6049 } else {
6050 panic!("Expected boolean literal");
6051 }
6052 }
6053
6054 #[test]
6055 fn test_unnest_to_explode() {
6056 let unnest = Expression::Unnest(Box::new(UnnestFunc {
6057 this: Expression::boxed_column(Column {
6058 name: Identifier::new("arr".to_string()),
6059 table: None,
6060 join_mark: false,
6061 trailing_comments: vec![],
6062 span: None,
6063 inferred_type: None,
6064 }),
6065 expressions: Vec::new(),
6066 with_ordinality: false,
6067 alias: None,
6068 offset_alias: None,
6069 inferred_type: None,
6070 }));
6071
6072 let result = unnest_to_explode(unnest).unwrap();
6073 assert!(matches!(result, Expression::Explode(_)));
6074 }
6075
6076 #[test]
6077 fn test_explode_to_unnest() {
6078 let explode = Expression::Explode(Box::new(UnaryFunc {
6079 this: Expression::boxed_column(Column {
6080 name: Identifier::new("arr".to_string()),
6081 table: None,
6082 join_mark: false,
6083 trailing_comments: vec![],
6084 span: None,
6085 inferred_type: None,
6086 }),
6087 original_name: None,
6088 inferred_type: None,
6089 }));
6090
6091 let result = explode_to_unnest(explode).unwrap();
6092 assert!(matches!(result, Expression::Unnest(_)));
6093 }
6094
6095 #[test]
6096 fn test_replace_bool_with_int() {
6097 let true_expr = Expression::Boolean(BooleanLiteral { value: true });
6098 let result = replace_bool_with_int(true_expr).unwrap();
6099 if let Expression::Literal(lit) = result {
6100 if let Literal::Number(n) = lit.as_ref() {
6101 assert_eq!(n, "1");
6102 }
6103 } else {
6104 panic!("Expected number literal");
6105 }
6106
6107 let false_expr = Expression::Boolean(BooleanLiteral { value: false });
6108 let result = replace_bool_with_int(false_expr).unwrap();
6109 if let Expression::Literal(lit) = result {
6110 if let Literal::Number(n) = lit.as_ref() {
6111 assert_eq!(n, "0");
6112 }
6113 } else {
6114 panic!("Expected number literal");
6115 }
6116 }
6117
6118 #[test]
6119 fn test_replace_int_with_bool() {
6120 let one_expr = Expression::Literal(Box::new(Literal::Number("1".to_string())));
6121 let result = replace_int_with_bool(one_expr).unwrap();
6122 if let Expression::Boolean(b) = result {
6123 assert!(b.value);
6124 } else {
6125 panic!("Expected boolean true");
6126 }
6127
6128 let zero_expr = Expression::Literal(Box::new(Literal::Number("0".to_string())));
6129 let result = replace_int_with_bool(zero_expr).unwrap();
6130 if let Expression::Boolean(b) = result {
6131 assert!(!b.value);
6132 } else {
6133 panic!("Expected boolean false");
6134 }
6135
6136 let two_expr = Expression::Literal(Box::new(Literal::Number("2".to_string())));
6138 let result = replace_int_with_bool(two_expr).unwrap();
6139 assert!(
6140 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
6141 );
6142 }
6143
6144 #[test]
6145 fn test_strip_data_type_params() {
6146 let decimal = DataType::Decimal {
6148 precision: Some(10),
6149 scale: Some(2),
6150 };
6151 let stripped = strip_data_type_params(decimal);
6152 assert_eq!(
6153 stripped,
6154 DataType::Decimal {
6155 precision: None,
6156 scale: None
6157 }
6158 );
6159
6160 let varchar = DataType::VarChar {
6162 length: Some(255),
6163 parenthesized_length: false,
6164 };
6165 let stripped = strip_data_type_params(varchar);
6166 assert_eq!(
6167 stripped,
6168 DataType::VarChar {
6169 length: None,
6170 parenthesized_length: false
6171 }
6172 );
6173
6174 let char_type = DataType::Char { length: Some(10) };
6176 let stripped = strip_data_type_params(char_type);
6177 assert_eq!(stripped, DataType::Char { length: None });
6178
6179 let timestamp = DataType::Timestamp {
6181 precision: Some(6),
6182 timezone: true,
6183 };
6184 let stripped = strip_data_type_params(timestamp);
6185 assert_eq!(
6186 stripped,
6187 DataType::Timestamp {
6188 precision: None,
6189 timezone: true
6190 }
6191 );
6192
6193 let array = DataType::Array {
6195 element_type: Box::new(DataType::VarChar {
6196 length: Some(100),
6197 parenthesized_length: false,
6198 }),
6199 dimension: None,
6200 };
6201 let stripped = strip_data_type_params(array);
6202 assert_eq!(
6203 stripped,
6204 DataType::Array {
6205 element_type: Box::new(DataType::VarChar {
6206 length: None,
6207 parenthesized_length: false
6208 }),
6209 dimension: None,
6210 }
6211 );
6212
6213 let text = DataType::Text;
6215 let stripped = strip_data_type_params(text);
6216 assert_eq!(stripped, DataType::Text);
6217 }
6218
6219 #[test]
6220 fn test_remove_precision_parameterized_types_cast() {
6221 let cast_expr = Expression::Cast(Box::new(Cast {
6223 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
6224 to: DataType::Decimal {
6225 precision: Some(10),
6226 scale: Some(2),
6227 },
6228 trailing_comments: vec![],
6229 double_colon_syntax: false,
6230 format: None,
6231 default: None,
6232 inferred_type: None,
6233 }));
6234
6235 let result = remove_precision_parameterized_types(cast_expr).unwrap();
6236 if let Expression::Cast(cast) = result {
6237 assert_eq!(
6238 cast.to,
6239 DataType::Decimal {
6240 precision: None,
6241 scale: None
6242 }
6243 );
6244 } else {
6245 panic!("Expected Cast expression");
6246 }
6247 }
6248
6249 #[test]
6250 fn test_remove_precision_parameterized_types_varchar() {
6251 let cast_expr = Expression::Cast(Box::new(Cast {
6253 this: Expression::Literal(Box::new(Literal::String("hello".to_string()))),
6254 to: DataType::VarChar {
6255 length: Some(10),
6256 parenthesized_length: false,
6257 },
6258 trailing_comments: vec![],
6259 double_colon_syntax: false,
6260 format: None,
6261 default: None,
6262 inferred_type: None,
6263 }));
6264
6265 let result = remove_precision_parameterized_types(cast_expr).unwrap();
6266 if let Expression::Cast(cast) = result {
6267 assert_eq!(
6268 cast.to,
6269 DataType::VarChar {
6270 length: None,
6271 parenthesized_length: false
6272 }
6273 );
6274 } else {
6275 panic!("Expected Cast expression");
6276 }
6277 }
6278
6279 #[test]
6280 fn test_remove_precision_direct_cast() {
6281 let cast = Expression::Cast(Box::new(Cast {
6285 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
6286 to: DataType::Decimal {
6287 precision: Some(10),
6288 scale: Some(2),
6289 },
6290 trailing_comments: vec![],
6291 double_colon_syntax: false,
6292 format: None,
6293 default: None,
6294 inferred_type: None,
6295 }));
6296
6297 let transformed = remove_precision_parameterized_types(cast).unwrap();
6298 let generated = gen(&transformed);
6299
6300 assert!(generated.contains("DECIMAL"));
6302 assert!(!generated.contains("(10"));
6303 }
6304
6305 #[test]
6306 fn test_epoch_cast_to_ts() {
6307 let cast_expr = Expression::Cast(Box::new(Cast {
6309 this: Expression::Literal(Box::new(Literal::String("epoch".to_string()))),
6310 to: DataType::Timestamp {
6311 precision: None,
6312 timezone: false,
6313 },
6314 trailing_comments: vec![],
6315 double_colon_syntax: false,
6316 format: None,
6317 default: None,
6318 inferred_type: None,
6319 }));
6320
6321 let result = epoch_cast_to_ts(cast_expr).unwrap();
6322 if let Expression::Cast(cast) = result {
6323 if let Expression::Literal(lit) = cast.this {
6324 if let Literal::String(s) = lit.as_ref() {
6325 assert_eq!(s, "1970-01-01 00:00:00");
6326 }
6327 } else {
6328 panic!("Expected string literal");
6329 }
6330 } else {
6331 panic!("Expected Cast expression");
6332 }
6333 }
6334
6335 #[test]
6336 fn test_epoch_cast_to_ts_preserves_non_epoch() {
6337 let cast_expr = Expression::Cast(Box::new(Cast {
6339 this: Expression::Literal(Box::new(Literal::String("2024-01-15".to_string()))),
6340 to: DataType::Timestamp {
6341 precision: None,
6342 timezone: false,
6343 },
6344 trailing_comments: vec![],
6345 double_colon_syntax: false,
6346 format: None,
6347 default: None,
6348 inferred_type: None,
6349 }));
6350
6351 let result = epoch_cast_to_ts(cast_expr).unwrap();
6352 if let Expression::Cast(cast) = result {
6353 if let Expression::Literal(lit) = cast.this {
6354 if let Literal::String(s) = lit.as_ref() {
6355 assert_eq!(s, "2024-01-15");
6356 }
6357 } else {
6358 panic!("Expected string literal");
6359 }
6360 } else {
6361 panic!("Expected Cast expression");
6362 }
6363 }
6364
6365 #[test]
6366 fn test_unqualify_columns() {
6367 let col = Expression::boxed_column(Column {
6369 name: Identifier::new("id".to_string()),
6370 table: Some(Identifier::new("users".to_string())),
6371 join_mark: false,
6372 trailing_comments: vec![],
6373 span: None,
6374 inferred_type: None,
6375 });
6376
6377 let result = unqualify_columns(col).unwrap();
6378 if let Expression::Column(c) = result {
6379 assert!(c.table.is_none());
6380 assert_eq!(c.name.name, "id");
6381 } else {
6382 panic!("Expected Column expression");
6383 }
6384 }
6385
6386 #[test]
6387 fn test_is_temporal_type() {
6388 assert!(is_temporal_type(&DataType::Date));
6389 assert!(is_temporal_type(&DataType::Timestamp {
6390 precision: None,
6391 timezone: false
6392 }));
6393 assert!(is_temporal_type(&DataType::Time {
6394 precision: None,
6395 timezone: false
6396 }));
6397 assert!(!is_temporal_type(&DataType::Int {
6398 length: None,
6399 integer_spelling: false
6400 }));
6401 assert!(!is_temporal_type(&DataType::VarChar {
6402 length: None,
6403 parenthesized_length: false
6404 }));
6405 }
6406
6407 #[test]
6408 fn test_eliminate_semi_join_basic() {
6409 use crate::expressions::{Join, TableRef};
6410
6411 let select = Expression::Select(Box::new(Select {
6413 expressions: vec![Expression::boxed_column(Column {
6414 name: Identifier::new("a".to_string()),
6415 table: None,
6416 join_mark: false,
6417 trailing_comments: vec![],
6418 span: None,
6419 inferred_type: None,
6420 })],
6421 from: Some(From {
6422 expressions: vec![Expression::Table(Box::new(TableRef::new("t1")))],
6423 }),
6424 joins: vec![Join {
6425 this: Expression::Table(Box::new(TableRef::new("t2"))),
6426 kind: JoinKind::Semi,
6427 on: Some(Expression::Eq(Box::new(BinaryOp {
6428 left: Expression::boxed_column(Column {
6429 name: Identifier::new("x".to_string()),
6430 table: None,
6431 join_mark: false,
6432 trailing_comments: vec![],
6433 span: None,
6434 inferred_type: None,
6435 }),
6436 right: Expression::boxed_column(Column {
6437 name: Identifier::new("y".to_string()),
6438 table: None,
6439 join_mark: false,
6440 trailing_comments: vec![],
6441 span: None,
6442 inferred_type: None,
6443 }),
6444 left_comments: vec![],
6445 operator_comments: vec![],
6446 trailing_comments: vec![],
6447 inferred_type: None,
6448 }))),
6449 using: vec![],
6450 use_inner_keyword: false,
6451 use_outer_keyword: false,
6452 deferred_condition: false,
6453 join_hint: None,
6454 match_condition: None,
6455 pivots: Vec::new(),
6456 comments: Vec::new(),
6457 nesting_group: 0,
6458 directed: false,
6459 }],
6460 ..Select::new()
6461 }));
6462
6463 let result = eliminate_semi_and_anti_joins(select).unwrap();
6464 if let Expression::Select(s) = result {
6465 assert!(s.joins.is_empty());
6467 assert!(s.where_clause.is_some());
6469 } else {
6470 panic!("Expected Select expression");
6471 }
6472 }
6473
6474 #[test]
6475 fn test_no_ilike_sql() {
6476 use crate::expressions::LikeOp;
6477
6478 let ilike_expr = Expression::ILike(Box::new(LikeOp {
6480 left: Expression::boxed_column(Column {
6481 name: Identifier::new("name".to_string()),
6482 table: None,
6483 join_mark: false,
6484 trailing_comments: vec![],
6485 span: None,
6486 inferred_type: None,
6487 }),
6488 right: Expression::Literal(Box::new(Literal::String("%test%".to_string()))),
6489 escape: None,
6490 quantifier: None,
6491 inferred_type: None,
6492 }));
6493
6494 let result = no_ilike_sql(ilike_expr).unwrap();
6495 if let Expression::Like(like) = result {
6496 if let Expression::Function(f) = &like.left {
6498 assert_eq!(f.name, "LOWER");
6499 } else {
6500 panic!("Expected LOWER function on left");
6501 }
6502 if let Expression::Function(f) = &like.right {
6504 assert_eq!(f.name, "LOWER");
6505 } else {
6506 panic!("Expected LOWER function on right");
6507 }
6508 } else {
6509 panic!("Expected Like expression");
6510 }
6511 }
6512
6513 #[test]
6514 fn test_no_trycast_sql() {
6515 let trycast_expr = Expression::TryCast(Box::new(Cast {
6517 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
6518 to: DataType::Int {
6519 length: None,
6520 integer_spelling: false,
6521 },
6522 trailing_comments: vec![],
6523 double_colon_syntax: false,
6524 format: None,
6525 default: None,
6526 inferred_type: None,
6527 }));
6528
6529 let result = no_trycast_sql(trycast_expr).unwrap();
6530 assert!(matches!(result, Expression::Cast(_)));
6531 }
6532
6533 #[test]
6534 fn test_no_safe_cast_sql() {
6535 let safe_cast_expr = Expression::SafeCast(Box::new(Cast {
6537 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
6538 to: DataType::Int {
6539 length: None,
6540 integer_spelling: false,
6541 },
6542 trailing_comments: vec![],
6543 double_colon_syntax: false,
6544 format: None,
6545 default: None,
6546 inferred_type: None,
6547 }));
6548
6549 let result = no_safe_cast_sql(safe_cast_expr).unwrap();
6550 assert!(matches!(result, Expression::Cast(_)));
6551 }
6552
6553 #[test]
6554 fn test_explode_to_unnest_presto() {
6555 let spark = Dialect::get(DialectType::Spark);
6556 let result = spark
6557 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::Presto)
6558 .unwrap();
6559 assert_eq!(
6560 result[0],
6561 "SELECT IF(_u.pos = _u_2.pos_2, _u_2.col) AS col FROM tbl CROSS JOIN UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(x)))) AS _u(pos) CROSS JOIN UNNEST(x) WITH ORDINALITY AS _u_2(col, pos_2) WHERE _u.pos = _u_2.pos_2 OR (_u.pos > CARDINALITY(x) AND _u_2.pos_2 = CARDINALITY(x))"
6562 );
6563 }
6564
6565 #[test]
6566 fn test_explode_to_unnest_bigquery() {
6567 let spark = Dialect::get(DialectType::Spark);
6568 let result = spark
6569 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::BigQuery)
6570 .unwrap();
6571 assert_eq!(
6572 result[0],
6573 "SELECT IF(pos = pos_2, col, NULL) AS col FROM tbl CROSS JOIN UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH(x)) - 1)) AS pos CROSS JOIN UNNEST(x) AS col WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH(x) - 1) AND pos_2 = (ARRAY_LENGTH(x) - 1))"
6574 );
6575 }
6576}