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 },
679 )
680 }
681 }
682 Expression::Unnest(unnest) => {
683 let alias = unnest.alias.clone();
684 (alias, Vec::new(), *unnest)
685 }
686 _ => (
687 None,
688 Vec::new(),
689 UnnestFunc {
690 this: expr,
691 expressions: Vec::new(),
692 with_ordinality: false,
693 alias: None,
694 offset_alias: None,
695 },
696 ),
697 }
698}
699
700pub fn explode_to_unnest(expr: Expression) -> Result<Expression> {
702 match expr {
703 Expression::Explode(explode) => Ok(Expression::Unnest(Box::new(UnnestFunc {
704 this: explode.this,
705 expressions: Vec::new(),
706 with_ordinality: false,
707 alias: None,
708 offset_alias: None,
709 }))),
710 _ => Ok(expr),
711 }
712}
713
714pub fn replace_bool_with_int(expr: Expression) -> Result<Expression> {
718 match expr {
719 Expression::Boolean(b) => {
720 let value = if b.value { "1" } else { "0" };
721 Ok(Expression::Literal(Box::new(Literal::Number(
722 value.to_string(),
723 ))))
724 }
725 _ => Ok(expr),
726 }
727}
728
729pub fn replace_int_with_bool(expr: Expression) -> Result<Expression> {
733 match expr {
734 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(n) if n == "1" || n == "0") =>
735 {
736 let Literal::Number(n) = lit.as_ref() else {
737 unreachable!()
738 };
739 Ok(Expression::Boolean(BooleanLiteral { value: n == "1" }))
740 }
741 _ => Ok(expr),
742 }
743}
744
745pub fn remove_precision_parameterized_types(expr: Expression) -> Result<Expression> {
750 Ok(strip_type_params_recursive(expr))
751}
752
753fn strip_type_params_recursive(expr: Expression) -> Expression {
755 match expr {
756 Expression::Cast(mut cast) => {
758 cast.to = strip_data_type_params(cast.to);
759 cast.this = strip_type_params_recursive(cast.this);
761 Expression::Cast(cast)
762 }
763 Expression::TryCast(mut try_cast) => {
765 try_cast.to = strip_data_type_params(try_cast.to);
766 try_cast.this = strip_type_params_recursive(try_cast.this);
767 Expression::TryCast(try_cast)
768 }
769 Expression::SafeCast(mut safe_cast) => {
771 safe_cast.to = strip_data_type_params(safe_cast.to);
772 safe_cast.this = strip_type_params_recursive(safe_cast.this);
773 Expression::SafeCast(safe_cast)
774 }
775 _ => expr,
778 }
779}
780
781fn strip_data_type_params(dt: DataType) -> DataType {
783 match dt {
784 DataType::Decimal { .. } => DataType::Decimal {
786 precision: None,
787 scale: None,
788 },
789 DataType::TinyInt { .. } => DataType::TinyInt { length: None },
790 DataType::SmallInt { .. } => DataType::SmallInt { length: None },
791 DataType::Int { .. } => DataType::Int {
792 length: None,
793 integer_spelling: false,
794 },
795 DataType::BigInt { .. } => DataType::BigInt { length: None },
796
797 DataType::Char { .. } => DataType::Char { length: None },
799 DataType::VarChar { .. } => DataType::VarChar {
800 length: None,
801 parenthesized_length: false,
802 },
803
804 DataType::Binary { .. } => DataType::Binary { length: None },
806 DataType::VarBinary { .. } => DataType::VarBinary { length: None },
807
808 DataType::Bit { .. } => DataType::Bit { length: None },
810 DataType::VarBit { .. } => DataType::VarBit { length: None },
811
812 DataType::Time { .. } => DataType::Time {
814 precision: None,
815 timezone: false,
816 },
817 DataType::Timestamp { timezone, .. } => DataType::Timestamp {
818 precision: None,
819 timezone,
820 },
821
822 DataType::Array {
824 element_type,
825 dimension,
826 } => DataType::Array {
827 element_type: Box::new(strip_data_type_params(*element_type)),
828 dimension,
829 },
830
831 DataType::Map {
833 key_type,
834 value_type,
835 } => DataType::Map {
836 key_type: Box::new(strip_data_type_params(*key_type)),
837 value_type: Box::new(strip_data_type_params(*value_type)),
838 },
839
840 DataType::Struct { fields, nested } => DataType::Struct {
842 fields: fields
843 .into_iter()
844 .map(|f| {
845 StructField::with_options(
846 f.name,
847 strip_data_type_params(f.data_type),
848 f.options,
849 )
850 })
851 .collect(),
852 nested,
853 },
854
855 DataType::Vector { element_type, .. } => DataType::Vector {
857 element_type: element_type.map(|et| Box::new(strip_data_type_params(*et))),
858 dimension: None,
859 },
860
861 DataType::Object { fields, modifier } => DataType::Object {
863 fields: fields
864 .into_iter()
865 .map(|(name, ty, not_null)| (name, strip_data_type_params(ty), not_null))
866 .collect(),
867 modifier,
868 },
869
870 other => other,
872 }
873}
874
875pub fn eliminate_qualify(expr: Expression) -> Result<Expression> {
890 match expr {
891 Expression::Select(mut select) => {
892 if let Some(qualify) = select.qualify.take() {
893 let qualify_filter = qualify.this;
900 let window_alias_name = "_w".to_string();
901 let window_alias_ident = Identifier::new(window_alias_name.clone());
902
903 let (window_expr, outer_where) =
906 extract_window_from_condition(qualify_filter.clone(), &window_alias_ident);
907
908 if let Some(win_expr) = window_expr {
909 let window_alias_expr =
911 Expression::Alias(Box::new(crate::expressions::Alias {
912 this: win_expr,
913 alias: window_alias_ident.clone(),
914 column_aliases: vec![],
915 alias_explicit_as: false,
916 alias_keyword: None,
917 pre_alias_comments: vec![],
918 trailing_comments: vec![],
919 inferred_type: None,
920 }));
921
922 let outer_exprs: Vec<Expression> = select
926 .expressions
927 .iter()
928 .map(|expr| {
929 if let Expression::Alias(a) = expr {
930 Expression::Column(Box::new(crate::expressions::Column {
932 name: a.alias.clone(),
933 table: None,
934 join_mark: false,
935 trailing_comments: vec![],
936 span: None,
937 inferred_type: None,
938 }))
939 } else {
940 expr.clone()
941 }
942 })
943 .collect();
944 select.expressions.push(window_alias_expr);
945
946 let inner_select = Expression::Select(select);
948 let subquery = Subquery {
949 this: inner_select,
950 alias: Some(Identifier::new("_t".to_string())),
951 column_aliases: vec![],
952 alias_explicit_as: false,
953 alias_keyword: None,
954 order_by: None,
955 limit: None,
956 offset: None,
957 distribute_by: None,
958 sort_by: None,
959 cluster_by: None,
960 lateral: false,
961 modifiers_inside: false,
962 trailing_comments: vec![],
963 inferred_type: None,
964 };
965
966 let outer_select = Select {
968 expressions: outer_exprs,
969 from: Some(From {
970 expressions: vec![Expression::Subquery(Box::new(subquery))],
971 }),
972 where_clause: Some(Where { this: outer_where }),
973 ..Select::new()
974 };
975
976 return Ok(Expression::Select(Box::new(outer_select)));
977 } else {
978 let qualify_alias = Expression::Alias(Box::new(crate::expressions::Alias {
980 this: qualify_filter.clone(),
981 alias: window_alias_ident.clone(),
982 column_aliases: vec![],
983 alias_explicit_as: false,
984 alias_keyword: None,
985 pre_alias_comments: vec![],
986 trailing_comments: vec![],
987 inferred_type: None,
988 }));
989
990 let original_exprs = select.expressions.clone();
991 select.expressions.push(qualify_alias);
992
993 let inner_select = Expression::Select(select);
994 let subquery = Subquery {
995 this: inner_select,
996 alias: Some(Identifier::new("_t".to_string())),
997 column_aliases: vec![],
998 alias_explicit_as: false,
999 alias_keyword: None,
1000 order_by: None,
1001 limit: None,
1002 offset: None,
1003 distribute_by: None,
1004 sort_by: None,
1005 cluster_by: None,
1006 lateral: false,
1007 modifiers_inside: false,
1008 trailing_comments: vec![],
1009 inferred_type: None,
1010 };
1011
1012 let outer_select = Select {
1013 expressions: original_exprs,
1014 from: Some(From {
1015 expressions: vec![Expression::Subquery(Box::new(subquery))],
1016 }),
1017 where_clause: Some(Where {
1018 this: Expression::Column(Box::new(crate::expressions::Column {
1019 name: window_alias_ident,
1020 table: None,
1021 join_mark: false,
1022 trailing_comments: vec![],
1023 span: None,
1024 inferred_type: None,
1025 })),
1026 }),
1027 ..Select::new()
1028 };
1029
1030 return Ok(Expression::Select(Box::new(outer_select)));
1031 }
1032 }
1033 Ok(Expression::Select(select))
1034 }
1035 other => Ok(other),
1036 }
1037}
1038
1039fn extract_window_from_condition(
1043 condition: Expression,
1044 alias: &Identifier,
1045) -> (Option<Expression>, Expression) {
1046 let alias_col = Expression::Column(Box::new(crate::expressions::Column {
1047 name: alias.clone(),
1048 table: None,
1049 join_mark: false,
1050 trailing_comments: vec![],
1051 span: None,
1052 inferred_type: None,
1053 }));
1054
1055 match condition {
1057 Expression::Eq(ref op) => {
1059 if is_window_expr(&op.left) {
1060 (
1061 Some(op.left.clone()),
1062 Expression::Eq(Box::new(BinaryOp {
1063 left: alias_col,
1064 right: op.right.clone(),
1065 ..(**op).clone()
1066 })),
1067 )
1068 } else if is_window_expr(&op.right) {
1069 (
1070 Some(op.right.clone()),
1071 Expression::Eq(Box::new(BinaryOp {
1072 left: op.left.clone(),
1073 right: alias_col,
1074 ..(**op).clone()
1075 })),
1076 )
1077 } else {
1078 (None, condition)
1079 }
1080 }
1081 Expression::Neq(ref op) => {
1082 if is_window_expr(&op.left) {
1083 (
1084 Some(op.left.clone()),
1085 Expression::Neq(Box::new(BinaryOp {
1086 left: alias_col,
1087 right: op.right.clone(),
1088 ..(**op).clone()
1089 })),
1090 )
1091 } else if is_window_expr(&op.right) {
1092 (
1093 Some(op.right.clone()),
1094 Expression::Neq(Box::new(BinaryOp {
1095 left: op.left.clone(),
1096 right: alias_col,
1097 ..(**op).clone()
1098 })),
1099 )
1100 } else {
1101 (None, condition)
1102 }
1103 }
1104 Expression::Lt(ref op) => {
1105 if is_window_expr(&op.left) {
1106 (
1107 Some(op.left.clone()),
1108 Expression::Lt(Box::new(BinaryOp {
1109 left: alias_col,
1110 right: op.right.clone(),
1111 ..(**op).clone()
1112 })),
1113 )
1114 } else if is_window_expr(&op.right) {
1115 (
1116 Some(op.right.clone()),
1117 Expression::Lt(Box::new(BinaryOp {
1118 left: op.left.clone(),
1119 right: alias_col,
1120 ..(**op).clone()
1121 })),
1122 )
1123 } else {
1124 (None, condition)
1125 }
1126 }
1127 Expression::Lte(ref op) => {
1128 if is_window_expr(&op.left) {
1129 (
1130 Some(op.left.clone()),
1131 Expression::Lte(Box::new(BinaryOp {
1132 left: alias_col,
1133 right: op.right.clone(),
1134 ..(**op).clone()
1135 })),
1136 )
1137 } else if is_window_expr(&op.right) {
1138 (
1139 Some(op.right.clone()),
1140 Expression::Lte(Box::new(BinaryOp {
1141 left: op.left.clone(),
1142 right: alias_col,
1143 ..(**op).clone()
1144 })),
1145 )
1146 } else {
1147 (None, condition)
1148 }
1149 }
1150 Expression::Gt(ref op) => {
1151 if is_window_expr(&op.left) {
1152 (
1153 Some(op.left.clone()),
1154 Expression::Gt(Box::new(BinaryOp {
1155 left: alias_col,
1156 right: op.right.clone(),
1157 ..(**op).clone()
1158 })),
1159 )
1160 } else if is_window_expr(&op.right) {
1161 (
1162 Some(op.right.clone()),
1163 Expression::Gt(Box::new(BinaryOp {
1164 left: op.left.clone(),
1165 right: alias_col,
1166 ..(**op).clone()
1167 })),
1168 )
1169 } else {
1170 (None, condition)
1171 }
1172 }
1173 Expression::Gte(ref op) => {
1174 if is_window_expr(&op.left) {
1175 (
1176 Some(op.left.clone()),
1177 Expression::Gte(Box::new(BinaryOp {
1178 left: alias_col,
1179 right: op.right.clone(),
1180 ..(**op).clone()
1181 })),
1182 )
1183 } else if is_window_expr(&op.right) {
1184 (
1185 Some(op.right.clone()),
1186 Expression::Gte(Box::new(BinaryOp {
1187 left: op.left.clone(),
1188 right: alias_col,
1189 ..(**op).clone()
1190 })),
1191 )
1192 } else {
1193 (None, condition)
1194 }
1195 }
1196 _ if is_window_expr(&condition) => (Some(condition), alias_col),
1198 _ => (None, condition),
1200 }
1201}
1202
1203fn is_window_expr(expr: &Expression) -> bool {
1205 matches!(expr, Expression::Window(_) | Expression::WindowFunction(_))
1206}
1207
1208pub fn eliminate_distinct_on(expr: Expression) -> Result<Expression> {
1227 eliminate_distinct_on_for_dialect(expr, None, None)
1228}
1229
1230pub fn strip_cte_materialization(expr: Expression) -> Result<Expression> {
1233 transform_recursive(expr, &strip_cte_materialization_single)
1234}
1235
1236fn strip_cte_materialization_single(expr: Expression) -> Result<Expression> {
1237 Ok(match expr {
1238 Expression::Select(mut select) => {
1239 strip_with_cte_materialization(&mut select.with);
1240 Expression::Select(select)
1241 }
1242 Expression::Union(mut union) => {
1243 strip_with_cte_materialization(&mut union.with);
1244 Expression::Union(union)
1245 }
1246 Expression::Intersect(mut intersect) => {
1247 strip_with_cte_materialization(&mut intersect.with);
1248 Expression::Intersect(intersect)
1249 }
1250 Expression::Except(mut except) => {
1251 strip_with_cte_materialization(&mut except.with);
1252 Expression::Except(except)
1253 }
1254 Expression::Pivot(mut pivot) => {
1255 strip_with_cte_materialization(&mut pivot.with);
1256 Expression::Pivot(pivot)
1257 }
1258 Expression::Insert(mut insert) => {
1259 strip_with_cte_materialization(&mut insert.with);
1260 Expression::Insert(insert)
1261 }
1262 Expression::Update(mut update) => {
1263 strip_with_cte_materialization(&mut update.with);
1264 Expression::Update(update)
1265 }
1266 Expression::Delete(mut delete) => {
1267 strip_with_cte_materialization(&mut delete.with);
1268 Expression::Delete(delete)
1269 }
1270 Expression::CreateTable(mut create_table) => {
1271 strip_with_cte_materialization(&mut create_table.with_cte);
1272 Expression::CreateTable(create_table)
1273 }
1274 Expression::With(mut with) => {
1275 strip_cte_materialization_in_with(&mut with);
1276 Expression::With(with)
1277 }
1278 Expression::Cte(mut cte) => {
1279 cte.materialized = None;
1280 Expression::Cte(cte)
1281 }
1282 _ => expr,
1283 })
1284}
1285
1286fn strip_with_cte_materialization(with: &mut Option<With>) {
1287 if let Some(with) = with {
1288 strip_cte_materialization_in_with(with);
1289 }
1290}
1291
1292fn strip_cte_materialization_in_with(with: &mut With) {
1293 for cte in &mut with.ctes {
1294 cte.materialized = None;
1295 }
1296}
1297
1298#[derive(Clone, Copy)]
1299enum DistinctOnNullsMode {
1300 None,
1301 NullsFirst,
1302 CaseExpr,
1303}
1304
1305pub fn eliminate_distinct_on_for_dialect(
1310 expr: Expression,
1311 target: Option<DialectType>,
1312 source: Option<DialectType>,
1313) -> Result<Expression> {
1314 if matches!(
1316 target,
1317 Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB)
1318 ) {
1319 return Ok(expr);
1320 }
1321
1322 let nulls_mode = match target {
1327 Some(DialectType::MySQL)
1328 | Some(DialectType::SingleStore)
1329 | Some(DialectType::TSQL)
1330 | Some(DialectType::Fabric) => DistinctOnNullsMode::CaseExpr,
1331 Some(DialectType::Oracle) | Some(DialectType::Redshift) | Some(DialectType::Snowflake) => {
1332 DistinctOnNullsMode::None
1333 }
1334 Some(DialectType::StarRocks) => {
1335 if matches!(source, Some(DialectType::Redshift)) {
1336 DistinctOnNullsMode::CaseExpr
1337 } else {
1338 DistinctOnNullsMode::None
1339 }
1340 }
1341 _ => DistinctOnNullsMode::NullsFirst,
1343 };
1344
1345 transform_recursive(expr, &|expr| eliminate_distinct_on_select(expr, nulls_mode))
1346}
1347
1348fn eliminate_distinct_on_select(
1349 expr: Expression,
1350 nulls_mode: DistinctOnNullsMode,
1351) -> Result<Expression> {
1352 use crate::expressions::Case;
1353
1354 match expr {
1355 Expression::Select(mut select) => {
1356 if let Some(distinct_cols) = select.distinct_on.take() {
1357 if !distinct_cols.is_empty() {
1358 let row_number_alias = Identifier::new("_row_number".to_string());
1360
1361 let order_exprs = if let Some(ref order_by) = select.order_by {
1363 let mut exprs = order_by.expressions.clone();
1364 match nulls_mode {
1366 DistinctOnNullsMode::NullsFirst => {
1367 for ord in &mut exprs {
1368 if ord.desc && ord.nulls_first.is_none() {
1369 ord.nulls_first = Some(true);
1370 }
1371 }
1372 }
1373 DistinctOnNullsMode::CaseExpr => {
1374 let mut new_exprs = Vec::new();
1377 for ord in &exprs {
1378 if ord.desc && ord.nulls_first.is_none() {
1379 let null_check = Expression::Case(Box::new(Case {
1381 operand: None,
1382 whens: vec![(
1383 Expression::IsNull(Box::new(
1384 crate::expressions::IsNull {
1385 this: ord.this.clone(),
1386 not: false,
1387 postfix_form: false,
1388 },
1389 )),
1390 Expression::Literal(Box::new(Literal::Number(
1391 "1".to_string(),
1392 ))),
1393 )],
1394 else_: Some(Expression::Literal(Box::new(
1395 Literal::Number("0".to_string()),
1396 ))),
1397 comments: Vec::new(),
1398 inferred_type: None,
1399 }));
1400 new_exprs.push(crate::expressions::Ordered {
1401 this: null_check,
1402 desc: true,
1403 nulls_first: None,
1404 explicit_asc: false,
1405 with_fill: None,
1406 });
1407 }
1408 new_exprs.push(ord.clone());
1409 }
1410 exprs = new_exprs;
1411 }
1412 DistinctOnNullsMode::None => {}
1413 }
1414 exprs
1415 } else {
1416 distinct_cols
1417 .iter()
1418 .map(|e| crate::expressions::Ordered {
1419 this: e.clone(),
1420 desc: false,
1421 nulls_first: None,
1422 explicit_asc: false,
1423 with_fill: None,
1424 })
1425 .collect()
1426 };
1427
1428 let row_number_func =
1430 Expression::WindowFunction(Box::new(crate::expressions::WindowFunction {
1431 this: Expression::RowNumber(crate::expressions::RowNumber),
1432 over: Over {
1433 partition_by: distinct_cols,
1434 order_by: order_exprs,
1435 frame: None,
1436 window_name: None,
1437 alias: None,
1438 },
1439 keep: None,
1440 inferred_type: None,
1441 }));
1442
1443 let mut inner_aliased_exprs = Vec::new();
1447 let mut outer_select_exprs = Vec::new();
1448 for orig_expr in &select.expressions {
1449 match orig_expr {
1450 Expression::Alias(alias) => {
1451 inner_aliased_exprs.push(orig_expr.clone());
1453 outer_select_exprs.push(Expression::Column(Box::new(
1454 crate::expressions::Column {
1455 name: alias.alias.clone(),
1456 table: None,
1457 join_mark: false,
1458 trailing_comments: vec![],
1459 span: None,
1460 inferred_type: None,
1461 },
1462 )));
1463 }
1464 Expression::Column(col) => {
1465 inner_aliased_exprs.push(Expression::Alias(Box::new(
1467 crate::expressions::Alias {
1468 this: orig_expr.clone(),
1469 alias: col.name.clone(),
1470 column_aliases: vec![],
1471 alias_explicit_as: false,
1472 alias_keyword: None,
1473 pre_alias_comments: vec![],
1474 trailing_comments: vec![],
1475 inferred_type: None,
1476 },
1477 )));
1478 outer_select_exprs.push(Expression::Column(Box::new(
1479 crate::expressions::Column {
1480 name: col.name.clone(),
1481 table: None,
1482 join_mark: false,
1483 trailing_comments: vec![],
1484 span: None,
1485 inferred_type: None,
1486 },
1487 )));
1488 }
1489 _ => {
1490 inner_aliased_exprs.push(orig_expr.clone());
1492 outer_select_exprs.push(orig_expr.clone());
1493 }
1494 }
1495 }
1496
1497 let row_number_alias_expr =
1499 Expression::Alias(Box::new(crate::expressions::Alias {
1500 this: row_number_func,
1501 alias: row_number_alias.clone(),
1502 column_aliases: vec![],
1503 alias_explicit_as: false,
1504 alias_keyword: None,
1505 pre_alias_comments: vec![],
1506 trailing_comments: vec![],
1507 inferred_type: None,
1508 }));
1509 inner_aliased_exprs.push(row_number_alias_expr);
1510
1511 select.expressions = inner_aliased_exprs;
1513
1514 let _inner_order_by = select.order_by.take();
1516
1517 select.distinct = false;
1519
1520 let inner_select = Expression::Select(select);
1522 let subquery = Subquery {
1523 this: inner_select,
1524 alias: Some(Identifier::new("_t".to_string())),
1525 column_aliases: vec![],
1526 alias_explicit_as: false,
1527 alias_keyword: None,
1528 order_by: None,
1529 limit: None,
1530 offset: None,
1531 distribute_by: None,
1532 sort_by: None,
1533 cluster_by: None,
1534 lateral: false,
1535 modifiers_inside: false,
1536 trailing_comments: vec![],
1537 inferred_type: None,
1538 };
1539
1540 let outer_select = Select {
1543 expressions: outer_select_exprs,
1544 from: Some(From {
1545 expressions: vec![Expression::Subquery(Box::new(subquery))],
1546 }),
1547 where_clause: Some(Where {
1548 this: Expression::Eq(Box::new(BinaryOp {
1549 left: Expression::Column(Box::new(crate::expressions::Column {
1550 name: row_number_alias,
1551 table: None,
1552 join_mark: false,
1553 trailing_comments: vec![],
1554 span: None,
1555 inferred_type: None,
1556 })),
1557 right: Expression::Literal(Box::new(Literal::Number(
1558 "1".to_string(),
1559 ))),
1560 left_comments: vec![],
1561 operator_comments: vec![],
1562 trailing_comments: vec![],
1563 inferred_type: None,
1564 })),
1565 }),
1566 ..Select::new()
1567 };
1568
1569 return Ok(Expression::Select(Box::new(outer_select)));
1570 }
1571 }
1572 Ok(Expression::Select(select))
1573 }
1574 other => Ok(other),
1575 }
1576}
1577
1578pub fn eliminate_semi_and_anti_joins(expr: Expression) -> Result<Expression> {
1586 match expr {
1587 Expression::Select(mut select) => {
1588 let mut new_joins = Vec::new();
1589 let mut extra_where_conditions = Vec::new();
1590
1591 for join in select.joins.drain(..) {
1592 match join.kind {
1593 JoinKind::Semi | JoinKind::LeftSemi => {
1594 if let Some(on_condition) = join.on {
1595 let subquery_select = Select {
1597 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1598 "1".to_string(),
1599 )))],
1600 from: Some(From {
1601 expressions: vec![join.this],
1602 }),
1603 where_clause: Some(Where { this: on_condition }),
1604 ..Select::new()
1605 };
1606
1607 let exists = Expression::Exists(Box::new(Exists {
1608 this: Expression::Subquery(Box::new(Subquery {
1609 this: Expression::Select(Box::new(subquery_select)),
1610 alias: None,
1611 column_aliases: vec![],
1612 alias_explicit_as: false,
1613 alias_keyword: None,
1614 order_by: None,
1615 limit: None,
1616 offset: None,
1617 distribute_by: None,
1618 sort_by: None,
1619 cluster_by: None,
1620 lateral: false,
1621 modifiers_inside: false,
1622 trailing_comments: vec![],
1623 inferred_type: None,
1624 })),
1625 not: false,
1626 }));
1627
1628 extra_where_conditions.push(exists);
1629 }
1630 }
1631 JoinKind::Anti | JoinKind::LeftAnti => {
1632 if let Some(on_condition) = join.on {
1633 let subquery_select = Select {
1635 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1636 "1".to_string(),
1637 )))],
1638 from: Some(From {
1639 expressions: vec![join.this],
1640 }),
1641 where_clause: Some(Where { this: on_condition }),
1642 ..Select::new()
1643 };
1644
1645 let not_exists = Expression::Exists(Box::new(Exists {
1647 this: Expression::Subquery(Box::new(Subquery {
1648 this: Expression::Select(Box::new(subquery_select)),
1649 alias: None,
1650 column_aliases: vec![],
1651 alias_explicit_as: false,
1652 alias_keyword: None,
1653 order_by: None,
1654 limit: None,
1655 offset: None,
1656 distribute_by: None,
1657 sort_by: None,
1658 cluster_by: None,
1659 lateral: false,
1660 modifiers_inside: false,
1661 trailing_comments: vec![],
1662 inferred_type: None,
1663 })),
1664 not: true,
1665 }));
1666
1667 extra_where_conditions.push(not_exists);
1668 }
1669 }
1670 _ => {
1671 new_joins.push(join);
1673 }
1674 }
1675 }
1676
1677 select.joins = new_joins;
1678
1679 if !extra_where_conditions.is_empty() {
1681 let combined = extra_where_conditions
1682 .into_iter()
1683 .reduce(|acc, cond| {
1684 Expression::And(Box::new(BinaryOp {
1685 left: acc,
1686 right: cond,
1687 left_comments: vec![],
1688 operator_comments: vec![],
1689 trailing_comments: vec![],
1690 inferred_type: None,
1691 }))
1692 })
1693 .unwrap();
1694
1695 select.where_clause = match select.where_clause {
1696 Some(Where { this: existing }) => Some(Where {
1697 this: Expression::And(Box::new(BinaryOp {
1698 left: existing,
1699 right: combined,
1700 left_comments: vec![],
1701 operator_comments: vec![],
1702 trailing_comments: vec![],
1703 inferred_type: None,
1704 })),
1705 }),
1706 None => Some(Where { this: combined }),
1707 };
1708 }
1709
1710 Ok(Expression::Select(select))
1711 }
1712 other => Ok(other),
1713 }
1714}
1715
1716pub fn eliminate_full_outer_join(expr: Expression) -> Result<Expression> {
1734 match expr {
1735 Expression::Select(mut select) => {
1736 let full_outer_join_idx = select.joins.iter().position(|j| j.kind == JoinKind::Full);
1738
1739 if let Some(idx) = full_outer_join_idx {
1740 let full_join_count = select
1742 .joins
1743 .iter()
1744 .filter(|j| j.kind == JoinKind::Full)
1745 .count();
1746 if full_join_count != 1 {
1747 return Ok(Expression::Select(select));
1748 }
1749
1750 let mut right_select = select.clone();
1752
1753 let full_join = &select.joins[idx];
1755 let join_condition = full_join.on.clone();
1756
1757 select.joins[idx].kind = JoinKind::Left;
1759
1760 right_select.joins[idx].kind = JoinKind::Right;
1762
1763 if let (Some(ref from), Some(ref join_cond)) = (&select.from, &join_condition) {
1765 if !from.expressions.is_empty() {
1766 let anti_subquery = Expression::Select(Box::new(Select {
1767 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1768 "1".to_string(),
1769 )))],
1770 from: Some(from.clone()),
1771 where_clause: Some(Where {
1772 this: join_cond.clone(),
1773 }),
1774 ..Select::new()
1775 }));
1776
1777 let not_exists = Expression::Not(Box::new(crate::expressions::UnaryOp {
1778 inferred_type: None,
1779 this: Expression::Exists(Box::new(Exists {
1780 this: Expression::Subquery(Box::new(Subquery {
1781 this: anti_subquery,
1782 alias: None,
1783 column_aliases: vec![],
1784 alias_explicit_as: false,
1785 alias_keyword: None,
1786 order_by: None,
1787 limit: None,
1788 offset: None,
1789 distribute_by: None,
1790 sort_by: None,
1791 cluster_by: None,
1792 lateral: false,
1793 modifiers_inside: false,
1794 trailing_comments: vec![],
1795 inferred_type: None,
1796 })),
1797 not: false,
1798 })),
1799 }));
1800
1801 right_select.where_clause = Some(Where {
1803 this: match right_select.where_clause {
1804 Some(w) => Expression::And(Box::new(BinaryOp {
1805 left: w.this,
1806 right: not_exists,
1807 left_comments: vec![],
1808 operator_comments: vec![],
1809 trailing_comments: vec![],
1810 inferred_type: None,
1811 })),
1812 None => not_exists,
1813 },
1814 });
1815 }
1816 }
1817
1818 right_select.with = None;
1820
1821 let order_by = select.order_by.take();
1823
1824 let union = crate::expressions::Union {
1826 left: Expression::Select(select),
1827 right: Expression::Select(right_select),
1828 all: true, distinct: false,
1830 with: None,
1831 order_by,
1832 limit: None,
1833 offset: None,
1834 distribute_by: None,
1835 sort_by: None,
1836 cluster_by: None,
1837 by_name: false,
1838 side: None,
1839 kind: None,
1840 corresponding: false,
1841 strict: false,
1842 on_columns: Vec::new(),
1843 };
1844
1845 return Ok(Expression::Union(Box::new(union)));
1846 }
1847
1848 Ok(Expression::Select(select))
1849 }
1850 other => Ok(other),
1851 }
1852}
1853
1854pub fn move_ctes_to_top_level(expr: Expression) -> Result<Expression> {
1867 match expr {
1868 Expression::Select(mut select) => {
1869 let mut collected_ctes: Vec<crate::expressions::Cte> = Vec::new();
1871 let mut has_recursive = false;
1872
1873 collect_nested_ctes(
1874 &Expression::Select(select.clone()),
1875 &mut collected_ctes,
1876 &mut has_recursive,
1877 true,
1878 );
1879
1880 let mut cte_body_collected: Vec<(String, Vec<crate::expressions::Cte>)> = Vec::new();
1883 if let Some(ref with) = select.with {
1884 for cte in &with.ctes {
1885 let mut body_ctes: Vec<crate::expressions::Cte> = Vec::new();
1886 collect_ctes_from_cte_body(&cte.this, &mut body_ctes, &mut has_recursive);
1887 if !body_ctes.is_empty() {
1888 cte_body_collected.push((cte.alias.name.clone(), body_ctes));
1889 }
1890 }
1891 }
1892
1893 let has_subquery_ctes = !collected_ctes.is_empty();
1894 let has_body_ctes = !cte_body_collected.is_empty();
1895
1896 if has_subquery_ctes || has_body_ctes {
1897 strip_nested_with_clauses(&mut select, true);
1899
1900 if has_body_ctes {
1902 if let Some(ref mut with) = select.with {
1903 for cte in with.ctes.iter_mut() {
1904 strip_with_from_cte_body(&mut cte.this);
1905 }
1906 }
1907 }
1908
1909 let top_with = select.with.get_or_insert_with(|| crate::expressions::With {
1910 ctes: Vec::new(),
1911 recursive: false,
1912 leading_comments: vec![],
1913 search: None,
1914 });
1915
1916 if has_recursive {
1917 top_with.recursive = true;
1918 }
1919
1920 if has_body_ctes {
1922 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
1923 for mut cte in top_with.ctes.drain(..) {
1924 if let Some(pos) = cte_body_collected
1926 .iter()
1927 .position(|(name, _)| *name == cte.alias.name)
1928 {
1929 let (_, mut nested) = cte_body_collected.remove(pos);
1930 for nested_cte in nested.iter_mut() {
1932 strip_with_from_cte_body(&mut nested_cte.this);
1933 }
1934 new_ctes.extend(nested);
1935 }
1936 strip_with_from_cte_body(&mut cte.this);
1938 new_ctes.push(cte);
1939 }
1940 top_with.ctes = new_ctes;
1941 }
1942
1943 top_with.ctes.extend(collected_ctes);
1945 }
1946
1947 Ok(Expression::Select(select))
1948 }
1949 other => Ok(other),
1950 }
1951}
1952
1953fn collect_ctes_from_cte_body(
1955 expr: &Expression,
1956 collected: &mut Vec<crate::expressions::Cte>,
1957 has_recursive: &mut bool,
1958) {
1959 if let Expression::Select(select) = expr {
1960 if let Some(ref with) = select.with {
1961 if with.recursive {
1962 *has_recursive = true;
1963 }
1964 for cte in &with.ctes {
1965 collect_ctes_from_cte_body(&cte.this, collected, has_recursive);
1967 collected.push(cte.clone());
1969 }
1970 }
1971 }
1972}
1973
1974fn strip_with_from_cte_body(expr: &mut Expression) {
1976 if let Expression::Select(ref mut select) = expr {
1977 select.with = None;
1978 }
1979}
1980
1981fn strip_nested_with_clauses(select: &mut Select, _is_top_level: bool) {
1983 if let Some(ref mut from) = select.from {
1985 for expr in from.expressions.iter_mut() {
1986 strip_with_from_expr(expr);
1987 }
1988 }
1989 for join in select.joins.iter_mut() {
1991 strip_with_from_expr(&mut join.this);
1992 }
1993 for expr in select.expressions.iter_mut() {
1995 strip_with_from_expr(expr);
1996 }
1997 if let Some(ref mut w) = select.where_clause {
1999 strip_with_from_expr(&mut w.this);
2000 }
2001}
2002
2003fn strip_with_from_expr(expr: &mut Expression) {
2004 match expr {
2005 Expression::Subquery(ref mut subquery) => {
2006 strip_with_from_inner_query(&mut subquery.this);
2007 }
2008 Expression::Alias(ref mut alias) => {
2009 strip_with_from_expr(&mut alias.this);
2010 }
2011 Expression::Select(ref mut select) => {
2012 select.with = None;
2014 strip_nested_with_clauses(select, false);
2016 }
2017 _ => {}
2018 }
2019}
2020
2021fn strip_with_from_inner_query(expr: &mut Expression) {
2022 if let Expression::Select(ref mut select) = expr {
2023 select.with = None;
2024 strip_nested_with_clauses(select, false);
2025 }
2026}
2027
2028fn collect_nested_ctes(
2030 expr: &Expression,
2031 collected: &mut Vec<crate::expressions::Cte>,
2032 has_recursive: &mut bool,
2033 is_top_level: bool,
2034) {
2035 match expr {
2036 Expression::Select(select) => {
2037 if !is_top_level {
2039 if let Some(ref with) = select.with {
2040 if with.recursive {
2041 *has_recursive = true;
2042 }
2043 collected.extend(with.ctes.clone());
2044 }
2045 }
2046
2047 if let Some(ref from) = select.from {
2049 for expr in &from.expressions {
2050 collect_nested_ctes(expr, collected, has_recursive, false);
2051 }
2052 }
2053
2054 for join in &select.joins {
2056 collect_nested_ctes(&join.this, collected, has_recursive, false);
2057 }
2058
2059 for sel_expr in &select.expressions {
2061 collect_nested_ctes(sel_expr, collected, has_recursive, false);
2062 }
2063
2064 if let Some(ref where_clause) = select.where_clause {
2066 collect_nested_ctes(&where_clause.this, collected, has_recursive, false);
2067 }
2068 }
2069 Expression::Subquery(subquery) => {
2070 collect_nested_ctes(&subquery.this, collected, has_recursive, false);
2072 }
2073 Expression::Alias(alias) => {
2074 collect_nested_ctes(&alias.this, collected, has_recursive, false);
2075 }
2076 _ => {}
2078 }
2079}
2080
2081pub fn eliminate_window_clause(expr: Expression) -> Result<Expression> {
2097 match expr {
2098 Expression::Select(mut select) => {
2099 if let Some(named_windows) = select.windows.take() {
2100 let window_map: std::collections::HashMap<String, &Over> = named_windows
2102 .iter()
2103 .map(|nw| (nw.name.name.to_lowercase(), &nw.spec))
2104 .collect();
2105
2106 select.expressions = select
2108 .expressions
2109 .into_iter()
2110 .map(|e| inline_window_refs(e, &window_map))
2111 .collect();
2112 }
2113 Ok(Expression::Select(select))
2114 }
2115 other => Ok(other),
2116 }
2117}
2118
2119fn inline_window_refs(
2121 expr: Expression,
2122 window_map: &std::collections::HashMap<String, &Over>,
2123) -> Expression {
2124 match expr {
2125 Expression::WindowFunction(mut wf) => {
2126 if let Some(ref name) = wf.over.window_name {
2128 let key = name.name.to_lowercase();
2129 if let Some(named_spec) = window_map.get(&key) {
2130 if wf.over.partition_by.is_empty() && !named_spec.partition_by.is_empty() {
2132 wf.over.partition_by = named_spec.partition_by.clone();
2133 }
2134 if wf.over.order_by.is_empty() && !named_spec.order_by.is_empty() {
2135 wf.over.order_by = named_spec.order_by.clone();
2136 }
2137 if wf.over.frame.is_none() && named_spec.frame.is_some() {
2138 wf.over.frame = named_spec.frame.clone();
2139 }
2140 wf.over.window_name = None;
2142 }
2143 }
2144 Expression::WindowFunction(wf)
2145 }
2146 Expression::Alias(mut alias) => {
2147 alias.this = inline_window_refs(alias.this, window_map);
2149 Expression::Alias(alias)
2150 }
2151 other => other,
2154 }
2155}
2156
2157pub fn eliminate_join_marks(expr: Expression) -> Result<Expression> {
2171 match expr {
2172 Expression::Select(mut select) => {
2173 let has_join_marks = select
2175 .where_clause
2176 .as_ref()
2177 .map_or(false, |w| contains_join_mark(&w.this));
2178
2179 if !has_join_marks {
2180 return Ok(Expression::Select(select));
2181 }
2182
2183 let from_tables: Vec<String> = select
2185 .from
2186 .as_ref()
2187 .map(|f| {
2188 f.expressions
2189 .iter()
2190 .filter_map(|e| get_table_name(e))
2191 .collect()
2192 })
2193 .unwrap_or_default();
2194
2195 let mut join_conditions: std::collections::HashMap<String, Vec<Expression>> =
2197 std::collections::HashMap::new();
2198 let mut remaining_conditions: Vec<Expression> = Vec::new();
2199
2200 if let Some(ref where_clause) = select.where_clause {
2201 extract_join_mark_conditions(
2202 &where_clause.this,
2203 &mut join_conditions,
2204 &mut remaining_conditions,
2205 );
2206 }
2207
2208 let mut new_joins = select.joins.clone();
2210 for (table_name, conditions) in join_conditions {
2211 let table_in_from = from_tables.contains(&table_name);
2213
2214 if table_in_from && !conditions.is_empty() {
2215 let combined_condition = conditions.into_iter().reduce(|a, b| {
2217 Expression::And(Box::new(BinaryOp {
2218 left: a,
2219 right: b,
2220 left_comments: vec![],
2221 operator_comments: vec![],
2222 trailing_comments: vec![],
2223 inferred_type: None,
2224 }))
2225 });
2226
2227 if let Some(ref mut from) = select.from {
2229 if let Some(pos) = from
2230 .expressions
2231 .iter()
2232 .position(|e| get_table_name(e).map_or(false, |n| n == table_name))
2233 {
2234 if from.expressions.len() > 1 {
2235 let join_table = from.expressions.remove(pos);
2236 new_joins.push(crate::expressions::Join {
2237 this: join_table,
2238 kind: JoinKind::Left,
2239 on: combined_condition,
2240 using: vec![],
2241 use_inner_keyword: false,
2242 use_outer_keyword: true,
2243 deferred_condition: false,
2244 join_hint: None,
2245 match_condition: None,
2246 pivots: Vec::new(),
2247 comments: Vec::new(),
2248 nesting_group: 0,
2249 directed: false,
2250 });
2251 }
2252 }
2253 }
2254 }
2255 }
2256
2257 select.joins = new_joins;
2258
2259 if remaining_conditions.is_empty() {
2261 select.where_clause = None;
2262 } else {
2263 let combined = remaining_conditions.into_iter().reduce(|a, b| {
2264 Expression::And(Box::new(BinaryOp {
2265 left: a,
2266 right: b,
2267 left_comments: vec![],
2268 operator_comments: vec![],
2269 trailing_comments: vec![],
2270 inferred_type: None,
2271 }))
2272 });
2273 select.where_clause = combined.map(|c| Where { this: c });
2274 }
2275
2276 clear_join_marks(&mut Expression::Select(select.clone()));
2278
2279 Ok(Expression::Select(select))
2280 }
2281 other => Ok(other),
2282 }
2283}
2284
2285fn contains_join_mark(expr: &Expression) -> bool {
2287 match expr {
2288 Expression::Column(col) => col.join_mark,
2289 Expression::And(op) | Expression::Or(op) => {
2290 contains_join_mark(&op.left) || contains_join_mark(&op.right)
2291 }
2292 Expression::Eq(op)
2293 | Expression::Neq(op)
2294 | Expression::Lt(op)
2295 | Expression::Lte(op)
2296 | Expression::Gt(op)
2297 | Expression::Gte(op) => contains_join_mark(&op.left) || contains_join_mark(&op.right),
2298 Expression::Not(op) => contains_join_mark(&op.this),
2299 _ => false,
2300 }
2301}
2302
2303fn get_table_name(expr: &Expression) -> Option<String> {
2305 match expr {
2306 Expression::Table(t) => Some(t.name.name.clone()),
2307 Expression::Alias(a) => Some(a.alias.name.clone()),
2308 _ => None,
2309 }
2310}
2311
2312fn extract_join_mark_conditions(
2314 expr: &Expression,
2315 join_conditions: &mut std::collections::HashMap<String, Vec<Expression>>,
2316 remaining: &mut Vec<Expression>,
2317) {
2318 match expr {
2319 Expression::And(op) => {
2320 extract_join_mark_conditions(&op.left, join_conditions, remaining);
2321 extract_join_mark_conditions(&op.right, join_conditions, remaining);
2322 }
2323 _ => {
2324 if let Some(table) = get_join_mark_table(expr) {
2325 join_conditions
2326 .entry(table)
2327 .or_insert_with(Vec::new)
2328 .push(expr.clone());
2329 } else {
2330 remaining.push(expr.clone());
2331 }
2332 }
2333 }
2334}
2335
2336fn get_join_mark_table(expr: &Expression) -> Option<String> {
2338 match expr {
2339 Expression::Eq(op)
2340 | Expression::Neq(op)
2341 | Expression::Lt(op)
2342 | Expression::Lte(op)
2343 | Expression::Gt(op)
2344 | Expression::Gte(op) => {
2345 if let Expression::Column(col) = &op.left {
2347 if col.join_mark {
2348 return col.table.as_ref().map(|t| t.name.clone());
2349 }
2350 }
2351 if let Expression::Column(col) = &op.right {
2352 if col.join_mark {
2353 return col.table.as_ref().map(|t| t.name.clone());
2354 }
2355 }
2356 None
2357 }
2358 _ => None,
2359 }
2360}
2361
2362fn clear_join_marks(expr: &mut Expression) {
2364 match expr {
2365 Expression::Column(col) => col.join_mark = false,
2366 Expression::Select(select) => {
2367 if let Some(ref mut w) = select.where_clause {
2368 clear_join_marks(&mut w.this);
2369 }
2370 for sel_expr in &mut select.expressions {
2371 clear_join_marks(sel_expr);
2372 }
2373 }
2374 Expression::And(op) | Expression::Or(op) => {
2375 clear_join_marks(&mut op.left);
2376 clear_join_marks(&mut op.right);
2377 }
2378 Expression::Eq(op)
2379 | Expression::Neq(op)
2380 | Expression::Lt(op)
2381 | Expression::Lte(op)
2382 | Expression::Gt(op)
2383 | Expression::Gte(op) => {
2384 clear_join_marks(&mut op.left);
2385 clear_join_marks(&mut op.right);
2386 }
2387 _ => {}
2388 }
2389}
2390
2391pub fn add_recursive_cte_column_names(expr: Expression) -> Result<Expression> {
2398 match expr {
2399 Expression::Select(mut select) => {
2400 if let Some(ref mut with) = select.with {
2401 if with.recursive {
2402 let mut counter = 0;
2403 for cte in &mut with.ctes {
2404 if cte.columns.is_empty() {
2405 if let Expression::Select(ref cte_select) = cte.this {
2407 let names: Vec<Identifier> = cte_select
2408 .expressions
2409 .iter()
2410 .map(|e| match e {
2411 Expression::Alias(a) => a.alias.clone(),
2412 Expression::Column(c) => c.name.clone(),
2413 _ => {
2414 counter += 1;
2415 Identifier::new(format!("_c_{}", counter))
2416 }
2417 })
2418 .collect();
2419 cte.columns = names;
2420 }
2421 }
2422 }
2423 }
2424 }
2425 Ok(Expression::Select(select))
2426 }
2427 other => Ok(other),
2428 }
2429}
2430
2431pub fn epoch_cast_to_ts(expr: Expression) -> Result<Expression> {
2438 match expr {
2439 Expression::Cast(mut cast) => {
2440 if let Expression::Literal(ref lit) = cast.this {
2441 if let Literal::String(ref s) = lit.as_ref() {
2442 if s.to_lowercase() == "epoch" {
2443 if is_temporal_type(&cast.to) {
2444 cast.this = Expression::Literal(Box::new(Literal::String(
2445 "1970-01-01 00:00:00".to_string(),
2446 )));
2447 }
2448 }
2449 }
2450 }
2451 Ok(Expression::Cast(cast))
2452 }
2453 Expression::TryCast(mut try_cast) => {
2454 if let Expression::Literal(ref lit) = try_cast.this {
2455 if let Literal::String(ref s) = lit.as_ref() {
2456 if s.to_lowercase() == "epoch" {
2457 if is_temporal_type(&try_cast.to) {
2458 try_cast.this = Expression::Literal(Box::new(Literal::String(
2459 "1970-01-01 00:00:00".to_string(),
2460 )));
2461 }
2462 }
2463 }
2464 }
2465 Ok(Expression::TryCast(try_cast))
2466 }
2467 other => Ok(other),
2468 }
2469}
2470
2471fn is_temporal_type(dt: &DataType) -> bool {
2473 matches!(
2474 dt,
2475 DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. }
2476 )
2477}
2478
2479pub fn ensure_bools(expr: Expression) -> Result<Expression> {
2504 let expr = ensure_bools_in_value_context(expr);
2505
2506 Ok(match expr {
2507 Expression::And(_) | Expression::Or(_) | Expression::Not(_) => ensure_bool_condition(expr),
2509 other => other,
2510 })
2511}
2512
2513fn ensure_bools_in_value_context(expr: Expression) -> Expression {
2517 match expr {
2518 Expression::Case(mut case) => {
2519 let is_simple_case = case.operand.is_some();
2520 if let Some(operand) = case.operand.take() {
2521 case.operand = Some(ensure_bools_in_value_context(operand));
2522 }
2523 case.whens = case
2524 .whens
2525 .into_iter()
2526 .map(|(condition, result)| {
2527 let new_condition = if is_simple_case {
2528 ensure_bools_in_value_context(condition)
2529 } else {
2530 ensure_bool_condition(ensure_bools_in_value_context(condition))
2531 };
2532 let new_result = ensure_bools_in_value_context(result);
2533 (new_condition, new_result)
2534 })
2535 .collect();
2536 if let Some(else_expr) = case.else_ {
2537 case.else_ = Some(ensure_bools_in_value_context(else_expr));
2538 }
2539 Expression::Case(Box::new(*case))
2540 }
2541 Expression::Select(select) => Expression::Select(Box::new(ensure_bools_in_select(*select))),
2542 Expression::Subquery(mut subquery) => {
2543 subquery.this = ensure_bools_in_value_context(subquery.this);
2544 Expression::Subquery(subquery)
2545 }
2546 Expression::JoinedTable(mut joined_table) => {
2547 joined_table.left = ensure_bools_in_value_context(joined_table.left);
2548 joined_table.joins = joined_table
2549 .joins
2550 .into_iter()
2551 .map(ensure_bools_in_join)
2552 .collect();
2553 joined_table.lateral_views = joined_table
2554 .lateral_views
2555 .into_iter()
2556 .map(|mut lateral_view| {
2557 lateral_view.this = ensure_bools_in_value_context(lateral_view.this);
2558 lateral_view
2559 })
2560 .collect();
2561 Expression::JoinedTable(joined_table)
2562 }
2563 Expression::Union(mut union) => {
2564 let left = std::mem::replace(&mut union.left, Expression::null());
2565 let right = std::mem::replace(&mut union.right, Expression::null());
2566 union.left = ensure_bools_in_value_context(left);
2567 union.right = ensure_bools_in_value_context(right);
2568 if let Some(with) = union.with.take() {
2569 union.with = Some(ensure_bools_in_with(with));
2570 }
2571 Expression::Union(union)
2572 }
2573 Expression::Intersect(mut intersect) => {
2574 let left = std::mem::replace(&mut intersect.left, Expression::null());
2575 let right = std::mem::replace(&mut intersect.right, Expression::null());
2576 intersect.left = ensure_bools_in_value_context(left);
2577 intersect.right = ensure_bools_in_value_context(right);
2578 if let Some(with) = intersect.with.take() {
2579 intersect.with = Some(ensure_bools_in_with(with));
2580 }
2581 Expression::Intersect(intersect)
2582 }
2583 Expression::Except(mut except) => {
2584 let left = std::mem::replace(&mut except.left, Expression::null());
2585 let right = std::mem::replace(&mut except.right, Expression::null());
2586 except.left = ensure_bools_in_value_context(left);
2587 except.right = ensure_bools_in_value_context(right);
2588 if let Some(with) = except.with.take() {
2589 except.with = Some(ensure_bools_in_with(with));
2590 }
2591 Expression::Except(except)
2592 }
2593 Expression::Alias(mut alias) => {
2594 alias.this = ensure_bools_in_value_context(alias.this);
2595 Expression::Alias(alias)
2596 }
2597 Expression::Paren(mut paren) => {
2598 paren.this = ensure_bools_in_value_context(paren.this);
2599 Expression::Paren(paren)
2600 }
2601 other => other,
2602 }
2603}
2604
2605fn ensure_bools_in_select(mut select: Select) -> Select {
2606 select.expressions = select
2607 .expressions
2608 .into_iter()
2609 .map(ensure_bools_in_value_context)
2610 .collect();
2611
2612 if let Some(from) = select.from.take() {
2613 select.from = Some(crate::expressions::From {
2614 expressions: from
2615 .expressions
2616 .into_iter()
2617 .map(ensure_bools_in_value_context)
2618 .collect(),
2619 });
2620 }
2621
2622 select.joins = select.joins.into_iter().map(ensure_bools_in_join).collect();
2623
2624 if let Some(mut where_clause) = select.where_clause.take() {
2625 where_clause.this = ensure_bool_condition(ensure_bools_in_value_context(where_clause.this));
2626 select.where_clause = Some(where_clause);
2627 }
2628
2629 if let Some(mut having) = select.having.take() {
2630 having.this = ensure_bool_condition(ensure_bools_in_value_context(having.this));
2631 select.having = Some(having);
2632 }
2633
2634 if let Some(with) = select.with.take() {
2635 select.with = Some(ensure_bools_in_with(with));
2636 }
2637
2638 select
2639}
2640
2641fn ensure_bools_in_join(mut join: Join) -> Join {
2642 join.this = ensure_bools_in_value_context(join.this);
2643
2644 if let Some(on) = join.on.take() {
2645 join.on = Some(ensure_bool_condition(ensure_bools_in_value_context(on)));
2646 }
2647
2648 if let Some(match_condition) = join.match_condition.take() {
2649 join.match_condition = Some(ensure_bool_condition(ensure_bools_in_value_context(
2650 match_condition,
2651 )));
2652 }
2653
2654 join.pivots = join
2655 .pivots
2656 .into_iter()
2657 .map(ensure_bools_in_value_context)
2658 .collect();
2659
2660 join
2661}
2662
2663fn ensure_bools_in_with(mut with: With) -> With {
2664 with.ctes = with
2665 .ctes
2666 .into_iter()
2667 .map(|mut cte| {
2668 cte.this = ensure_bools_in_value_context(cte.this);
2669 cte
2670 })
2671 .collect();
2672 with
2673}
2674
2675fn is_boolean_expression(expr: &Expression) -> bool {
2678 matches!(
2679 expr,
2680 Expression::Eq(_)
2681 | Expression::Neq(_)
2682 | Expression::Lt(_)
2683 | Expression::Lte(_)
2684 | Expression::Gt(_)
2685 | Expression::Gte(_)
2686 | Expression::Is(_)
2687 | Expression::IsNull(_)
2688 | Expression::IsTrue(_)
2689 | Expression::IsFalse(_)
2690 | Expression::Like(_)
2691 | Expression::ILike(_)
2692 | Expression::StartsWith(_)
2693 | Expression::SimilarTo(_)
2694 | Expression::Glob(_)
2695 | Expression::RegexpLike(_)
2696 | Expression::In(_)
2697 | Expression::Between(_)
2698 | Expression::Exists(_)
2699 | Expression::And(_)
2700 | Expression::Or(_)
2701 | Expression::Not(_)
2702 | Expression::Any(_)
2703 | Expression::All(_)
2704 | Expression::NullSafeEq(_)
2705 | Expression::NullSafeNeq(_)
2706 | Expression::EqualNull(_)
2707 )
2708}
2709
2710fn wrap_neq_zero(expr: Expression) -> Expression {
2712 Expression::Neq(Box::new(BinaryOp {
2713 left: expr,
2714 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
2715 left_comments: vec![],
2716 operator_comments: vec![],
2717 trailing_comments: vec![],
2718 inferred_type: None,
2719 }))
2720}
2721
2722pub(crate) fn ensure_bool_condition(expr: Expression) -> Expression {
2728 match expr {
2729 Expression::And(op) => {
2731 let new_op = BinaryOp {
2732 left: ensure_bool_condition(op.left.clone()),
2733 right: ensure_bool_condition(op.right.clone()),
2734 left_comments: op.left_comments.clone(),
2735 operator_comments: op.operator_comments.clone(),
2736 trailing_comments: op.trailing_comments.clone(),
2737 inferred_type: None,
2738 };
2739 Expression::And(Box::new(new_op))
2740 }
2741 Expression::Or(op) => {
2742 let new_op = BinaryOp {
2743 left: ensure_bool_condition(op.left.clone()),
2744 right: ensure_bool_condition(op.right.clone()),
2745 left_comments: op.left_comments.clone(),
2746 operator_comments: op.operator_comments.clone(),
2747 trailing_comments: op.trailing_comments.clone(),
2748 inferred_type: None,
2749 };
2750 Expression::Or(Box::new(new_op))
2751 }
2752 Expression::Not(op) => Expression::Not(Box::new(crate::expressions::UnaryOp {
2754 this: ensure_bool_condition(op.this.clone()),
2755 inferred_type: None,
2756 })),
2757 Expression::Paren(paren) => Expression::Paren(Box::new(crate::expressions::Paren {
2759 this: ensure_bool_condition(paren.this.clone()),
2760 trailing_comments: paren.trailing_comments.clone(),
2761 })),
2762 Expression::Boolean(BooleanLiteral { value: true }) => {
2764 Expression::Paren(Box::new(crate::expressions::Paren {
2765 this: Expression::Eq(Box::new(BinaryOp {
2766 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2767 right: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2768 left_comments: vec![],
2769 operator_comments: vec![],
2770 trailing_comments: vec![],
2771 inferred_type: None,
2772 })),
2773 trailing_comments: vec![],
2774 }))
2775 }
2776 Expression::Boolean(BooleanLiteral { value: false }) => {
2777 Expression::Paren(Box::new(crate::expressions::Paren {
2778 this: Expression::Eq(Box::new(BinaryOp {
2779 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2780 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
2781 left_comments: vec![],
2782 operator_comments: vec![],
2783 trailing_comments: vec![],
2784 inferred_type: None,
2785 })),
2786 trailing_comments: vec![],
2787 }))
2788 }
2789 ref e if is_boolean_expression(e) => expr,
2791 _ => wrap_neq_zero(expr),
2794 }
2795}
2796
2797pub fn unqualify_columns(expr: Expression) -> Result<Expression> {
2803 Ok(unqualify_columns_recursive(expr))
2804}
2805
2806fn unqualify_columns_recursive(expr: Expression) -> Expression {
2808 match expr {
2809 Expression::Column(mut col) => {
2810 col.table = None;
2811 Expression::Column(col)
2812 }
2813 Expression::Select(mut select) => {
2814 select.expressions = select
2815 .expressions
2816 .into_iter()
2817 .map(unqualify_columns_recursive)
2818 .collect();
2819 if let Some(ref mut where_clause) = select.where_clause {
2820 where_clause.this = unqualify_columns_recursive(where_clause.this.clone());
2821 }
2822 if let Some(ref mut having) = select.having {
2823 having.this = unqualify_columns_recursive(having.this.clone());
2824 }
2825 if let Some(ref mut group_by) = select.group_by {
2826 group_by.expressions = group_by
2827 .expressions
2828 .iter()
2829 .cloned()
2830 .map(unqualify_columns_recursive)
2831 .collect();
2832 }
2833 if let Some(ref mut order_by) = select.order_by {
2834 order_by.expressions = order_by
2835 .expressions
2836 .iter()
2837 .map(|o| crate::expressions::Ordered {
2838 this: unqualify_columns_recursive(o.this.clone()),
2839 desc: o.desc,
2840 nulls_first: o.nulls_first,
2841 explicit_asc: o.explicit_asc,
2842 with_fill: o.with_fill.clone(),
2843 })
2844 .collect();
2845 }
2846 for join in &mut select.joins {
2847 if let Some(ref mut on) = join.on {
2848 *on = unqualify_columns_recursive(on.clone());
2849 }
2850 }
2851 Expression::Select(select)
2852 }
2853 Expression::Alias(mut alias) => {
2854 alias.this = unqualify_columns_recursive(alias.this);
2855 Expression::Alias(alias)
2856 }
2857 Expression::And(op) => Expression::And(Box::new(unqualify_binary_op(*op))),
2859 Expression::Or(op) => Expression::Or(Box::new(unqualify_binary_op(*op))),
2860 Expression::Eq(op) => Expression::Eq(Box::new(unqualify_binary_op(*op))),
2861 Expression::Neq(op) => Expression::Neq(Box::new(unqualify_binary_op(*op))),
2862 Expression::Lt(op) => Expression::Lt(Box::new(unqualify_binary_op(*op))),
2863 Expression::Lte(op) => Expression::Lte(Box::new(unqualify_binary_op(*op))),
2864 Expression::Gt(op) => Expression::Gt(Box::new(unqualify_binary_op(*op))),
2865 Expression::Gte(op) => Expression::Gte(Box::new(unqualify_binary_op(*op))),
2866 Expression::Add(op) => Expression::Add(Box::new(unqualify_binary_op(*op))),
2867 Expression::Sub(op) => Expression::Sub(Box::new(unqualify_binary_op(*op))),
2868 Expression::Mul(op) => Expression::Mul(Box::new(unqualify_binary_op(*op))),
2869 Expression::Div(op) => Expression::Div(Box::new(unqualify_binary_op(*op))),
2870 Expression::Function(mut func) => {
2872 func.args = func
2873 .args
2874 .into_iter()
2875 .map(unqualify_columns_recursive)
2876 .collect();
2877 Expression::Function(func)
2878 }
2879 Expression::AggregateFunction(mut func) => {
2880 func.args = func
2881 .args
2882 .into_iter()
2883 .map(unqualify_columns_recursive)
2884 .collect();
2885 Expression::AggregateFunction(func)
2886 }
2887 Expression::Case(mut case) => {
2888 case.whens = case
2889 .whens
2890 .into_iter()
2891 .map(|(cond, result)| {
2892 (
2893 unqualify_columns_recursive(cond),
2894 unqualify_columns_recursive(result),
2895 )
2896 })
2897 .collect();
2898 if let Some(else_expr) = case.else_ {
2899 case.else_ = Some(unqualify_columns_recursive(else_expr));
2900 }
2901 Expression::Case(case)
2902 }
2903 other => other,
2905 }
2906}
2907
2908fn unqualify_binary_op(mut op: BinaryOp) -> BinaryOp {
2910 op.left = unqualify_columns_recursive(op.left);
2911 op.right = unqualify_columns_recursive(op.right);
2912 op
2913}
2914
2915pub fn unnest_generate_date_array_using_recursive_cte(expr: Expression) -> Result<Expression> {
2935 match expr {
2936 Expression::Select(mut select) => {
2937 let mut cte_count = 0;
2938 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
2939
2940 if let Some(ref mut with) = select.with {
2942 for cte in &mut with.ctes {
2943 process_expression_for_gda(&mut cte.this, &mut cte_count, &mut new_ctes);
2944 }
2945 }
2946
2947 if let Some(ref mut from) = select.from {
2949 for table_expr in &mut from.expressions {
2950 if let Some((cte, replacement)) =
2951 try_convert_generate_date_array(table_expr, &mut cte_count)
2952 {
2953 new_ctes.push(cte);
2954 *table_expr = replacement;
2955 }
2956 }
2957 }
2958
2959 for join in &mut select.joins {
2961 if let Some((cte, replacement)) =
2962 try_convert_generate_date_array(&join.this, &mut cte_count)
2963 {
2964 new_ctes.push(cte);
2965 join.this = replacement;
2966 }
2967 }
2968
2969 if !new_ctes.is_empty() {
2971 let with_clause = select.with.get_or_insert_with(|| crate::expressions::With {
2972 ctes: Vec::new(),
2973 recursive: true, leading_comments: vec![],
2975 search: None,
2976 });
2977 with_clause.recursive = true;
2978
2979 let mut all_ctes = new_ctes;
2981 all_ctes.append(&mut with_clause.ctes);
2982 with_clause.ctes = all_ctes;
2983 }
2984
2985 Ok(Expression::Select(select))
2986 }
2987 other => Ok(other),
2988 }
2989}
2990
2991fn process_expression_for_gda(
2994 expr: &mut Expression,
2995 cte_count: &mut usize,
2996 new_ctes: &mut Vec<crate::expressions::Cte>,
2997) {
2998 match expr {
2999 Expression::Select(ref mut select) => {
3000 if let Some(ref mut from) = select.from {
3002 for table_expr in &mut from.expressions {
3003 if let Some((cte, replacement)) =
3004 try_convert_generate_date_array(table_expr, cte_count)
3005 {
3006 new_ctes.push(cte);
3007 *table_expr = replacement;
3008 }
3009 }
3010 }
3011 for join in &mut select.joins {
3013 if let Some((cte, replacement)) =
3014 try_convert_generate_date_array(&join.this, cte_count)
3015 {
3016 new_ctes.push(cte);
3017 join.this = replacement;
3018 }
3019 }
3020 }
3021 Expression::Union(ref mut u) => {
3022 process_expression_for_gda(&mut u.left, cte_count, new_ctes);
3023 process_expression_for_gda(&mut u.right, cte_count, new_ctes);
3024 }
3025 Expression::Subquery(ref mut sq) => {
3026 process_expression_for_gda(&mut sq.this, cte_count, new_ctes);
3027 }
3028 _ => {}
3029 }
3030}
3031
3032fn try_convert_generate_date_array(
3035 expr: &Expression,
3036 cte_count: &mut usize,
3037) -> Option<(crate::expressions::Cte, Expression)> {
3038 try_convert_generate_date_array_with_name(expr, cte_count, None)
3039}
3040
3041fn try_convert_generate_date_array_with_name(
3042 expr: &Expression,
3043 cte_count: &mut usize,
3044 column_name_override: Option<&str>,
3045) -> Option<(crate::expressions::Cte, Expression)> {
3046 fn extract_gda_args(
3048 inner: &Expression,
3049 ) -> Option<(&Expression, &Expression, Option<&Expression>)> {
3050 match inner {
3051 Expression::GenerateDateArray(gda) => {
3052 let start = gda.start.as_ref()?;
3053 let end = gda.end.as_ref()?;
3054 let step = gda.step.as_deref();
3055 Some((start, end, step))
3056 }
3057 Expression::GenerateSeries(gs) => {
3058 let start = gs.start.as_deref()?;
3059 let end = gs.end.as_deref()?;
3060 let step = gs.step.as_deref();
3061 Some((start, end, step))
3062 }
3063 Expression::Function(f) if f.name.eq_ignore_ascii_case("GENERATE_DATE_ARRAY") => {
3064 if f.args.len() >= 2 {
3065 let start = &f.args[0];
3066 let end = &f.args[1];
3067 let step = f.args.get(2);
3068 Some((start, end, step))
3069 } else {
3070 None
3071 }
3072 }
3073 _ => None,
3074 }
3075 }
3076
3077 if let Expression::Unnest(unnest) = expr {
3079 if let Some((start, end, step_opt)) = extract_gda_args(&unnest.this) {
3080 let start = start;
3081 let end = end;
3082 let step: Option<&Expression> = step_opt;
3083
3084 let cte_name = if *cte_count == 0 {
3086 "_generated_dates".to_string()
3087 } else {
3088 format!("_generated_dates_{}", cte_count)
3089 };
3090 *cte_count += 1;
3091
3092 let column_name =
3093 Identifier::new(column_name_override.unwrap_or("date_value").to_string());
3094
3095 let cast_to_date = |expr: &Expression| -> Expression {
3097 match expr {
3098 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
3099 if let Expression::Literal(lit) = expr {
3101 if let Literal::Date(d) = lit.as_ref() {
3102 Expression::Cast(Box::new(Cast {
3103 this: Expression::Literal(Box::new(Literal::String(d.clone()))),
3104 to: DataType::Date,
3105 trailing_comments: vec![],
3106 double_colon_syntax: false,
3107 format: None,
3108 default: None,
3109 inferred_type: None,
3110 }))
3111 } else {
3112 expr.clone()
3113 }
3114 } else {
3115 unreachable!()
3116 }
3117 }
3118 Expression::Cast(c) if matches!(c.to, DataType::Date) => expr.clone(),
3119 _ => Expression::Cast(Box::new(Cast {
3120 this: expr.clone(),
3121 to: DataType::Date,
3122 trailing_comments: vec![],
3123 double_colon_syntax: false,
3124 format: None,
3125 default: None,
3126 inferred_type: None,
3127 })),
3128 }
3129 };
3130
3131 let base_select = Select {
3133 expressions: vec![Expression::Alias(Box::new(crate::expressions::Alias {
3134 this: cast_to_date(start),
3135 alias: column_name.clone(),
3136 column_aliases: vec![],
3137 alias_explicit_as: false,
3138 alias_keyword: None,
3139 pre_alias_comments: vec![],
3140 trailing_comments: vec![],
3141 inferred_type: None,
3142 }))],
3143 ..Select::new()
3144 };
3145
3146 let normalize_interval = |expr: &Expression| -> Expression {
3148 if let Expression::Interval(ref iv) = expr {
3149 let mut iv_clone = iv.as_ref().clone();
3150 if let Some(Expression::Literal(ref lit)) = iv_clone.this {
3151 if let Literal::String(ref s) = lit.as_ref() {
3152 if s.parse::<f64>().is_ok() {
3154 iv_clone.this =
3155 Some(Expression::Literal(Box::new(Literal::Number(s.clone()))));
3156 }
3157 }
3158 }
3159 Expression::Interval(Box::new(iv_clone))
3160 } else {
3161 expr.clone()
3162 }
3163 };
3164
3165 let normalized_step = step.map(|s| normalize_interval(s)).unwrap_or_else(|| {
3168 Expression::Interval(Box::new(crate::expressions::Interval {
3169 this: Some(Expression::Literal(Box::new(Literal::Number(
3170 "1".to_string(),
3171 )))),
3172 unit: Some(crate::expressions::IntervalUnitSpec::Simple {
3173 unit: crate::expressions::IntervalUnit::Day,
3174 use_plural: false,
3175 }),
3176 }))
3177 });
3178
3179 let (add_unit, add_count) = extract_interval_unit_and_count(&normalized_step);
3181
3182 let date_add_expr = Expression::DateAdd(Box::new(crate::expressions::DateAddFunc {
3183 this: Expression::Column(Box::new(crate::expressions::Column {
3184 name: column_name.clone(),
3185 table: None,
3186 join_mark: false,
3187 trailing_comments: vec![],
3188 span: None,
3189 inferred_type: None,
3190 })),
3191 interval: add_count,
3192 unit: add_unit,
3193 }));
3194
3195 let cast_date_add = Expression::Cast(Box::new(Cast {
3196 this: date_add_expr.clone(),
3197 to: DataType::Date,
3198 trailing_comments: vec![],
3199 double_colon_syntax: false,
3200 format: None,
3201 default: None,
3202 inferred_type: None,
3203 }));
3204
3205 let recursive_select = Select {
3206 expressions: vec![cast_date_add.clone()],
3207 from: Some(From {
3208 expressions: vec![Expression::Table(Box::new(
3209 crate::expressions::TableRef::new(&cte_name),
3210 ))],
3211 }),
3212 where_clause: Some(Where {
3213 this: Expression::Lte(Box::new(BinaryOp {
3214 left: cast_date_add,
3215 right: cast_to_date(end),
3216 left_comments: vec![],
3217 operator_comments: vec![],
3218 trailing_comments: vec![],
3219 inferred_type: None,
3220 })),
3221 }),
3222 ..Select::new()
3223 };
3224
3225 let union = crate::expressions::Union {
3227 left: Expression::Select(Box::new(base_select)),
3228 right: Expression::Select(Box::new(recursive_select)),
3229 all: true, distinct: false,
3231 with: None,
3232 order_by: None,
3233 limit: None,
3234 offset: None,
3235 distribute_by: None,
3236 sort_by: None,
3237 cluster_by: None,
3238 by_name: false,
3239 side: None,
3240 kind: None,
3241 corresponding: false,
3242 strict: false,
3243 on_columns: Vec::new(),
3244 };
3245
3246 let cte = crate::expressions::Cte {
3248 this: Expression::Union(Box::new(union)),
3249 alias: Identifier::new(cte_name.clone()),
3250 columns: vec![column_name.clone()],
3251 materialized: None,
3252 key_expressions: Vec::new(),
3253 alias_first: true,
3254 comments: Vec::new(),
3255 };
3256
3257 let replacement_select = Select {
3259 expressions: vec![Expression::Column(Box::new(crate::expressions::Column {
3260 name: column_name,
3261 table: None,
3262 join_mark: false,
3263 trailing_comments: vec![],
3264 span: None,
3265 inferred_type: None,
3266 }))],
3267 from: Some(From {
3268 expressions: vec![Expression::Table(Box::new(
3269 crate::expressions::TableRef::new(&cte_name),
3270 ))],
3271 }),
3272 ..Select::new()
3273 };
3274
3275 let replacement = Expression::Subquery(Box::new(Subquery {
3276 this: Expression::Select(Box::new(replacement_select)),
3277 alias: Some(Identifier::new(cte_name)),
3278 column_aliases: vec![],
3279 alias_explicit_as: false,
3280 alias_keyword: None,
3281 order_by: None,
3282 limit: None,
3283 offset: None,
3284 distribute_by: None,
3285 sort_by: None,
3286 cluster_by: None,
3287 lateral: false,
3288 modifiers_inside: false,
3289 trailing_comments: vec![],
3290 inferred_type: None,
3291 }));
3292
3293 return Some((cte, replacement));
3294 }
3295 }
3296
3297 if let Expression::Alias(alias) = expr {
3299 let col_name = alias.column_aliases.first().map(|id| id.name.as_str());
3301 if let Some((cte, replacement)) =
3302 try_convert_generate_date_array_with_name(&alias.this, cte_count, col_name)
3303 {
3304 if col_name.is_some() {
3307 return Some((cte, replacement));
3308 }
3309 let new_alias = Expression::Alias(Box::new(crate::expressions::Alias {
3310 this: replacement,
3311 alias: alias.alias.clone(),
3312 column_aliases: alias.column_aliases.clone(),
3313 alias_explicit_as: false,
3314 alias_keyword: None,
3315 pre_alias_comments: alias.pre_alias_comments.clone(),
3316 trailing_comments: alias.trailing_comments.clone(),
3317 inferred_type: None,
3318 }));
3319 return Some((cte, new_alias));
3320 }
3321 }
3322
3323 None
3324}
3325
3326fn extract_interval_unit_and_count(
3331 expr: &Expression,
3332) -> (crate::expressions::IntervalUnit, Expression) {
3333 use crate::expressions::{IntervalUnit, IntervalUnitSpec, Literal};
3334
3335 if let Expression::Interval(ref iv) = expr {
3336 if let Some(ref unit_spec) = iv.unit {
3338 if let IntervalUnitSpec::Simple { unit, .. } = unit_spec {
3339 let count = match &iv.this {
3340 Some(e) => e.clone(),
3341 None => Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3342 };
3343 return (unit.clone(), count);
3344 }
3345 }
3346
3347 if let Some(ref val_expr) = iv.this {
3349 match val_expr {
3350 Expression::Literal(lit)
3351 if matches!(lit.as_ref(), Literal::String(_) | Literal::Number(_)) =>
3352 {
3353 let s = match lit.as_ref() {
3354 Literal::String(s) | Literal::Number(s) => s,
3355 _ => unreachable!(),
3356 };
3357 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
3359 if parts.len() == 2 {
3360 let count_str = parts[0].trim();
3361 let unit_str = parts[1].trim().to_uppercase();
3362 let unit = match unit_str.as_str() {
3363 "YEAR" | "YEARS" => IntervalUnit::Year,
3364 "QUARTER" | "QUARTERS" => IntervalUnit::Quarter,
3365 "MONTH" | "MONTHS" => IntervalUnit::Month,
3366 "WEEK" | "WEEKS" => IntervalUnit::Week,
3367 "DAY" | "DAYS" => IntervalUnit::Day,
3368 "HOUR" | "HOURS" => IntervalUnit::Hour,
3369 "MINUTE" | "MINUTES" => IntervalUnit::Minute,
3370 "SECOND" | "SECONDS" => IntervalUnit::Second,
3371 "MILLISECOND" | "MILLISECONDS" => IntervalUnit::Millisecond,
3372 "MICROSECOND" | "MICROSECONDS" => IntervalUnit::Microsecond,
3373 _ => IntervalUnit::Day,
3374 };
3375 return (
3376 unit,
3377 Expression::Literal(Box::new(Literal::Number(count_str.to_string()))),
3378 );
3379 }
3380 if s.parse::<f64>().is_ok() {
3382 return (
3383 IntervalUnit::Day,
3384 Expression::Literal(Box::new(Literal::Number(s.clone()))),
3385 );
3386 }
3387 }
3388 _ => {}
3389 }
3390 }
3391
3392 (
3394 IntervalUnit::Day,
3395 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3396 )
3397 } else {
3398 (
3399 IntervalUnit::Day,
3400 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3401 )
3402 }
3403}
3404
3405pub fn no_ilike_sql(expr: Expression) -> Result<Expression> {
3418 match expr {
3419 Expression::ILike(ilike) => {
3420 let lower_left = Expression::Function(Box::new(crate::expressions::Function {
3422 name: "LOWER".to_string(),
3423 args: vec![ilike.left],
3424 distinct: false,
3425 trailing_comments: vec![],
3426 use_bracket_syntax: false,
3427 no_parens: false,
3428 quoted: false,
3429 span: None,
3430 inferred_type: None,
3431 }));
3432
3433 let lower_right = Expression::Function(Box::new(crate::expressions::Function {
3434 name: "LOWER".to_string(),
3435 args: vec![ilike.right],
3436 distinct: false,
3437 trailing_comments: vec![],
3438 use_bracket_syntax: false,
3439 no_parens: false,
3440 quoted: false,
3441 span: None,
3442 inferred_type: None,
3443 }));
3444
3445 Ok(Expression::Like(Box::new(crate::expressions::LikeOp {
3446 left: lower_left,
3447 right: lower_right,
3448 escape: ilike.escape,
3449 quantifier: ilike.quantifier,
3450 inferred_type: None,
3451 })))
3452 }
3453 other => Ok(other),
3454 }
3455}
3456
3457pub fn no_trycast_sql(expr: Expression) -> Result<Expression> {
3465 match expr {
3466 Expression::TryCast(try_cast) => Ok(Expression::Cast(try_cast)),
3467 other => Ok(other),
3468 }
3469}
3470
3471pub fn no_safe_cast_sql(expr: Expression) -> Result<Expression> {
3476 match expr {
3477 Expression::SafeCast(safe_cast) => Ok(Expression::Cast(safe_cast)),
3478 other => Ok(other),
3479 }
3480}
3481
3482pub fn no_comment_column_constraint(expr: Expression) -> Result<Expression> {
3489 Ok(expr)
3491}
3492
3493pub fn unnest_generate_series(expr: Expression) -> Result<Expression> {
3507 match expr {
3510 Expression::Table(ref table) => {
3511 if table.name.name.to_uppercase() == "GENERATE_SERIES" {
3514 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3516 this: expr.clone(),
3517 expressions: Vec::new(),
3518 with_ordinality: false,
3519 alias: None,
3520 offset_alias: None,
3521 }));
3522
3523 return Ok(Expression::Alias(Box::new(crate::expressions::Alias {
3525 this: unnest,
3526 alias: Identifier::new("_u".to_string()),
3527 column_aliases: vec![],
3528 alias_explicit_as: false,
3529 alias_keyword: None,
3530 pre_alias_comments: vec![],
3531 trailing_comments: vec![],
3532 inferred_type: None,
3533 })));
3534 }
3535 Ok(expr)
3536 }
3537 Expression::GenerateSeries(gs) => {
3538 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3540 this: Expression::GenerateSeries(gs),
3541 expressions: Vec::new(),
3542 with_ordinality: false,
3543 alias: None,
3544 offset_alias: None,
3545 }));
3546 Ok(unnest)
3547 }
3548 other => Ok(other),
3549 }
3550}
3551
3552pub fn unwrap_unnest_generate_series_for_postgres(expr: Expression) -> Result<Expression> {
3563 use crate::dialects::transform_recursive;
3564 transform_recursive(expr, &unwrap_unnest_generate_series_single)
3565}
3566
3567fn unwrap_unnest_generate_series_single(expr: Expression) -> Result<Expression> {
3568 use crate::expressions::*;
3569 match expr {
3571 Expression::Select(mut select) => {
3572 if let Some(ref mut from) = select.from {
3574 for table_expr in &mut from.expressions {
3575 if let Some(replacement) = try_unwrap_unnest_gen_series(table_expr) {
3576 *table_expr = replacement;
3577 }
3578 }
3579 }
3580 for join in &mut select.joins {
3582 if let Some(replacement) = try_unwrap_unnest_gen_series(&join.this) {
3583 join.this = replacement;
3584 }
3585 }
3586 Ok(Expression::Select(select))
3587 }
3588 other => Ok(other),
3589 }
3590}
3591
3592fn try_unwrap_unnest_gen_series(expr: &Expression) -> Option<Expression> {
3595 use crate::expressions::*;
3596
3597 let gen_series = match expr {
3599 Expression::Unnest(unnest) => {
3600 if let Expression::GenerateSeries(ref gs) = unnest.this {
3601 Some(gs.as_ref().clone())
3602 } else {
3603 None
3604 }
3605 }
3606 Expression::Alias(alias) => {
3607 if let Expression::Unnest(ref unnest) = alias.this {
3608 if let Expression::GenerateSeries(ref gs) = unnest.this {
3609 Some(gs.as_ref().clone())
3610 } else {
3611 None
3612 }
3613 } else {
3614 None
3615 }
3616 }
3617 _ => None,
3618 };
3619
3620 let gs = gen_series?;
3621
3622 let value_col = Expression::boxed_column(Column {
3624 name: Identifier::new("value".to_string()),
3625 table: None,
3626 join_mark: false,
3627 trailing_comments: vec![],
3628 span: None,
3629 inferred_type: None,
3630 });
3631
3632 let cast_value = Expression::Cast(Box::new(Cast {
3633 this: value_col,
3634 to: DataType::Date,
3635 trailing_comments: vec![],
3636 double_colon_syntax: false,
3637 format: None,
3638 default: None,
3639 inferred_type: None,
3640 }));
3641
3642 let gen_series_expr = Expression::GenerateSeries(Box::new(gs));
3643
3644 let gen_series_aliased = Expression::Alias(Box::new(Alias {
3646 this: gen_series_expr,
3647 alias: Identifier::new("_t".to_string()),
3648 column_aliases: vec![Identifier::new("value".to_string())],
3649 alias_explicit_as: false,
3650 alias_keyword: None,
3651 pre_alias_comments: vec![],
3652 trailing_comments: vec![],
3653 inferred_type: None,
3654 }));
3655
3656 let mut inner_select = Select::new();
3657 inner_select.expressions = vec![cast_value];
3658 inner_select.from = Some(From {
3659 expressions: vec![gen_series_aliased],
3660 });
3661
3662 let inner_select_expr = Expression::Select(Box::new(inner_select));
3663
3664 let subquery = Expression::Subquery(Box::new(Subquery {
3665 this: inner_select_expr,
3666 alias: None,
3667 column_aliases: vec![],
3668 alias_explicit_as: false,
3669 alias_keyword: None,
3670 order_by: None,
3671 limit: None,
3672 offset: None,
3673 distribute_by: None,
3674 sort_by: None,
3675 cluster_by: None,
3676 lateral: false,
3677 modifiers_inside: false,
3678 trailing_comments: vec![],
3679 inferred_type: None,
3680 }));
3681
3682 Some(Expression::Alias(Box::new(Alias {
3684 this: subquery,
3685 alias: Identifier::new("_unnested_generate_series".to_string()),
3686 column_aliases: vec![],
3687 alias_explicit_as: false,
3688 alias_keyword: None,
3689 pre_alias_comments: vec![],
3690 trailing_comments: vec![],
3691 inferred_type: None,
3692 })))
3693}
3694
3695pub fn expand_between_in_delete(expr: Expression) -> Result<Expression> {
3703 match expr {
3704 Expression::Delete(mut delete) => {
3705 if let Some(ref mut where_clause) = delete.where_clause {
3707 where_clause.this = expand_between_recursive(where_clause.this.clone());
3708 }
3709 Ok(Expression::Delete(delete))
3710 }
3711 other => Ok(other),
3712 }
3713}
3714
3715fn expand_between_recursive(expr: Expression) -> Expression {
3717 match expr {
3718 Expression::Between(between) => {
3721 let this = expand_between_recursive(between.this.clone());
3722 let low = expand_between_recursive(between.low);
3723 let high = expand_between_recursive(between.high);
3724
3725 if between.not {
3726 Expression::Or(Box::new(BinaryOp::new(
3728 Expression::Lt(Box::new(BinaryOp::new(this.clone(), low))),
3729 Expression::Gt(Box::new(BinaryOp::new(this, high))),
3730 )))
3731 } else {
3732 Expression::And(Box::new(BinaryOp::new(
3734 Expression::Gte(Box::new(BinaryOp::new(this.clone(), low))),
3735 Expression::Lte(Box::new(BinaryOp::new(this, high))),
3736 )))
3737 }
3738 }
3739
3740 Expression::And(mut op) => {
3742 op.left = expand_between_recursive(op.left);
3743 op.right = expand_between_recursive(op.right);
3744 Expression::And(op)
3745 }
3746 Expression::Or(mut op) => {
3747 op.left = expand_between_recursive(op.left);
3748 op.right = expand_between_recursive(op.right);
3749 Expression::Or(op)
3750 }
3751 Expression::Not(mut op) => {
3752 op.this = expand_between_recursive(op.this);
3753 Expression::Not(op)
3754 }
3755
3756 Expression::Paren(mut paren) => {
3758 paren.this = expand_between_recursive(paren.this);
3759 Expression::Paren(paren)
3760 }
3761
3762 other => other,
3764 }
3765}
3766
3767pub fn pushdown_cte_column_names(expr: Expression) -> Result<Expression> {
3776 match expr {
3777 Expression::Select(mut select) => {
3778 if let Some(ref mut with) = select.with {
3779 for cte in &mut with.ctes {
3780 if !cte.columns.is_empty() {
3781 let is_star = matches!(&cte.this, Expression::Select(s) if
3783 s.expressions.len() == 1 && matches!(&s.expressions[0], Expression::Star(_)));
3784
3785 if is_star {
3786 cte.columns.clear();
3788 continue;
3789 }
3790
3791 let column_names: Vec<Identifier> = cte.columns.drain(..).collect();
3793
3794 if let Expression::Select(ref mut inner_select) = cte.this {
3796 let new_exprs: Vec<Expression> = inner_select
3797 .expressions
3798 .drain(..)
3799 .zip(
3800 column_names
3801 .into_iter()
3802 .chain(std::iter::repeat_with(|| Identifier::new(""))),
3803 )
3804 .map(|(expr, col_name)| {
3805 if col_name.name.is_empty() {
3806 return expr;
3807 }
3808 match expr {
3810 Expression::Alias(mut a) => {
3811 a.alias = col_name;
3812 Expression::Alias(a)
3813 }
3814 other => {
3815 Expression::Alias(Box::new(crate::expressions::Alias {
3816 this: other,
3817 alias: col_name,
3818 column_aliases: Vec::new(),
3819 alias_explicit_as: false,
3820 alias_keyword: None,
3821 pre_alias_comments: Vec::new(),
3822 trailing_comments: Vec::new(),
3823 inferred_type: None,
3824 }))
3825 }
3826 }
3827 })
3828 .collect();
3829 inner_select.expressions = new_exprs;
3830 }
3831 }
3832 }
3833 }
3834 Ok(Expression::Select(select))
3835 }
3836 other => Ok(other),
3837 }
3838}
3839
3840pub fn simplify_nested_paren_values(expr: Expression) -> Result<Expression> {
3844 match expr {
3845 Expression::Select(mut select) => {
3846 if let Some(ref mut from) = select.from {
3847 for from_item in from.expressions.iter_mut() {
3848 simplify_paren_values_in_from(from_item);
3849 }
3850 }
3851 Ok(Expression::Select(select))
3852 }
3853 other => Ok(other),
3854 }
3855}
3856
3857fn simplify_paren_values_in_from(expr: &mut Expression) {
3858 let replacement = match expr {
3860 Expression::Subquery(ref subquery) => {
3862 if let Expression::Paren(ref paren) = subquery.this {
3863 if matches!(&paren.this, Expression::Values(_)) {
3864 let mut new_sub = subquery.as_ref().clone();
3865 new_sub.this = paren.this.clone();
3866 Some(Expression::Subquery(Box::new(new_sub)))
3867 } else {
3868 None
3869 }
3870 } else {
3871 None
3872 }
3873 }
3874 Expression::Paren(ref outer_paren) => {
3877 if let Expression::Subquery(ref subquery) = outer_paren.this {
3878 if matches!(&subquery.this, Expression::Values(_)) {
3880 Some(outer_paren.this.clone())
3881 }
3882 else if let Expression::Paren(ref paren) = subquery.this {
3884 if matches!(&paren.this, Expression::Values(_)) {
3885 let mut new_sub = subquery.as_ref().clone();
3886 new_sub.this = paren.this.clone();
3887 Some(Expression::Subquery(Box::new(new_sub)))
3888 } else {
3889 None
3890 }
3891 } else {
3892 None
3893 }
3894 } else if let Expression::Paren(ref inner_paren) = outer_paren.this {
3895 if matches!(&inner_paren.this, Expression::Values(_)) {
3896 Some(outer_paren.this.clone())
3897 } else {
3898 None
3899 }
3900 } else {
3901 None
3902 }
3903 }
3904 _ => None,
3905 };
3906 if let Some(new_expr) = replacement {
3907 *expr = new_expr;
3908 }
3909}
3910
3911pub fn add_auto_table_alias(expr: Expression) -> Result<Expression> {
3915 match expr {
3916 Expression::Select(mut select) => {
3917 if let Some(ref mut from) = select.from {
3919 let mut counter = 0usize;
3920 for from_item in from.expressions.iter_mut() {
3921 add_auto_alias_to_from_item(from_item, &mut counter);
3922 }
3923 }
3924 Ok(Expression::Select(select))
3925 }
3926 other => Ok(other),
3927 }
3928}
3929
3930fn add_auto_alias_to_from_item(expr: &mut Expression, counter: &mut usize) {
3931 use crate::expressions::Identifier;
3932
3933 match expr {
3934 Expression::Alias(ref mut alias) => {
3935 if alias.alias.name.is_empty() && !alias.column_aliases.is_empty() {
3937 alias.alias = Identifier::new(format!("_t{}", counter));
3938 *counter += 1;
3939 }
3940 }
3941 _ => {}
3942 }
3943}
3944
3945pub fn propagate_struct_field_names(expr: Expression) -> Result<Expression> {
3955 use crate::dialects::transform_recursive;
3956 transform_recursive(expr, &propagate_struct_names_in_expr)
3957}
3958
3959fn propagate_struct_names_in_expr(expr: Expression) -> Result<Expression> {
3960 use crate::expressions::{Alias, ArrayConstructor, Function, Identifier};
3961
3962 fn propagate_in_elements(elements: &[Expression]) -> Option<Vec<Expression>> {
3964 if elements.len() <= 1 {
3965 return None;
3966 }
3967 if let Some(Expression::Function(ref first_struct)) = elements.first() {
3969 if first_struct.name.eq_ignore_ascii_case("STRUCT") {
3970 let field_names: Vec<Option<String>> = first_struct
3972 .args
3973 .iter()
3974 .map(|arg| {
3975 if let Expression::Alias(a) = arg {
3976 Some(a.alias.name.clone())
3977 } else {
3978 None
3979 }
3980 })
3981 .collect();
3982
3983 if field_names.iter().any(|n| n.is_some()) {
3985 let mut new_elements = Vec::with_capacity(elements.len());
3986 new_elements.push(elements[0].clone());
3987
3988 for elem in &elements[1..] {
3989 if let Expression::Function(ref s) = elem {
3990 if s.name.eq_ignore_ascii_case("STRUCT")
3991 && s.args.len() == field_names.len()
3992 {
3993 let all_unnamed =
3995 s.args.iter().all(|a| !matches!(a, Expression::Alias(_)));
3996 if all_unnamed {
3997 let new_args: Vec<Expression> = s
3999 .args
4000 .iter()
4001 .zip(field_names.iter())
4002 .map(|(val, name)| {
4003 if let Some(n) = name {
4004 Expression::Alias(Box::new(Alias::new(
4005 val.clone(),
4006 Identifier::new(n.clone()),
4007 )))
4008 } else {
4009 val.clone()
4010 }
4011 })
4012 .collect();
4013 new_elements.push(Expression::Function(Box::new(
4014 Function::new("STRUCT".to_string(), new_args),
4015 )));
4016 continue;
4017 }
4018 }
4019 }
4020 new_elements.push(elem.clone());
4021 }
4022
4023 return Some(new_elements);
4024 }
4025 }
4026 }
4027 None
4028 }
4029
4030 if let Expression::Array(ref arr) = expr {
4032 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
4033 return Ok(Expression::Array(Box::new(crate::expressions::Array {
4034 expressions: new_elements,
4035 })));
4036 }
4037 }
4038
4039 if let Expression::ArrayFunc(ref arr) = expr {
4041 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
4042 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
4043 expressions: new_elements,
4044 bracket_notation: arr.bracket_notation,
4045 use_list_keyword: arr.use_list_keyword,
4046 })));
4047 }
4048 }
4049
4050 Ok(expr)
4051}
4052
4053pub fn unnest_alias_to_column_alias(expr: Expression) -> Result<Expression> {
4056 use crate::dialects::transform_recursive;
4057 transform_recursive(expr, &unnest_alias_transform_single_select)
4058}
4059
4060pub fn unnest_from_to_cross_join(expr: Expression) -> Result<Expression> {
4063 use crate::dialects::transform_recursive;
4064 transform_recursive(expr, &unnest_from_to_cross_join_single_select)
4065}
4066
4067fn unnest_from_to_cross_join_single_select(expr: Expression) -> Result<Expression> {
4068 if let Expression::Select(mut select) = expr {
4069 if let Some(ref mut from) = select.from {
4070 if from.expressions.len() > 1 {
4071 let mut new_from_exprs = Vec::new();
4072 let mut new_cross_joins = Vec::new();
4073
4074 for (idx, from_item) in from.expressions.drain(..).enumerate() {
4075 if idx == 0 {
4076 new_from_exprs.push(from_item);
4077 } else {
4078 let is_unnest = match &from_item {
4079 Expression::Unnest(_) => true,
4080 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
4081 _ => false,
4082 };
4083
4084 if is_unnest {
4085 new_cross_joins.push(crate::expressions::Join {
4086 this: from_item,
4087 on: None,
4088 using: Vec::new(),
4089 kind: JoinKind::Cross,
4090 use_inner_keyword: false,
4091 use_outer_keyword: false,
4092 deferred_condition: false,
4093 join_hint: None,
4094 match_condition: None,
4095 pivots: Vec::new(),
4096 comments: Vec::new(),
4097 nesting_group: 0,
4098 directed: false,
4099 });
4100 } else {
4101 new_from_exprs.push(from_item);
4102 }
4103 }
4104 }
4105
4106 from.expressions = new_from_exprs;
4107 new_cross_joins.append(&mut select.joins);
4108 select.joins = new_cross_joins;
4109 }
4110 }
4111
4112 Ok(Expression::Select(select))
4113 } else {
4114 Ok(expr)
4115 }
4116}
4117
4118pub fn wrap_unnest_join_aliases(expr: Expression) -> Result<Expression> {
4122 use crate::dialects::transform_recursive;
4123 transform_recursive(expr, &wrap_unnest_join_aliases_single)
4124}
4125
4126fn wrap_unnest_join_aliases_single(expr: Expression) -> Result<Expression> {
4127 if let Expression::Select(mut select) = expr {
4128 for join in &mut select.joins {
4130 wrap_unnest_alias_in_join_item(&mut join.this);
4131 }
4132 Ok(Expression::Select(select))
4133 } else {
4134 Ok(expr)
4135 }
4136}
4137
4138fn wrap_unnest_alias_in_join_item(expr: &mut Expression) {
4140 use crate::expressions::Identifier;
4141 if let Expression::Alias(alias) = expr {
4142 let is_unnest = match &alias.this {
4144 Expression::Function(f) => f.name.eq_ignore_ascii_case("UNNEST"),
4145 _ => false,
4146 };
4147
4148 if is_unnest && alias.column_aliases.is_empty() {
4149 let original_alias_name = alias.alias.name.clone();
4151 alias.alias = Identifier {
4152 name: "_u".to_string(),
4153 quoted: false,
4154 trailing_comments: Vec::new(),
4155 span: None,
4156 };
4157 alias.column_aliases = vec![Identifier {
4158 name: original_alias_name,
4159 quoted: false,
4160 trailing_comments: Vec::new(),
4161 span: None,
4162 }];
4163 }
4164 }
4165}
4166
4167fn unnest_alias_transform_single_select(expr: Expression) -> Result<Expression> {
4168 if let Expression::Select(mut select) = expr {
4169 let mut counter = 0usize;
4170
4171 if let Some(ref mut from) = select.from {
4173 for from_item in from.expressions.iter_mut() {
4175 convert_unnest_alias_in_from(from_item, &mut counter);
4176 }
4177
4178 if from.expressions.len() > 1 {
4180 let mut new_from_exprs = Vec::new();
4181 let mut new_cross_joins = Vec::new();
4182
4183 for (idx, from_item) in from.expressions.drain(..).enumerate() {
4184 if idx == 0 {
4185 new_from_exprs.push(from_item);
4187 } else {
4188 let is_unnest = match &from_item {
4190 Expression::Unnest(_) => true,
4191 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
4192 _ => false,
4193 };
4194
4195 if is_unnest {
4196 new_cross_joins.push(crate::expressions::Join {
4198 this: from_item,
4199 on: None,
4200 using: Vec::new(),
4201 kind: JoinKind::Cross,
4202 use_inner_keyword: false,
4203 use_outer_keyword: false,
4204 deferred_condition: false,
4205 join_hint: None,
4206 match_condition: None,
4207 pivots: Vec::new(),
4208 comments: Vec::new(),
4209 nesting_group: 0,
4210 directed: false,
4211 });
4212 } else {
4213 new_from_exprs.push(from_item);
4215 }
4216 }
4217 }
4218
4219 from.expressions = new_from_exprs;
4220 new_cross_joins.append(&mut select.joins);
4222 select.joins = new_cross_joins;
4223 }
4224 }
4225
4226 for join in select.joins.iter_mut() {
4228 convert_unnest_alias_in_from(&mut join.this, &mut counter);
4229 }
4230
4231 Ok(Expression::Select(select))
4232 } else {
4233 Ok(expr)
4234 }
4235}
4236
4237fn convert_unnest_alias_in_from(expr: &mut Expression, counter: &mut usize) {
4238 use crate::expressions::Identifier;
4239
4240 if let Expression::Alias(ref mut alias) = expr {
4241 let is_unnest = matches!(&alias.this, Expression::Unnest(_))
4243 || matches!(&alias.this, Expression::Function(f) if f.name.eq_ignore_ascii_case("EXPLODE"));
4244
4245 if is_unnest && alias.column_aliases.is_empty() {
4246 let col_alias = alias.alias.clone();
4248 alias.column_aliases = vec![col_alias];
4249 alias.alias = Identifier::new(format!("_t{}", counter));
4250 *counter += 1;
4251 }
4252 }
4253}
4254
4255pub fn expand_posexplode_duckdb(expr: Expression) -> Result<Expression> {
4262 use crate::expressions::{Alias, Function};
4263
4264 match expr {
4265 Expression::Select(mut select) => {
4266 let mut new_expressions = Vec::new();
4268 let mut changed = false;
4269
4270 for sel_expr in select.expressions.drain(..) {
4271 if let Expression::Alias(ref alias_box) = sel_expr {
4273 if let Expression::Function(ref func) = alias_box.this {
4274 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4275 let arg = func.args[0].clone();
4276 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
4278 (
4279 alias_box.column_aliases[0].name.clone(),
4280 alias_box.column_aliases[1].name.clone(),
4281 )
4282 } else if !alias_box.alias.is_empty() {
4283 ("pos".to_string(), alias_box.alias.name.clone())
4285 } else {
4286 ("pos".to_string(), "col".to_string())
4287 };
4288
4289 let gen_subscripts = Expression::Function(Box::new(Function::new(
4291 "GENERATE_SUBSCRIPTS".to_string(),
4292 vec![
4293 arg.clone(),
4294 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4295 ],
4296 )));
4297 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4298 gen_subscripts,
4299 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4300 )));
4301 let pos_alias = Expression::Alias(Box::new(Alias {
4302 this: sub_one,
4303 alias: Identifier::new(pos_name),
4304 column_aliases: Vec::new(),
4305 alias_explicit_as: false,
4306 alias_keyword: None,
4307 pre_alias_comments: Vec::new(),
4308 trailing_comments: Vec::new(),
4309 inferred_type: None,
4310 }));
4311
4312 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4314 this: arg,
4315 expressions: Vec::new(),
4316 with_ordinality: false,
4317 alias: None,
4318 offset_alias: None,
4319 }));
4320 let col_alias = Expression::Alias(Box::new(Alias {
4321 this: unnest,
4322 alias: Identifier::new(col_name),
4323 column_aliases: Vec::new(),
4324 alias_explicit_as: false,
4325 alias_keyword: None,
4326 pre_alias_comments: Vec::new(),
4327 trailing_comments: Vec::new(),
4328 inferred_type: None,
4329 }));
4330
4331 new_expressions.push(pos_alias);
4332 new_expressions.push(col_alias);
4333 changed = true;
4334 continue;
4335 }
4336 }
4337 }
4338
4339 if let Expression::Function(ref func) = sel_expr {
4341 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4342 let arg = func.args[0].clone();
4343 let pos_name = "pos";
4344 let col_name = "col";
4345
4346 let gen_subscripts = Expression::Function(Box::new(Function::new(
4348 "GENERATE_SUBSCRIPTS".to_string(),
4349 vec![
4350 arg.clone(),
4351 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4352 ],
4353 )));
4354 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4355 gen_subscripts,
4356 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4357 )));
4358 let pos_alias = Expression::Alias(Box::new(Alias {
4359 this: sub_one,
4360 alias: Identifier::new(pos_name),
4361 column_aliases: Vec::new(),
4362 alias_explicit_as: false,
4363 alias_keyword: None,
4364 pre_alias_comments: Vec::new(),
4365 trailing_comments: Vec::new(),
4366 inferred_type: None,
4367 }));
4368
4369 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4371 this: arg,
4372 expressions: Vec::new(),
4373 with_ordinality: false,
4374 alias: None,
4375 offset_alias: None,
4376 }));
4377 let col_alias = Expression::Alias(Box::new(Alias {
4378 this: unnest,
4379 alias: Identifier::new(col_name),
4380 column_aliases: Vec::new(),
4381 alias_explicit_as: false,
4382 alias_keyword: None,
4383 pre_alias_comments: Vec::new(),
4384 trailing_comments: Vec::new(),
4385 inferred_type: None,
4386 }));
4387
4388 new_expressions.push(pos_alias);
4389 new_expressions.push(col_alias);
4390 changed = true;
4391 continue;
4392 }
4393 }
4394
4395 new_expressions.push(sel_expr);
4397 }
4398
4399 if changed {
4400 select.expressions = new_expressions;
4401 } else {
4402 select.expressions = new_expressions;
4403 }
4404
4405 if let Some(ref mut from) = select.from {
4408 expand_posexplode_in_from_duckdb(from)?;
4409 }
4410
4411 Ok(Expression::Select(select))
4412 }
4413 other => Ok(other),
4414 }
4415}
4416
4417fn expand_posexplode_in_from_duckdb(from: &mut From) -> Result<()> {
4419 use crate::expressions::{Alias, Function};
4420
4421 let mut new_expressions = Vec::new();
4422 let mut _changed = false;
4423
4424 for table_expr in from.expressions.drain(..) {
4425 if let Expression::Alias(ref alias_box) = table_expr {
4427 if let Expression::Function(ref func) = alias_box.this {
4428 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4429 let arg = func.args[0].clone();
4430 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
4431 (
4432 alias_box.column_aliases[0].name.clone(),
4433 alias_box.column_aliases[1].name.clone(),
4434 )
4435 } else {
4436 ("pos".to_string(), "col".to_string())
4437 };
4438
4439 let gen_subscripts = Expression::Function(Box::new(Function::new(
4441 "GENERATE_SUBSCRIPTS".to_string(),
4442 vec![
4443 arg.clone(),
4444 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4445 ],
4446 )));
4447 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4448 gen_subscripts,
4449 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4450 )));
4451 let pos_alias = Expression::Alias(Box::new(Alias {
4452 this: sub_one,
4453 alias: Identifier::new(&pos_name),
4454 column_aliases: Vec::new(),
4455 alias_explicit_as: false,
4456 alias_keyword: None,
4457 pre_alias_comments: Vec::new(),
4458 trailing_comments: Vec::new(),
4459 inferred_type: None,
4460 }));
4461 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4462 this: arg,
4463 expressions: Vec::new(),
4464 with_ordinality: false,
4465 alias: None,
4466 offset_alias: None,
4467 }));
4468 let col_alias = Expression::Alias(Box::new(Alias {
4469 this: unnest,
4470 alias: Identifier::new(&col_name),
4471 column_aliases: Vec::new(),
4472 alias_explicit_as: false,
4473 alias_keyword: None,
4474 pre_alias_comments: Vec::new(),
4475 trailing_comments: Vec::new(),
4476 inferred_type: None,
4477 }));
4478
4479 let mut inner_select = Select::new();
4480 inner_select.expressions = vec![pos_alias, col_alias];
4481
4482 let subquery = Expression::Subquery(Box::new(Subquery {
4483 this: Expression::Select(Box::new(inner_select)),
4484 alias: None,
4485 column_aliases: Vec::new(),
4486 alias_explicit_as: false,
4487 alias_keyword: None,
4488 order_by: None,
4489 limit: None,
4490 offset: None,
4491 distribute_by: None,
4492 sort_by: None,
4493 cluster_by: None,
4494 lateral: false,
4495 modifiers_inside: false,
4496 trailing_comments: Vec::new(),
4497 inferred_type: None,
4498 }));
4499 new_expressions.push(subquery);
4500 _changed = true;
4501 continue;
4502 }
4503 }
4504 }
4505
4506 if let Expression::Function(ref func) = table_expr {
4508 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4509 let arg = func.args[0].clone();
4510
4511 let gen_subscripts = Expression::Function(Box::new(Function::new(
4513 "GENERATE_SUBSCRIPTS".to_string(),
4514 vec![
4515 arg.clone(),
4516 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4517 ],
4518 )));
4519 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4520 gen_subscripts,
4521 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4522 )));
4523 let pos_alias = Expression::Alias(Box::new(Alias {
4524 this: sub_one,
4525 alias: Identifier::new("pos"),
4526 column_aliases: Vec::new(),
4527 alias_explicit_as: false,
4528 alias_keyword: None,
4529 pre_alias_comments: Vec::new(),
4530 trailing_comments: Vec::new(),
4531 inferred_type: None,
4532 }));
4533 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4534 this: arg,
4535 expressions: Vec::new(),
4536 with_ordinality: false,
4537 alias: None,
4538 offset_alias: None,
4539 }));
4540 let col_alias = Expression::Alias(Box::new(Alias {
4541 this: unnest,
4542 alias: Identifier::new("col"),
4543 column_aliases: Vec::new(),
4544 alias_explicit_as: false,
4545 alias_keyword: None,
4546 pre_alias_comments: Vec::new(),
4547 trailing_comments: Vec::new(),
4548 inferred_type: None,
4549 }));
4550
4551 let mut inner_select = Select::new();
4552 inner_select.expressions = vec![pos_alias, col_alias];
4553
4554 let subquery = Expression::Subquery(Box::new(Subquery {
4555 this: Expression::Select(Box::new(inner_select)),
4556 alias: None,
4557 column_aliases: Vec::new(),
4558 alias_explicit_as: false,
4559 alias_keyword: None,
4560 order_by: None,
4561 limit: None,
4562 offset: None,
4563 distribute_by: None,
4564 sort_by: None,
4565 cluster_by: None,
4566 lateral: false,
4567 modifiers_inside: false,
4568 trailing_comments: Vec::new(),
4569 inferred_type: None,
4570 }));
4571 new_expressions.push(subquery);
4572 _changed = true;
4573 continue;
4574 }
4575 }
4576
4577 new_expressions.push(table_expr);
4578 }
4579
4580 from.expressions = new_expressions;
4581 Ok(())
4582}
4583
4584pub fn explode_projection_to_unnest(expr: Expression, target: DialectType) -> Result<Expression> {
4599 match expr {
4600 Expression::Select(select) => explode_projection_to_unnest_impl(*select, target),
4601 other => Ok(other),
4602 }
4603}
4604
4605pub fn snowflake_flatten_projection_to_unnest(expr: Expression) -> Result<Expression> {
4615 match expr {
4616 Expression::Select(select) => snowflake_flatten_projection_to_unnest_impl(*select),
4617 other => Ok(other),
4618 }
4619}
4620
4621fn snowflake_flatten_projection_to_unnest_impl(mut select: Select) -> Result<Expression> {
4622 let mut flattened_inputs: Vec<Expression> = Vec::new();
4623 let mut new_selects: Vec<Expression> = Vec::with_capacity(select.expressions.len());
4624
4625 for sel_expr in select.expressions.into_iter() {
4626 let found_input: RefCell<Option<Expression>> = RefCell::new(None);
4627
4628 let rewritten = transform_recursive(sel_expr, &|e| {
4629 if let Expression::Lateral(lat) = e {
4630 if let Some(input_expr) = extract_flatten_input(&lat) {
4631 if found_input.borrow().is_none() {
4632 *found_input.borrow_mut() = Some(input_expr);
4633 }
4634 return Ok(Expression::Lateral(Box::new(rewrite_flatten_lateral(*lat))));
4635 }
4636 return Ok(Expression::Lateral(lat));
4637 }
4638 Ok(e)
4639 })?;
4640
4641 if let Some(input) = found_input.into_inner() {
4642 flattened_inputs.push(input);
4643 }
4644 new_selects.push(rewritten);
4645 }
4646
4647 if flattened_inputs.is_empty() {
4648 select.expressions = new_selects;
4649 return Ok(Expression::Select(Box::new(select)));
4650 }
4651
4652 select.expressions = new_selects;
4653
4654 for (idx, input_expr) in flattened_inputs.into_iter().enumerate() {
4655 let is_first = idx == 0;
4657 let series_alias = if is_first {
4658 "pos".to_string()
4659 } else {
4660 format!("pos_{}", idx + 1)
4661 };
4662 let series_source_alias = if is_first {
4663 "_u".to_string()
4664 } else {
4665 format!("_u_{}", idx * 2 + 1)
4666 };
4667 let unnest_source_alias = if is_first {
4668 "_u_2".to_string()
4669 } else {
4670 format!("_u_{}", idx * 2 + 2)
4671 };
4672 let pos2_alias = if is_first {
4673 "pos_2".to_string()
4674 } else {
4675 format!("{}_2", series_alias)
4676 };
4677 let entity_alias = if is_first {
4678 "entity".to_string()
4679 } else {
4680 format!("entity_{}", idx + 1)
4681 };
4682
4683 let array_size_call = Expression::Function(Box::new(Function::new(
4684 "ARRAY_SIZE".to_string(),
4685 vec![Expression::NamedArgument(Box::new(NamedArgument {
4686 name: Identifier::new("INPUT"),
4687 value: input_expr.clone(),
4688 separator: NamedArgSeparator::DArrow,
4689 }))],
4690 )));
4691
4692 let greatest = Expression::Function(Box::new(Function::new(
4693 "GREATEST".to_string(),
4694 vec![array_size_call.clone()],
4695 )));
4696
4697 let series_end = Expression::Add(Box::new(BinaryOp::new(
4698 Expression::Paren(Box::new(crate::expressions::Paren {
4699 this: Expression::Sub(Box::new(BinaryOp::new(
4700 greatest,
4701 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4702 ))),
4703 trailing_comments: Vec::new(),
4704 })),
4705 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4706 )));
4707
4708 let series_range = Expression::Function(Box::new(Function::new(
4709 "ARRAY_GENERATE_RANGE".to_string(),
4710 vec![
4711 Expression::Literal(Box::new(Literal::Number("0".to_string()))),
4712 series_end,
4713 ],
4714 )));
4715
4716 let series_flatten = Expression::Function(Box::new(Function::new(
4717 "FLATTEN".to_string(),
4718 vec![Expression::NamedArgument(Box::new(NamedArgument {
4719 name: Identifier::new("INPUT"),
4720 value: series_range,
4721 separator: NamedArgSeparator::DArrow,
4722 }))],
4723 )));
4724
4725 let series_table = Expression::Function(Box::new(Function::new(
4726 "TABLE".to_string(),
4727 vec![series_flatten],
4728 )));
4729
4730 let series_alias_expr = Expression::Alias(Box::new(Alias {
4731 this: series_table,
4732 alias: Identifier::new(series_source_alias.clone()),
4733 column_aliases: vec![
4734 Identifier::new("seq"),
4735 Identifier::new("key"),
4736 Identifier::new("path"),
4737 Identifier::new("index"),
4738 Identifier::new(series_alias.clone()),
4739 Identifier::new("this"),
4740 ],
4741 alias_explicit_as: false,
4742 alias_keyword: None,
4743 pre_alias_comments: Vec::new(),
4744 trailing_comments: Vec::new(),
4745 inferred_type: None,
4746 }));
4747
4748 select.joins.push(Join {
4749 this: series_alias_expr,
4750 on: None,
4751 using: Vec::new(),
4752 kind: JoinKind::Cross,
4753 use_inner_keyword: false,
4754 use_outer_keyword: false,
4755 deferred_condition: false,
4756 join_hint: None,
4757 match_condition: None,
4758 pivots: Vec::new(),
4759 comments: Vec::new(),
4760 nesting_group: 0,
4761 directed: false,
4762 });
4763
4764 let entity_flatten = Expression::Function(Box::new(Function::new(
4765 "FLATTEN".to_string(),
4766 vec![Expression::NamedArgument(Box::new(NamedArgument {
4767 name: Identifier::new("INPUT"),
4768 value: input_expr.clone(),
4769 separator: NamedArgSeparator::DArrow,
4770 }))],
4771 )));
4772
4773 let entity_table = Expression::Function(Box::new(Function::new(
4774 "TABLE".to_string(),
4775 vec![entity_flatten],
4776 )));
4777
4778 let entity_alias_expr = Expression::Alias(Box::new(Alias {
4779 this: entity_table,
4780 alias: Identifier::new(unnest_source_alias.clone()),
4781 column_aliases: vec![
4782 Identifier::new("seq"),
4783 Identifier::new("key"),
4784 Identifier::new("path"),
4785 Identifier::new(pos2_alias.clone()),
4786 Identifier::new(entity_alias.clone()),
4787 Identifier::new("this"),
4788 ],
4789 alias_explicit_as: false,
4790 alias_keyword: None,
4791 pre_alias_comments: Vec::new(),
4792 trailing_comments: Vec::new(),
4793 inferred_type: None,
4794 }));
4795
4796 select.joins.push(Join {
4797 this: entity_alias_expr,
4798 on: None,
4799 using: Vec::new(),
4800 kind: JoinKind::Cross,
4801 use_inner_keyword: false,
4802 use_outer_keyword: false,
4803 deferred_condition: false,
4804 join_hint: None,
4805 match_condition: None,
4806 pivots: Vec::new(),
4807 comments: Vec::new(),
4808 nesting_group: 0,
4809 directed: false,
4810 });
4811
4812 let pos_col =
4813 Expression::qualified_column(series_source_alias.clone(), series_alias.clone());
4814 let pos2_col =
4815 Expression::qualified_column(unnest_source_alias.clone(), pos2_alias.clone());
4816
4817 let eq = Expression::Eq(Box::new(BinaryOp::new(pos_col.clone(), pos2_col.clone())));
4818 let size_minus_1 = Expression::Paren(Box::new(crate::expressions::Paren {
4819 this: Expression::Sub(Box::new(BinaryOp::new(
4820 array_size_call,
4821 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4822 ))),
4823 trailing_comments: Vec::new(),
4824 }));
4825 let gt = Expression::Gt(Box::new(BinaryOp::new(pos_col, size_minus_1.clone())));
4826 let pos2_eq_size = Expression::Eq(Box::new(BinaryOp::new(pos2_col, size_minus_1)));
4827 let and_cond = Expression::And(Box::new(BinaryOp::new(gt, pos2_eq_size)));
4828 let or_cond = Expression::Or(Box::new(BinaryOp::new(
4829 eq,
4830 Expression::Paren(Box::new(crate::expressions::Paren {
4831 this: and_cond,
4832 trailing_comments: Vec::new(),
4833 })),
4834 )));
4835
4836 select.where_clause = Some(match select.where_clause.take() {
4837 Some(existing) => Where {
4838 this: Expression::And(Box::new(BinaryOp::new(existing.this, or_cond))),
4839 },
4840 None => Where { this: or_cond },
4841 });
4842 }
4843
4844 Ok(Expression::Select(Box::new(select)))
4845}
4846
4847fn extract_flatten_input(lat: &Lateral) -> Option<Expression> {
4848 let Expression::Function(f) = lat.this.as_ref() else {
4849 return None;
4850 };
4851 if !f.name.eq_ignore_ascii_case("FLATTEN") {
4852 return None;
4853 }
4854
4855 for arg in &f.args {
4856 if let Expression::NamedArgument(na) = arg {
4857 if na.name.name.eq_ignore_ascii_case("INPUT") {
4858 return Some(na.value.clone());
4859 }
4860 }
4861 }
4862 f.args.first().cloned()
4863}
4864
4865fn rewrite_flatten_lateral(mut lat: Lateral) -> Lateral {
4866 let cond = Expression::Eq(Box::new(BinaryOp::new(
4867 Expression::qualified_column("_u", "pos"),
4868 Expression::qualified_column("_u_2", "pos_2"),
4869 )));
4870 let true_expr = Expression::qualified_column("_u_2", "entity");
4871 let iff_expr = Expression::Function(Box::new(Function::new(
4872 "IFF".to_string(),
4873 vec![cond, true_expr, Expression::Null(crate::expressions::Null)],
4874 )));
4875
4876 lat.this = Box::new(iff_expr);
4877 if lat.column_aliases.is_empty() {
4878 lat.column_aliases = vec![
4879 "SEQ".to_string(),
4880 "KEY".to_string(),
4881 "PATH".to_string(),
4882 "INDEX".to_string(),
4883 "VALUE".to_string(),
4884 "THIS".to_string(),
4885 ];
4886 }
4887 lat
4888}
4889
4890struct ExplodeInfo {
4892 arg_sql: String,
4894 explode_alias: String,
4896 pos_alias: String,
4898 unnest_source_alias: String,
4900}
4901
4902fn explode_projection_to_unnest_impl(select: Select, target: DialectType) -> Result<Expression> {
4903 let is_presto = matches!(
4904 target,
4905 DialectType::Presto | DialectType::Trino | DialectType::Athena
4906 );
4907 let is_bigquery = matches!(target, DialectType::BigQuery);
4908
4909 if !is_presto && !is_bigquery {
4910 return Ok(Expression::Select(Box::new(select)));
4911 }
4912
4913 let has_explode = select.expressions.iter().any(|e| expr_contains_explode(e));
4915 if !has_explode {
4916 return Ok(Expression::Select(Box::new(select)));
4917 }
4918
4919 let mut taken_select_names = std::collections::HashSet::new();
4921 let mut taken_source_names = std::collections::HashSet::new();
4922
4923 for sel in &select.expressions {
4925 if let Some(name) = get_output_name(sel) {
4926 taken_select_names.insert(name);
4927 }
4928 }
4929
4930 for sel in &select.expressions {
4932 let explode_expr = find_explode_in_expr(sel);
4933 if let Some(arg) = explode_expr {
4934 if let Some(name) = get_output_name(&arg) {
4935 taken_select_names.insert(name);
4936 }
4937 }
4938 }
4939
4940 if let Some(ref from) = select.from {
4942 for from_expr in &from.expressions {
4943 collect_source_names(from_expr, &mut taken_source_names);
4944 }
4945 }
4946 for join in &select.joins {
4948 collect_source_names(&join.this, &mut taken_source_names);
4949 }
4950
4951 let series_alias = new_name(&mut taken_select_names, "pos");
4953
4954 let series_source_alias = new_name(&mut taken_source_names, "_u");
4956
4957 let target_dialect = Dialect::get(target);
4959
4960 let mut explode_infos: Vec<ExplodeInfo> = Vec::new();
4962 let mut new_projections: Vec<String> = Vec::new();
4963
4964 for (_idx, sel_expr) in select.expressions.iter().enumerate() {
4965 let explode_data = extract_explode_data(sel_expr);
4966
4967 if let Some((is_posexplode, arg_expr, explicit_alias, explicit_pos_alias)) = explode_data {
4968 let arg_sql = target_dialect
4970 .generate(&arg_expr)
4971 .unwrap_or_else(|_| "NULL".to_string());
4972
4973 let unnest_source_alias = new_name(&mut taken_source_names, "_u");
4974
4975 let explode_alias = if let Some(ref ea) = explicit_alias {
4976 taken_select_names.remove(ea.as_str());
4979 let name = new_name(&mut taken_select_names, ea);
4981 name
4982 } else {
4983 new_name(&mut taken_select_names, "col")
4984 };
4985
4986 let pos_alias = if let Some(ref pa) = explicit_pos_alias {
4987 taken_select_names.remove(pa.as_str());
4989 let name = new_name(&mut taken_select_names, pa);
4990 name
4991 } else {
4992 new_name(&mut taken_select_names, "pos")
4993 };
4994
4995 if is_presto {
4997 let if_col = format!(
4999 "IF({}.{} = {}.{}, {}.{}) AS {}",
5000 series_source_alias,
5001 series_alias,
5002 unnest_source_alias,
5003 pos_alias,
5004 unnest_source_alias,
5005 explode_alias,
5006 explode_alias
5007 );
5008 new_projections.push(if_col);
5009
5010 if is_posexplode {
5012 let if_pos = format!(
5013 "IF({}.{} = {}.{}, {}.{}) AS {}",
5014 series_source_alias,
5015 series_alias,
5016 unnest_source_alias,
5017 pos_alias,
5018 unnest_source_alias,
5019 pos_alias,
5020 pos_alias
5021 );
5022 new_projections.push(if_pos);
5023 }
5024 } else {
5025 let if_col = format!(
5027 "IF({} = {}, {}, NULL) AS {}",
5028 series_alias, pos_alias, explode_alias, explode_alias
5029 );
5030 new_projections.push(if_col);
5031
5032 if is_posexplode {
5034 let if_pos = format!(
5035 "IF({} = {}, {}, NULL) AS {}",
5036 series_alias, pos_alias, pos_alias, pos_alias
5037 );
5038 new_projections.push(if_pos);
5039 }
5040 }
5041
5042 explode_infos.push(ExplodeInfo {
5043 arg_sql,
5044 explode_alias,
5045 pos_alias,
5046 unnest_source_alias,
5047 });
5048 } else {
5049 let sel_sql = target_dialect
5051 .generate(sel_expr)
5052 .unwrap_or_else(|_| "*".to_string());
5053 new_projections.push(sel_sql);
5054 }
5055 }
5056
5057 if explode_infos.is_empty() {
5058 return Ok(Expression::Select(Box::new(select)));
5059 }
5060
5061 let mut from_parts: Vec<String> = Vec::new();
5063
5064 if let Some(ref from) = select.from {
5066 for from_expr in &from.expressions {
5067 let from_sql = target_dialect.generate(from_expr).unwrap_or_default();
5068 from_parts.push(from_sql);
5069 }
5070 }
5071
5072 let size_exprs: Vec<String> = explode_infos
5074 .iter()
5075 .map(|info| {
5076 if is_presto {
5077 format!("CARDINALITY({})", info.arg_sql)
5078 } else {
5079 format!("ARRAY_LENGTH({})", info.arg_sql)
5080 }
5081 })
5082 .collect();
5083
5084 let greatest_arg = if size_exprs.len() == 1 {
5085 size_exprs[0].clone()
5086 } else {
5087 format!("GREATEST({})", size_exprs.join(", "))
5088 };
5089
5090 let series_sql = if is_presto {
5093 if size_exprs.len() == 1 {
5095 format!(
5096 "UNNEST(SEQUENCE(1, GREATEST({}))) AS {}({})",
5097 greatest_arg, series_source_alias, series_alias
5098 )
5099 } else {
5100 format!(
5102 "UNNEST(SEQUENCE(1, {})) AS {}({})",
5103 greatest_arg, series_source_alias, series_alias
5104 )
5105 }
5106 } else {
5107 if size_exprs.len() == 1 {
5109 format!(
5110 "UNNEST(GENERATE_ARRAY(0, GREATEST({}) - 1)) AS {}",
5111 greatest_arg, series_alias
5112 )
5113 } else {
5114 format!(
5116 "UNNEST(GENERATE_ARRAY(0, {} - 1)) AS {}",
5117 greatest_arg, series_alias
5118 )
5119 }
5120 };
5121
5122 let mut cross_joins: Vec<String> = Vec::new();
5126
5127 for info in &explode_infos {
5128 cross_joins.push(format!(
5130 "CROSS JOIN UNNEST({}) WITH ORDINALITY AS {}({}, {})",
5131 info.arg_sql, info.unnest_source_alias, info.explode_alias, info.pos_alias
5132 ));
5133 }
5134
5135 let mut where_conditions: Vec<String> = Vec::new();
5137
5138 for info in &explode_infos {
5139 let size_expr = if is_presto {
5140 format!("CARDINALITY({})", info.arg_sql)
5141 } else {
5142 format!("ARRAY_LENGTH({})", info.arg_sql)
5143 };
5144
5145 let cond = if is_presto {
5146 format!(
5147 "{series_src}.{series_al} = {unnest_src}.{pos_al} OR ({series_src}.{series_al} > {size} AND {unnest_src}.{pos_al} = {size})",
5148 series_src = series_source_alias,
5149 series_al = series_alias,
5150 unnest_src = info.unnest_source_alias,
5151 pos_al = info.pos_alias,
5152 size = size_expr
5153 )
5154 } else {
5155 format!(
5156 "{series_al} = {pos_al} OR ({series_al} > ({size} - 1) AND {pos_al} = ({size} - 1))",
5157 series_al = series_alias,
5158 pos_al = info.pos_alias,
5159 size = size_expr
5160 )
5161 };
5162
5163 where_conditions.push(cond);
5164 }
5165
5166 let where_sql = if where_conditions.len() == 1 {
5168 where_conditions[0].clone()
5169 } else {
5170 where_conditions
5171 .iter()
5172 .map(|c| format!("({})", c))
5173 .collect::<Vec<_>>()
5174 .join(" AND ")
5175 };
5176
5177 let select_part = new_projections.join(", ");
5179
5180 let from_and_joins = if from_parts.is_empty() {
5182 format!("FROM {} {}", series_sql, cross_joins.join(" "))
5184 } else {
5185 format!(
5186 "FROM {} {} {}",
5187 from_parts.join(", "),
5188 format!("CROSS JOIN {}", series_sql),
5189 cross_joins.join(" ")
5190 )
5191 };
5192
5193 let full_sql = format!(
5194 "SELECT {} {} WHERE {}",
5195 select_part, from_and_joins, where_sql
5196 );
5197
5198 let generic_dialect = Dialect::get(DialectType::Generic);
5201 let parsed = generic_dialect.parse(&full_sql);
5202 match parsed {
5203 Ok(mut stmts) if !stmts.is_empty() => {
5204 let mut result = stmts.remove(0);
5205
5206 if is_bigquery {
5210 convert_unnest_presto_to_bigquery(&mut result);
5211 }
5212
5213 Ok(result)
5214 }
5215 _ => {
5216 Ok(Expression::Select(Box::new(select)))
5218 }
5219 }
5220}
5221
5222fn convert_unnest_presto_to_bigquery(expr: &mut Expression) {
5226 match expr {
5227 Expression::Select(ref mut select) => {
5228 if let Some(ref mut from) = select.from {
5230 for from_item in from.expressions.iter_mut() {
5231 convert_unnest_presto_to_bigquery(from_item);
5232 }
5233 }
5234 for join in select.joins.iter_mut() {
5236 convert_unnest_presto_to_bigquery(&mut join.this);
5237 }
5238 }
5239 Expression::Alias(ref alias) => {
5240 if let Expression::Unnest(ref unnest) = alias.this {
5242 if unnest.with_ordinality && alias.column_aliases.len() >= 2 {
5243 let col_alias = alias.column_aliases[0].clone();
5244 let pos_alias = alias.column_aliases[1].clone();
5245 let mut new_unnest = unnest.as_ref().clone();
5246 new_unnest.alias = Some(col_alias);
5247 new_unnest.offset_alias = Some(pos_alias);
5248 *expr = Expression::Unnest(Box::new(new_unnest));
5250 }
5251 }
5252 }
5253 _ => {}
5254 }
5255}
5256
5257fn new_name(names: &mut std::collections::HashSet<String>, base: &str) -> String {
5260 if !names.contains(base) {
5261 names.insert(base.to_string());
5262 return base.to_string();
5263 }
5264 let mut i = 2;
5265 loop {
5266 let candidate = format!("{}_{}", base, i);
5267 if !names.contains(&candidate) {
5268 names.insert(candidate.clone());
5269 return candidate;
5270 }
5271 i += 1;
5272 }
5273}
5274
5275fn expr_contains_explode(expr: &Expression) -> bool {
5277 match expr {
5278 Expression::Explode(_) => true,
5279 Expression::ExplodeOuter(_) => true,
5280 Expression::Function(f) => {
5281 let name = f.name.to_uppercase();
5282 name == "POSEXPLODE" || name == "POSEXPLODE_OUTER"
5283 }
5284 Expression::Alias(a) => expr_contains_explode(&a.this),
5285 _ => false,
5286 }
5287}
5288
5289fn find_explode_in_expr(expr: &Expression) -> Option<Expression> {
5291 match expr {
5292 Expression::Explode(uf) => Some(uf.this.clone()),
5293 Expression::ExplodeOuter(uf) => Some(uf.this.clone()),
5294 Expression::Function(f) => {
5295 let name = f.name.to_uppercase();
5296 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5297 Some(f.args[0].clone())
5298 } else {
5299 None
5300 }
5301 }
5302 Expression::Alias(a) => find_explode_in_expr(&a.this),
5303 _ => None,
5304 }
5305}
5306
5307fn extract_explode_data(
5310 expr: &Expression,
5311) -> Option<(bool, Expression, Option<String>, Option<String>)> {
5312 match expr {
5313 Expression::Explode(uf) => Some((false, uf.this.clone(), None, None)),
5315 Expression::ExplodeOuter(uf) => Some((false, uf.this.clone(), None, None)),
5316 Expression::Function(f) => {
5318 let name = f.name.to_uppercase();
5319 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5320 Some((true, f.args[0].clone(), None, None))
5321 } else {
5322 None
5323 }
5324 }
5325 Expression::Alias(a) => {
5327 match &a.this {
5328 Expression::Explode(uf) => {
5329 let alias = if !a.alias.is_empty() {
5330 Some(a.alias.name.clone())
5331 } else {
5332 None
5333 };
5334 Some((false, uf.this.clone(), alias, None))
5335 }
5336 Expression::ExplodeOuter(uf) => {
5337 let alias = if !a.alias.is_empty() {
5338 Some(a.alias.name.clone())
5339 } else {
5340 None
5341 };
5342 Some((false, uf.this.clone(), alias, None))
5343 }
5344 Expression::Function(f) => {
5345 let name = f.name.to_uppercase();
5346 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5347 if a.column_aliases.len() == 2 {
5349 let pos_alias = a.column_aliases[0].name.clone();
5350 let col_alias = a.column_aliases[1].name.clone();
5351 Some((true, f.args[0].clone(), Some(col_alias), Some(pos_alias)))
5352 } else if !a.alias.is_empty() {
5353 Some((true, f.args[0].clone(), Some(a.alias.name.clone()), None))
5355 } else {
5356 Some((true, f.args[0].clone(), None, None))
5357 }
5358 } else {
5359 None
5360 }
5361 }
5362 _ => None,
5363 }
5364 }
5365 _ => None,
5366 }
5367}
5368
5369fn get_output_name(expr: &Expression) -> Option<String> {
5371 match expr {
5372 Expression::Alias(a) => {
5373 if !a.alias.is_empty() {
5374 Some(a.alias.name.clone())
5375 } else {
5376 None
5377 }
5378 }
5379 Expression::Column(c) => Some(c.name.name.clone()),
5380 Expression::Identifier(id) => Some(id.name.clone()),
5381 _ => None,
5382 }
5383}
5384
5385fn collect_source_names(expr: &Expression, names: &mut std::collections::HashSet<String>) {
5387 match expr {
5388 Expression::Alias(a) => {
5389 if !a.alias.is_empty() {
5390 names.insert(a.alias.name.clone());
5391 }
5392 }
5393 Expression::Subquery(s) => {
5394 if let Some(ref alias) = s.alias {
5395 names.insert(alias.name.clone());
5396 }
5397 }
5398 Expression::Table(t) => {
5399 if let Some(ref alias) = t.alias {
5400 names.insert(alias.name.clone());
5401 } else {
5402 names.insert(t.name.name.clone());
5403 }
5404 }
5405 Expression::Column(c) => {
5406 names.insert(c.name.name.clone());
5407 }
5408 Expression::Identifier(id) => {
5409 names.insert(id.name.clone());
5410 }
5411 _ => {}
5412 }
5413}
5414
5415pub fn strip_unnest_column_refs(expr: Expression) -> Result<Expression> {
5418 use crate::dialects::transform_recursive;
5419 transform_recursive(expr, &strip_unnest_column_refs_single)
5420}
5421
5422fn strip_unnest_column_refs_single(expr: Expression) -> Result<Expression> {
5423 if let Expression::Select(mut select) = expr {
5424 for join in select.joins.iter_mut() {
5426 strip_unnest_from_expr(&mut join.this);
5427 }
5428 if let Some(ref mut from) = select.from {
5430 for from_item in from.expressions.iter_mut() {
5431 strip_unnest_from_expr(from_item);
5432 }
5433 }
5434 Ok(Expression::Select(select))
5435 } else {
5436 Ok(expr)
5437 }
5438}
5439
5440fn strip_unnest_from_expr(expr: &mut Expression) {
5443 if let Expression::Alias(ref mut alias) = expr {
5444 if let Expression::Unnest(ref unnest) = alias.this {
5445 let is_column_ref = matches!(&unnest.this, Expression::Column(_) | Expression::Dot(_));
5446 if is_column_ref {
5447 let inner = unnest.this.clone();
5449 alias.this = inner;
5450 }
5451 }
5452 }
5453}
5454
5455pub fn wrap_duckdb_unnest_struct(expr: Expression) -> Result<Expression> {
5458 use crate::dialects::transform_recursive;
5459 transform_recursive(expr, &wrap_duckdb_unnest_struct_single)
5460}
5461
5462fn wrap_duckdb_unnest_struct_single(expr: Expression) -> Result<Expression> {
5463 if let Expression::Select(mut select) = expr {
5464 if let Some(ref mut from) = select.from {
5466 for from_item in from.expressions.iter_mut() {
5467 try_wrap_unnest_in_subquery(from_item);
5468 }
5469 }
5470
5471 for join in select.joins.iter_mut() {
5473 try_wrap_unnest_in_subquery(&mut join.this);
5474 }
5475
5476 Ok(Expression::Select(select))
5477 } else {
5478 Ok(expr)
5479 }
5480}
5481
5482fn is_struct_array_unnest_arg(expr: &Expression) -> bool {
5484 match expr {
5485 Expression::Array(arr) => arr
5487 .expressions
5488 .iter()
5489 .any(|e| matches!(e, Expression::Struct(_))),
5490 Expression::ArrayFunc(arr) => arr
5491 .expressions
5492 .iter()
5493 .any(|e| matches!(e, Expression::Struct(_))),
5494 Expression::Cast(c) => {
5496 matches!(&c.to, DataType::Array { element_type, .. } if matches!(**element_type, DataType::Struct { .. }))
5497 }
5498 _ => false,
5499 }
5500}
5501
5502fn try_wrap_unnest_in_subquery(expr: &mut Expression) {
5505 if let Expression::Alias(ref alias) = expr {
5507 if let Expression::Unnest(ref unnest) = alias.this {
5508 if is_struct_array_unnest_arg(&unnest.this) {
5509 let unnest_clone = (**unnest).clone();
5510 let alias_name = alias.alias.clone();
5511 let new_expr = make_unnest_subquery(unnest_clone, Some(alias_name));
5512 *expr = new_expr;
5513 return;
5514 }
5515 }
5516 }
5517
5518 if let Expression::Unnest(ref unnest) = expr {
5520 if is_struct_array_unnest_arg(&unnest.this) {
5521 let unnest_clone = (**unnest).clone();
5522 let new_expr = make_unnest_subquery(unnest_clone, None);
5523 *expr = new_expr;
5524 }
5525 }
5526}
5527
5528fn make_unnest_subquery(unnest: UnnestFunc, alias: Option<Identifier>) -> Expression {
5530 let max_depth_arg = Expression::NamedArgument(Box::new(NamedArgument {
5532 name: Identifier::new("max_depth".to_string()),
5533 value: Expression::Literal(Box::new(Literal::Number("2".to_string()))),
5534 separator: NamedArgSeparator::DArrow,
5535 }));
5536
5537 let mut unnest_args = vec![unnest.this];
5538 unnest_args.extend(unnest.expressions);
5539 unnest_args.push(max_depth_arg);
5540
5541 let unnest_func =
5542 Expression::Function(Box::new(Function::new("UNNEST".to_string(), unnest_args)));
5543
5544 let mut inner_select = Select::new();
5546 inner_select.expressions = vec![unnest_func];
5547 let inner_select = Expression::Select(Box::new(inner_select));
5548
5549 let subquery = Subquery {
5551 this: inner_select,
5552 alias,
5553 column_aliases: Vec::new(),
5554 alias_explicit_as: false,
5555 alias_keyword: None,
5556 order_by: None,
5557 limit: None,
5558 offset: None,
5559 distribute_by: None,
5560 sort_by: None,
5561 cluster_by: None,
5562 lateral: false,
5563 modifiers_inside: false,
5564 trailing_comments: Vec::new(),
5565 inferred_type: None,
5566 };
5567
5568 Expression::Subquery(Box::new(subquery))
5569}
5570
5571pub fn no_limit_order_by_union(expr: Expression) -> Result<Expression> {
5583 use crate::expressions::{Limit as LimitClause, Offset as OffsetClause, OrderBy, Star};
5584
5585 match expr {
5586 Expression::Union(mut u) => {
5587 if u.order_by.is_none() && u.limit.is_none() && u.offset.is_none() {
5590 if let Expression::Select(ref mut right_select) = u.right {
5592 if right_select.order_by.is_some()
5593 || right_select.limit.is_some()
5594 || right_select.offset.is_some()
5595 {
5596 u.order_by = right_select.order_by.take();
5598 u.limit = right_select.limit.take().map(|l| Box::new(l.this));
5599 u.offset = right_select.offset.take().map(|o| Box::new(o.this));
5600 }
5601 }
5602 }
5603
5604 let has_order_or_limit =
5605 u.order_by.is_some() || u.limit.is_some() || u.offset.is_some();
5606 if has_order_or_limit {
5607 let order_by: Option<OrderBy> = u.order_by.take();
5609 let union_limit: Option<Box<Expression>> = u.limit.take();
5610 let union_offset: Option<Box<Expression>> = u.offset.take();
5611
5612 let select_limit: Option<LimitClause> = union_limit.map(|l| LimitClause {
5614 this: *l,
5615 percent: false,
5616 comments: Vec::new(),
5617 });
5618
5619 let select_offset: Option<OffsetClause> = union_offset.map(|o| OffsetClause {
5621 this: *o,
5622 rows: None,
5623 });
5624
5625 let subquery = Subquery {
5627 this: Expression::Union(u),
5628 alias: Some(Identifier::new("_l_0")),
5629 column_aliases: Vec::new(),
5630 alias_explicit_as: true,
5631 alias_keyword: None,
5632 lateral: false,
5633 modifiers_inside: false,
5634 order_by: None,
5635 limit: None,
5636 offset: None,
5637 distribute_by: None,
5638 sort_by: None,
5639 cluster_by: None,
5640 trailing_comments: Vec::new(),
5641 inferred_type: None,
5642 };
5643
5644 let mut select = Select::default();
5646 select.expressions = vec![Expression::Star(Star {
5647 table: None,
5648 except: None,
5649 replace: None,
5650 rename: None,
5651 trailing_comments: Vec::new(),
5652 span: None,
5653 })];
5654 select.from = Some(From {
5655 expressions: vec![Expression::Subquery(Box::new(subquery))],
5656 });
5657 select.order_by = order_by;
5658 select.limit = select_limit;
5659 select.offset = select_offset;
5660
5661 Ok(Expression::Select(Box::new(select)))
5662 } else {
5663 Ok(Expression::Union(u))
5664 }
5665 }
5666 _ => Ok(expr),
5667 }
5668}
5669
5670pub fn expand_like_any(expr: Expression) -> Result<Expression> {
5678 use crate::expressions::{BinaryOp, LikeOp, Paren};
5679
5680 const LIKE_ALL_MARKER: &str = "__LIKE_ALL_EXPANSION__";
5683
5684 fn unwrap_parens(e: &Expression) -> &Expression {
5685 match e {
5686 Expression::Paren(p) => unwrap_parens(&p.this),
5687 _ => e,
5688 }
5689 }
5690
5691 fn extract_tuple_values(e: &Expression) -> Option<Vec<Expression>> {
5692 let inner = unwrap_parens(e);
5693 match inner {
5694 Expression::Tuple(t) => Some(t.expressions.clone()),
5695 _ if !matches!(e, Expression::Tuple(_)) => Some(vec![inner.clone()]),
5697 _ => None,
5698 }
5699 }
5700
5701 fn expand_like_quantifier(
5703 op: &LikeOp,
5704 values: Vec<Expression>,
5705 is_ilike: bool,
5706 combiner: fn(Expression, Expression) -> Expression,
5707 wrap_marker: bool,
5708 ) -> Expression {
5709 let num_values = values.len();
5710 let mut result: Option<Expression> = None;
5711 for val in values {
5712 let like = if is_ilike {
5713 Expression::ILike(Box::new(LikeOp {
5714 left: op.left.clone(),
5715 right: val,
5716 escape: op.escape.clone(),
5717 quantifier: None,
5718 inferred_type: None,
5719 }))
5720 } else {
5721 Expression::Like(Box::new(LikeOp {
5722 left: op.left.clone(),
5723 right: val,
5724 escape: op.escape.clone(),
5725 quantifier: None,
5726 inferred_type: None,
5727 }))
5728 };
5729 result = Some(match result {
5730 None => like,
5731 Some(prev) => combiner(prev, like),
5732 });
5733 }
5734 let expanded = result.unwrap_or_else(|| unreachable!("values is non-empty"));
5735 if wrap_marker && num_values > 1 {
5739 Expression::Paren(Box::new(Paren {
5740 this: expanded,
5741 trailing_comments: vec![LIKE_ALL_MARKER.to_string()],
5742 }))
5743 } else {
5744 expanded
5745 }
5746 }
5747
5748 fn or_combiner(a: Expression, b: Expression) -> Expression {
5749 Expression::Or(Box::new(BinaryOp::new(a, b)))
5750 }
5751
5752 fn and_combiner(a: Expression, b: Expression) -> Expression {
5753 Expression::And(Box::new(BinaryOp::new(a, b)))
5754 }
5755
5756 fn is_like_all_marker(p: &Paren) -> bool {
5757 p.trailing_comments.len() == 1 && p.trailing_comments[0] == LIKE_ALL_MARKER
5758 }
5759
5760 let result = transform_recursive(expr, &|e| {
5768 match e {
5769 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ANY") => {
5771 if let Some(values) = extract_tuple_values(&op.right) {
5772 if values.is_empty() {
5773 return Ok(e);
5774 }
5775 Ok(expand_like_quantifier(
5776 op,
5777 values,
5778 false,
5779 or_combiner,
5780 false,
5781 ))
5782 } else {
5783 Ok(e)
5784 }
5785 }
5786 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ALL") => {
5788 if let Some(values) = extract_tuple_values(&op.right) {
5789 if values.is_empty() {
5790 return Ok(e);
5791 }
5792 Ok(expand_like_quantifier(
5793 op,
5794 values,
5795 false,
5796 and_combiner,
5797 true,
5798 ))
5799 } else {
5800 Ok(e)
5801 }
5802 }
5803 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ANY") => {
5805 if let Some(values) = extract_tuple_values(&op.right) {
5806 if values.is_empty() {
5807 return Ok(e);
5808 }
5809 Ok(expand_like_quantifier(op, values, true, or_combiner, false))
5810 } else {
5811 Ok(e)
5812 }
5813 }
5814 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ALL") => {
5816 if let Some(values) = extract_tuple_values(&op.right) {
5817 if values.is_empty() {
5818 return Ok(e);
5819 }
5820 Ok(expand_like_quantifier(op, values, true, and_combiner, true))
5821 } else {
5822 Ok(e)
5823 }
5824 }
5825 Expression::And(mut op) => {
5830 if matches!(&op.left, Expression::Or(_)) {
5831 op.left = Expression::Paren(Box::new(Paren {
5832 this: op.left,
5833 trailing_comments: vec![],
5834 }));
5835 }
5836 if matches!(&op.right, Expression::Or(_)) {
5837 op.right = Expression::Paren(Box::new(Paren {
5838 this: op.right,
5839 trailing_comments: vec![],
5840 }));
5841 }
5842 Ok(Expression::And(op))
5843 }
5844 Expression::Or(mut op) => {
5847 if let Expression::Paren(ref mut p) = op.left {
5848 if is_like_all_marker(p) {
5849 p.trailing_comments.clear();
5850 }
5851 }
5852 if let Expression::Paren(ref mut p) = op.right {
5853 if is_like_all_marker(p) {
5854 p.trailing_comments.clear();
5855 }
5856 }
5857 Ok(Expression::Or(op))
5858 }
5859 _ => Ok(e),
5860 }
5861 })?;
5862
5863 transform_recursive(result, &|e| {
5867 if let Expression::Paren(p) = &e {
5868 if is_like_all_marker(p) {
5869 let Expression::Paren(p) = e else {
5870 unreachable!()
5871 };
5872 return Ok(p.this);
5873 }
5874 }
5875 Ok(e)
5876 })
5877}
5878
5879pub fn qualify_derived_table_outputs(expr: Expression) -> Result<Expression> {
5887 use crate::expressions::Alias;
5888
5889 fn add_self_aliases_to_select(select: &mut Select) {
5890 let new_expressions: Vec<Expression> = select
5891 .expressions
5892 .iter()
5893 .map(|e| {
5894 match e {
5895 Expression::Column(col) => {
5897 let alias_name = col.name.clone();
5898 Expression::Alias(Box::new(Alias {
5899 this: e.clone(),
5900 alias: alias_name,
5901 column_aliases: Vec::new(),
5902 alias_explicit_as: false,
5903 alias_keyword: None,
5904 pre_alias_comments: Vec::new(),
5905 trailing_comments: Vec::new(),
5906 inferred_type: None,
5907 }))
5908 }
5909 _ => e.clone(),
5911 }
5912 })
5913 .collect();
5914 select.expressions = new_expressions;
5915 }
5916
5917 fn walk_and_qualify(expr: &mut Expression) {
5918 match expr {
5919 Expression::Select(ref mut select) => {
5920 if let Some(ref mut from) = select.from {
5922 for e in from.expressions.iter_mut() {
5923 qualify_subquery_expr(e);
5924 walk_and_qualify(e);
5925 }
5926 }
5927 for join in select.joins.iter_mut() {
5929 qualify_subquery_expr(&mut join.this);
5930 walk_and_qualify(&mut join.this);
5931 }
5932 for e in select.expressions.iter_mut() {
5934 walk_and_qualify(e);
5935 }
5936 if let Some(ref mut w) = select.where_clause {
5938 walk_and_qualify(&mut w.this);
5939 }
5940 }
5941 Expression::Subquery(ref mut subquery) => {
5942 walk_and_qualify(&mut subquery.this);
5943 }
5944 Expression::Union(ref mut u) => {
5945 walk_and_qualify(&mut u.left);
5946 walk_and_qualify(&mut u.right);
5947 }
5948 Expression::Intersect(ref mut i) => {
5949 walk_and_qualify(&mut i.left);
5950 walk_and_qualify(&mut i.right);
5951 }
5952 Expression::Except(ref mut e) => {
5953 walk_and_qualify(&mut e.left);
5954 walk_and_qualify(&mut e.right);
5955 }
5956 Expression::Cte(ref mut cte) => {
5957 walk_and_qualify(&mut cte.this);
5958 }
5959 _ => {}
5960 }
5961 }
5962
5963 fn qualify_subquery_expr(expr: &mut Expression) {
5964 match expr {
5965 Expression::Subquery(ref mut subquery) => {
5966 if subquery.alias.is_some() && subquery.column_aliases.is_empty() {
5968 if let Expression::Select(ref mut inner_select) = subquery.this {
5969 let has_star = inner_select
5971 .expressions
5972 .iter()
5973 .any(|e| matches!(e, Expression::Star(_)));
5974 if !has_star {
5975 add_self_aliases_to_select(inner_select);
5976 }
5977 }
5978 }
5979 walk_and_qualify(&mut subquery.this);
5981 }
5982 Expression::Alias(ref mut alias) => {
5983 qualify_subquery_expr(&mut alias.this);
5984 }
5985 _ => {}
5986 }
5987 }
5988
5989 let mut result = expr;
5990 walk_and_qualify(&mut result);
5991
5992 if let Expression::Select(ref mut select) = result {
5994 if let Some(ref mut with) = select.with {
5995 for cte in with.ctes.iter_mut() {
5996 if cte.columns.is_empty() {
5998 walk_and_qualify(&mut cte.this);
6000 }
6001 }
6002 }
6003 }
6004
6005 Ok(result)
6006}
6007
6008#[cfg(test)]
6009mod tests {
6010 use super::*;
6011 use crate::dialects::{Dialect, DialectType};
6012 use crate::expressions::Column;
6013
6014 fn gen(expr: &Expression) -> String {
6015 let dialect = Dialect::get(DialectType::Generic);
6016 dialect.generate(expr).unwrap()
6017 }
6018
6019 #[test]
6020 fn test_preprocess() {
6021 let expr = Expression::Boolean(BooleanLiteral { value: true });
6022 let result = preprocess(expr, &[replace_bool_with_int]).unwrap();
6023 assert!(
6024 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
6025 );
6026 }
6027
6028 #[test]
6029 fn test_preprocess_chain() {
6030 let expr = Expression::Boolean(BooleanLiteral { value: true });
6032 let transforms: Vec<fn(Expression) -> Result<Expression>> =
6034 vec![replace_bool_with_int, replace_int_with_bool];
6035 let result = preprocess(expr, &transforms).unwrap();
6036 if let Expression::Boolean(b) = result {
6039 assert!(b.value);
6040 } else {
6041 panic!("Expected boolean literal");
6042 }
6043 }
6044
6045 #[test]
6046 fn test_unnest_to_explode() {
6047 let unnest = Expression::Unnest(Box::new(UnnestFunc {
6048 this: Expression::boxed_column(Column {
6049 name: Identifier::new("arr".to_string()),
6050 table: None,
6051 join_mark: false,
6052 trailing_comments: vec![],
6053 span: None,
6054 inferred_type: None,
6055 }),
6056 expressions: Vec::new(),
6057 with_ordinality: false,
6058 alias: None,
6059 offset_alias: None,
6060 }));
6061
6062 let result = unnest_to_explode(unnest).unwrap();
6063 assert!(matches!(result, Expression::Explode(_)));
6064 }
6065
6066 #[test]
6067 fn test_explode_to_unnest() {
6068 let explode = Expression::Explode(Box::new(UnaryFunc {
6069 this: Expression::boxed_column(Column {
6070 name: Identifier::new("arr".to_string()),
6071 table: None,
6072 join_mark: false,
6073 trailing_comments: vec![],
6074 span: None,
6075 inferred_type: None,
6076 }),
6077 original_name: None,
6078 inferred_type: None,
6079 }));
6080
6081 let result = explode_to_unnest(explode).unwrap();
6082 assert!(matches!(result, Expression::Unnest(_)));
6083 }
6084
6085 #[test]
6086 fn test_replace_bool_with_int() {
6087 let true_expr = Expression::Boolean(BooleanLiteral { value: true });
6088 let result = replace_bool_with_int(true_expr).unwrap();
6089 if let Expression::Literal(lit) = result {
6090 if let Literal::Number(n) = lit.as_ref() {
6091 assert_eq!(n, "1");
6092 }
6093 } else {
6094 panic!("Expected number literal");
6095 }
6096
6097 let false_expr = Expression::Boolean(BooleanLiteral { value: false });
6098 let result = replace_bool_with_int(false_expr).unwrap();
6099 if let Expression::Literal(lit) = result {
6100 if let Literal::Number(n) = lit.as_ref() {
6101 assert_eq!(n, "0");
6102 }
6103 } else {
6104 panic!("Expected number literal");
6105 }
6106 }
6107
6108 #[test]
6109 fn test_replace_int_with_bool() {
6110 let one_expr = Expression::Literal(Box::new(Literal::Number("1".to_string())));
6111 let result = replace_int_with_bool(one_expr).unwrap();
6112 if let Expression::Boolean(b) = result {
6113 assert!(b.value);
6114 } else {
6115 panic!("Expected boolean true");
6116 }
6117
6118 let zero_expr = Expression::Literal(Box::new(Literal::Number("0".to_string())));
6119 let result = replace_int_with_bool(zero_expr).unwrap();
6120 if let Expression::Boolean(b) = result {
6121 assert!(!b.value);
6122 } else {
6123 panic!("Expected boolean false");
6124 }
6125
6126 let two_expr = Expression::Literal(Box::new(Literal::Number("2".to_string())));
6128 let result = replace_int_with_bool(two_expr).unwrap();
6129 assert!(
6130 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
6131 );
6132 }
6133
6134 #[test]
6135 fn test_strip_data_type_params() {
6136 let decimal = DataType::Decimal {
6138 precision: Some(10),
6139 scale: Some(2),
6140 };
6141 let stripped = strip_data_type_params(decimal);
6142 assert_eq!(
6143 stripped,
6144 DataType::Decimal {
6145 precision: None,
6146 scale: None
6147 }
6148 );
6149
6150 let varchar = DataType::VarChar {
6152 length: Some(255),
6153 parenthesized_length: false,
6154 };
6155 let stripped = strip_data_type_params(varchar);
6156 assert_eq!(
6157 stripped,
6158 DataType::VarChar {
6159 length: None,
6160 parenthesized_length: false
6161 }
6162 );
6163
6164 let char_type = DataType::Char { length: Some(10) };
6166 let stripped = strip_data_type_params(char_type);
6167 assert_eq!(stripped, DataType::Char { length: None });
6168
6169 let timestamp = DataType::Timestamp {
6171 precision: Some(6),
6172 timezone: true,
6173 };
6174 let stripped = strip_data_type_params(timestamp);
6175 assert_eq!(
6176 stripped,
6177 DataType::Timestamp {
6178 precision: None,
6179 timezone: true
6180 }
6181 );
6182
6183 let array = DataType::Array {
6185 element_type: Box::new(DataType::VarChar {
6186 length: Some(100),
6187 parenthesized_length: false,
6188 }),
6189 dimension: None,
6190 };
6191 let stripped = strip_data_type_params(array);
6192 assert_eq!(
6193 stripped,
6194 DataType::Array {
6195 element_type: Box::new(DataType::VarChar {
6196 length: None,
6197 parenthesized_length: false
6198 }),
6199 dimension: None,
6200 }
6201 );
6202
6203 let text = DataType::Text;
6205 let stripped = strip_data_type_params(text);
6206 assert_eq!(stripped, DataType::Text);
6207 }
6208
6209 #[test]
6210 fn test_remove_precision_parameterized_types_cast() {
6211 let cast_expr = Expression::Cast(Box::new(Cast {
6213 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
6214 to: DataType::Decimal {
6215 precision: Some(10),
6216 scale: Some(2),
6217 },
6218 trailing_comments: vec![],
6219 double_colon_syntax: false,
6220 format: None,
6221 default: None,
6222 inferred_type: None,
6223 }));
6224
6225 let result = remove_precision_parameterized_types(cast_expr).unwrap();
6226 if let Expression::Cast(cast) = result {
6227 assert_eq!(
6228 cast.to,
6229 DataType::Decimal {
6230 precision: None,
6231 scale: None
6232 }
6233 );
6234 } else {
6235 panic!("Expected Cast expression");
6236 }
6237 }
6238
6239 #[test]
6240 fn test_remove_precision_parameterized_types_varchar() {
6241 let cast_expr = Expression::Cast(Box::new(Cast {
6243 this: Expression::Literal(Box::new(Literal::String("hello".to_string()))),
6244 to: DataType::VarChar {
6245 length: Some(10),
6246 parenthesized_length: false,
6247 },
6248 trailing_comments: vec![],
6249 double_colon_syntax: false,
6250 format: None,
6251 default: None,
6252 inferred_type: None,
6253 }));
6254
6255 let result = remove_precision_parameterized_types(cast_expr).unwrap();
6256 if let Expression::Cast(cast) = result {
6257 assert_eq!(
6258 cast.to,
6259 DataType::VarChar {
6260 length: None,
6261 parenthesized_length: false
6262 }
6263 );
6264 } else {
6265 panic!("Expected Cast expression");
6266 }
6267 }
6268
6269 #[test]
6270 fn test_remove_precision_direct_cast() {
6271 let cast = Expression::Cast(Box::new(Cast {
6275 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
6276 to: DataType::Decimal {
6277 precision: Some(10),
6278 scale: Some(2),
6279 },
6280 trailing_comments: vec![],
6281 double_colon_syntax: false,
6282 format: None,
6283 default: None,
6284 inferred_type: None,
6285 }));
6286
6287 let transformed = remove_precision_parameterized_types(cast).unwrap();
6288 let generated = gen(&transformed);
6289
6290 assert!(generated.contains("DECIMAL"));
6292 assert!(!generated.contains("(10"));
6293 }
6294
6295 #[test]
6296 fn test_epoch_cast_to_ts() {
6297 let cast_expr = Expression::Cast(Box::new(Cast {
6299 this: Expression::Literal(Box::new(Literal::String("epoch".to_string()))),
6300 to: DataType::Timestamp {
6301 precision: None,
6302 timezone: false,
6303 },
6304 trailing_comments: vec![],
6305 double_colon_syntax: false,
6306 format: None,
6307 default: None,
6308 inferred_type: None,
6309 }));
6310
6311 let result = epoch_cast_to_ts(cast_expr).unwrap();
6312 if let Expression::Cast(cast) = result {
6313 if let Expression::Literal(lit) = cast.this {
6314 if let Literal::String(s) = lit.as_ref() {
6315 assert_eq!(s, "1970-01-01 00:00:00");
6316 }
6317 } else {
6318 panic!("Expected string literal");
6319 }
6320 } else {
6321 panic!("Expected Cast expression");
6322 }
6323 }
6324
6325 #[test]
6326 fn test_epoch_cast_to_ts_preserves_non_epoch() {
6327 let cast_expr = Expression::Cast(Box::new(Cast {
6329 this: Expression::Literal(Box::new(Literal::String("2024-01-15".to_string()))),
6330 to: DataType::Timestamp {
6331 precision: None,
6332 timezone: false,
6333 },
6334 trailing_comments: vec![],
6335 double_colon_syntax: false,
6336 format: None,
6337 default: None,
6338 inferred_type: None,
6339 }));
6340
6341 let result = epoch_cast_to_ts(cast_expr).unwrap();
6342 if let Expression::Cast(cast) = result {
6343 if let Expression::Literal(lit) = cast.this {
6344 if let Literal::String(s) = lit.as_ref() {
6345 assert_eq!(s, "2024-01-15");
6346 }
6347 } else {
6348 panic!("Expected string literal");
6349 }
6350 } else {
6351 panic!("Expected Cast expression");
6352 }
6353 }
6354
6355 #[test]
6356 fn test_unqualify_columns() {
6357 let col = Expression::boxed_column(Column {
6359 name: Identifier::new("id".to_string()),
6360 table: Some(Identifier::new("users".to_string())),
6361 join_mark: false,
6362 trailing_comments: vec![],
6363 span: None,
6364 inferred_type: None,
6365 });
6366
6367 let result = unqualify_columns(col).unwrap();
6368 if let Expression::Column(c) = result {
6369 assert!(c.table.is_none());
6370 assert_eq!(c.name.name, "id");
6371 } else {
6372 panic!("Expected Column expression");
6373 }
6374 }
6375
6376 #[test]
6377 fn test_is_temporal_type() {
6378 assert!(is_temporal_type(&DataType::Date));
6379 assert!(is_temporal_type(&DataType::Timestamp {
6380 precision: None,
6381 timezone: false
6382 }));
6383 assert!(is_temporal_type(&DataType::Time {
6384 precision: None,
6385 timezone: false
6386 }));
6387 assert!(!is_temporal_type(&DataType::Int {
6388 length: None,
6389 integer_spelling: false
6390 }));
6391 assert!(!is_temporal_type(&DataType::VarChar {
6392 length: None,
6393 parenthesized_length: false
6394 }));
6395 }
6396
6397 #[test]
6398 fn test_eliminate_semi_join_basic() {
6399 use crate::expressions::{Join, TableRef};
6400
6401 let select = Expression::Select(Box::new(Select {
6403 expressions: vec![Expression::boxed_column(Column {
6404 name: Identifier::new("a".to_string()),
6405 table: None,
6406 join_mark: false,
6407 trailing_comments: vec![],
6408 span: None,
6409 inferred_type: None,
6410 })],
6411 from: Some(From {
6412 expressions: vec![Expression::Table(Box::new(TableRef::new("t1")))],
6413 }),
6414 joins: vec![Join {
6415 this: Expression::Table(Box::new(TableRef::new("t2"))),
6416 kind: JoinKind::Semi,
6417 on: Some(Expression::Eq(Box::new(BinaryOp {
6418 left: Expression::boxed_column(Column {
6419 name: Identifier::new("x".to_string()),
6420 table: None,
6421 join_mark: false,
6422 trailing_comments: vec![],
6423 span: None,
6424 inferred_type: None,
6425 }),
6426 right: Expression::boxed_column(Column {
6427 name: Identifier::new("y".to_string()),
6428 table: None,
6429 join_mark: false,
6430 trailing_comments: vec![],
6431 span: None,
6432 inferred_type: None,
6433 }),
6434 left_comments: vec![],
6435 operator_comments: vec![],
6436 trailing_comments: vec![],
6437 inferred_type: None,
6438 }))),
6439 using: vec![],
6440 use_inner_keyword: false,
6441 use_outer_keyword: false,
6442 deferred_condition: false,
6443 join_hint: None,
6444 match_condition: None,
6445 pivots: Vec::new(),
6446 comments: Vec::new(),
6447 nesting_group: 0,
6448 directed: false,
6449 }],
6450 ..Select::new()
6451 }));
6452
6453 let result = eliminate_semi_and_anti_joins(select).unwrap();
6454 if let Expression::Select(s) = result {
6455 assert!(s.joins.is_empty());
6457 assert!(s.where_clause.is_some());
6459 } else {
6460 panic!("Expected Select expression");
6461 }
6462 }
6463
6464 #[test]
6465 fn test_no_ilike_sql() {
6466 use crate::expressions::LikeOp;
6467
6468 let ilike_expr = Expression::ILike(Box::new(LikeOp {
6470 left: Expression::boxed_column(Column {
6471 name: Identifier::new("name".to_string()),
6472 table: None,
6473 join_mark: false,
6474 trailing_comments: vec![],
6475 span: None,
6476 inferred_type: None,
6477 }),
6478 right: Expression::Literal(Box::new(Literal::String("%test%".to_string()))),
6479 escape: None,
6480 quantifier: None,
6481 inferred_type: None,
6482 }));
6483
6484 let result = no_ilike_sql(ilike_expr).unwrap();
6485 if let Expression::Like(like) = result {
6486 if let Expression::Function(f) = &like.left {
6488 assert_eq!(f.name, "LOWER");
6489 } else {
6490 panic!("Expected LOWER function on left");
6491 }
6492 if let Expression::Function(f) = &like.right {
6494 assert_eq!(f.name, "LOWER");
6495 } else {
6496 panic!("Expected LOWER function on right");
6497 }
6498 } else {
6499 panic!("Expected Like expression");
6500 }
6501 }
6502
6503 #[test]
6504 fn test_no_trycast_sql() {
6505 let trycast_expr = Expression::TryCast(Box::new(Cast {
6507 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
6508 to: DataType::Int {
6509 length: None,
6510 integer_spelling: false,
6511 },
6512 trailing_comments: vec![],
6513 double_colon_syntax: false,
6514 format: None,
6515 default: None,
6516 inferred_type: None,
6517 }));
6518
6519 let result = no_trycast_sql(trycast_expr).unwrap();
6520 assert!(matches!(result, Expression::Cast(_)));
6521 }
6522
6523 #[test]
6524 fn test_no_safe_cast_sql() {
6525 let safe_cast_expr = Expression::SafeCast(Box::new(Cast {
6527 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
6528 to: DataType::Int {
6529 length: None,
6530 integer_spelling: false,
6531 },
6532 trailing_comments: vec![],
6533 double_colon_syntax: false,
6534 format: None,
6535 default: None,
6536 inferred_type: None,
6537 }));
6538
6539 let result = no_safe_cast_sql(safe_cast_expr).unwrap();
6540 assert!(matches!(result, Expression::Cast(_)));
6541 }
6542
6543 #[test]
6544 fn test_explode_to_unnest_presto() {
6545 let spark = Dialect::get(DialectType::Spark);
6546 let result = spark
6547 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::Presto)
6548 .unwrap();
6549 assert_eq!(
6550 result[0],
6551 "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))"
6552 );
6553 }
6554
6555 #[test]
6556 fn test_explode_to_unnest_bigquery() {
6557 let spark = Dialect::get(DialectType::Spark);
6558 let result = spark
6559 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::BigQuery)
6560 .unwrap();
6561 assert_eq!(
6562 result[0],
6563 "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))"
6564 );
6565 }
6566}