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
41#[cfg(any(feature = "dialect-tsql", feature = "dialect-fabric"))]
45pub(crate) fn normalize_grouping_sets_for_tsql(expr: Expression) -> Result<Expression> {
46 transform_recursive(expr, &|expr| {
47 let Expression::Select(mut select) = expr else {
48 return Ok(expr);
49 };
50
51 if let Some(group_by) = select.group_by.as_mut() {
52 group_by.expressions = std::mem::take(&mut group_by.expressions)
53 .into_iter()
54 .map(normalize_tsql_grouping_element)
55 .collect();
56 }
57
58 Ok(Expression::Select(select))
59 })
60}
61
62#[cfg(any(feature = "dialect-tsql", feature = "dialect-fabric"))]
63fn normalize_tsql_grouping_element(expression: Expression) -> Expression {
64 match expression {
65 Expression::Function(mut function)
66 if !function.quoted && function.name.eq_ignore_ascii_case("GROUPING SETS") =>
67 {
68 function.args = normalize_tsql_grouping_sets(std::mem::take(&mut function.args));
69 Expression::Function(function)
70 }
71 Expression::GroupingSets(mut grouping_sets) => {
72 grouping_sets.expressions =
73 normalize_tsql_grouping_sets(std::mem::take(&mut grouping_sets.expressions));
74 Expression::GroupingSets(grouping_sets)
75 }
76 Expression::Function(mut function)
77 if !function.quoted
78 && (function.name.eq_ignore_ascii_case("ROLLUP")
79 || function.name.eq_ignore_ascii_case("CUBE")) =>
80 {
81 function.args = std::mem::take(&mut function.args)
82 .into_iter()
83 .map(normalize_tsql_grouping_unit)
84 .collect();
85 Expression::Function(function)
86 }
87 Expression::Rollup(mut rollup) => {
88 rollup.expressions = std::mem::take(&mut rollup.expressions)
89 .into_iter()
90 .map(normalize_tsql_grouping_unit)
91 .collect();
92 Expression::Rollup(rollup)
93 }
94 Expression::Cube(mut cube) => {
95 cube.expressions = std::mem::take(&mut cube.expressions)
96 .into_iter()
97 .map(normalize_tsql_grouping_unit)
98 .collect();
99 Expression::Cube(cube)
100 }
101 other => other,
102 }
103}
104
105#[cfg(any(feature = "dialect-tsql", feature = "dialect-fabric"))]
106fn normalize_tsql_grouping_sets(expressions: Vec<Expression>) -> Vec<Expression> {
107 let mut normalized = Vec::new();
108
109 for expression in expressions {
110 match expression {
111 Expression::Function(mut function)
112 if !function.quoted && function.name.eq_ignore_ascii_case("GROUPING SETS") =>
113 {
114 normalized.extend(normalize_tsql_grouping_sets(std::mem::take(
115 &mut function.args,
116 )));
117 }
118 Expression::GroupingSets(mut grouping_sets) => {
119 normalized.extend(normalize_tsql_grouping_sets(std::mem::take(
120 &mut grouping_sets.expressions,
121 )));
122 }
123 other => normalized.push(normalize_tsql_grouping_unit(
124 normalize_tsql_grouping_element(other),
125 )),
126 }
127 }
128
129 normalized
130}
131
132#[cfg(any(feature = "dialect-tsql", feature = "dialect-fabric"))]
133fn normalize_tsql_grouping_unit(expression: Expression) -> Expression {
134 let Expression::Tuple(tuple) = expression else {
135 return expression;
136 };
137
138 let mut expressions = Vec::new();
139 for expression in tuple.expressions {
140 append_tsql_grouping_unit(expression, &mut expressions);
141 }
142
143 Expression::Tuple(Box::new(Tuple { expressions }))
144}
145
146#[cfg(any(feature = "dialect-tsql", feature = "dialect-fabric"))]
147fn append_tsql_grouping_unit(expression: Expression, expressions: &mut Vec<Expression>) {
148 match expression {
149 Expression::Tuple(tuple) => {
150 for expression in tuple.expressions {
151 append_tsql_grouping_unit(expression, expressions);
152 }
153 }
154 Expression::Paren(paren) => append_tsql_grouping_unit(paren.this, expressions),
155 other => {
156 if !expressions.contains(&other) {
157 expressions.push(other);
158 }
159 }
160 }
161}
162
163pub fn expand_distinct_grouping_sets_for_tsql(
166 expr: Expression,
167 target: DialectType,
168) -> Result<Expression> {
169 transform_recursive(expr, &|expr| {
170 let Expression::Select(mut select) = expr else {
171 return Ok(expr);
172 };
173
174 let Some(group_by) = select.group_by.as_mut() else {
175 return Ok(Expression::Select(select));
176 };
177 if group_by.all != Some(false) {
178 return Ok(Expression::Select(select));
179 }
180
181 let mut product = vec![Vec::new()];
182 let mut has_advanced_grouping = false;
183
184 for element in &group_by.expressions {
185 let alternatives = match expand_grouping_element(element, target)? {
186 Some(alternatives) => {
187 has_advanced_grouping = true;
188 alternatives
189 }
190 None => vec![vec![element.clone()]],
191 };
192
193 let expanded_len = product
194 .len()
195 .checked_mul(alternatives.len())
196 .filter(|len| *len <= MAX_TSQL_GROUPING_SETS)
197 .ok_or_else(|| grouping_set_expansion_error(target))?;
198 let mut next = Vec::with_capacity(expanded_len);
199
200 for left in &product {
201 for right in &alternatives {
202 let mut combined = left.clone();
203 for expression in right {
204 if !combined.contains(expression) {
205 combined.push(expression.clone());
206 }
207 }
208 next.push(combined);
209 }
210 }
211 product = next;
212 }
213
214 if !has_advanced_grouping {
215 return Ok(Expression::Select(select));
216 }
217
218 let mut distinct_sets = Vec::with_capacity(product.len());
219 for grouping_set in product {
220 if !distinct_sets.contains(&grouping_set) {
221 distinct_sets.push(grouping_set);
222 }
223 }
224
225 let sets = distinct_sets
226 .into_iter()
227 .map(|expressions| Expression::Tuple(Box::new(Tuple { expressions })))
228 .collect();
229 group_by.all = None;
230 group_by.expressions = vec![Expression::Function(Box::new(Function::new(
231 "GROUPING SETS".to_string(),
232 sets,
233 )))];
234
235 Ok(Expression::Select(select))
236 })
237}
238
239fn expand_grouping_element(
240 expression: &Expression,
241 target: DialectType,
242) -> Result<Option<Vec<Vec<Expression>>>> {
243 match expression {
244 Expression::Function(function) if function.name.eq_ignore_ascii_case("ROLLUP") => {
245 Ok(Some(expand_rollup(&function.args)))
246 }
247 Expression::Function(function) if function.name.eq_ignore_ascii_case("CUBE") => {
248 Ok(Some(expand_cube(&function.args, target)?))
249 }
250 Expression::Function(function) if function.name.eq_ignore_ascii_case("GROUPING SETS") => {
251 Ok(Some(expand_explicit_grouping_sets(&function.args, target)?))
252 }
253 Expression::Rollup(rollup) => Ok(Some(expand_rollup(&rollup.expressions))),
254 Expression::Cube(cube) => Ok(Some(expand_cube(&cube.expressions, target)?)),
255 Expression::GroupingSets(grouping_sets) => Ok(Some(expand_explicit_grouping_sets(
256 &grouping_sets.expressions,
257 target,
258 )?)),
259 _ => Ok(None),
260 }
261}
262
263fn expand_rollup(elements: &[Expression]) -> Vec<Vec<Expression>> {
264 (0..=elements.len())
265 .rev()
266 .map(|end| flatten_grouping_units(&elements[..end]))
267 .collect()
268}
269
270fn expand_cube(elements: &[Expression], target: DialectType) -> Result<Vec<Vec<Expression>>> {
271 let set_count = 1usize
272 .checked_shl(elements.len() as u32)
273 .filter(|count| *count <= MAX_TSQL_GROUPING_SETS)
274 .ok_or_else(|| grouping_set_expansion_error(target))?;
275
276 Ok((0..set_count)
277 .rev()
278 .map(|mask| {
279 let selected = elements
280 .iter()
281 .enumerate()
282 .filter_map(|(index, element)| {
283 let bit = elements.len() - index - 1;
284 (mask & (1usize << bit) != 0).then_some(element)
285 })
286 .cloned()
287 .collect::<Vec<_>>();
288 flatten_grouping_units(&selected)
289 })
290 .collect())
291}
292
293fn expand_explicit_grouping_sets(
294 elements: &[Expression],
295 target: DialectType,
296) -> Result<Vec<Vec<Expression>>> {
297 let mut sets = Vec::new();
298 for element in elements {
299 if let Some(nested) = expand_grouping_element(element, target)? {
300 sets.extend(nested);
301 } else {
302 sets.push(flatten_grouping_unit(element));
303 }
304 if sets.len() > MAX_TSQL_GROUPING_SETS {
305 return Err(grouping_set_expansion_error(target));
306 }
307 }
308 Ok(sets)
309}
310
311fn flatten_grouping_units(elements: &[Expression]) -> Vec<Expression> {
312 elements.iter().flat_map(flatten_grouping_unit).collect()
313}
314
315fn flatten_grouping_unit(expression: &Expression) -> Vec<Expression> {
316 match expression {
317 Expression::Tuple(tuple) => tuple.expressions.clone(),
318 Expression::Paren(paren) => flatten_grouping_unit(&paren.this),
319 _ => vec![expression.clone()],
320 }
321}
322
323fn grouping_set_expansion_error(target: DialectType) -> Error {
324 Error::unsupported(
325 format!("GROUP BY DISTINCT expansion beyond {MAX_TSQL_GROUPING_SETS} grouping sets"),
326 target.to_string(),
327 )
328}
329
330pub fn grouped_percentiles_to_tsql_windows(expr: Expression) -> Result<Expression> {
341 transform_recursive(expr, &grouped_percentiles_to_tsql_windows_inner)
342}
343
344fn grouped_percentiles_to_tsql_windows_inner(expr: Expression) -> Result<Expression> {
345 let Expression::Select(select) = expr else {
346 return Ok(expr);
347 };
348
349 rewrite_grouped_percentile_select(*select)
350}
351
352fn rewrite_grouped_percentile_select(mut select: Select) -> Result<Expression> {
353 let Some(group_by) = &select.group_by else {
354 return Ok(Expression::Select(Box::new(select)));
355 };
356
357 if select.having.is_some()
358 || group_by.all.is_some()
359 || group_by.totals
360 || group_by.expressions.is_empty()
361 || group_by.expressions.iter().any(is_complex_grouping_expr)
362 {
363 return Ok(Expression::Select(Box::new(select)));
364 }
365
366 let partition_by = group_by.expressions.clone();
367 let original_expressions = select.expressions.clone();
368 let mut changed = false;
369 let mut rewritten_expressions = Vec::with_capacity(select.expressions.len());
370
371 for expression in &select.expressions {
372 if is_group_projection(expression, &partition_by) {
373 rewritten_expressions.push(expression.clone());
374 continue;
375 }
376
377 let Some(rewritten) = rewrite_grouped_percentile_projection(expression, &partition_by)
378 else {
379 return Ok(Expression::Select(Box::new(select)));
380 };
381
382 changed = true;
383 rewritten_expressions.push(rewritten);
384 }
385
386 if !changed {
387 return Ok(Expression::Select(Box::new(select)));
388 }
389
390 let all_grouping_keys_projected = partition_by.iter().all(|group_expr| {
391 original_expressions
392 .iter()
393 .any(|projection| is_projection_of_group_expr(projection, group_expr))
394 });
395
396 if all_grouping_keys_projected {
397 select.expressions = rewritten_expressions;
398 select.group_by = None;
399 select.distinct = true;
400 return Ok(Expression::Select(Box::new(select)));
401 }
402
403 rewrite_grouped_percentile_select_with_hidden_groups(
404 select,
405 original_expressions,
406 rewritten_expressions,
407 partition_by,
408 )
409}
410
411fn is_complex_grouping_expr(expr: &Expression) -> bool {
412 matches!(
413 expr,
414 Expression::Cube(_) | Expression::Rollup(_) | Expression::GroupingSets(_)
415 ) || matches!(expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("GROUPING SETS"))
416}
417
418fn is_group_projection(expr: &Expression, group_by: &[Expression]) -> bool {
419 let inner = unalias_expression(expr);
420
421 group_by.iter().any(|group_expr| inner == group_expr)
422}
423
424fn is_projection_of_group_expr(projection: &Expression, group_expr: &Expression) -> bool {
425 unalias_expression(projection) == group_expr
426}
427
428fn unalias_expression(expr: &Expression) -> &Expression {
429 match expr {
430 Expression::Alias(alias) => &alias.this,
431 other => other,
432 }
433}
434
435fn rewrite_grouped_percentile_select_with_hidden_groups(
436 mut inner: Select,
437 original_expressions: Vec<Expression>,
438 rewritten_expressions: Vec<Expression>,
439 group_by: Vec<Expression>,
440) -> Result<Expression> {
441 let original_distinct = inner.distinct;
442
443 let mut used_column_names = original_expressions
444 .iter()
445 .filter_map(grouped_percentile_output_identifier)
446 .map(|identifier| identifier.name)
447 .collect::<Vec<_>>();
448 let projection_aliases = (0..rewritten_expressions.len())
449 .map(|index| {
450 Identifier::new(fresh_grouped_percentile_name(
451 &mut used_column_names,
452 &format!("_polyglot_projection_{index}"),
453 ))
454 })
455 .collect::<Vec<_>>();
456 let group_aliases = (0..group_by.len())
457 .map(|index| {
458 Identifier::new(fresh_grouped_percentile_name(
459 &mut used_column_names,
460 &format!("_polyglot_group_{index}"),
461 ))
462 })
463 .collect::<Vec<_>>();
464
465 let mut used_source_names = Vec::new();
466 if let Some(from) = &inner.from {
467 for source in &from.expressions {
468 collect_grouped_percentile_source_names(source, &mut used_source_names);
469 }
470 }
471 for join in &inner.joins {
472 collect_grouped_percentile_source_names(&join.this, &mut used_source_names);
473 }
474 let derived_alias = Identifier::new(fresh_grouped_percentile_name(
475 &mut used_source_names,
476 "_polyglot_grouped_percentile",
477 ));
478
479 let mut inner_expressions = rewritten_expressions
480 .into_iter()
481 .zip(&projection_aliases)
482 .map(|(expression, alias)| {
483 Expression::Alias(Box::new(Alias::new(
484 take_alias_expression(expression),
485 alias.clone(),
486 )))
487 })
488 .collect::<Vec<_>>();
489 inner_expressions.extend(group_by.iter().cloned().zip(&group_aliases).map(
490 |(expression, alias)| Expression::Alias(Box::new(Alias::new(expression, alias.clone()))),
491 ));
492
493 let outer_order_by = inner.order_by.take();
494 let outer_with = inner.with.take();
495 let outer_top = inner.top.take();
496 let outer_limit = inner.limit.take();
497 let outer_offset = inner.offset.take();
498 let outer_limit_by = inner.limit_by.take();
499 let outer_fetch = inner.fetch.take();
500 let outer_distribute_by = inner.distribute_by.take();
501 let outer_cluster_by = inner.cluster_by.take();
502 let outer_sort_by = inner.sort_by.take();
503 let outer_settings = inner.settings.take();
504 let outer_format = inner.format.take();
505 let outer_hint = inner.hint.take();
506 let outer_into = inner.into.take();
507 let outer_locks = std::mem::take(&mut inner.locks);
508 let outer_for_xml = std::mem::take(&mut inner.for_xml);
509 let outer_for_json = std::mem::take(&mut inner.for_json);
510 let outer_leading_comments = std::mem::take(&mut inner.leading_comments);
511 let outer_post_select_comments = std::mem::take(&mut inner.post_select_comments);
512 let outer_kind = inner.kind.take();
513 let outer_operation_modifiers = std::mem::take(&mut inner.operation_modifiers);
514 let outer_option = inner.option.take();
515 let outer_exclude = inner.exclude.take();
516
517 inner.expressions = inner_expressions;
518 inner.group_by = None;
519 inner.distinct = true;
520
521 let outer_expressions = original_expressions
522 .iter()
523 .zip(&projection_aliases)
524 .map(|(original, internal_alias)| {
525 let reference = grouped_percentile_derived_column(&derived_alias, internal_alias);
526 match original {
527 Expression::Alias(alias) => {
528 let mut outer_alias = alias.as_ref().clone();
529 outer_alias.this = reference;
530 Expression::Alias(Box::new(outer_alias))
531 }
532 _ => grouped_percentile_output_identifier(original)
533 .map_or(reference.clone(), |output_alias| {
534 Expression::Alias(Box::new(Alias::new(reference, output_alias)))
535 }),
536 }
537 })
538 .collect::<Vec<_>>();
539
540 let outer_order_by = outer_order_by
541 .map(|mut order_by| {
542 for ordered in &mut order_by.expressions {
543 ordered.this = rewrite_grouped_percentile_outer_reference(
544 std::mem::replace(
545 &mut ordered.this,
546 Expression::Null(crate::expressions::Null),
547 ),
548 &original_expressions,
549 &projection_aliases,
550 &group_by,
551 &group_aliases,
552 &derived_alias,
553 )?;
554 }
555 Ok(order_by)
556 })
557 .transpose()?;
558
559 let subquery = Subquery {
560 this: Expression::Select(Box::new(inner)),
561 alias: Some(derived_alias),
562 column_aliases: Vec::new(),
563 alias_explicit_as: true,
564 alias_keyword: None,
565 order_by: None,
566 limit: None,
567 offset: None,
568 distribute_by: None,
569 sort_by: None,
570 cluster_by: None,
571 lateral: false,
572 modifiers_inside: false,
573 trailing_comments: Vec::new(),
574 inferred_type: None,
575 };
576
577 let mut outer = Select::new();
578 outer.expressions = outer_expressions;
579 outer.from = Some(From {
580 expressions: vec![Expression::Subquery(Box::new(subquery))],
581 });
582 outer.distinct = original_distinct;
583 outer.with = outer_with;
584 outer.order_by = outer_order_by;
585 outer.top = outer_top;
586 outer.limit = outer_limit;
587 outer.offset = outer_offset;
588 outer.limit_by = outer_limit_by;
589 outer.fetch = outer_fetch;
590 outer.distribute_by = outer_distribute_by;
591 outer.cluster_by = outer_cluster_by;
592 outer.sort_by = outer_sort_by;
593 outer.settings = outer_settings;
594 outer.format = outer_format;
595 outer.hint = outer_hint;
596 outer.into = outer_into;
597 outer.locks = outer_locks;
598 outer.for_xml = outer_for_xml;
599 outer.for_json = outer_for_json;
600 outer.leading_comments = outer_leading_comments;
601 outer.post_select_comments = outer_post_select_comments;
602 outer.kind = outer_kind;
603 outer.operation_modifiers = outer_operation_modifiers;
604 outer.option = outer_option;
605 outer.exclude = outer_exclude;
606
607 Ok(Expression::Select(Box::new(outer)))
608}
609
610fn take_alias_expression(expression: Expression) -> Expression {
611 match expression {
612 Expression::Alias(alias) => alias.this,
613 other => other,
614 }
615}
616
617fn grouped_percentile_output_identifier(expression: &Expression) -> Option<Identifier> {
618 match expression {
619 Expression::Alias(alias) if !alias.alias.is_empty() => Some(alias.alias.clone()),
620 Expression::Column(column) => Some(column.name.clone()),
621 Expression::Identifier(identifier) => Some(identifier.clone()),
622 Expression::Function(function) => Some(if function.quoted {
623 Identifier::quoted(function.name.clone())
624 } else {
625 Identifier::new(function.name.to_ascii_lowercase())
626 }),
627 Expression::AggregateFunction(function) => {
628 Some(Identifier::new(function.name.to_ascii_lowercase()))
629 }
630 Expression::WithinGroup(within_group) => {
631 grouped_percentile_output_identifier(&within_group.this)
632 }
633 Expression::PercentileCont(_) => Some(Identifier::new("percentile_cont")),
634 Expression::PercentileDisc(_) => Some(Identifier::new("percentile_disc")),
635 _ => None,
636 }
637}
638
639fn fresh_grouped_percentile_name(used_names: &mut Vec<String>, base: &str) -> String {
640 let mut suffix = 1;
641 loop {
642 let candidate = if suffix == 1 {
643 base.to_string()
644 } else {
645 format!("{base}_{suffix}")
646 };
647 if !used_names
648 .iter()
649 .any(|name| name.eq_ignore_ascii_case(&candidate))
650 {
651 used_names.push(candidate.clone());
652 return candidate;
653 }
654 suffix += 1;
655 }
656}
657
658fn collect_grouped_percentile_source_names(expression: &Expression, names: &mut Vec<String>) {
659 match expression {
660 Expression::Alias(alias) if !alias.alias.is_empty() => names.push(alias.alias.name.clone()),
661 Expression::Subquery(subquery) => {
662 if let Some(alias) = &subquery.alias {
663 names.push(alias.name.clone());
664 }
665 }
666 Expression::Table(table) => {
667 names.push(table.alias.as_ref().unwrap_or(&table.name).name.clone())
668 }
669 _ => {}
670 }
671}
672
673fn grouped_percentile_derived_column(
674 derived_alias: &Identifier,
675 column_alias: &Identifier,
676) -> Expression {
677 Expression::qualified_column(derived_alias.name.clone(), column_alias.name.clone())
678}
679
680fn rewrite_grouped_percentile_outer_reference(
681 expression: Expression,
682 original_expressions: &[Expression],
683 projection_aliases: &[Identifier],
684 group_by: &[Expression],
685 group_aliases: &[Identifier],
686 derived_alias: &Identifier,
687) -> Result<Expression> {
688 transform_recursive(expression, &|node| {
689 if let Some((_, alias)) =
690 original_expressions
691 .iter()
692 .zip(projection_aliases)
693 .find(|(original, _)| {
694 unalias_expression(original) == &node
695 || grouped_percentile_output_identifier(original).is_some_and(
696 |identifier| expression_references_identifier(&node, &identifier),
697 )
698 })
699 {
700 return Ok(grouped_percentile_derived_column(derived_alias, alias));
701 }
702
703 if let Some((_, alias)) = group_by
704 .iter()
705 .zip(group_aliases)
706 .find(|(group_expr, _)| *group_expr == &node)
707 {
708 return Ok(grouped_percentile_derived_column(derived_alias, alias));
709 }
710
711 Ok(node)
712 })
713}
714
715fn expression_references_identifier(expression: &Expression, identifier: &Identifier) -> bool {
716 let referenced = match expression {
717 Expression::Column(column) if column.table.is_none() => Some(&column.name),
718 Expression::Identifier(referenced) => Some(referenced),
719 _ => None,
720 };
721
722 referenced.is_some_and(|referenced| {
723 if referenced.quoted || identifier.quoted {
724 referenced.name == identifier.name
725 } else {
726 referenced.name.eq_ignore_ascii_case(&identifier.name)
727 }
728 })
729}
730
731fn rewrite_grouped_percentile_projection(
732 expr: &Expression,
733 partition_by: &[Expression],
734) -> Option<Expression> {
735 match expr {
736 Expression::Alias(alias) => {
737 let rewritten = rewrite_grouped_percentile_expr(&alias.this, partition_by)?;
738 let mut alias = alias.as_ref().clone();
739 alias.this = rewritten;
740 Some(Expression::Alias(Box::new(alias)))
741 }
742 other => rewrite_grouped_percentile_expr(other, partition_by),
743 }
744}
745
746fn rewrite_grouped_percentile_expr(
747 expr: &Expression,
748 partition_by: &[Expression],
749) -> Option<Expression> {
750 let Expression::WithinGroup(within_group) = expr else {
751 return None;
752 };
753
754 if !is_percentile_ordered_set(&within_group.this) || within_group.order_by.len() != 1 {
755 return None;
756 }
757
758 let mut order_by = within_group.order_by.clone();
759 order_by[0].nulls_first = None;
763
764 Some(Expression::WindowFunction(Box::new(WindowFunction {
765 this: Expression::WithinGroup(Box::new(WithinGroup {
766 this: within_group.this.clone(),
767 order_by,
768 })),
769 over: Over {
770 window_name: None,
771 partition_by: partition_by.to_vec(),
772 order_by: Vec::new(),
773 frame: None,
774 alias: None,
775 },
776 keep: None,
777 inferred_type: None,
778 })))
779}
780
781fn is_percentile_ordered_set(expr: &Expression) -> bool {
782 match expr {
783 Expression::Function(function) => is_percentile_name(&function.name),
784 Expression::AggregateFunction(function) => is_percentile_name(&function.name),
785 Expression::PercentileCont(_) | Expression::PercentileDisc(_) => true,
786 _ => false,
787 }
788}
789
790fn is_percentile_name(name: &str) -> bool {
791 name.eq_ignore_ascii_case("PERCENTILE_CONT") || name.eq_ignore_ascii_case("PERCENTILE_DISC")
792}
793
794pub fn unnest_to_explode(expr: Expression) -> Result<Expression> {
798 match expr {
799 Expression::Unnest(unnest) => {
800 Ok(Expression::Explode(Box::new(UnaryFunc::new(unnest.this))))
801 }
802 _ => Ok(expr),
803 }
804}
805
806pub fn unnest_to_explode_select(expr: Expression) -> Result<Expression> {
816 transform_recursive(expr, &unnest_to_explode_select_inner)
817}
818
819fn make_udtf_expr(unnest: &UnnestFunc) -> Expression {
822 let has_multi_expr = !unnest.expressions.is_empty();
823 if has_multi_expr {
824 let mut all_args = vec![unnest.this.clone()];
826 all_args.extend(unnest.expressions.iter().cloned());
827 let arrays_zip =
828 Expression::Function(Box::new(Function::new("ARRAYS_ZIP".to_string(), all_args)));
829 Expression::Function(Box::new(Function::new(
830 "INLINE".to_string(),
831 vec![arrays_zip],
832 )))
833 } else {
834 Expression::Explode(Box::new(UnaryFunc::new(unnest.this.clone())))
836 }
837}
838
839fn unnest_to_explode_select_inner(expr: Expression) -> Result<Expression> {
840 let Expression::Select(mut select) = expr else {
841 return Ok(expr);
842 };
843
844 if let Some(ref mut from) = select.from {
846 if from.expressions.len() >= 1 {
847 let mut new_from_exprs = Vec::new();
848 let mut new_lateral_views = Vec::new();
849 let first_is_unnest = is_unnest_expr(&from.expressions[0]);
850
851 for (idx, from_item) in from.expressions.drain(..).enumerate() {
852 if idx == 0 && first_is_unnest {
853 let replaced = replace_from_unnest(from_item);
856 new_from_exprs.push(replaced);
857 } else if idx > 0 && is_unnest_expr(&from_item) {
858 let (alias_name, column_aliases, unnest_func) = extract_unnest_info(from_item);
860 let udtf = make_udtf_expr(&unnest_func);
861 new_lateral_views.push(LateralView {
862 this: udtf,
863 table_alias: alias_name,
864 column_aliases,
865 outer: false,
866 });
867 } else {
868 new_from_exprs.push(from_item);
869 }
870 }
871
872 from.expressions = new_from_exprs;
873 select.lateral_views.extend(new_lateral_views);
875 }
876 }
877
878 let mut remaining_joins = Vec::new();
880 for join in select.joins.drain(..) {
881 if matches!(join.kind, JoinKind::Cross | JoinKind::Inner) {
882 let (is_unnest, is_lateral) = check_join_unnest(&join.this);
883 if is_unnest {
884 let (lateral_alias, lateral_col_aliases, join_expr) = if is_lateral {
886 if let Expression::Lateral(lat) = join.this {
887 let alias = lat.alias.map(|s| Identifier::new(&s));
889 let col_aliases: Vec<Identifier> = lat
890 .column_aliases
891 .iter()
892 .map(|s| Identifier::new(s))
893 .collect();
894 (alias, col_aliases, *lat.this)
895 } else {
896 (None, Vec::new(), join.this)
897 }
898 } else {
899 (None, Vec::new(), join.this)
900 };
901
902 let (alias_name, column_aliases, unnest_func) = extract_unnest_info(join_expr);
903
904 let final_alias = lateral_alias.or(alias_name);
906 let final_col_aliases = if !lateral_col_aliases.is_empty() {
907 lateral_col_aliases
908 } else {
909 column_aliases
910 };
911
912 let table_alias = final_alias.or_else(|| Some(Identifier::new("unnest")));
914 let col_aliases = if final_col_aliases.is_empty() {
915 vec![Identifier::new("unnest")]
916 } else {
917 final_col_aliases
918 };
919
920 let udtf = make_udtf_expr(&unnest_func);
921 select.lateral_views.push(LateralView {
922 this: udtf,
923 table_alias,
924 column_aliases: col_aliases,
925 outer: false,
926 });
927 } else {
928 remaining_joins.push(join);
929 }
930 } else {
931 remaining_joins.push(join);
932 }
933 }
934 select.joins = remaining_joins;
935
936 Ok(Expression::Select(select))
937}
938
939fn is_unnest_expr(expr: &Expression) -> bool {
941 match expr {
942 Expression::Unnest(_) => true,
943 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
944 _ => false,
945 }
946}
947
948fn check_join_unnest(expr: &Expression) -> (bool, bool) {
950 match expr {
951 Expression::Unnest(_) => (true, false),
952 Expression::Alias(a) => {
953 if matches!(a.this, Expression::Unnest(_)) {
954 (true, false)
955 } else {
956 (false, false)
957 }
958 }
959 Expression::Lateral(lat) => match &*lat.this {
960 Expression::Unnest(_) => (true, true),
961 Expression::Alias(a) => {
962 if matches!(a.this, Expression::Unnest(_)) {
963 (true, true)
964 } else {
965 (false, true)
966 }
967 }
968 _ => (false, true),
969 },
970 _ => (false, false),
971 }
972}
973
974fn replace_from_unnest(from_item: Expression) -> Expression {
976 match from_item {
977 Expression::Alias(mut a) => {
978 if let Expression::Unnest(unnest) = a.this {
979 a.this = make_udtf_expr(&unnest);
980 }
981 Expression::Alias(a)
982 }
983 Expression::Unnest(unnest) => make_udtf_expr(&unnest),
984 other => other,
985 }
986}
987
988fn extract_unnest_info(expr: Expression) -> (Option<Identifier>, Vec<Identifier>, UnnestFunc) {
990 match expr {
991 Expression::Alias(a) => {
992 if let Expression::Unnest(unnest) = a.this {
993 (Some(a.alias), a.column_aliases, *unnest)
994 } else {
995 (
997 Some(a.alias),
998 a.column_aliases,
999 UnnestFunc {
1000 this: a.this,
1001 expressions: Vec::new(),
1002 with_ordinality: false,
1003 alias: None,
1004 offset_alias: None,
1005 inferred_type: None,
1006 },
1007 )
1008 }
1009 }
1010 Expression::Unnest(unnest) => {
1011 let alias = unnest.alias.clone();
1012 (alias, Vec::new(), *unnest)
1013 }
1014 _ => (
1015 None,
1016 Vec::new(),
1017 UnnestFunc {
1018 this: expr,
1019 expressions: Vec::new(),
1020 with_ordinality: false,
1021 alias: None,
1022 offset_alias: None,
1023 inferred_type: None,
1024 },
1025 ),
1026 }
1027}
1028
1029pub fn explode_to_unnest(expr: Expression) -> Result<Expression> {
1031 match expr {
1032 Expression::Explode(explode) => Ok(Expression::Unnest(Box::new(UnnestFunc {
1033 this: explode.this,
1034 expressions: Vec::new(),
1035 with_ordinality: false,
1036 alias: None,
1037 offset_alias: None,
1038 inferred_type: None,
1039 }))),
1040 _ => Ok(expr),
1041 }
1042}
1043
1044pub fn replace_bool_with_int(expr: Expression) -> Result<Expression> {
1048 match expr {
1049 Expression::Boolean(b) => {
1050 let value = if b.value { "1" } else { "0" };
1051 Ok(Expression::Literal(Box::new(Literal::Number(
1052 value.to_string(),
1053 ))))
1054 }
1055 _ => Ok(expr),
1056 }
1057}
1058
1059pub fn replace_int_with_bool(expr: Expression) -> Result<Expression> {
1063 match expr {
1064 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(n) if n == "1" || n == "0") =>
1065 {
1066 let Literal::Number(n) = lit.as_ref() else {
1067 unreachable!()
1068 };
1069 Ok(Expression::Boolean(BooleanLiteral { value: n == "1" }))
1070 }
1071 _ => Ok(expr),
1072 }
1073}
1074
1075pub fn remove_precision_parameterized_types(expr: Expression) -> Result<Expression> {
1080 Ok(strip_type_params_recursive(expr))
1081}
1082
1083fn strip_type_params_recursive(expr: Expression) -> Expression {
1085 match expr {
1086 Expression::Cast(mut cast) => {
1088 cast.to = strip_data_type_params(cast.to);
1089 cast.this = strip_type_params_recursive(cast.this);
1091 Expression::Cast(cast)
1092 }
1093 Expression::TryCast(mut try_cast) => {
1095 try_cast.to = strip_data_type_params(try_cast.to);
1096 try_cast.this = strip_type_params_recursive(try_cast.this);
1097 Expression::TryCast(try_cast)
1098 }
1099 Expression::SafeCast(mut safe_cast) => {
1101 safe_cast.to = strip_data_type_params(safe_cast.to);
1102 safe_cast.this = strip_type_params_recursive(safe_cast.this);
1103 Expression::SafeCast(safe_cast)
1104 }
1105 _ => expr,
1108 }
1109}
1110
1111fn strip_data_type_params(dt: DataType) -> DataType {
1113 match dt {
1114 DataType::Decimal { .. } => DataType::Decimal {
1116 precision: None,
1117 scale: None,
1118 },
1119 DataType::TinyInt { .. } => DataType::TinyInt { length: None },
1120 DataType::SmallInt { .. } => DataType::SmallInt { length: None },
1121 DataType::Int { .. } => DataType::Int {
1122 length: None,
1123 integer_spelling: false,
1124 },
1125 DataType::BigInt { .. } => DataType::BigInt { length: None },
1126
1127 DataType::Char { .. } => DataType::Char { length: None },
1129 DataType::VarChar { .. } => DataType::VarChar {
1130 length: None,
1131 parenthesized_length: false,
1132 },
1133
1134 DataType::Binary { .. } => DataType::Binary { length: None },
1136 DataType::VarBinary { .. } => DataType::VarBinary { length: None },
1137
1138 DataType::Bit { .. } => DataType::Bit { length: None },
1140 DataType::VarBit { .. } => DataType::VarBit { length: None },
1141
1142 DataType::Time { .. } => DataType::Time {
1144 precision: None,
1145 timezone: false,
1146 },
1147 DataType::Timestamp { timezone, .. } => DataType::Timestamp {
1148 precision: None,
1149 timezone,
1150 },
1151
1152 DataType::Array {
1154 element_type,
1155 dimension,
1156 } => DataType::Array {
1157 element_type: Box::new(strip_data_type_params(*element_type)),
1158 dimension,
1159 },
1160
1161 DataType::Map {
1163 key_type,
1164 value_type,
1165 } => DataType::Map {
1166 key_type: Box::new(strip_data_type_params(*key_type)),
1167 value_type: Box::new(strip_data_type_params(*value_type)),
1168 },
1169
1170 DataType::Struct { fields, nested } => DataType::Struct {
1172 fields: fields
1173 .into_iter()
1174 .map(|f| {
1175 StructField::with_options(
1176 f.name,
1177 strip_data_type_params(f.data_type),
1178 f.options,
1179 )
1180 })
1181 .collect(),
1182 nested,
1183 },
1184
1185 DataType::Vector { element_type, .. } => DataType::Vector {
1187 element_type: element_type.map(|et| Box::new(strip_data_type_params(*et))),
1188 dimension: None,
1189 },
1190
1191 DataType::Object { fields, modifier } => DataType::Object {
1193 fields: fields
1194 .into_iter()
1195 .map(|(name, ty, not_null)| (name, strip_data_type_params(ty), not_null))
1196 .collect(),
1197 modifier,
1198 },
1199
1200 other => other,
1202 }
1203}
1204
1205pub fn eliminate_qualify(expr: Expression) -> Result<Expression> {
1220 match expr {
1221 Expression::Select(mut select) => {
1222 if let Some(qualify) = select.qualify.take() {
1223 let qualify_filter = qualify.this;
1230 let window_alias_name = "_w".to_string();
1231 let window_alias_ident = Identifier::new(window_alias_name.clone());
1232
1233 let (window_expr, outer_where) =
1236 extract_window_from_condition(qualify_filter.clone(), &window_alias_ident);
1237
1238 if let Some(win_expr) = window_expr {
1239 let window_alias_expr =
1241 Expression::Alias(Box::new(crate::expressions::Alias {
1242 this: win_expr,
1243 alias: window_alias_ident.clone(),
1244 column_aliases: vec![],
1245 alias_explicit_as: false,
1246 alias_keyword: None,
1247 pre_alias_comments: vec![],
1248 trailing_comments: vec![],
1249 inferred_type: None,
1250 }));
1251
1252 let outer_exprs: Vec<Expression> = select
1256 .expressions
1257 .iter()
1258 .map(|expr| {
1259 if let Expression::Alias(a) = expr {
1260 Expression::Column(Box::new(crate::expressions::Column {
1262 name: a.alias.clone(),
1263 table: None,
1264 join_mark: false,
1265 trailing_comments: vec![],
1266 span: None,
1267 inferred_type: None,
1268 }))
1269 } else {
1270 expr.clone()
1271 }
1272 })
1273 .collect();
1274 select.expressions.push(window_alias_expr);
1275
1276 let inner_select = Expression::Select(select);
1278 let subquery = Subquery {
1279 this: inner_select,
1280 alias: Some(Identifier::new("_t".to_string())),
1281 column_aliases: vec![],
1282 alias_explicit_as: false,
1283 alias_keyword: None,
1284 order_by: None,
1285 limit: None,
1286 offset: None,
1287 distribute_by: None,
1288 sort_by: None,
1289 cluster_by: None,
1290 lateral: false,
1291 modifiers_inside: false,
1292 trailing_comments: vec![],
1293 inferred_type: None,
1294 };
1295
1296 let outer_select = Select {
1298 vertica: None,
1299 expressions: outer_exprs,
1300 from: Some(From {
1301 expressions: vec![Expression::Subquery(Box::new(subquery))],
1302 }),
1303 where_clause: Some(Where { this: outer_where }),
1304 ..Select::new()
1305 };
1306
1307 return Ok(Expression::Select(Box::new(outer_select)));
1308 } else {
1309 let qualify_alias = Expression::Alias(Box::new(crate::expressions::Alias {
1311 this: qualify_filter.clone(),
1312 alias: window_alias_ident.clone(),
1313 column_aliases: vec![],
1314 alias_explicit_as: false,
1315 alias_keyword: None,
1316 pre_alias_comments: vec![],
1317 trailing_comments: vec![],
1318 inferred_type: None,
1319 }));
1320
1321 let original_exprs = select.expressions.clone();
1322 select.expressions.push(qualify_alias);
1323
1324 let inner_select = Expression::Select(select);
1325 let subquery = Subquery {
1326 this: inner_select,
1327 alias: Some(Identifier::new("_t".to_string())),
1328 column_aliases: vec![],
1329 alias_explicit_as: false,
1330 alias_keyword: None,
1331 order_by: None,
1332 limit: None,
1333 offset: None,
1334 distribute_by: None,
1335 sort_by: None,
1336 cluster_by: None,
1337 lateral: false,
1338 modifiers_inside: false,
1339 trailing_comments: vec![],
1340 inferred_type: None,
1341 };
1342
1343 let outer_select = Select {
1344 vertica: None,
1345 expressions: original_exprs,
1346 from: Some(From {
1347 expressions: vec![Expression::Subquery(Box::new(subquery))],
1348 }),
1349 where_clause: Some(Where {
1350 this: Expression::Column(Box::new(crate::expressions::Column {
1351 name: window_alias_ident,
1352 table: None,
1353 join_mark: false,
1354 trailing_comments: vec![],
1355 span: None,
1356 inferred_type: None,
1357 })),
1358 }),
1359 ..Select::new()
1360 };
1361
1362 return Ok(Expression::Select(Box::new(outer_select)));
1363 }
1364 }
1365 Ok(Expression::Select(select))
1366 }
1367 other => Ok(other),
1368 }
1369}
1370
1371fn extract_window_from_condition(
1375 condition: Expression,
1376 alias: &Identifier,
1377) -> (Option<Expression>, Expression) {
1378 let alias_col = Expression::Column(Box::new(crate::expressions::Column {
1379 name: alias.clone(),
1380 table: None,
1381 join_mark: false,
1382 trailing_comments: vec![],
1383 span: None,
1384 inferred_type: None,
1385 }));
1386
1387 match condition {
1389 Expression::Eq(ref op) => {
1391 if is_window_expr(&op.left) {
1392 (
1393 Some(op.left.clone()),
1394 Expression::Eq(Box::new(BinaryOp {
1395 left: alias_col,
1396 right: op.right.clone(),
1397 ..(**op).clone()
1398 })),
1399 )
1400 } else if is_window_expr(&op.right) {
1401 (
1402 Some(op.right.clone()),
1403 Expression::Eq(Box::new(BinaryOp {
1404 left: op.left.clone(),
1405 right: alias_col,
1406 ..(**op).clone()
1407 })),
1408 )
1409 } else {
1410 (None, condition)
1411 }
1412 }
1413 Expression::Neq(ref op) => {
1414 if is_window_expr(&op.left) {
1415 (
1416 Some(op.left.clone()),
1417 Expression::Neq(Box::new(BinaryOp {
1418 left: alias_col,
1419 right: op.right.clone(),
1420 ..(**op).clone()
1421 })),
1422 )
1423 } else if is_window_expr(&op.right) {
1424 (
1425 Some(op.right.clone()),
1426 Expression::Neq(Box::new(BinaryOp {
1427 left: op.left.clone(),
1428 right: alias_col,
1429 ..(**op).clone()
1430 })),
1431 )
1432 } else {
1433 (None, condition)
1434 }
1435 }
1436 Expression::Lt(ref op) => {
1437 if is_window_expr(&op.left) {
1438 (
1439 Some(op.left.clone()),
1440 Expression::Lt(Box::new(BinaryOp {
1441 left: alias_col,
1442 right: op.right.clone(),
1443 ..(**op).clone()
1444 })),
1445 )
1446 } else if is_window_expr(&op.right) {
1447 (
1448 Some(op.right.clone()),
1449 Expression::Lt(Box::new(BinaryOp {
1450 left: op.left.clone(),
1451 right: alias_col,
1452 ..(**op).clone()
1453 })),
1454 )
1455 } else {
1456 (None, condition)
1457 }
1458 }
1459 Expression::Lte(ref op) => {
1460 if is_window_expr(&op.left) {
1461 (
1462 Some(op.left.clone()),
1463 Expression::Lte(Box::new(BinaryOp {
1464 left: alias_col,
1465 right: op.right.clone(),
1466 ..(**op).clone()
1467 })),
1468 )
1469 } else if is_window_expr(&op.right) {
1470 (
1471 Some(op.right.clone()),
1472 Expression::Lte(Box::new(BinaryOp {
1473 left: op.left.clone(),
1474 right: alias_col,
1475 ..(**op).clone()
1476 })),
1477 )
1478 } else {
1479 (None, condition)
1480 }
1481 }
1482 Expression::Gt(ref op) => {
1483 if is_window_expr(&op.left) {
1484 (
1485 Some(op.left.clone()),
1486 Expression::Gt(Box::new(BinaryOp {
1487 left: alias_col,
1488 right: op.right.clone(),
1489 ..(**op).clone()
1490 })),
1491 )
1492 } else if is_window_expr(&op.right) {
1493 (
1494 Some(op.right.clone()),
1495 Expression::Gt(Box::new(BinaryOp {
1496 left: op.left.clone(),
1497 right: alias_col,
1498 ..(**op).clone()
1499 })),
1500 )
1501 } else {
1502 (None, condition)
1503 }
1504 }
1505 Expression::Gte(ref op) => {
1506 if is_window_expr(&op.left) {
1507 (
1508 Some(op.left.clone()),
1509 Expression::Gte(Box::new(BinaryOp {
1510 left: alias_col,
1511 right: op.right.clone(),
1512 ..(**op).clone()
1513 })),
1514 )
1515 } else if is_window_expr(&op.right) {
1516 (
1517 Some(op.right.clone()),
1518 Expression::Gte(Box::new(BinaryOp {
1519 left: op.left.clone(),
1520 right: alias_col,
1521 ..(**op).clone()
1522 })),
1523 )
1524 } else {
1525 (None, condition)
1526 }
1527 }
1528 _ if is_window_expr(&condition) => (Some(condition), alias_col),
1530 _ => (None, condition),
1532 }
1533}
1534
1535fn is_window_expr(expr: &Expression) -> bool {
1537 matches!(expr, Expression::Window(_) | Expression::WindowFunction(_))
1538}
1539
1540pub fn eliminate_distinct_on(expr: Expression) -> Result<Expression> {
1559 eliminate_distinct_on_for_dialect(expr, None, None)
1560}
1561
1562pub fn strip_cte_materialization(expr: Expression) -> Result<Expression> {
1565 transform_recursive(expr, &strip_cte_materialization_single)
1566}
1567
1568fn strip_cte_materialization_single(expr: Expression) -> Result<Expression> {
1569 Ok(match expr {
1570 Expression::Select(mut select) => {
1571 strip_with_cte_materialization(&mut select.with);
1572 Expression::Select(select)
1573 }
1574 Expression::Union(mut union) => {
1575 strip_with_cte_materialization(&mut union.with);
1576 Expression::Union(union)
1577 }
1578 Expression::Intersect(mut intersect) => {
1579 strip_with_cte_materialization(&mut intersect.with);
1580 Expression::Intersect(intersect)
1581 }
1582 Expression::Except(mut except) => {
1583 strip_with_cte_materialization(&mut except.with);
1584 Expression::Except(except)
1585 }
1586 Expression::Pivot(mut pivot) => {
1587 strip_with_cte_materialization(&mut pivot.with);
1588 Expression::Pivot(pivot)
1589 }
1590 Expression::Insert(mut insert) => {
1591 strip_with_cte_materialization(&mut insert.with);
1592 Expression::Insert(insert)
1593 }
1594 Expression::Update(mut update) => {
1595 strip_with_cte_materialization(&mut update.with);
1596 Expression::Update(update)
1597 }
1598 Expression::Delete(mut delete) => {
1599 strip_with_cte_materialization(&mut delete.with);
1600 Expression::Delete(delete)
1601 }
1602 Expression::CreateTable(mut create_table) => {
1603 strip_with_cte_materialization(&mut create_table.with_cte);
1604 Expression::CreateTable(create_table)
1605 }
1606 Expression::With(mut with) => {
1607 strip_cte_materialization_in_with(&mut with);
1608 Expression::With(with)
1609 }
1610 Expression::Cte(mut cte) => {
1611 cte.materialized = None;
1612 Expression::Cte(cte)
1613 }
1614 _ => expr,
1615 })
1616}
1617
1618fn strip_with_cte_materialization(with: &mut Option<With>) {
1619 if let Some(with) = with {
1620 strip_cte_materialization_in_with(with);
1621 }
1622}
1623
1624fn strip_cte_materialization_in_with(with: &mut With) {
1625 for cte in &mut with.ctes {
1626 cte.materialized = None;
1627 }
1628}
1629
1630#[derive(Clone, Copy)]
1631enum DistinctOnNullsMode {
1632 None,
1633 NullsFirst,
1634 CaseExpr,
1635}
1636
1637pub fn eliminate_distinct_on_for_dialect(
1642 expr: Expression,
1643 target: Option<DialectType>,
1644 source: Option<DialectType>,
1645) -> Result<Expression> {
1646 if matches!(
1648 target,
1649 Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB)
1650 ) {
1651 return Ok(expr);
1652 }
1653
1654 let nulls_mode = match target {
1659 Some(DialectType::MySQL)
1660 | Some(DialectType::SingleStore)
1661 | Some(DialectType::TSQL)
1662 | Some(DialectType::Fabric) => DistinctOnNullsMode::CaseExpr,
1663 Some(DialectType::Oracle) | Some(DialectType::Redshift) | Some(DialectType::Snowflake) => {
1664 DistinctOnNullsMode::None
1665 }
1666 Some(DialectType::StarRocks) => {
1667 if matches!(source, Some(DialectType::Redshift)) {
1668 DistinctOnNullsMode::CaseExpr
1669 } else {
1670 DistinctOnNullsMode::None
1671 }
1672 }
1673 _ => DistinctOnNullsMode::NullsFirst,
1675 };
1676
1677 transform_recursive(expr, &|expr| {
1678 eliminate_distinct_on_select(expr, nulls_mode, target)
1679 })
1680}
1681
1682fn resolve_positional_order_by(
1686 exprs: Vec<crate::expressions::Ordered>,
1687 select_exprs: &[Expression],
1688 target: Option<DialectType>,
1689) -> Result<Vec<crate::expressions::Ordered>> {
1690 exprs
1691 .into_iter()
1692 .map(|mut ord| {
1693 if let Expression::Literal(lit) = &ord.this {
1694 if let Literal::Number(n) = lit.as_ref() {
1695 if let Ok(idx) = n.parse::<usize>() {
1696 if idx >= 1 && idx <= select_exprs.len() {
1697 ord.this = match select_exprs[idx - 1].clone() {
1698 Expression::Alias(alias) => alias.this,
1699 other => other,
1700 };
1701 }
1702 }
1703 }
1704 }
1705 if crate::dialects::contains_in_projection(&ord.this, |e| matches!(e, Expression::WindowFunction(_))) {
1706 return Err(Error::unsupported(
1707 "DISTINCT ON ordering by a window expression requires an additional query layer",
1708 format!("{target:?}"),
1709 ));
1710 }
1711 Ok(ord)
1712 })
1713 .collect()
1714}
1715
1716fn eliminate_distinct_on_select(
1717 expr: Expression,
1718 nulls_mode: DistinctOnNullsMode,
1719 target: Option<DialectType>,
1720) -> Result<Expression> {
1721 use crate::expressions::Case;
1722
1723 match expr {
1724 Expression::Select(mut select) => {
1725 if let Some(distinct_cols) = select.distinct_on.take() {
1726 if !distinct_cols.is_empty() {
1727 let row_number_alias = Identifier::new("_row_number".to_string());
1729
1730 let order_exprs = if let Some(ref order_by) = select.order_by {
1732 let mut exprs = resolve_positional_order_by(
1738 order_by.expressions.clone(),
1739 &select.expressions,
1740 target,
1741 )?;
1742 match nulls_mode {
1744 DistinctOnNullsMode::NullsFirst => {
1745 for ord in &mut exprs {
1746 if ord.desc && ord.nulls_first.is_none() {
1747 ord.nulls_first = Some(true);
1748 }
1749 }
1750 }
1751 DistinctOnNullsMode::CaseExpr => {
1752 let mut new_exprs = Vec::new();
1755 for ord in &exprs {
1756 if ord.desc && ord.nulls_first.is_none() {
1757 let null_check = Expression::Case(Box::new(Case {
1759 operand: None,
1760 whens: vec![(
1761 Expression::IsNull(Box::new(
1762 crate::expressions::IsNull {
1763 this: ord.this.clone(),
1764 not: false,
1765 postfix_form: false,
1766 },
1767 )),
1768 Expression::Literal(Box::new(Literal::Number(
1769 "1".to_string(),
1770 ))),
1771 )],
1772 else_: Some(Expression::Literal(Box::new(
1773 Literal::Number("0".to_string()),
1774 ))),
1775 comments: Vec::new(),
1776 inferred_type: None,
1777 }));
1778 new_exprs.push(crate::expressions::Ordered {
1779 nulls_auto: false,
1780 this: null_check,
1781 desc: true,
1782 nulls_first: None,
1783 explicit_asc: false,
1784 with_fill: None,
1785 });
1786 }
1787 new_exprs.push(ord.clone());
1788 }
1789 exprs = new_exprs;
1790 }
1791 DistinctOnNullsMode::None => {}
1792 }
1793 exprs
1794 } else {
1795 distinct_cols
1796 .iter()
1797 .map(|e| crate::expressions::Ordered {
1798 nulls_auto: false,
1799 this: e.clone(),
1800 desc: false,
1801 nulls_first: None,
1802 explicit_asc: false,
1803 with_fill: None,
1804 })
1805 .collect()
1806 };
1807
1808 let row_number_func =
1810 Expression::WindowFunction(Box::new(crate::expressions::WindowFunction {
1811 this: Expression::RowNumber(crate::expressions::RowNumber),
1812 over: Over {
1813 partition_by: distinct_cols,
1814 order_by: order_exprs,
1815 frame: None,
1816 window_name: None,
1817 alias: None,
1818 },
1819 keep: None,
1820 inferred_type: None,
1821 }));
1822
1823 let mut inner_aliased_exprs = Vec::new();
1827 let mut outer_select_exprs = Vec::new();
1828 for orig_expr in &select.expressions {
1829 match orig_expr {
1830 Expression::Alias(alias) => {
1831 inner_aliased_exprs.push(orig_expr.clone());
1833 outer_select_exprs.push(Expression::Column(Box::new(
1834 crate::expressions::Column {
1835 name: alias.alias.clone(),
1836 table: None,
1837 join_mark: false,
1838 trailing_comments: vec![],
1839 span: None,
1840 inferred_type: None,
1841 },
1842 )));
1843 }
1844 Expression::Column(col) => {
1845 inner_aliased_exprs.push(Expression::Alias(Box::new(
1847 crate::expressions::Alias {
1848 this: orig_expr.clone(),
1849 alias: col.name.clone(),
1850 column_aliases: vec![],
1851 alias_explicit_as: false,
1852 alias_keyword: None,
1853 pre_alias_comments: vec![],
1854 trailing_comments: vec![],
1855 inferred_type: None,
1856 },
1857 )));
1858 outer_select_exprs.push(Expression::Column(Box::new(
1859 crate::expressions::Column {
1860 name: col.name.clone(),
1861 table: None,
1862 join_mark: false,
1863 trailing_comments: vec![],
1864 span: None,
1865 inferred_type: None,
1866 },
1867 )));
1868 }
1869 _ => {
1870 inner_aliased_exprs.push(orig_expr.clone());
1872 outer_select_exprs.push(orig_expr.clone());
1873 }
1874 }
1875 }
1876
1877 let row_number_alias_expr =
1879 Expression::Alias(Box::new(crate::expressions::Alias {
1880 this: row_number_func,
1881 alias: row_number_alias.clone(),
1882 column_aliases: vec![],
1883 alias_explicit_as: false,
1884 alias_keyword: None,
1885 pre_alias_comments: vec![],
1886 trailing_comments: vec![],
1887 inferred_type: None,
1888 }));
1889 inner_aliased_exprs.push(row_number_alias_expr);
1890
1891 select.expressions = inner_aliased_exprs;
1893
1894 let _inner_order_by = select.order_by.take();
1896
1897 select.distinct = false;
1899
1900 let inner_select = Expression::Select(select);
1902 let subquery = Subquery {
1903 this: inner_select,
1904 alias: Some(Identifier::new("_t".to_string())),
1905 column_aliases: vec![],
1906 alias_explicit_as: false,
1907 alias_keyword: None,
1908 order_by: None,
1909 limit: None,
1910 offset: None,
1911 distribute_by: None,
1912 sort_by: None,
1913 cluster_by: None,
1914 lateral: false,
1915 modifiers_inside: false,
1916 trailing_comments: vec![],
1917 inferred_type: None,
1918 };
1919
1920 let outer_select = Select {
1923 vertica: None,
1924 expressions: outer_select_exprs,
1925 from: Some(From {
1926 expressions: vec![Expression::Subquery(Box::new(subquery))],
1927 }),
1928 where_clause: Some(Where {
1929 this: Expression::Eq(Box::new(BinaryOp {
1930 left: Expression::Column(Box::new(crate::expressions::Column {
1931 name: row_number_alias,
1932 table: None,
1933 join_mark: false,
1934 trailing_comments: vec![],
1935 span: None,
1936 inferred_type: None,
1937 })),
1938 right: Expression::Literal(Box::new(Literal::Number(
1939 "1".to_string(),
1940 ))),
1941 left_comments: vec![],
1942 operator_comments: vec![],
1943 trailing_comments: vec![],
1944 inferred_type: None,
1945 })),
1946 }),
1947 ..Select::new()
1948 };
1949
1950 return Ok(Expression::Select(Box::new(outer_select)));
1951 }
1952 }
1953 Ok(Expression::Select(select))
1954 }
1955 other => Ok(other),
1956 }
1957}
1958
1959pub fn eliminate_semi_and_anti_joins(expr: Expression) -> Result<Expression> {
1967 match expr {
1968 Expression::Select(mut select) => {
1969 let mut new_joins = Vec::new();
1970 let mut extra_where_conditions = Vec::new();
1971
1972 for join in select.joins.drain(..) {
1973 match join.kind {
1974 JoinKind::Semi | JoinKind::LeftSemi => {
1975 if let Some(on_condition) = join.on {
1976 let subquery_select = Select {
1978 vertica: None,
1979 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1980 "1".to_string(),
1981 )))],
1982 from: Some(From {
1983 expressions: vec![join.this],
1984 }),
1985 where_clause: Some(Where { this: on_condition }),
1986 ..Select::new()
1987 };
1988
1989 let exists = Expression::Exists(Box::new(Exists {
1990 this: Expression::Subquery(Box::new(Subquery {
1991 this: Expression::Select(Box::new(subquery_select)),
1992 alias: None,
1993 column_aliases: vec![],
1994 alias_explicit_as: false,
1995 alias_keyword: None,
1996 order_by: None,
1997 limit: None,
1998 offset: None,
1999 distribute_by: None,
2000 sort_by: None,
2001 cluster_by: None,
2002 lateral: false,
2003 modifiers_inside: false,
2004 trailing_comments: vec![],
2005 inferred_type: None,
2006 })),
2007 not: false,
2008 }));
2009
2010 extra_where_conditions.push(exists);
2011 }
2012 }
2013 JoinKind::Anti | JoinKind::LeftAnti => {
2014 if let Some(on_condition) = join.on {
2015 let subquery_select = Select {
2017 vertica: None,
2018 expressions: vec![Expression::Literal(Box::new(Literal::Number(
2019 "1".to_string(),
2020 )))],
2021 from: Some(From {
2022 expressions: vec![join.this],
2023 }),
2024 where_clause: Some(Where { this: on_condition }),
2025 ..Select::new()
2026 };
2027
2028 let not_exists = Expression::Exists(Box::new(Exists {
2030 this: Expression::Subquery(Box::new(Subquery {
2031 this: Expression::Select(Box::new(subquery_select)),
2032 alias: None,
2033 column_aliases: vec![],
2034 alias_explicit_as: false,
2035 alias_keyword: None,
2036 order_by: None,
2037 limit: None,
2038 offset: None,
2039 distribute_by: None,
2040 sort_by: None,
2041 cluster_by: None,
2042 lateral: false,
2043 modifiers_inside: false,
2044 trailing_comments: vec![],
2045 inferred_type: None,
2046 })),
2047 not: true,
2048 }));
2049
2050 extra_where_conditions.push(not_exists);
2051 }
2052 }
2053 _ => {
2054 new_joins.push(join);
2056 }
2057 }
2058 }
2059
2060 select.joins = new_joins;
2061
2062 if !extra_where_conditions.is_empty() {
2064 let combined = extra_where_conditions
2065 .into_iter()
2066 .reduce(|acc, cond| {
2067 Expression::And(Box::new(BinaryOp {
2068 left: acc,
2069 right: cond,
2070 left_comments: vec![],
2071 operator_comments: vec![],
2072 trailing_comments: vec![],
2073 inferred_type: None,
2074 }))
2075 })
2076 .unwrap();
2077
2078 select.where_clause = match select.where_clause {
2079 Some(Where { this: existing }) => Some(Where {
2080 this: Expression::And(Box::new(BinaryOp {
2081 left: existing,
2082 right: combined,
2083 left_comments: vec![],
2084 operator_comments: vec![],
2085 trailing_comments: vec![],
2086 inferred_type: None,
2087 })),
2088 }),
2089 None => Some(Where { this: combined }),
2090 };
2091 }
2092
2093 Ok(Expression::Select(select))
2094 }
2095 other => Ok(other),
2096 }
2097}
2098
2099pub fn eliminate_full_outer_join(expr: Expression) -> Result<Expression> {
2117 match expr {
2118 Expression::Select(mut select) => {
2119 let full_outer_join_idx = select.joins.iter().position(|j| j.kind == JoinKind::Full);
2121
2122 if let Some(idx) = full_outer_join_idx {
2123 let full_join_count = select
2125 .joins
2126 .iter()
2127 .filter(|j| j.kind == JoinKind::Full)
2128 .count();
2129 if full_join_count != 1 {
2130 return Ok(Expression::Select(select));
2131 }
2132
2133 let mut right_select = select.clone();
2135
2136 let full_join = &select.joins[idx];
2138 let join_condition = full_join.on.clone();
2139
2140 select.joins[idx].kind = JoinKind::Left;
2142
2143 right_select.joins[idx].kind = JoinKind::Right;
2145
2146 if let (Some(ref from), Some(ref join_cond)) = (&select.from, &join_condition) {
2148 if !from.expressions.is_empty() {
2149 let anti_subquery = Expression::Select(Box::new(Select {
2150 vertica: None,
2151 expressions: vec![Expression::Literal(Box::new(Literal::Number(
2152 "1".to_string(),
2153 )))],
2154 from: Some(from.clone()),
2155 where_clause: Some(Where {
2156 this: join_cond.clone(),
2157 }),
2158 ..Select::new()
2159 }));
2160
2161 let not_exists = Expression::Not(Box::new(crate::expressions::UnaryOp {
2162 inferred_type: None,
2163 this: Expression::Exists(Box::new(Exists {
2164 this: Expression::Subquery(Box::new(Subquery {
2165 this: anti_subquery,
2166 alias: None,
2167 column_aliases: vec![],
2168 alias_explicit_as: false,
2169 alias_keyword: None,
2170 order_by: None,
2171 limit: None,
2172 offset: None,
2173 distribute_by: None,
2174 sort_by: None,
2175 cluster_by: None,
2176 lateral: false,
2177 modifiers_inside: false,
2178 trailing_comments: vec![],
2179 inferred_type: None,
2180 })),
2181 not: false,
2182 })),
2183 }));
2184
2185 right_select.where_clause = Some(Where {
2187 this: match right_select.where_clause {
2188 Some(w) => Expression::And(Box::new(BinaryOp {
2189 left: w.this,
2190 right: not_exists,
2191 left_comments: vec![],
2192 operator_comments: vec![],
2193 trailing_comments: vec![],
2194 inferred_type: None,
2195 })),
2196 None => not_exists,
2197 },
2198 });
2199 }
2200 }
2201
2202 right_select.with = None;
2204
2205 let order_by = select.order_by.take();
2207
2208 let union = crate::expressions::Union {
2210 left: Expression::Select(select),
2211 right: Expression::Select(right_select),
2212 all: true, distinct: false,
2214 with: None,
2215 order_by,
2216 limit: None,
2217 offset: None,
2218 distribute_by: None,
2219 sort_by: None,
2220 cluster_by: None,
2221 by_name: false,
2222 side: None,
2223 kind: None,
2224 corresponding: false,
2225 strict: false,
2226 on_columns: Vec::new(),
2227 };
2228
2229 return Ok(Expression::Union(Box::new(union)));
2230 }
2231
2232 Ok(Expression::Select(select))
2233 }
2234 other => Ok(other),
2235 }
2236}
2237
2238pub fn move_ctes_to_top_level(expr: Expression) -> Result<Expression> {
2251 match expr {
2252 Expression::Select(mut select) => {
2253 let mut collected_ctes: Vec<crate::expressions::Cte> = Vec::new();
2255 let mut has_recursive = false;
2256
2257 collect_nested_ctes(
2258 &Expression::Select(select.clone()),
2259 &mut collected_ctes,
2260 &mut has_recursive,
2261 true,
2262 );
2263
2264 let mut cte_body_collected: Vec<(String, Vec<crate::expressions::Cte>)> = Vec::new();
2267 if let Some(ref with) = select.with {
2268 for cte in &with.ctes {
2269 let mut body_ctes: Vec<crate::expressions::Cte> = Vec::new();
2270 collect_ctes_from_cte_body(&cte.this, &mut body_ctes, &mut has_recursive);
2271 if !body_ctes.is_empty() {
2272 cte_body_collected.push((cte.alias.name.clone(), body_ctes));
2273 }
2274 }
2275 }
2276
2277 let has_subquery_ctes = !collected_ctes.is_empty();
2278 let has_body_ctes = !cte_body_collected.is_empty();
2279
2280 if has_subquery_ctes || has_body_ctes {
2281 strip_nested_with_clauses(&mut select, true);
2283
2284 if has_body_ctes {
2286 if let Some(ref mut with) = select.with {
2287 for cte in with.ctes.iter_mut() {
2288 strip_with_from_cte_body(&mut cte.this);
2289 }
2290 }
2291 }
2292
2293 let top_with = select.with.get_or_insert_with(|| crate::expressions::With {
2294 ctes: Vec::new(),
2295 recursive: false,
2296 leading_comments: vec![],
2297 search: None,
2298 });
2299
2300 if has_recursive {
2301 top_with.recursive = true;
2302 }
2303
2304 if has_body_ctes {
2306 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
2307 for mut cte in top_with.ctes.drain(..) {
2308 if let Some(pos) = cte_body_collected
2310 .iter()
2311 .position(|(name, _)| *name == cte.alias.name)
2312 {
2313 let (_, mut nested) = cte_body_collected.remove(pos);
2314 for nested_cte in nested.iter_mut() {
2316 strip_with_from_cte_body(&mut nested_cte.this);
2317 }
2318 new_ctes.extend(nested);
2319 }
2320 strip_with_from_cte_body(&mut cte.this);
2322 new_ctes.push(cte);
2323 }
2324 top_with.ctes = new_ctes;
2325 }
2326
2327 top_with.ctes.extend(collected_ctes);
2329 }
2330
2331 Ok(Expression::Select(select))
2332 }
2333 other => Ok(other),
2334 }
2335}
2336
2337fn collect_ctes_from_cte_body(
2339 expr: &Expression,
2340 collected: &mut Vec<crate::expressions::Cte>,
2341 has_recursive: &mut bool,
2342) {
2343 if let Expression::Select(select) = expr {
2344 if let Some(ref with) = select.with {
2345 if with.recursive {
2346 *has_recursive = true;
2347 }
2348 for cte in &with.ctes {
2349 collect_ctes_from_cte_body(&cte.this, collected, has_recursive);
2351 collected.push(cte.clone());
2353 }
2354 }
2355 }
2356}
2357
2358fn strip_with_from_cte_body(expr: &mut Expression) {
2360 if let Expression::Select(ref mut select) = expr {
2361 select.with = None;
2362 }
2363}
2364
2365fn strip_nested_with_clauses(select: &mut Select, _is_top_level: bool) {
2367 if let Some(ref mut from) = select.from {
2369 for expr in from.expressions.iter_mut() {
2370 strip_with_from_expr(expr);
2371 }
2372 }
2373 for join in select.joins.iter_mut() {
2375 strip_with_from_expr(&mut join.this);
2376 }
2377 for expr in select.expressions.iter_mut() {
2379 strip_with_from_expr(expr);
2380 }
2381 if let Some(ref mut w) = select.where_clause {
2383 strip_with_from_expr(&mut w.this);
2384 }
2385}
2386
2387fn strip_with_from_expr(expr: &mut Expression) {
2388 match expr {
2389 Expression::Subquery(ref mut subquery) => {
2390 strip_with_from_inner_query(&mut subquery.this);
2391 }
2392 Expression::Alias(ref mut alias) => {
2393 strip_with_from_expr(&mut alias.this);
2394 }
2395 Expression::Select(ref mut select) => {
2396 select.with = None;
2398 strip_nested_with_clauses(select, false);
2400 }
2401 _ => {}
2402 }
2403}
2404
2405fn strip_with_from_inner_query(expr: &mut Expression) {
2406 if let Expression::Select(ref mut select) = expr {
2407 select.with = None;
2408 strip_nested_with_clauses(select, false);
2409 }
2410}
2411
2412fn collect_nested_ctes(
2414 expr: &Expression,
2415 collected: &mut Vec<crate::expressions::Cte>,
2416 has_recursive: &mut bool,
2417 is_top_level: bool,
2418) {
2419 match expr {
2420 Expression::Select(select) => {
2421 if !is_top_level {
2423 if let Some(ref with) = select.with {
2424 if with.recursive {
2425 *has_recursive = true;
2426 }
2427 collected.extend(with.ctes.clone());
2428 }
2429 }
2430
2431 if let Some(ref from) = select.from {
2433 for expr in &from.expressions {
2434 collect_nested_ctes(expr, collected, has_recursive, false);
2435 }
2436 }
2437
2438 for join in &select.joins {
2440 collect_nested_ctes(&join.this, collected, has_recursive, false);
2441 }
2442
2443 for sel_expr in &select.expressions {
2445 collect_nested_ctes(sel_expr, collected, has_recursive, false);
2446 }
2447
2448 if let Some(ref where_clause) = select.where_clause {
2450 collect_nested_ctes(&where_clause.this, collected, has_recursive, false);
2451 }
2452 }
2453 Expression::Subquery(subquery) => {
2454 collect_nested_ctes(&subquery.this, collected, has_recursive, false);
2456 }
2457 Expression::Alias(alias) => {
2458 collect_nested_ctes(&alias.this, collected, has_recursive, false);
2459 }
2460 _ => {}
2462 }
2463}
2464
2465pub fn eliminate_window_clause(expr: Expression) -> Result<Expression> {
2481 match expr {
2482 Expression::Select(mut select) => {
2483 if let Some(named_windows) = select.windows.take() {
2484 let window_map: std::collections::HashMap<String, &Over> = named_windows
2486 .iter()
2487 .map(|nw| (nw.name.name.to_lowercase(), &nw.spec))
2488 .collect();
2489
2490 select.expressions = select
2492 .expressions
2493 .into_iter()
2494 .map(|e| inline_window_refs(e, &window_map))
2495 .collect();
2496 }
2497 Ok(Expression::Select(select))
2498 }
2499 other => Ok(other),
2500 }
2501}
2502
2503fn inline_window_refs(
2505 expr: Expression,
2506 window_map: &std::collections::HashMap<String, &Over>,
2507) -> Expression {
2508 match expr {
2509 Expression::WindowFunction(mut wf) => {
2510 if let Some(ref name) = wf.over.window_name {
2512 let key = name.name.to_lowercase();
2513 if let Some(named_spec) = window_map.get(&key) {
2514 if wf.over.partition_by.is_empty() && !named_spec.partition_by.is_empty() {
2516 wf.over.partition_by = named_spec.partition_by.clone();
2517 }
2518 if wf.over.order_by.is_empty() && !named_spec.order_by.is_empty() {
2519 wf.over.order_by = named_spec.order_by.clone();
2520 }
2521 if wf.over.frame.is_none() && named_spec.frame.is_some() {
2522 wf.over.frame = named_spec.frame.clone();
2523 }
2524 wf.over.window_name = None;
2526 }
2527 }
2528 Expression::WindowFunction(wf)
2529 }
2530 Expression::Alias(mut alias) => {
2531 alias.this = inline_window_refs(alias.this, window_map);
2533 Expression::Alias(alias)
2534 }
2535 other => other,
2538 }
2539}
2540
2541pub fn eliminate_join_marks(expr: Expression) -> Result<Expression> {
2555 match expr {
2556 Expression::Select(mut select) => {
2557 let has_join_marks = select
2559 .where_clause
2560 .as_ref()
2561 .map_or(false, |w| contains_join_mark(&w.this));
2562
2563 if !has_join_marks {
2564 return Ok(Expression::Select(select));
2565 }
2566
2567 let from_tables: Vec<String> = select
2569 .from
2570 .as_ref()
2571 .map(|f| {
2572 f.expressions
2573 .iter()
2574 .filter_map(|e| get_table_name(e))
2575 .collect()
2576 })
2577 .unwrap_or_default();
2578
2579 let mut join_conditions: std::collections::HashMap<String, Vec<Expression>> =
2581 std::collections::HashMap::new();
2582 let mut remaining_conditions: Vec<Expression> = Vec::new();
2583
2584 if let Some(ref where_clause) = select.where_clause {
2585 extract_join_mark_conditions(
2586 &where_clause.this,
2587 &mut join_conditions,
2588 &mut remaining_conditions,
2589 );
2590 }
2591
2592 let mut new_joins = select.joins.clone();
2594 for (table_name, conditions) in join_conditions {
2595 let table_in_from = from_tables.contains(&table_name);
2597
2598 if table_in_from && !conditions.is_empty() {
2599 let combined_condition = conditions.into_iter().reduce(|a, b| {
2601 Expression::And(Box::new(BinaryOp {
2602 left: a,
2603 right: b,
2604 left_comments: vec![],
2605 operator_comments: vec![],
2606 trailing_comments: vec![],
2607 inferred_type: None,
2608 }))
2609 });
2610
2611 if let Some(ref mut from) = select.from {
2613 if let Some(pos) = from
2614 .expressions
2615 .iter()
2616 .position(|e| get_table_name(e).map_or(false, |n| n == table_name))
2617 {
2618 if from.expressions.len() > 1 {
2619 let join_table = from.expressions.remove(pos);
2620 new_joins.push(crate::expressions::Join {
2621 this: join_table,
2622 kind: JoinKind::Left,
2623 on: combined_condition,
2624 using: vec![],
2625 use_inner_keyword: false,
2626 use_outer_keyword: true,
2627 deferred_condition: false,
2628 join_hint: None,
2629 match_condition: None,
2630 pivots: Vec::new(),
2631 comments: Vec::new(),
2632 nesting_group: 0,
2633 directed: false,
2634 });
2635 }
2636 }
2637 }
2638 }
2639 }
2640
2641 select.joins = new_joins;
2642
2643 if remaining_conditions.is_empty() {
2645 select.where_clause = None;
2646 } else {
2647 let combined = remaining_conditions.into_iter().reduce(|a, b| {
2648 Expression::And(Box::new(BinaryOp {
2649 left: a,
2650 right: b,
2651 left_comments: vec![],
2652 operator_comments: vec![],
2653 trailing_comments: vec![],
2654 inferred_type: None,
2655 }))
2656 });
2657 select.where_clause = combined.map(|c| Where { this: c });
2658 }
2659
2660 clear_join_marks(&mut Expression::Select(select.clone()));
2662
2663 Ok(Expression::Select(select))
2664 }
2665 other => Ok(other),
2666 }
2667}
2668
2669fn contains_join_mark(expr: &Expression) -> bool {
2671 match expr {
2672 Expression::Column(col) => col.join_mark,
2673 Expression::And(op) | Expression::Or(op) => {
2674 contains_join_mark(&op.left) || contains_join_mark(&op.right)
2675 }
2676 Expression::Eq(op)
2677 | Expression::Neq(op)
2678 | Expression::Lt(op)
2679 | Expression::Lte(op)
2680 | Expression::Gt(op)
2681 | Expression::Gte(op) => contains_join_mark(&op.left) || contains_join_mark(&op.right),
2682 Expression::Not(op) => contains_join_mark(&op.this),
2683 _ => false,
2684 }
2685}
2686
2687fn get_table_name(expr: &Expression) -> Option<String> {
2689 match expr {
2690 Expression::Table(t) => Some(t.name.name.clone()),
2691 Expression::Alias(a) => Some(a.alias.name.clone()),
2692 _ => None,
2693 }
2694}
2695
2696fn extract_join_mark_conditions(
2698 expr: &Expression,
2699 join_conditions: &mut std::collections::HashMap<String, Vec<Expression>>,
2700 remaining: &mut Vec<Expression>,
2701) {
2702 match expr {
2703 Expression::And(op) => {
2704 extract_join_mark_conditions(&op.left, join_conditions, remaining);
2705 extract_join_mark_conditions(&op.right, join_conditions, remaining);
2706 }
2707 _ => {
2708 if let Some(table) = get_join_mark_table(expr) {
2709 join_conditions
2710 .entry(table)
2711 .or_insert_with(Vec::new)
2712 .push(expr.clone());
2713 } else {
2714 remaining.push(expr.clone());
2715 }
2716 }
2717 }
2718}
2719
2720fn get_join_mark_table(expr: &Expression) -> Option<String> {
2722 match expr {
2723 Expression::Eq(op)
2724 | Expression::Neq(op)
2725 | Expression::Lt(op)
2726 | Expression::Lte(op)
2727 | Expression::Gt(op)
2728 | Expression::Gte(op) => {
2729 if let Expression::Column(col) = &op.left {
2731 if col.join_mark {
2732 return col.table.as_ref().map(|t| t.name.clone());
2733 }
2734 }
2735 if let Expression::Column(col) = &op.right {
2736 if col.join_mark {
2737 return col.table.as_ref().map(|t| t.name.clone());
2738 }
2739 }
2740 None
2741 }
2742 _ => None,
2743 }
2744}
2745
2746fn clear_join_marks(expr: &mut Expression) {
2748 match expr {
2749 Expression::Column(col) => col.join_mark = false,
2750 Expression::Select(select) => {
2751 if let Some(ref mut w) = select.where_clause {
2752 clear_join_marks(&mut w.this);
2753 }
2754 for sel_expr in &mut select.expressions {
2755 clear_join_marks(sel_expr);
2756 }
2757 }
2758 Expression::And(op) | Expression::Or(op) => {
2759 clear_join_marks(&mut op.left);
2760 clear_join_marks(&mut op.right);
2761 }
2762 Expression::Eq(op)
2763 | Expression::Neq(op)
2764 | Expression::Lt(op)
2765 | Expression::Lte(op)
2766 | Expression::Gt(op)
2767 | Expression::Gte(op) => {
2768 clear_join_marks(&mut op.left);
2769 clear_join_marks(&mut op.right);
2770 }
2771 _ => {}
2772 }
2773}
2774
2775pub fn add_recursive_cte_column_names(expr: Expression) -> Result<Expression> {
2782 match expr {
2783 Expression::Select(mut select) => {
2784 if let Some(ref mut with) = select.with {
2785 if with.recursive {
2786 let mut counter = 0;
2787 for cte in &mut with.ctes {
2788 if cte.columns.is_empty() {
2789 if let Expression::Select(ref cte_select) = cte.this {
2791 let names: Vec<Identifier> = cte_select
2792 .expressions
2793 .iter()
2794 .map(|e| match e {
2795 Expression::Alias(a) => a.alias.clone(),
2796 Expression::Column(c) => c.name.clone(),
2797 _ => {
2798 counter += 1;
2799 Identifier::new(format!("_c_{}", counter))
2800 }
2801 })
2802 .collect();
2803 cte.columns = names;
2804 }
2805 }
2806 }
2807 }
2808 }
2809 Ok(Expression::Select(select))
2810 }
2811 other => Ok(other),
2812 }
2813}
2814
2815pub fn epoch_cast_to_ts(expr: Expression) -> Result<Expression> {
2822 match expr {
2823 Expression::Cast(mut cast) => {
2824 if let Expression::Literal(ref lit) = cast.this {
2825 if let Literal::String(ref s) = lit.as_ref() {
2826 if s.to_lowercase() == "epoch" {
2827 if is_temporal_type(&cast.to) {
2828 cast.this = Expression::Literal(Box::new(Literal::String(
2829 "1970-01-01 00:00:00".to_string(),
2830 )));
2831 }
2832 }
2833 }
2834 }
2835 Ok(Expression::Cast(cast))
2836 }
2837 Expression::TryCast(mut try_cast) => {
2838 if let Expression::Literal(ref lit) = try_cast.this {
2839 if let Literal::String(ref s) = lit.as_ref() {
2840 if s.to_lowercase() == "epoch" {
2841 if is_temporal_type(&try_cast.to) {
2842 try_cast.this = Expression::Literal(Box::new(Literal::String(
2843 "1970-01-01 00:00:00".to_string(),
2844 )));
2845 }
2846 }
2847 }
2848 }
2849 Ok(Expression::TryCast(try_cast))
2850 }
2851 other => Ok(other),
2852 }
2853}
2854
2855fn is_temporal_type(dt: &DataType) -> bool {
2857 matches!(
2858 dt,
2859 DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. }
2860 )
2861}
2862
2863pub fn ensure_bools(expr: Expression) -> Result<Expression> {
2888 let expr = ensure_bools_in_value_context(expr);
2889
2890 Ok(match expr {
2891 Expression::And(_) | Expression::Or(_) | Expression::Not(_) => ensure_bool_condition(expr),
2893 other => other,
2894 })
2895}
2896
2897fn ensure_bools_in_value_context(expr: Expression) -> Expression {
2901 match expr {
2902 Expression::Case(mut case) => {
2903 let is_simple_case = case.operand.is_some();
2904 if let Some(operand) = case.operand.take() {
2905 case.operand = Some(ensure_bools_in_value_context(operand));
2906 }
2907 case.whens = case
2908 .whens
2909 .into_iter()
2910 .map(|(condition, result)| {
2911 let new_condition = if is_simple_case {
2912 ensure_bools_in_value_context(condition)
2913 } else {
2914 ensure_bool_condition(ensure_bools_in_value_context(condition))
2915 };
2916 let new_result = ensure_bools_in_value_context(result);
2917 (new_condition, new_result)
2918 })
2919 .collect();
2920 if let Some(else_expr) = case.else_ {
2921 case.else_ = Some(ensure_bools_in_value_context(else_expr));
2922 }
2923 Expression::Case(Box::new(*case))
2924 }
2925 Expression::Select(select) => Expression::Select(Box::new(ensure_bools_in_select(*select))),
2926 Expression::Subquery(mut subquery) => {
2927 subquery.this = ensure_bools_in_value_context(subquery.this);
2928 Expression::Subquery(subquery)
2929 }
2930 Expression::JoinedTable(mut joined_table) => {
2931 joined_table.left = ensure_bools_in_value_context(joined_table.left);
2932 joined_table.joins = joined_table
2933 .joins
2934 .into_iter()
2935 .map(ensure_bools_in_join)
2936 .collect();
2937 joined_table.lateral_views = joined_table
2938 .lateral_views
2939 .into_iter()
2940 .map(|mut lateral_view| {
2941 lateral_view.this = ensure_bools_in_value_context(lateral_view.this);
2942 lateral_view
2943 })
2944 .collect();
2945 Expression::JoinedTable(joined_table)
2946 }
2947 Expression::Union(mut union) => {
2948 let left = std::mem::replace(&mut union.left, Expression::null());
2949 let right = std::mem::replace(&mut union.right, Expression::null());
2950 union.left = ensure_bools_in_value_context(left);
2951 union.right = ensure_bools_in_value_context(right);
2952 if let Some(with) = union.with.take() {
2953 union.with = Some(ensure_bools_in_with(with));
2954 }
2955 Expression::Union(union)
2956 }
2957 Expression::Intersect(mut intersect) => {
2958 let left = std::mem::replace(&mut intersect.left, Expression::null());
2959 let right = std::mem::replace(&mut intersect.right, Expression::null());
2960 intersect.left = ensure_bools_in_value_context(left);
2961 intersect.right = ensure_bools_in_value_context(right);
2962 if let Some(with) = intersect.with.take() {
2963 intersect.with = Some(ensure_bools_in_with(with));
2964 }
2965 Expression::Intersect(intersect)
2966 }
2967 Expression::Except(mut except) => {
2968 let left = std::mem::replace(&mut except.left, Expression::null());
2969 let right = std::mem::replace(&mut except.right, Expression::null());
2970 except.left = ensure_bools_in_value_context(left);
2971 except.right = ensure_bools_in_value_context(right);
2972 if let Some(with) = except.with.take() {
2973 except.with = Some(ensure_bools_in_with(with));
2974 }
2975 Expression::Except(except)
2976 }
2977 Expression::Alias(mut alias) => {
2978 alias.this = ensure_bools_in_value_context(alias.this);
2979 Expression::Alias(alias)
2980 }
2981 Expression::Paren(mut paren) => {
2982 paren.this = ensure_bools_in_value_context(paren.this);
2983 Expression::Paren(paren)
2984 }
2985 other => other,
2986 }
2987}
2988
2989fn ensure_bools_in_select(mut select: Select) -> Select {
2990 select.expressions = select
2991 .expressions
2992 .into_iter()
2993 .map(ensure_bools_in_value_context)
2994 .collect();
2995
2996 if let Some(from) = select.from.take() {
2997 select.from = Some(crate::expressions::From {
2998 expressions: from
2999 .expressions
3000 .into_iter()
3001 .map(ensure_bools_in_value_context)
3002 .collect(),
3003 });
3004 }
3005
3006 select.joins = select.joins.into_iter().map(ensure_bools_in_join).collect();
3007
3008 if let Some(mut where_clause) = select.where_clause.take() {
3009 where_clause.this = ensure_bool_condition(ensure_bools_in_value_context(where_clause.this));
3010 select.where_clause = Some(where_clause);
3011 }
3012
3013 if let Some(mut having) = select.having.take() {
3014 having.this = ensure_bool_condition(ensure_bools_in_value_context(having.this));
3015 select.having = Some(having);
3016 }
3017
3018 if let Some(with) = select.with.take() {
3019 select.with = Some(ensure_bools_in_with(with));
3020 }
3021
3022 select
3023}
3024
3025fn ensure_bools_in_join(mut join: Join) -> Join {
3026 join.this = ensure_bools_in_value_context(join.this);
3027
3028 if let Some(on) = join.on.take() {
3029 join.on = Some(ensure_bool_condition(ensure_bools_in_value_context(on)));
3030 }
3031
3032 if let Some(match_condition) = join.match_condition.take() {
3033 join.match_condition = Some(ensure_bool_condition(ensure_bools_in_value_context(
3034 match_condition,
3035 )));
3036 }
3037
3038 join.pivots = join
3039 .pivots
3040 .into_iter()
3041 .map(ensure_bools_in_value_context)
3042 .collect();
3043
3044 join
3045}
3046
3047fn ensure_bools_in_with(mut with: With) -> With {
3048 with.ctes = with
3049 .ctes
3050 .into_iter()
3051 .map(|mut cte| {
3052 cte.this = ensure_bools_in_value_context(cte.this);
3053 cte
3054 })
3055 .collect();
3056 with
3057}
3058
3059fn is_boolean_expression(expr: &Expression) -> bool {
3062 matches!(
3063 expr,
3064 Expression::Eq(_)
3065 | Expression::Neq(_)
3066 | Expression::Lt(_)
3067 | Expression::Lte(_)
3068 | Expression::Gt(_)
3069 | Expression::Gte(_)
3070 | Expression::Is(_)
3071 | Expression::IsNull(_)
3072 | Expression::IsTrue(_)
3073 | Expression::IsFalse(_)
3074 | Expression::Like(_)
3075 | Expression::ILike(_)
3076 | Expression::StartsWith(_)
3077 | Expression::SimilarTo(_)
3078 | Expression::Glob(_)
3079 | Expression::RegexpLike(_)
3080 | Expression::In(_)
3081 | Expression::Between(_)
3082 | Expression::Exists(_)
3083 | Expression::And(_)
3084 | Expression::Or(_)
3085 | Expression::Not(_)
3086 | Expression::Any(_)
3087 | Expression::All(_)
3088 | Expression::NullSafeEq(_)
3089 | Expression::NullSafeNeq(_)
3090 | Expression::EqualNull(_)
3091 )
3092}
3093
3094fn wrap_neq_zero(expr: Expression) -> Expression {
3096 Expression::Neq(Box::new(BinaryOp {
3097 left: expr,
3098 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
3099 left_comments: vec![],
3100 operator_comments: vec![],
3101 trailing_comments: vec![],
3102 inferred_type: None,
3103 }))
3104}
3105
3106pub(crate) fn ensure_bool_condition(expr: Expression) -> Expression {
3112 match expr {
3113 Expression::And(op) => {
3115 let new_op = BinaryOp {
3116 left: ensure_bool_condition(op.left.clone()),
3117 right: ensure_bool_condition(op.right.clone()),
3118 left_comments: op.left_comments.clone(),
3119 operator_comments: op.operator_comments.clone(),
3120 trailing_comments: op.trailing_comments.clone(),
3121 inferred_type: None,
3122 };
3123 Expression::And(Box::new(new_op))
3124 }
3125 Expression::Or(op) => {
3126 let new_op = BinaryOp {
3127 left: ensure_bool_condition(op.left.clone()),
3128 right: ensure_bool_condition(op.right.clone()),
3129 left_comments: op.left_comments.clone(),
3130 operator_comments: op.operator_comments.clone(),
3131 trailing_comments: op.trailing_comments.clone(),
3132 inferred_type: None,
3133 };
3134 Expression::Or(Box::new(new_op))
3135 }
3136 Expression::Not(op) => Expression::Not(Box::new(crate::expressions::UnaryOp {
3138 this: ensure_bool_condition(op.this.clone()),
3139 inferred_type: None,
3140 })),
3141 Expression::Paren(paren) => Expression::Paren(Box::new(crate::expressions::Paren {
3143 this: ensure_bool_condition(paren.this.clone()),
3144 trailing_comments: paren.trailing_comments.clone(),
3145 })),
3146 Expression::Boolean(BooleanLiteral { value: true }) => {
3148 Expression::Paren(Box::new(crate::expressions::Paren {
3149 this: Expression::Eq(Box::new(BinaryOp {
3150 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3151 right: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3152 left_comments: vec![],
3153 operator_comments: vec![],
3154 trailing_comments: vec![],
3155 inferred_type: None,
3156 })),
3157 trailing_comments: vec![],
3158 }))
3159 }
3160 Expression::Boolean(BooleanLiteral { value: false }) => {
3161 Expression::Paren(Box::new(crate::expressions::Paren {
3162 this: Expression::Eq(Box::new(BinaryOp {
3163 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3164 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
3165 left_comments: vec![],
3166 operator_comments: vec![],
3167 trailing_comments: vec![],
3168 inferred_type: None,
3169 })),
3170 trailing_comments: vec![],
3171 }))
3172 }
3173 ref e if is_boolean_expression(e) => expr,
3175 _ => wrap_neq_zero(expr),
3178 }
3179}
3180
3181pub fn unqualify_columns(expr: Expression) -> Result<Expression> {
3187 Ok(unqualify_columns_recursive(expr))
3188}
3189
3190fn unqualify_columns_recursive(expr: Expression) -> Expression {
3192 match expr {
3193 Expression::Column(mut col) => {
3194 col.table = None;
3195 Expression::Column(col)
3196 }
3197 Expression::Select(mut select) => {
3198 select.expressions = select
3199 .expressions
3200 .into_iter()
3201 .map(unqualify_columns_recursive)
3202 .collect();
3203 if let Some(ref mut where_clause) = select.where_clause {
3204 where_clause.this = unqualify_columns_recursive(where_clause.this.clone());
3205 }
3206 if let Some(ref mut having) = select.having {
3207 having.this = unqualify_columns_recursive(having.this.clone());
3208 }
3209 if let Some(ref mut group_by) = select.group_by {
3210 group_by.expressions = group_by
3211 .expressions
3212 .iter()
3213 .cloned()
3214 .map(unqualify_columns_recursive)
3215 .collect();
3216 }
3217 if let Some(ref mut order_by) = select.order_by {
3218 order_by.expressions = order_by
3219 .expressions
3220 .iter()
3221 .map(|o| crate::expressions::Ordered {
3222 nulls_auto: o.nulls_auto,
3223 this: unqualify_columns_recursive(o.this.clone()),
3224 desc: o.desc,
3225 nulls_first: o.nulls_first,
3226 explicit_asc: o.explicit_asc,
3227 with_fill: o.with_fill.clone(),
3228 })
3229 .collect();
3230 }
3231 for join in &mut select.joins {
3232 if let Some(ref mut on) = join.on {
3233 *on = unqualify_columns_recursive(on.clone());
3234 }
3235 }
3236 Expression::Select(select)
3237 }
3238 Expression::Alias(mut alias) => {
3239 alias.this = unqualify_columns_recursive(alias.this);
3240 Expression::Alias(alias)
3241 }
3242 Expression::And(op) => Expression::And(Box::new(unqualify_binary_op(*op))),
3244 Expression::Or(op) => Expression::Or(Box::new(unqualify_binary_op(*op))),
3245 Expression::Eq(op) => Expression::Eq(Box::new(unqualify_binary_op(*op))),
3246 Expression::Neq(op) => Expression::Neq(Box::new(unqualify_binary_op(*op))),
3247 Expression::Lt(op) => Expression::Lt(Box::new(unqualify_binary_op(*op))),
3248 Expression::Lte(op) => Expression::Lte(Box::new(unqualify_binary_op(*op))),
3249 Expression::Gt(op) => Expression::Gt(Box::new(unqualify_binary_op(*op))),
3250 Expression::Gte(op) => Expression::Gte(Box::new(unqualify_binary_op(*op))),
3251 Expression::Add(op) => Expression::Add(Box::new(unqualify_binary_op(*op))),
3252 Expression::Sub(op) => Expression::Sub(Box::new(unqualify_binary_op(*op))),
3253 Expression::Mul(op) => Expression::Mul(Box::new(unqualify_binary_op(*op))),
3254 Expression::Div(op) => Expression::Div(Box::new(unqualify_binary_op(*op))),
3255 Expression::Function(mut func) => {
3257 func.args = func
3258 .args
3259 .into_iter()
3260 .map(unqualify_columns_recursive)
3261 .collect();
3262 Expression::Function(func)
3263 }
3264 Expression::AggregateFunction(mut func) => {
3265 func.args = func
3266 .args
3267 .into_iter()
3268 .map(unqualify_columns_recursive)
3269 .collect();
3270 Expression::AggregateFunction(func)
3271 }
3272 Expression::Case(mut case) => {
3273 case.whens = case
3274 .whens
3275 .into_iter()
3276 .map(|(cond, result)| {
3277 (
3278 unqualify_columns_recursive(cond),
3279 unqualify_columns_recursive(result),
3280 )
3281 })
3282 .collect();
3283 if let Some(else_expr) = case.else_ {
3284 case.else_ = Some(unqualify_columns_recursive(else_expr));
3285 }
3286 Expression::Case(case)
3287 }
3288 other => other,
3290 }
3291}
3292
3293fn unqualify_binary_op(mut op: BinaryOp) -> BinaryOp {
3295 op.left = unqualify_columns_recursive(op.left);
3296 op.right = unqualify_columns_recursive(op.right);
3297 op
3298}
3299
3300pub fn unnest_generate_date_array_using_recursive_cte(expr: Expression) -> Result<Expression> {
3320 match expr {
3321 Expression::Select(mut select) => {
3322 let mut cte_count = 0;
3323 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
3324
3325 if let Some(ref mut with) = select.with {
3327 for cte in &mut with.ctes {
3328 process_expression_for_gda(&mut cte.this, &mut cte_count, &mut new_ctes);
3329 }
3330 }
3331
3332 if let Some(ref mut from) = select.from {
3334 for table_expr in &mut from.expressions {
3335 if let Some((cte, replacement)) =
3336 try_convert_generate_date_array(table_expr, &mut cte_count)
3337 {
3338 new_ctes.push(cte);
3339 *table_expr = replacement;
3340 }
3341 }
3342 }
3343
3344 for join in &mut select.joins {
3346 if let Some((cte, replacement)) =
3347 try_convert_generate_date_array(&join.this, &mut cte_count)
3348 {
3349 new_ctes.push(cte);
3350 join.this = replacement;
3351 }
3352 }
3353
3354 if !new_ctes.is_empty() {
3356 let with_clause = select.with.get_or_insert_with(|| crate::expressions::With {
3357 ctes: Vec::new(),
3358 recursive: true, leading_comments: vec![],
3360 search: None,
3361 });
3362 with_clause.recursive = true;
3363
3364 let mut all_ctes = new_ctes;
3366 all_ctes.append(&mut with_clause.ctes);
3367 with_clause.ctes = all_ctes;
3368 }
3369
3370 Ok(Expression::Select(select))
3371 }
3372 other => Ok(other),
3373 }
3374}
3375
3376fn process_expression_for_gda(
3379 expr: &mut Expression,
3380 cte_count: &mut usize,
3381 new_ctes: &mut Vec<crate::expressions::Cte>,
3382) {
3383 match expr {
3384 Expression::Select(ref mut select) => {
3385 if let Some(ref mut from) = select.from {
3387 for table_expr in &mut from.expressions {
3388 if let Some((cte, replacement)) =
3389 try_convert_generate_date_array(table_expr, cte_count)
3390 {
3391 new_ctes.push(cte);
3392 *table_expr = replacement;
3393 }
3394 }
3395 }
3396 for join in &mut select.joins {
3398 if let Some((cte, replacement)) =
3399 try_convert_generate_date_array(&join.this, cte_count)
3400 {
3401 new_ctes.push(cte);
3402 join.this = replacement;
3403 }
3404 }
3405 }
3406 Expression::Union(ref mut u) => {
3407 process_expression_for_gda(&mut u.left, cte_count, new_ctes);
3408 process_expression_for_gda(&mut u.right, cte_count, new_ctes);
3409 }
3410 Expression::Subquery(ref mut sq) => {
3411 process_expression_for_gda(&mut sq.this, cte_count, new_ctes);
3412 }
3413 _ => {}
3414 }
3415}
3416
3417fn try_convert_generate_date_array(
3420 expr: &Expression,
3421 cte_count: &mut usize,
3422) -> Option<(crate::expressions::Cte, Expression)> {
3423 try_convert_generate_date_array_with_name(expr, cte_count, None)
3424}
3425
3426fn try_convert_generate_date_array_with_name(
3427 expr: &Expression,
3428 cte_count: &mut usize,
3429 column_name_override: Option<&str>,
3430) -> Option<(crate::expressions::Cte, Expression)> {
3431 fn extract_gda_args(
3433 inner: &Expression,
3434 ) -> Option<(&Expression, &Expression, Option<&Expression>)> {
3435 match inner {
3436 Expression::GenerateDateArray(gda) => {
3437 let start = gda.start.as_ref()?;
3438 let end = gda.end.as_ref()?;
3439 let step = gda.step.as_deref();
3440 Some((start, end, step))
3441 }
3442 Expression::GenerateSeries(gs) => {
3443 let start = gs.start.as_deref()?;
3444 let end = gs.end.as_deref()?;
3445 let step = gs.step.as_deref();
3446 Some((start, end, step))
3447 }
3448 Expression::Function(f) if f.name.eq_ignore_ascii_case("GENERATE_DATE_ARRAY") => {
3449 if f.args.len() >= 2 {
3450 let start = &f.args[0];
3451 let end = &f.args[1];
3452 let step = f.args.get(2);
3453 Some((start, end, step))
3454 } else {
3455 None
3456 }
3457 }
3458 _ => None,
3459 }
3460 }
3461
3462 if let Expression::Unnest(unnest) = expr {
3464 if let Some((start, end, step_opt)) = extract_gda_args(&unnest.this) {
3465 let start = start;
3466 let end = end;
3467 let step: Option<&Expression> = step_opt;
3468
3469 let cte_name = if *cte_count == 0 {
3471 "_generated_dates".to_string()
3472 } else {
3473 format!("_generated_dates_{}", cte_count)
3474 };
3475 *cte_count += 1;
3476
3477 let column_name =
3478 Identifier::new(column_name_override.unwrap_or("date_value").to_string());
3479
3480 let cast_to_date = |expr: &Expression| -> Expression {
3482 match expr {
3483 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
3484 if let Expression::Literal(lit) = expr {
3486 if let Literal::Date(d) = lit.as_ref() {
3487 Expression::Cast(Box::new(Cast {
3488 this: Expression::Literal(Box::new(Literal::String(d.clone()))),
3489 to: DataType::Date,
3490 trailing_comments: vec![],
3491 double_colon_syntax: false,
3492 format: None,
3493 default: None,
3494 inferred_type: None,
3495 }))
3496 } else {
3497 expr.clone()
3498 }
3499 } else {
3500 unreachable!()
3501 }
3502 }
3503 Expression::Cast(c) if matches!(c.to, DataType::Date) => expr.clone(),
3504 _ => Expression::Cast(Box::new(Cast {
3505 this: expr.clone(),
3506 to: DataType::Date,
3507 trailing_comments: vec![],
3508 double_colon_syntax: false,
3509 format: None,
3510 default: None,
3511 inferred_type: None,
3512 })),
3513 }
3514 };
3515
3516 let base_select = Select {
3518 vertica: None,
3519 expressions: vec![Expression::Alias(Box::new(crate::expressions::Alias {
3520 this: cast_to_date(start),
3521 alias: column_name.clone(),
3522 column_aliases: vec![],
3523 alias_explicit_as: false,
3524 alias_keyword: None,
3525 pre_alias_comments: vec![],
3526 trailing_comments: vec![],
3527 inferred_type: None,
3528 }))],
3529 ..Select::new()
3530 };
3531
3532 let normalize_interval = |expr: &Expression| -> Expression {
3534 if let Expression::Interval(ref iv) = expr {
3535 let mut iv_clone = iv.as_ref().clone();
3536 if let Some(Expression::Literal(ref lit)) = iv_clone.this {
3537 if let Literal::String(ref s) = lit.as_ref() {
3538 if s.parse::<f64>().is_ok() {
3540 iv_clone.this =
3541 Some(Expression::Literal(Box::new(Literal::Number(s.clone()))));
3542 }
3543 }
3544 }
3545 Expression::Interval(Box::new(iv_clone))
3546 } else {
3547 expr.clone()
3548 }
3549 };
3550
3551 let normalized_step = step.map(|s| normalize_interval(s)).unwrap_or_else(|| {
3554 Expression::Interval(Box::new(crate::expressions::Interval {
3555 this: Some(Expression::Literal(Box::new(Literal::Number(
3556 "1".to_string(),
3557 )))),
3558 unit: Some(crate::expressions::IntervalUnitSpec::Simple {
3559 unit: crate::expressions::IntervalUnit::Day,
3560 use_plural: false,
3561 }),
3562 }))
3563 });
3564
3565 let (add_unit, add_count) = extract_interval_unit_and_count(&normalized_step);
3567
3568 let date_add_expr = Expression::DateAdd(Box::new(crate::expressions::DateAddFunc {
3569 this: Expression::Column(Box::new(crate::expressions::Column {
3570 name: column_name.clone(),
3571 table: None,
3572 join_mark: false,
3573 trailing_comments: vec![],
3574 span: None,
3575 inferred_type: None,
3576 })),
3577 interval: add_count,
3578 unit: add_unit,
3579 }));
3580
3581 let cast_date_add = Expression::Cast(Box::new(Cast {
3582 this: date_add_expr.clone(),
3583 to: DataType::Date,
3584 trailing_comments: vec![],
3585 double_colon_syntax: false,
3586 format: None,
3587 default: None,
3588 inferred_type: None,
3589 }));
3590
3591 let recursive_select = Select {
3592 vertica: None,
3593 expressions: vec![cast_date_add.clone()],
3594 from: Some(From {
3595 expressions: vec![Expression::Table(Box::new(
3596 crate::expressions::TableRef::new(&cte_name),
3597 ))],
3598 }),
3599 where_clause: Some(Where {
3600 this: Expression::Lte(Box::new(BinaryOp {
3601 left: cast_date_add,
3602 right: cast_to_date(end),
3603 left_comments: vec![],
3604 operator_comments: vec![],
3605 trailing_comments: vec![],
3606 inferred_type: None,
3607 })),
3608 }),
3609 ..Select::new()
3610 };
3611
3612 let union = crate::expressions::Union {
3614 left: Expression::Select(Box::new(base_select)),
3615 right: Expression::Select(Box::new(recursive_select)),
3616 all: true, distinct: false,
3618 with: None,
3619 order_by: None,
3620 limit: None,
3621 offset: None,
3622 distribute_by: None,
3623 sort_by: None,
3624 cluster_by: None,
3625 by_name: false,
3626 side: None,
3627 kind: None,
3628 corresponding: false,
3629 strict: false,
3630 on_columns: Vec::new(),
3631 };
3632
3633 let cte = crate::expressions::Cte {
3635 this: Expression::Union(Box::new(union)),
3636 alias: Identifier::new(cte_name.clone()),
3637 columns: vec![column_name.clone()],
3638 materialized: None,
3639 key_expressions: Vec::new(),
3640 alias_first: true,
3641 comments: Vec::new(),
3642 };
3643
3644 let replacement_select = Select {
3646 vertica: None,
3647 expressions: vec![Expression::Column(Box::new(crate::expressions::Column {
3648 name: column_name,
3649 table: None,
3650 join_mark: false,
3651 trailing_comments: vec![],
3652 span: None,
3653 inferred_type: None,
3654 }))],
3655 from: Some(From {
3656 expressions: vec![Expression::Table(Box::new(
3657 crate::expressions::TableRef::new(&cte_name),
3658 ))],
3659 }),
3660 ..Select::new()
3661 };
3662
3663 let replacement = Expression::Subquery(Box::new(Subquery {
3664 this: Expression::Select(Box::new(replacement_select)),
3665 alias: Some(Identifier::new(cte_name)),
3666 column_aliases: vec![],
3667 alias_explicit_as: false,
3668 alias_keyword: None,
3669 order_by: None,
3670 limit: None,
3671 offset: None,
3672 distribute_by: None,
3673 sort_by: None,
3674 cluster_by: None,
3675 lateral: false,
3676 modifiers_inside: false,
3677 trailing_comments: vec![],
3678 inferred_type: None,
3679 }));
3680
3681 return Some((cte, replacement));
3682 }
3683 }
3684
3685 if let Expression::Alias(alias) = expr {
3687 let col_name = alias.column_aliases.first().map(|id| id.name.as_str());
3689 if let Some((cte, replacement)) =
3690 try_convert_generate_date_array_with_name(&alias.this, cte_count, col_name)
3691 {
3692 if col_name.is_some() {
3695 return Some((cte, replacement));
3696 }
3697 let new_alias = Expression::Alias(Box::new(crate::expressions::Alias {
3698 this: replacement,
3699 alias: alias.alias.clone(),
3700 column_aliases: alias.column_aliases.clone(),
3701 alias_explicit_as: false,
3702 alias_keyword: None,
3703 pre_alias_comments: alias.pre_alias_comments.clone(),
3704 trailing_comments: alias.trailing_comments.clone(),
3705 inferred_type: None,
3706 }));
3707 return Some((cte, new_alias));
3708 }
3709 }
3710
3711 None
3712}
3713
3714fn extract_interval_unit_and_count(
3719 expr: &Expression,
3720) -> (crate::expressions::IntervalUnit, Expression) {
3721 use crate::expressions::{IntervalUnit, IntervalUnitSpec, Literal};
3722
3723 if let Expression::Interval(ref iv) = expr {
3724 if let Some(ref unit_spec) = iv.unit {
3726 if let IntervalUnitSpec::Simple { unit, .. } = unit_spec {
3727 let count = match &iv.this {
3728 Some(e) => e.clone(),
3729 None => Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3730 };
3731 return (unit.clone(), count);
3732 }
3733 }
3734
3735 if let Some(ref val_expr) = iv.this {
3737 match val_expr {
3738 Expression::Literal(lit)
3739 if matches!(lit.as_ref(), Literal::String(_) | Literal::Number(_)) =>
3740 {
3741 let s = match lit.as_ref() {
3742 Literal::String(s) | Literal::Number(s) => s,
3743 _ => unreachable!(),
3744 };
3745 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
3747 if parts.len() == 2 {
3748 let count_str = parts[0].trim();
3749 let unit_str = parts[1].trim().to_uppercase();
3750 let unit = match unit_str.as_str() {
3751 "YEAR" | "YEARS" => IntervalUnit::Year,
3752 "QUARTER" | "QUARTERS" => IntervalUnit::Quarter,
3753 "MONTH" | "MONTHS" => IntervalUnit::Month,
3754 "WEEK" | "WEEKS" => IntervalUnit::Week,
3755 "DAY" | "DAYS" => IntervalUnit::Day,
3756 "HOUR" | "HOURS" => IntervalUnit::Hour,
3757 "MINUTE" | "MINUTES" => IntervalUnit::Minute,
3758 "SECOND" | "SECONDS" => IntervalUnit::Second,
3759 "MILLISECOND" | "MILLISECONDS" => IntervalUnit::Millisecond,
3760 "MICROSECOND" | "MICROSECONDS" => IntervalUnit::Microsecond,
3761 _ => IntervalUnit::Day,
3762 };
3763 return (
3764 unit,
3765 Expression::Literal(Box::new(Literal::Number(count_str.to_string()))),
3766 );
3767 }
3768 if s.parse::<f64>().is_ok() {
3770 return (
3771 IntervalUnit::Day,
3772 Expression::Literal(Box::new(Literal::Number(s.clone()))),
3773 );
3774 }
3775 }
3776 _ => {}
3777 }
3778 }
3779
3780 (
3782 IntervalUnit::Day,
3783 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3784 )
3785 } else {
3786 (
3787 IntervalUnit::Day,
3788 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3789 )
3790 }
3791}
3792
3793pub fn no_ilike_sql(expr: Expression) -> Result<Expression> {
3806 match expr {
3807 Expression::ILike(ilike) => {
3808 let lower_left = Expression::Function(Box::new(crate::expressions::Function {
3810 on_error: None,
3811 qualified_name: Vec::new(),
3812 source_dialect: None,
3813
3814 name: "LOWER".to_string(),
3815 args: vec![ilike.left],
3816 distinct: false,
3817 trailing_comments: vec![],
3818 use_bracket_syntax: false,
3819 no_parens: false,
3820 quoted: false,
3821 span: None,
3822 inferred_type: None,
3823 }));
3824
3825 let lower_right = Expression::Function(Box::new(crate::expressions::Function {
3826 on_error: None,
3827 qualified_name: Vec::new(),
3828 source_dialect: None,
3829
3830 name: "LOWER".to_string(),
3831 args: vec![ilike.right],
3832 distinct: false,
3833 trailing_comments: vec![],
3834 use_bracket_syntax: false,
3835 no_parens: false,
3836 quoted: false,
3837 span: None,
3838 inferred_type: None,
3839 }));
3840
3841 Ok(Expression::Like(Box::new(crate::expressions::LikeOp {
3842 left: lower_left,
3843 right: lower_right,
3844 escape: ilike.escape,
3845 quantifier: ilike.quantifier,
3846 inferred_type: None,
3847 })))
3848 }
3849 other => Ok(other),
3850 }
3851}
3852
3853pub fn no_trycast_sql(expr: Expression) -> Result<Expression> {
3861 match expr {
3862 Expression::TryCast(try_cast) => Ok(Expression::Cast(try_cast)),
3863 other => Ok(other),
3864 }
3865}
3866
3867pub fn no_safe_cast_sql(expr: Expression) -> Result<Expression> {
3872 match expr {
3873 Expression::SafeCast(safe_cast) => Ok(Expression::Cast(safe_cast)),
3874 other => Ok(other),
3875 }
3876}
3877
3878pub fn no_comment_column_constraint(expr: Expression) -> Result<Expression> {
3885 Ok(expr)
3887}
3888
3889pub fn unnest_generate_series(expr: Expression) -> Result<Expression> {
3903 match expr {
3906 Expression::Table(ref table) => {
3907 if table.name.name.to_uppercase() == "GENERATE_SERIES" {
3910 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3912 this: expr.clone(),
3913 expressions: Vec::new(),
3914 with_ordinality: false,
3915 alias: None,
3916 offset_alias: None,
3917 inferred_type: None,
3918 }));
3919
3920 return Ok(Expression::Alias(Box::new(crate::expressions::Alias {
3922 this: unnest,
3923 alias: Identifier::new("_u".to_string()),
3924 column_aliases: vec![],
3925 alias_explicit_as: false,
3926 alias_keyword: None,
3927 pre_alias_comments: vec![],
3928 trailing_comments: vec![],
3929 inferred_type: None,
3930 })));
3931 }
3932 Ok(expr)
3933 }
3934 Expression::GenerateSeries(gs) => {
3935 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3937 this: Expression::GenerateSeries(gs),
3938 expressions: Vec::new(),
3939 with_ordinality: false,
3940 alias: None,
3941 offset_alias: None,
3942 inferred_type: None,
3943 }));
3944 Ok(unnest)
3945 }
3946 other => Ok(other),
3947 }
3948}
3949
3950pub fn unwrap_unnest_generate_series_for_postgres(expr: Expression) -> Result<Expression> {
3961 use crate::dialects::transform_recursive;
3962 transform_recursive(expr, &unwrap_unnest_generate_series_single)
3963}
3964
3965fn unwrap_unnest_generate_series_single(expr: Expression) -> Result<Expression> {
3966 use crate::expressions::*;
3967 match expr {
3969 Expression::Select(mut select) => {
3970 if let Some(ref mut from) = select.from {
3972 for table_expr in &mut from.expressions {
3973 if let Some(replacement) = try_unwrap_unnest_gen_series(table_expr) {
3974 *table_expr = replacement;
3975 }
3976 }
3977 }
3978 for join in &mut select.joins {
3980 if let Some(replacement) = try_unwrap_unnest_gen_series(&join.this) {
3981 join.this = replacement;
3982 }
3983 }
3984 Ok(Expression::Select(select))
3985 }
3986 other => Ok(other),
3987 }
3988}
3989
3990fn try_unwrap_unnest_gen_series(expr: &Expression) -> Option<Expression> {
3993 use crate::expressions::*;
3994
3995 let gen_series = match expr {
3997 Expression::Unnest(unnest) => {
3998 if let Expression::GenerateSeries(ref gs) = unnest.this {
3999 Some(gs.as_ref().clone())
4000 } else {
4001 None
4002 }
4003 }
4004 Expression::Alias(alias) => {
4005 if let Expression::Unnest(ref unnest) = alias.this {
4006 if let Expression::GenerateSeries(ref gs) = unnest.this {
4007 Some(gs.as_ref().clone())
4008 } else {
4009 None
4010 }
4011 } else {
4012 None
4013 }
4014 }
4015 _ => None,
4016 };
4017
4018 let gs = gen_series?;
4019
4020 let value_col = Expression::boxed_column(Column {
4022 name: Identifier::new("value".to_string()),
4023 table: None,
4024 join_mark: false,
4025 trailing_comments: vec![],
4026 span: None,
4027 inferred_type: None,
4028 });
4029
4030 let cast_value = Expression::Cast(Box::new(Cast {
4031 this: value_col,
4032 to: DataType::Date,
4033 trailing_comments: vec![],
4034 double_colon_syntax: false,
4035 format: None,
4036 default: None,
4037 inferred_type: None,
4038 }));
4039
4040 let gen_series_expr = Expression::GenerateSeries(Box::new(gs));
4041
4042 let gen_series_aliased = Expression::Alias(Box::new(Alias {
4044 this: gen_series_expr,
4045 alias: Identifier::new("_t".to_string()),
4046 column_aliases: vec![Identifier::new("value".to_string())],
4047 alias_explicit_as: false,
4048 alias_keyword: None,
4049 pre_alias_comments: vec![],
4050 trailing_comments: vec![],
4051 inferred_type: None,
4052 }));
4053
4054 let mut inner_select = Select::new();
4055 inner_select.expressions = vec![cast_value];
4056 inner_select.from = Some(From {
4057 expressions: vec![gen_series_aliased],
4058 });
4059
4060 let inner_select_expr = Expression::Select(Box::new(inner_select));
4061
4062 let subquery = Expression::Subquery(Box::new(Subquery {
4063 this: inner_select_expr,
4064 alias: None,
4065 column_aliases: vec![],
4066 alias_explicit_as: false,
4067 alias_keyword: None,
4068 order_by: None,
4069 limit: None,
4070 offset: None,
4071 distribute_by: None,
4072 sort_by: None,
4073 cluster_by: None,
4074 lateral: false,
4075 modifiers_inside: false,
4076 trailing_comments: vec![],
4077 inferred_type: None,
4078 }));
4079
4080 Some(Expression::Alias(Box::new(Alias {
4082 this: subquery,
4083 alias: Identifier::new("_unnested_generate_series".to_string()),
4084 column_aliases: vec![],
4085 alias_explicit_as: false,
4086 alias_keyword: None,
4087 pre_alias_comments: vec![],
4088 trailing_comments: vec![],
4089 inferred_type: None,
4090 })))
4091}
4092
4093pub fn expand_between_in_delete(expr: Expression) -> Result<Expression> {
4101 match expr {
4102 Expression::Delete(mut delete) => {
4103 if let Some(ref mut where_clause) = delete.where_clause {
4105 where_clause.this = expand_between_recursive(where_clause.this.clone());
4106 }
4107 Ok(Expression::Delete(delete))
4108 }
4109 other => Ok(other),
4110 }
4111}
4112
4113fn expand_between_recursive(expr: Expression) -> Expression {
4115 match expr {
4116 Expression::Between(between) => {
4119 let this = expand_between_recursive(between.this.clone());
4120 let low = expand_between_recursive(between.low);
4121 let high = expand_between_recursive(between.high);
4122
4123 if between.not {
4124 Expression::Or(Box::new(BinaryOp::new(
4126 Expression::Lt(Box::new(BinaryOp::new(this.clone(), low))),
4127 Expression::Gt(Box::new(BinaryOp::new(this, high))),
4128 )))
4129 } else {
4130 Expression::And(Box::new(BinaryOp::new(
4132 Expression::Gte(Box::new(BinaryOp::new(this.clone(), low))),
4133 Expression::Lte(Box::new(BinaryOp::new(this, high))),
4134 )))
4135 }
4136 }
4137
4138 Expression::And(mut op) => {
4140 op.left = expand_between_recursive(op.left);
4141 op.right = expand_between_recursive(op.right);
4142 Expression::And(op)
4143 }
4144 Expression::Or(mut op) => {
4145 op.left = expand_between_recursive(op.left);
4146 op.right = expand_between_recursive(op.right);
4147 Expression::Or(op)
4148 }
4149 Expression::Not(mut op) => {
4150 op.this = expand_between_recursive(op.this);
4151 Expression::Not(op)
4152 }
4153
4154 Expression::Paren(mut paren) => {
4156 paren.this = expand_between_recursive(paren.this);
4157 Expression::Paren(paren)
4158 }
4159
4160 other => other,
4162 }
4163}
4164
4165pub fn pushdown_cte_column_names(expr: Expression) -> Result<Expression> {
4174 match expr {
4175 Expression::Select(mut select) => {
4176 if let Some(ref mut with) = select.with {
4177 for cte in &mut with.ctes {
4178 if !cte.columns.is_empty() {
4179 let is_star = matches!(&cte.this, Expression::Select(s) if
4181 s.expressions.len() == 1 && matches!(&s.expressions[0], Expression::Star(_)));
4182
4183 if is_star {
4184 cte.columns.clear();
4186 continue;
4187 }
4188
4189 let column_names: Vec<Identifier> = cte.columns.drain(..).collect();
4191
4192 if let Expression::Select(ref mut inner_select) = cte.this {
4194 let new_exprs: Vec<Expression> = inner_select
4195 .expressions
4196 .drain(..)
4197 .zip(
4198 column_names
4199 .into_iter()
4200 .chain(std::iter::repeat_with(|| Identifier::new(""))),
4201 )
4202 .map(|(expr, col_name)| {
4203 if col_name.name.is_empty() {
4204 return expr;
4205 }
4206 match expr {
4208 Expression::Alias(mut a) => {
4209 a.alias = col_name;
4210 Expression::Alias(a)
4211 }
4212 other => {
4213 Expression::Alias(Box::new(crate::expressions::Alias {
4214 this: other,
4215 alias: col_name,
4216 column_aliases: Vec::new(),
4217 alias_explicit_as: false,
4218 alias_keyword: None,
4219 pre_alias_comments: Vec::new(),
4220 trailing_comments: Vec::new(),
4221 inferred_type: None,
4222 }))
4223 }
4224 }
4225 })
4226 .collect();
4227 inner_select.expressions = new_exprs;
4228 }
4229 }
4230 }
4231 }
4232 Ok(Expression::Select(select))
4233 }
4234 other => Ok(other),
4235 }
4236}
4237
4238pub fn simplify_nested_paren_values(expr: Expression) -> Result<Expression> {
4242 match expr {
4243 Expression::Select(mut select) => {
4244 if let Some(ref mut from) = select.from {
4245 for from_item in from.expressions.iter_mut() {
4246 simplify_paren_values_in_from(from_item);
4247 }
4248 }
4249 Ok(Expression::Select(select))
4250 }
4251 other => Ok(other),
4252 }
4253}
4254
4255fn simplify_paren_values_in_from(expr: &mut Expression) {
4256 let replacement = match expr {
4258 Expression::Subquery(ref subquery) => {
4260 if let Expression::Paren(ref paren) = subquery.this {
4261 if matches!(&paren.this, Expression::Values(_)) {
4262 let mut new_sub = subquery.as_ref().clone();
4263 new_sub.this = paren.this.clone();
4264 Some(Expression::Subquery(Box::new(new_sub)))
4265 } else {
4266 None
4267 }
4268 } else {
4269 None
4270 }
4271 }
4272 Expression::Paren(ref outer_paren) => {
4275 if let Expression::Subquery(ref subquery) = outer_paren.this {
4276 if matches!(&subquery.this, Expression::Values(_)) {
4278 Some(outer_paren.this.clone())
4279 }
4280 else if let Expression::Paren(ref paren) = subquery.this {
4282 if matches!(&paren.this, Expression::Values(_)) {
4283 let mut new_sub = subquery.as_ref().clone();
4284 new_sub.this = paren.this.clone();
4285 Some(Expression::Subquery(Box::new(new_sub)))
4286 } else {
4287 None
4288 }
4289 } else {
4290 None
4291 }
4292 } else if let Expression::Paren(ref inner_paren) = outer_paren.this {
4293 if matches!(&inner_paren.this, Expression::Values(_)) {
4294 Some(outer_paren.this.clone())
4295 } else {
4296 None
4297 }
4298 } else {
4299 None
4300 }
4301 }
4302 _ => None,
4303 };
4304 if let Some(new_expr) = replacement {
4305 *expr = new_expr;
4306 }
4307}
4308
4309pub fn add_auto_table_alias(expr: Expression) -> Result<Expression> {
4313 match expr {
4314 Expression::Select(mut select) => {
4315 if let Some(ref mut from) = select.from {
4317 let mut counter = 0usize;
4318 for from_item in from.expressions.iter_mut() {
4319 add_auto_alias_to_from_item(from_item, &mut counter);
4320 }
4321 }
4322 Ok(Expression::Select(select))
4323 }
4324 other => Ok(other),
4325 }
4326}
4327
4328fn add_auto_alias_to_from_item(expr: &mut Expression, counter: &mut usize) {
4329 use crate::expressions::Identifier;
4330
4331 match expr {
4332 Expression::Alias(ref mut alias) => {
4333 if alias.alias.name.is_empty() && !alias.column_aliases.is_empty() {
4335 alias.alias = Identifier::new(format!("_t{}", counter));
4336 *counter += 1;
4337 }
4338 }
4339 _ => {}
4340 }
4341}
4342
4343pub fn propagate_struct_field_names(expr: Expression) -> Result<Expression> {
4353 use crate::dialects::transform_recursive;
4354 transform_recursive(expr, &propagate_struct_names_in_expr)
4355}
4356
4357fn propagate_struct_names_in_expr(expr: Expression) -> Result<Expression> {
4358 use crate::expressions::{Alias, ArrayConstructor, Function, Identifier};
4359
4360 fn propagate_in_elements(elements: &[Expression]) -> Option<Vec<Expression>> {
4362 if elements.len() <= 1 {
4363 return None;
4364 }
4365 if let Some(Expression::Function(ref first_struct)) = elements.first() {
4367 if first_struct.name.eq_ignore_ascii_case("STRUCT") {
4368 let field_names: Vec<Option<String>> = first_struct
4370 .args
4371 .iter()
4372 .map(|arg| {
4373 if let Expression::Alias(a) = arg {
4374 Some(a.alias.name.clone())
4375 } else {
4376 None
4377 }
4378 })
4379 .collect();
4380
4381 if field_names.iter().any(|n| n.is_some()) {
4383 let mut new_elements = Vec::with_capacity(elements.len());
4384 new_elements.push(elements[0].clone());
4385
4386 for elem in &elements[1..] {
4387 if let Expression::Function(ref s) = elem {
4388 if s.name.eq_ignore_ascii_case("STRUCT")
4389 && s.args.len() == field_names.len()
4390 {
4391 let all_unnamed =
4393 s.args.iter().all(|a| !matches!(a, Expression::Alias(_)));
4394 if all_unnamed {
4395 let new_args: Vec<Expression> = s
4397 .args
4398 .iter()
4399 .zip(field_names.iter())
4400 .map(|(val, name)| {
4401 if let Some(n) = name {
4402 Expression::Alias(Box::new(Alias::new(
4403 val.clone(),
4404 Identifier::new(n.clone()),
4405 )))
4406 } else {
4407 val.clone()
4408 }
4409 })
4410 .collect();
4411 new_elements.push(Expression::Function(Box::new(
4412 Function::new("STRUCT".to_string(), new_args),
4413 )));
4414 continue;
4415 }
4416 }
4417 }
4418 new_elements.push(elem.clone());
4419 }
4420
4421 return Some(new_elements);
4422 }
4423 }
4424 }
4425 None
4426 }
4427
4428 if let Expression::Array(ref arr) = expr {
4430 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
4431 return Ok(Expression::Array(Box::new(crate::expressions::Array {
4432 expressions: new_elements,
4433 inferred_type: arr.inferred_type.clone(),
4434 })));
4435 }
4436 }
4437
4438 if let Expression::ArrayFunc(ref arr) = expr {
4440 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
4441 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
4442 expressions: new_elements,
4443 bracket_notation: arr.bracket_notation,
4444 use_list_keyword: arr.use_list_keyword,
4445 inferred_type: arr.inferred_type.clone(),
4446 })));
4447 }
4448 }
4449
4450 Ok(expr)
4451}
4452
4453pub fn unnest_alias_to_column_alias(expr: Expression) -> Result<Expression> {
4456 use crate::dialects::transform_recursive;
4457 transform_recursive(expr, &unnest_alias_transform_single_select)
4458}
4459
4460pub fn unnest_from_to_cross_join(expr: Expression) -> Result<Expression> {
4463 use crate::dialects::transform_recursive;
4464 transform_recursive(expr, &unnest_from_to_cross_join_single_select)
4465}
4466
4467fn unnest_from_to_cross_join_single_select(expr: Expression) -> Result<Expression> {
4468 if let Expression::Select(mut select) = expr {
4469 if let Some(ref mut from) = select.from {
4470 if from.expressions.len() > 1 {
4471 let mut new_from_exprs = Vec::new();
4472 let mut new_cross_joins = Vec::new();
4473
4474 for (idx, from_item) in from.expressions.drain(..).enumerate() {
4475 if idx == 0 {
4476 new_from_exprs.push(from_item);
4477 } else {
4478 let is_unnest = match &from_item {
4479 Expression::Unnest(_) => true,
4480 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
4481 _ => false,
4482 };
4483
4484 if is_unnest {
4485 new_cross_joins.push(crate::expressions::Join {
4486 this: from_item,
4487 on: None,
4488 using: Vec::new(),
4489 kind: JoinKind::Cross,
4490 use_inner_keyword: false,
4491 use_outer_keyword: false,
4492 deferred_condition: false,
4493 join_hint: None,
4494 match_condition: None,
4495 pivots: Vec::new(),
4496 comments: Vec::new(),
4497 nesting_group: 0,
4498 directed: false,
4499 });
4500 } else {
4501 new_from_exprs.push(from_item);
4502 }
4503 }
4504 }
4505
4506 from.expressions = new_from_exprs;
4507 new_cross_joins.append(&mut select.joins);
4508 select.joins = new_cross_joins;
4509 }
4510 }
4511
4512 Ok(Expression::Select(select))
4513 } else {
4514 Ok(expr)
4515 }
4516}
4517
4518pub fn wrap_unnest_join_aliases(expr: Expression) -> Result<Expression> {
4522 use crate::dialects::transform_recursive;
4523 transform_recursive(expr, &wrap_unnest_join_aliases_single)
4524}
4525
4526fn wrap_unnest_join_aliases_single(expr: Expression) -> Result<Expression> {
4527 if let Expression::Select(mut select) = expr {
4528 for join in &mut select.joins {
4530 wrap_unnest_alias_in_join_item(&mut join.this);
4531 }
4532 Ok(Expression::Select(select))
4533 } else {
4534 Ok(expr)
4535 }
4536}
4537
4538fn wrap_unnest_alias_in_join_item(expr: &mut Expression) {
4540 use crate::expressions::Identifier;
4541 if let Expression::Alias(alias) = expr {
4542 let is_unnest = match &alias.this {
4544 Expression::Function(f) => f.name.eq_ignore_ascii_case("UNNEST"),
4545 _ => false,
4546 };
4547
4548 if is_unnest && alias.column_aliases.is_empty() {
4549 let original_alias_name = alias.alias.name.clone();
4551 alias.alias = Identifier {
4552 name: "_u".to_string(),
4553 quoted: false,
4554 trailing_comments: Vec::new(),
4555 span: None,
4556 };
4557 alias.column_aliases = vec![Identifier {
4558 name: original_alias_name,
4559 quoted: false,
4560 trailing_comments: Vec::new(),
4561 span: None,
4562 }];
4563 }
4564 }
4565}
4566
4567fn unnest_alias_transform_single_select(expr: Expression) -> Result<Expression> {
4568 if let Expression::Select(mut select) = expr {
4569 let mut counter = 0usize;
4570
4571 if let Some(ref mut from) = select.from {
4573 for from_item in from.expressions.iter_mut() {
4575 convert_unnest_alias_in_from(from_item, &mut counter);
4576 }
4577
4578 if from.expressions.len() > 1 {
4580 let mut new_from_exprs = Vec::new();
4581 let mut new_cross_joins = Vec::new();
4582
4583 for (idx, from_item) in from.expressions.drain(..).enumerate() {
4584 if idx == 0 {
4585 new_from_exprs.push(from_item);
4587 } else {
4588 let is_unnest = match &from_item {
4590 Expression::Unnest(_) => true,
4591 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
4592 _ => false,
4593 };
4594
4595 if is_unnest {
4596 new_cross_joins.push(crate::expressions::Join {
4598 this: from_item,
4599 on: None,
4600 using: Vec::new(),
4601 kind: JoinKind::Cross,
4602 use_inner_keyword: false,
4603 use_outer_keyword: false,
4604 deferred_condition: false,
4605 join_hint: None,
4606 match_condition: None,
4607 pivots: Vec::new(),
4608 comments: Vec::new(),
4609 nesting_group: 0,
4610 directed: false,
4611 });
4612 } else {
4613 new_from_exprs.push(from_item);
4615 }
4616 }
4617 }
4618
4619 from.expressions = new_from_exprs;
4620 new_cross_joins.append(&mut select.joins);
4622 select.joins = new_cross_joins;
4623 }
4624 }
4625
4626 for join in select.joins.iter_mut() {
4628 convert_unnest_alias_in_from(&mut join.this, &mut counter);
4629 }
4630
4631 Ok(Expression::Select(select))
4632 } else {
4633 Ok(expr)
4634 }
4635}
4636
4637fn convert_unnest_alias_in_from(expr: &mut Expression, counter: &mut usize) {
4638 use crate::expressions::Identifier;
4639
4640 if let Expression::Alias(ref mut alias) = expr {
4641 let is_unnest = matches!(&alias.this, Expression::Unnest(_))
4643 || matches!(&alias.this, Expression::Function(f) if f.name.eq_ignore_ascii_case("EXPLODE"));
4644
4645 if is_unnest && alias.column_aliases.is_empty() {
4646 let col_alias = alias.alias.clone();
4648 alias.column_aliases = vec![col_alias];
4649 alias.alias = Identifier::new(format!("_t{}", counter));
4650 *counter += 1;
4651 }
4652 }
4653}
4654
4655pub fn expand_posexplode_duckdb(expr: Expression) -> Result<Expression> {
4662 use crate::expressions::{Alias, Function};
4663
4664 match expr {
4665 Expression::Select(mut select) => {
4666 let mut new_expressions = Vec::new();
4668 let mut changed = false;
4669
4670 for sel_expr in select.expressions.drain(..) {
4671 if let Expression::Alias(ref alias_box) = sel_expr {
4673 if let Expression::Function(ref func) = alias_box.this {
4674 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4675 let arg = func.args[0].clone();
4676 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
4678 (
4679 alias_box.column_aliases[0].name.clone(),
4680 alias_box.column_aliases[1].name.clone(),
4681 )
4682 } else if !alias_box.alias.is_empty() {
4683 ("pos".to_string(), alias_box.alias.name.clone())
4685 } else {
4686 ("pos".to_string(), "col".to_string())
4687 };
4688
4689 let gen_subscripts = Expression::Function(Box::new(Function::new(
4691 "GENERATE_SUBSCRIPTS".to_string(),
4692 vec![
4693 arg.clone(),
4694 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4695 ],
4696 )));
4697 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4698 gen_subscripts,
4699 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4700 )));
4701 let pos_alias = Expression::Alias(Box::new(Alias {
4702 this: sub_one,
4703 alias: Identifier::new(pos_name),
4704 column_aliases: Vec::new(),
4705 alias_explicit_as: false,
4706 alias_keyword: None,
4707 pre_alias_comments: Vec::new(),
4708 trailing_comments: Vec::new(),
4709 inferred_type: None,
4710 }));
4711
4712 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4714 this: arg,
4715 expressions: Vec::new(),
4716 with_ordinality: false,
4717 alias: None,
4718 offset_alias: None,
4719 inferred_type: None,
4720 }));
4721 let col_alias = Expression::Alias(Box::new(Alias {
4722 this: unnest,
4723 alias: Identifier::new(col_name),
4724 column_aliases: Vec::new(),
4725 alias_explicit_as: false,
4726 alias_keyword: None,
4727 pre_alias_comments: Vec::new(),
4728 trailing_comments: Vec::new(),
4729 inferred_type: None,
4730 }));
4731
4732 new_expressions.push(pos_alias);
4733 new_expressions.push(col_alias);
4734 changed = true;
4735 continue;
4736 }
4737 }
4738 }
4739
4740 if let Expression::Function(ref func) = sel_expr {
4742 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4743 let arg = func.args[0].clone();
4744 let pos_name = "pos";
4745 let col_name = "col";
4746
4747 let gen_subscripts = Expression::Function(Box::new(Function::new(
4749 "GENERATE_SUBSCRIPTS".to_string(),
4750 vec![
4751 arg.clone(),
4752 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4753 ],
4754 )));
4755 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4756 gen_subscripts,
4757 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4758 )));
4759 let pos_alias = Expression::Alias(Box::new(Alias {
4760 this: sub_one,
4761 alias: Identifier::new(pos_name),
4762 column_aliases: Vec::new(),
4763 alias_explicit_as: false,
4764 alias_keyword: None,
4765 pre_alias_comments: Vec::new(),
4766 trailing_comments: Vec::new(),
4767 inferred_type: None,
4768 }));
4769
4770 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4772 this: arg,
4773 expressions: Vec::new(),
4774 with_ordinality: false,
4775 alias: None,
4776 offset_alias: None,
4777 inferred_type: None,
4778 }));
4779 let col_alias = Expression::Alias(Box::new(Alias {
4780 this: unnest,
4781 alias: Identifier::new(col_name),
4782 column_aliases: Vec::new(),
4783 alias_explicit_as: false,
4784 alias_keyword: None,
4785 pre_alias_comments: Vec::new(),
4786 trailing_comments: Vec::new(),
4787 inferred_type: None,
4788 }));
4789
4790 new_expressions.push(pos_alias);
4791 new_expressions.push(col_alias);
4792 changed = true;
4793 continue;
4794 }
4795 }
4796
4797 new_expressions.push(sel_expr);
4799 }
4800
4801 if changed {
4802 select.expressions = new_expressions;
4803 } else {
4804 select.expressions = new_expressions;
4805 }
4806
4807 if let Some(ref mut from) = select.from {
4810 expand_posexplode_in_from_duckdb(from)?;
4811 }
4812
4813 Ok(Expression::Select(select))
4814 }
4815 other => Ok(other),
4816 }
4817}
4818
4819fn expand_posexplode_in_from_duckdb(from: &mut From) -> Result<()> {
4821 use crate::expressions::{Alias, Function};
4822
4823 let mut new_expressions = Vec::new();
4824 let mut _changed = false;
4825
4826 for table_expr in from.expressions.drain(..) {
4827 if let Expression::Alias(ref alias_box) = table_expr {
4829 if let Expression::Function(ref func) = alias_box.this {
4830 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4831 let arg = func.args[0].clone();
4832 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
4833 (
4834 alias_box.column_aliases[0].name.clone(),
4835 alias_box.column_aliases[1].name.clone(),
4836 )
4837 } else {
4838 ("pos".to_string(), "col".to_string())
4839 };
4840
4841 let gen_subscripts = Expression::Function(Box::new(Function::new(
4843 "GENERATE_SUBSCRIPTS".to_string(),
4844 vec![
4845 arg.clone(),
4846 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4847 ],
4848 )));
4849 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4850 gen_subscripts,
4851 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4852 )));
4853 let pos_alias = Expression::Alias(Box::new(Alias {
4854 this: sub_one,
4855 alias: Identifier::new(&pos_name),
4856 column_aliases: Vec::new(),
4857 alias_explicit_as: false,
4858 alias_keyword: None,
4859 pre_alias_comments: Vec::new(),
4860 trailing_comments: Vec::new(),
4861 inferred_type: None,
4862 }));
4863 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4864 this: arg,
4865 expressions: Vec::new(),
4866 with_ordinality: false,
4867 alias: None,
4868 offset_alias: None,
4869 inferred_type: None,
4870 }));
4871 let col_alias = Expression::Alias(Box::new(Alias {
4872 this: unnest,
4873 alias: Identifier::new(&col_name),
4874 column_aliases: Vec::new(),
4875 alias_explicit_as: false,
4876 alias_keyword: None,
4877 pre_alias_comments: Vec::new(),
4878 trailing_comments: Vec::new(),
4879 inferred_type: None,
4880 }));
4881
4882 let mut inner_select = Select::new();
4883 inner_select.expressions = vec![pos_alias, col_alias];
4884
4885 let subquery = Expression::Subquery(Box::new(Subquery {
4886 this: Expression::Select(Box::new(inner_select)),
4887 alias: None,
4888 column_aliases: Vec::new(),
4889 alias_explicit_as: false,
4890 alias_keyword: None,
4891 order_by: None,
4892 limit: None,
4893 offset: None,
4894 distribute_by: None,
4895 sort_by: None,
4896 cluster_by: None,
4897 lateral: false,
4898 modifiers_inside: false,
4899 trailing_comments: Vec::new(),
4900 inferred_type: None,
4901 }));
4902 new_expressions.push(subquery);
4903 _changed = true;
4904 continue;
4905 }
4906 }
4907 }
4908
4909 if let Expression::Function(ref func) = table_expr {
4911 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
4912 let arg = func.args[0].clone();
4913
4914 let gen_subscripts = Expression::Function(Box::new(Function::new(
4916 "GENERATE_SUBSCRIPTS".to_string(),
4917 vec![
4918 arg.clone(),
4919 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4920 ],
4921 )));
4922 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
4923 gen_subscripts,
4924 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4925 )));
4926 let pos_alias = Expression::Alias(Box::new(Alias {
4927 this: sub_one,
4928 alias: Identifier::new("pos"),
4929 column_aliases: Vec::new(),
4930 alias_explicit_as: false,
4931 alias_keyword: None,
4932 pre_alias_comments: Vec::new(),
4933 trailing_comments: Vec::new(),
4934 inferred_type: None,
4935 }));
4936 let unnest = Expression::Unnest(Box::new(UnnestFunc {
4937 this: arg,
4938 expressions: Vec::new(),
4939 with_ordinality: false,
4940 alias: None,
4941 offset_alias: None,
4942 inferred_type: None,
4943 }));
4944 let col_alias = Expression::Alias(Box::new(Alias {
4945 this: unnest,
4946 alias: Identifier::new("col"),
4947 column_aliases: Vec::new(),
4948 alias_explicit_as: false,
4949 alias_keyword: None,
4950 pre_alias_comments: Vec::new(),
4951 trailing_comments: Vec::new(),
4952 inferred_type: None,
4953 }));
4954
4955 let mut inner_select = Select::new();
4956 inner_select.expressions = vec![pos_alias, col_alias];
4957
4958 let subquery = Expression::Subquery(Box::new(Subquery {
4959 this: Expression::Select(Box::new(inner_select)),
4960 alias: None,
4961 column_aliases: Vec::new(),
4962 alias_explicit_as: false,
4963 alias_keyword: None,
4964 order_by: None,
4965 limit: None,
4966 offset: None,
4967 distribute_by: None,
4968 sort_by: None,
4969 cluster_by: None,
4970 lateral: false,
4971 modifiers_inside: false,
4972 trailing_comments: Vec::new(),
4973 inferred_type: None,
4974 }));
4975 new_expressions.push(subquery);
4976 _changed = true;
4977 continue;
4978 }
4979 }
4980
4981 new_expressions.push(table_expr);
4982 }
4983
4984 from.expressions = new_expressions;
4985 Ok(())
4986}
4987
4988pub fn explode_projection_to_unnest(expr: Expression, target: DialectType) -> Result<Expression> {
5003 match expr {
5004 Expression::Select(select) => explode_projection_to_unnest_impl(*select, target),
5005 other => Ok(other),
5006 }
5007}
5008
5009pub fn snowflake_flatten_projection_to_unnest(expr: Expression) -> Result<Expression> {
5019 match expr {
5020 Expression::Select(select) => snowflake_flatten_projection_to_unnest_impl(*select),
5021 other => Ok(other),
5022 }
5023}
5024
5025fn snowflake_flatten_projection_to_unnest_impl(mut select: Select) -> Result<Expression> {
5026 let mut flattened_inputs: Vec<Expression> = Vec::new();
5027 let mut new_selects: Vec<Expression> = Vec::with_capacity(select.expressions.len());
5028
5029 for sel_expr in select.expressions.into_iter() {
5030 let found_input: RefCell<Option<Expression>> = RefCell::new(None);
5031
5032 let rewritten = transform_recursive(sel_expr, &|e| {
5033 if let Expression::Lateral(lat) = e {
5034 if let Some(input_expr) = extract_flatten_input(&lat) {
5035 if found_input.borrow().is_none() {
5036 *found_input.borrow_mut() = Some(input_expr);
5037 }
5038 return Ok(Expression::Lateral(Box::new(rewrite_flatten_lateral(*lat))));
5039 }
5040 return Ok(Expression::Lateral(lat));
5041 }
5042 Ok(e)
5043 })?;
5044
5045 if let Some(input) = found_input.into_inner() {
5046 flattened_inputs.push(input);
5047 }
5048 new_selects.push(rewritten);
5049 }
5050
5051 if flattened_inputs.is_empty() {
5052 select.expressions = new_selects;
5053 return Ok(Expression::Select(Box::new(select)));
5054 }
5055
5056 select.expressions = new_selects;
5057
5058 for (idx, input_expr) in flattened_inputs.into_iter().enumerate() {
5059 let is_first = idx == 0;
5061 let series_alias = if is_first {
5062 "pos".to_string()
5063 } else {
5064 format!("pos_{}", idx + 1)
5065 };
5066 let series_source_alias = if is_first {
5067 "_u".to_string()
5068 } else {
5069 format!("_u_{}", idx * 2 + 1)
5070 };
5071 let unnest_source_alias = if is_first {
5072 "_u_2".to_string()
5073 } else {
5074 format!("_u_{}", idx * 2 + 2)
5075 };
5076 let pos2_alias = if is_first {
5077 "pos_2".to_string()
5078 } else {
5079 format!("{}_2", series_alias)
5080 };
5081 let entity_alias = if is_first {
5082 "entity".to_string()
5083 } else {
5084 format!("entity_{}", idx + 1)
5085 };
5086
5087 let array_size_call = Expression::Function(Box::new(Function::new(
5088 "ARRAY_SIZE".to_string(),
5089 vec![Expression::NamedArgument(Box::new(NamedArgument {
5090 name: Identifier::new("INPUT"),
5091 value: input_expr.clone(),
5092 separator: NamedArgSeparator::DArrow,
5093 }))],
5094 )));
5095
5096 let greatest = Expression::Function(Box::new(Function::new(
5097 "GREATEST".to_string(),
5098 vec![array_size_call.clone()],
5099 )));
5100
5101 let series_end = Expression::Add(Box::new(BinaryOp::new(
5102 Expression::Paren(Box::new(crate::expressions::Paren {
5103 this: Expression::Sub(Box::new(BinaryOp::new(
5104 greatest,
5105 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
5106 ))),
5107 trailing_comments: Vec::new(),
5108 })),
5109 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
5110 )));
5111
5112 let series_range = Expression::Function(Box::new(Function::new(
5113 "ARRAY_GENERATE_RANGE".to_string(),
5114 vec![
5115 Expression::Literal(Box::new(Literal::Number("0".to_string()))),
5116 series_end,
5117 ],
5118 )));
5119
5120 let series_flatten = Expression::Function(Box::new(Function::new(
5121 "FLATTEN".to_string(),
5122 vec![Expression::NamedArgument(Box::new(NamedArgument {
5123 name: Identifier::new("INPUT"),
5124 value: series_range,
5125 separator: NamedArgSeparator::DArrow,
5126 }))],
5127 )));
5128
5129 let series_table = Expression::Function(Box::new(Function::new(
5130 "TABLE".to_string(),
5131 vec![series_flatten],
5132 )));
5133
5134 let series_alias_expr = Expression::Alias(Box::new(Alias {
5135 this: series_table,
5136 alias: Identifier::new(series_source_alias.clone()),
5137 column_aliases: vec![
5138 Identifier::new("seq"),
5139 Identifier::new("key"),
5140 Identifier::new("path"),
5141 Identifier::new("index"),
5142 Identifier::new(series_alias.clone()),
5143 Identifier::new("this"),
5144 ],
5145 alias_explicit_as: false,
5146 alias_keyword: None,
5147 pre_alias_comments: Vec::new(),
5148 trailing_comments: Vec::new(),
5149 inferred_type: None,
5150 }));
5151
5152 select.joins.push(Join {
5153 this: series_alias_expr,
5154 on: None,
5155 using: Vec::new(),
5156 kind: JoinKind::Cross,
5157 use_inner_keyword: false,
5158 use_outer_keyword: false,
5159 deferred_condition: false,
5160 join_hint: None,
5161 match_condition: None,
5162 pivots: Vec::new(),
5163 comments: Vec::new(),
5164 nesting_group: 0,
5165 directed: false,
5166 });
5167
5168 let entity_flatten = Expression::Function(Box::new(Function::new(
5169 "FLATTEN".to_string(),
5170 vec![Expression::NamedArgument(Box::new(NamedArgument {
5171 name: Identifier::new("INPUT"),
5172 value: input_expr.clone(),
5173 separator: NamedArgSeparator::DArrow,
5174 }))],
5175 )));
5176
5177 let entity_table = Expression::Function(Box::new(Function::new(
5178 "TABLE".to_string(),
5179 vec![entity_flatten],
5180 )));
5181
5182 let entity_alias_expr = Expression::Alias(Box::new(Alias {
5183 this: entity_table,
5184 alias: Identifier::new(unnest_source_alias.clone()),
5185 column_aliases: vec![
5186 Identifier::new("seq"),
5187 Identifier::new("key"),
5188 Identifier::new("path"),
5189 Identifier::new(pos2_alias.clone()),
5190 Identifier::new(entity_alias.clone()),
5191 Identifier::new("this"),
5192 ],
5193 alias_explicit_as: false,
5194 alias_keyword: None,
5195 pre_alias_comments: Vec::new(),
5196 trailing_comments: Vec::new(),
5197 inferred_type: None,
5198 }));
5199
5200 select.joins.push(Join {
5201 this: entity_alias_expr,
5202 on: None,
5203 using: Vec::new(),
5204 kind: JoinKind::Cross,
5205 use_inner_keyword: false,
5206 use_outer_keyword: false,
5207 deferred_condition: false,
5208 join_hint: None,
5209 match_condition: None,
5210 pivots: Vec::new(),
5211 comments: Vec::new(),
5212 nesting_group: 0,
5213 directed: false,
5214 });
5215
5216 let pos_col =
5217 Expression::qualified_column(series_source_alias.clone(), series_alias.clone());
5218 let pos2_col =
5219 Expression::qualified_column(unnest_source_alias.clone(), pos2_alias.clone());
5220
5221 let eq = Expression::Eq(Box::new(BinaryOp::new(pos_col.clone(), pos2_col.clone())));
5222 let size_minus_1 = Expression::Paren(Box::new(crate::expressions::Paren {
5223 this: Expression::Sub(Box::new(BinaryOp::new(
5224 array_size_call,
5225 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
5226 ))),
5227 trailing_comments: Vec::new(),
5228 }));
5229 let gt = Expression::Gt(Box::new(BinaryOp::new(pos_col, size_minus_1.clone())));
5230 let pos2_eq_size = Expression::Eq(Box::new(BinaryOp::new(pos2_col, size_minus_1)));
5231 let and_cond = Expression::And(Box::new(BinaryOp::new(gt, pos2_eq_size)));
5232 let or_cond = Expression::Or(Box::new(BinaryOp::new(
5233 eq,
5234 Expression::Paren(Box::new(crate::expressions::Paren {
5235 this: and_cond,
5236 trailing_comments: Vec::new(),
5237 })),
5238 )));
5239
5240 select.where_clause = Some(match select.where_clause.take() {
5241 Some(existing) => Where {
5242 this: Expression::And(Box::new(BinaryOp::new(existing.this, or_cond))),
5243 },
5244 None => Where { this: or_cond },
5245 });
5246 }
5247
5248 Ok(Expression::Select(Box::new(select)))
5249}
5250
5251fn extract_flatten_input(lat: &Lateral) -> Option<Expression> {
5252 let Expression::Function(f) = lat.this.as_ref() else {
5253 return None;
5254 };
5255 if !f.name.eq_ignore_ascii_case("FLATTEN") {
5256 return None;
5257 }
5258
5259 for arg in &f.args {
5260 if let Expression::NamedArgument(na) = arg {
5261 if na.name.name.eq_ignore_ascii_case("INPUT") {
5262 return Some(na.value.clone());
5263 }
5264 }
5265 }
5266 f.args.first().cloned()
5267}
5268
5269fn rewrite_flatten_lateral(mut lat: Lateral) -> Lateral {
5270 let cond = Expression::Eq(Box::new(BinaryOp::new(
5271 Expression::qualified_column("_u", "pos"),
5272 Expression::qualified_column("_u_2", "pos_2"),
5273 )));
5274 let true_expr = Expression::qualified_column("_u_2", "entity");
5275 let iff_expr = Expression::Function(Box::new(Function::new(
5276 "IFF".to_string(),
5277 vec![cond, true_expr, Expression::Null(crate::expressions::Null)],
5278 )));
5279
5280 lat.this = Box::new(iff_expr);
5281 if lat.column_aliases.is_empty() {
5282 lat.column_aliases = vec![
5283 "SEQ".to_string(),
5284 "KEY".to_string(),
5285 "PATH".to_string(),
5286 "INDEX".to_string(),
5287 "VALUE".to_string(),
5288 "THIS".to_string(),
5289 ];
5290 }
5291 lat
5292}
5293
5294struct ExplodeInfo {
5296 arg_sql: String,
5298 explode_alias: String,
5300 pos_alias: String,
5302 unnest_source_alias: String,
5304}
5305
5306fn explode_projection_to_unnest_impl(select: Select, target: DialectType) -> Result<Expression> {
5307 let is_presto = matches!(
5308 target,
5309 DialectType::Presto | DialectType::Trino | DialectType::Athena
5310 );
5311 let is_bigquery = matches!(target, DialectType::BigQuery);
5312
5313 if !is_presto && !is_bigquery {
5314 return Ok(Expression::Select(Box::new(select)));
5315 }
5316
5317 let has_explode = select.expressions.iter().any(|e| expr_contains_explode(e));
5319 if !has_explode {
5320 return Ok(Expression::Select(Box::new(select)));
5321 }
5322
5323 let mut taken_select_names = std::collections::HashSet::new();
5325 let mut taken_source_names = std::collections::HashSet::new();
5326
5327 for sel in &select.expressions {
5329 if let Some(name) = get_output_name(sel) {
5330 taken_select_names.insert(name);
5331 }
5332 }
5333
5334 for sel in &select.expressions {
5336 let explode_expr = find_explode_in_expr(sel);
5337 if let Some(arg) = explode_expr {
5338 if let Some(name) = get_output_name(&arg) {
5339 taken_select_names.insert(name);
5340 }
5341 }
5342 }
5343
5344 if let Some(ref from) = select.from {
5346 for from_expr in &from.expressions {
5347 collect_source_names(from_expr, &mut taken_source_names);
5348 }
5349 }
5350 for join in &select.joins {
5352 collect_source_names(&join.this, &mut taken_source_names);
5353 }
5354
5355 let series_alias = new_name(&mut taken_select_names, "pos");
5357
5358 let series_source_alias = new_name(&mut taken_source_names, "_u");
5360
5361 let target_dialect = Dialect::get(target);
5363
5364 let mut explode_infos: Vec<ExplodeInfo> = Vec::new();
5366 let mut new_projections: Vec<String> = Vec::new();
5367
5368 for (_idx, sel_expr) in select.expressions.iter().enumerate() {
5369 let explode_data = extract_explode_data(sel_expr);
5370
5371 if let Some((is_posexplode, arg_expr, explicit_alias, explicit_pos_alias)) = explode_data {
5372 let arg_sql = target_dialect
5374 .generate(&arg_expr)
5375 .unwrap_or_else(|_| "NULL".to_string());
5376
5377 let unnest_source_alias = new_name(&mut taken_source_names, "_u");
5378
5379 let explode_alias = if let Some(ref ea) = explicit_alias {
5380 taken_select_names.remove(ea.as_str());
5383 let name = new_name(&mut taken_select_names, ea);
5385 name
5386 } else {
5387 new_name(&mut taken_select_names, "col")
5388 };
5389
5390 let pos_alias = if let Some(ref pa) = explicit_pos_alias {
5391 taken_select_names.remove(pa.as_str());
5393 let name = new_name(&mut taken_select_names, pa);
5394 name
5395 } else {
5396 new_name(&mut taken_select_names, "pos")
5397 };
5398
5399 if is_presto {
5401 let if_col = format!(
5403 "IF({}.{} = {}.{}, {}.{}) AS {}",
5404 series_source_alias,
5405 series_alias,
5406 unnest_source_alias,
5407 pos_alias,
5408 unnest_source_alias,
5409 explode_alias,
5410 explode_alias
5411 );
5412 new_projections.push(if_col);
5413
5414 if is_posexplode {
5416 let if_pos = format!(
5417 "IF({}.{} = {}.{}, {}.{}) AS {}",
5418 series_source_alias,
5419 series_alias,
5420 unnest_source_alias,
5421 pos_alias,
5422 unnest_source_alias,
5423 pos_alias,
5424 pos_alias
5425 );
5426 new_projections.push(if_pos);
5427 }
5428 } else {
5429 let if_col = format!(
5431 "IF({} = {}, {}, NULL) AS {}",
5432 series_alias, pos_alias, explode_alias, explode_alias
5433 );
5434 new_projections.push(if_col);
5435
5436 if is_posexplode {
5438 let if_pos = format!(
5439 "IF({} = {}, {}, NULL) AS {}",
5440 series_alias, pos_alias, pos_alias, pos_alias
5441 );
5442 new_projections.push(if_pos);
5443 }
5444 }
5445
5446 explode_infos.push(ExplodeInfo {
5447 arg_sql,
5448 explode_alias,
5449 pos_alias,
5450 unnest_source_alias,
5451 });
5452 } else {
5453 let sel_sql = target_dialect
5455 .generate(sel_expr)
5456 .unwrap_or_else(|_| "*".to_string());
5457 new_projections.push(sel_sql);
5458 }
5459 }
5460
5461 if explode_infos.is_empty() {
5462 return Ok(Expression::Select(Box::new(select)));
5463 }
5464
5465 let mut from_parts: Vec<String> = Vec::new();
5467
5468 if let Some(ref from) = select.from {
5470 for from_expr in &from.expressions {
5471 let from_sql = target_dialect.generate(from_expr).unwrap_or_default();
5472 from_parts.push(from_sql);
5473 }
5474 }
5475
5476 let size_exprs: Vec<String> = explode_infos
5478 .iter()
5479 .map(|info| {
5480 if is_presto {
5481 format!("CARDINALITY({})", info.arg_sql)
5482 } else {
5483 format!("ARRAY_LENGTH({})", info.arg_sql)
5484 }
5485 })
5486 .collect();
5487
5488 let greatest_arg = if size_exprs.len() == 1 {
5489 size_exprs[0].clone()
5490 } else {
5491 format!("GREATEST({})", size_exprs.join(", "))
5492 };
5493
5494 let series_sql = if is_presto {
5497 if size_exprs.len() == 1 {
5499 format!(
5500 "UNNEST(SEQUENCE(1, GREATEST({}))) AS {}({})",
5501 greatest_arg, series_source_alias, series_alias
5502 )
5503 } else {
5504 format!(
5506 "UNNEST(SEQUENCE(1, {})) AS {}({})",
5507 greatest_arg, series_source_alias, series_alias
5508 )
5509 }
5510 } else {
5511 if size_exprs.len() == 1 {
5513 format!(
5514 "UNNEST(GENERATE_ARRAY(0, GREATEST({}) - 1)) AS {}",
5515 greatest_arg, series_alias
5516 )
5517 } else {
5518 format!(
5520 "UNNEST(GENERATE_ARRAY(0, {} - 1)) AS {}",
5521 greatest_arg, series_alias
5522 )
5523 }
5524 };
5525
5526 let mut cross_joins: Vec<String> = Vec::new();
5530
5531 for info in &explode_infos {
5532 cross_joins.push(format!(
5534 "CROSS JOIN UNNEST({}) WITH ORDINALITY AS {}({}, {})",
5535 info.arg_sql, info.unnest_source_alias, info.explode_alias, info.pos_alias
5536 ));
5537 }
5538
5539 let mut where_conditions: Vec<String> = Vec::new();
5541
5542 for info in &explode_infos {
5543 let size_expr = if is_presto {
5544 format!("CARDINALITY({})", info.arg_sql)
5545 } else {
5546 format!("ARRAY_LENGTH({})", info.arg_sql)
5547 };
5548
5549 let cond = if is_presto {
5550 format!(
5551 "{series_src}.{series_al} = {unnest_src}.{pos_al} OR ({series_src}.{series_al} > {size} AND {unnest_src}.{pos_al} = {size})",
5552 series_src = series_source_alias,
5553 series_al = series_alias,
5554 unnest_src = info.unnest_source_alias,
5555 pos_al = info.pos_alias,
5556 size = size_expr
5557 )
5558 } else {
5559 format!(
5560 "{series_al} = {pos_al} OR ({series_al} > ({size} - 1) AND {pos_al} = ({size} - 1))",
5561 series_al = series_alias,
5562 pos_al = info.pos_alias,
5563 size = size_expr
5564 )
5565 };
5566
5567 where_conditions.push(cond);
5568 }
5569
5570 let where_sql = if where_conditions.len() == 1 {
5572 where_conditions[0].clone()
5573 } else {
5574 where_conditions
5575 .iter()
5576 .map(|c| format!("({})", c))
5577 .collect::<Vec<_>>()
5578 .join(" AND ")
5579 };
5580
5581 let select_part = new_projections.join(", ");
5583
5584 let from_and_joins = if from_parts.is_empty() {
5586 format!("FROM {} {}", series_sql, cross_joins.join(" "))
5588 } else {
5589 format!(
5590 "FROM {} {} {}",
5591 from_parts.join(", "),
5592 format!("CROSS JOIN {}", series_sql),
5593 cross_joins.join(" ")
5594 )
5595 };
5596
5597 let full_sql = format!(
5598 "SELECT {} {} WHERE {}",
5599 select_part, from_and_joins, where_sql
5600 );
5601
5602 let generic_dialect = Dialect::get(DialectType::Generic);
5605 let parsed = generic_dialect.parse(&full_sql);
5606 match parsed {
5607 Ok(mut stmts) if !stmts.is_empty() => {
5608 let mut result = stmts.remove(0);
5609
5610 if is_bigquery {
5614 convert_unnest_presto_to_bigquery(&mut result);
5615 }
5616
5617 Ok(result)
5618 }
5619 _ => {
5620 Ok(Expression::Select(Box::new(select)))
5622 }
5623 }
5624}
5625
5626fn convert_unnest_presto_to_bigquery(expr: &mut Expression) {
5630 match expr {
5631 Expression::Select(ref mut select) => {
5632 if let Some(ref mut from) = select.from {
5634 for from_item in from.expressions.iter_mut() {
5635 convert_unnest_presto_to_bigquery(from_item);
5636 }
5637 }
5638 for join in select.joins.iter_mut() {
5640 convert_unnest_presto_to_bigquery(&mut join.this);
5641 }
5642 }
5643 Expression::Alias(ref alias) => {
5644 if let Expression::Unnest(ref unnest) = alias.this {
5646 if unnest.with_ordinality && alias.column_aliases.len() >= 2 {
5647 let col_alias = alias.column_aliases[0].clone();
5648 let pos_alias = alias.column_aliases[1].clone();
5649 let mut new_unnest = unnest.as_ref().clone();
5650 new_unnest.alias = Some(col_alias);
5651 new_unnest.offset_alias = Some(pos_alias);
5652 *expr = Expression::Unnest(Box::new(new_unnest));
5654 }
5655 }
5656 }
5657 _ => {}
5658 }
5659}
5660
5661fn new_name(names: &mut std::collections::HashSet<String>, base: &str) -> String {
5664 if !names.contains(base) {
5665 names.insert(base.to_string());
5666 return base.to_string();
5667 }
5668 let mut i = 2;
5669 loop {
5670 let candidate = format!("{}_{}", base, i);
5671 if !names.contains(&candidate) {
5672 names.insert(candidate.clone());
5673 return candidate;
5674 }
5675 i += 1;
5676 }
5677}
5678
5679fn expr_contains_explode(expr: &Expression) -> bool {
5681 match expr {
5682 Expression::Explode(_) => true,
5683 Expression::ExplodeOuter(_) => true,
5684 Expression::Function(f) => {
5685 let name = f.name.to_uppercase();
5686 name == "POSEXPLODE" || name == "POSEXPLODE_OUTER"
5687 }
5688 Expression::Alias(a) => expr_contains_explode(&a.this),
5689 _ => false,
5690 }
5691}
5692
5693fn find_explode_in_expr(expr: &Expression) -> Option<Expression> {
5695 match expr {
5696 Expression::Explode(uf) => Some(uf.this.clone()),
5697 Expression::ExplodeOuter(uf) => Some(uf.this.clone()),
5698 Expression::Function(f) => {
5699 let name = f.name.to_uppercase();
5700 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5701 Some(f.args[0].clone())
5702 } else {
5703 None
5704 }
5705 }
5706 Expression::Alias(a) => find_explode_in_expr(&a.this),
5707 _ => None,
5708 }
5709}
5710
5711fn extract_explode_data(
5714 expr: &Expression,
5715) -> Option<(bool, Expression, Option<String>, Option<String>)> {
5716 match expr {
5717 Expression::Explode(uf) => Some((false, uf.this.clone(), None, None)),
5719 Expression::ExplodeOuter(uf) => Some((false, uf.this.clone(), None, None)),
5720 Expression::Function(f) => {
5722 let name = f.name.to_uppercase();
5723 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5724 Some((true, f.args[0].clone(), None, None))
5725 } else {
5726 None
5727 }
5728 }
5729 Expression::Alias(a) => {
5731 match &a.this {
5732 Expression::Explode(uf) => {
5733 let alias = if !a.alias.is_empty() {
5734 Some(a.alias.name.clone())
5735 } else {
5736 None
5737 };
5738 Some((false, uf.this.clone(), alias, None))
5739 }
5740 Expression::ExplodeOuter(uf) => {
5741 let alias = if !a.alias.is_empty() {
5742 Some(a.alias.name.clone())
5743 } else {
5744 None
5745 };
5746 Some((false, uf.this.clone(), alias, None))
5747 }
5748 Expression::Function(f) => {
5749 let name = f.name.to_uppercase();
5750 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
5751 if a.column_aliases.len() == 2 {
5753 let pos_alias = a.column_aliases[0].name.clone();
5754 let col_alias = a.column_aliases[1].name.clone();
5755 Some((true, f.args[0].clone(), Some(col_alias), Some(pos_alias)))
5756 } else if !a.alias.is_empty() {
5757 Some((true, f.args[0].clone(), Some(a.alias.name.clone()), None))
5759 } else {
5760 Some((true, f.args[0].clone(), None, None))
5761 }
5762 } else {
5763 None
5764 }
5765 }
5766 _ => None,
5767 }
5768 }
5769 _ => None,
5770 }
5771}
5772
5773fn get_output_name(expr: &Expression) -> Option<String> {
5775 match expr {
5776 Expression::Alias(a) => {
5777 if !a.alias.is_empty() {
5778 Some(a.alias.name.clone())
5779 } else {
5780 None
5781 }
5782 }
5783 Expression::Column(c) => Some(c.name.name.clone()),
5784 Expression::Identifier(id) => Some(id.name.clone()),
5785 _ => None,
5786 }
5787}
5788
5789fn collect_source_names(expr: &Expression, names: &mut std::collections::HashSet<String>) {
5791 match expr {
5792 Expression::Alias(a) => {
5793 if !a.alias.is_empty() {
5794 names.insert(a.alias.name.clone());
5795 }
5796 }
5797 Expression::Subquery(s) => {
5798 if let Some(ref alias) = s.alias {
5799 names.insert(alias.name.clone());
5800 }
5801 }
5802 Expression::Table(t) => {
5803 if let Some(ref alias) = t.alias {
5804 names.insert(alias.name.clone());
5805 } else {
5806 names.insert(t.name.name.clone());
5807 }
5808 }
5809 Expression::Column(c) => {
5810 names.insert(c.name.name.clone());
5811 }
5812 Expression::Identifier(id) => {
5813 names.insert(id.name.clone());
5814 }
5815 _ => {}
5816 }
5817}
5818
5819pub fn strip_unnest_column_refs(expr: Expression) -> Result<Expression> {
5822 use crate::dialects::transform_recursive;
5823 transform_recursive(expr, &strip_unnest_column_refs_single)
5824}
5825
5826fn strip_unnest_column_refs_single(expr: Expression) -> Result<Expression> {
5827 if let Expression::Select(mut select) = expr {
5828 for join in select.joins.iter_mut() {
5830 strip_unnest_from_expr(&mut join.this);
5831 }
5832 if let Some(ref mut from) = select.from {
5834 for from_item in from.expressions.iter_mut() {
5835 strip_unnest_from_expr(from_item);
5836 }
5837 }
5838 Ok(Expression::Select(select))
5839 } else {
5840 Ok(expr)
5841 }
5842}
5843
5844fn strip_unnest_from_expr(expr: &mut Expression) {
5847 if let Expression::Alias(ref mut alias) = expr {
5848 if let Expression::Unnest(ref unnest) = alias.this {
5849 let is_column_ref = matches!(&unnest.this, Expression::Column(_) | Expression::Dot(_));
5850 if is_column_ref {
5851 let inner = unnest.this.clone();
5853 alias.this = inner;
5854 }
5855 }
5856 }
5857}
5858
5859pub fn wrap_duckdb_unnest_struct(expr: Expression) -> Result<Expression> {
5862 use crate::dialects::transform_recursive;
5863 transform_recursive(expr, &wrap_duckdb_unnest_struct_single)
5864}
5865
5866fn wrap_duckdb_unnest_struct_single(expr: Expression) -> Result<Expression> {
5867 if let Expression::Select(mut select) = expr {
5868 if let Some(ref mut from) = select.from {
5870 for from_item in from.expressions.iter_mut() {
5871 try_wrap_unnest_in_subquery(from_item);
5872 }
5873 }
5874
5875 for join in select.joins.iter_mut() {
5877 try_wrap_unnest_in_subquery(&mut join.this);
5878 }
5879
5880 Ok(Expression::Select(select))
5881 } else {
5882 Ok(expr)
5883 }
5884}
5885
5886fn is_struct_array_unnest_arg(expr: &Expression) -> bool {
5888 match expr {
5889 Expression::Array(arr) => arr
5891 .expressions
5892 .iter()
5893 .any(|e| matches!(e, Expression::Struct(_))),
5894 Expression::ArrayFunc(arr) => arr
5895 .expressions
5896 .iter()
5897 .any(|e| matches!(e, Expression::Struct(_))),
5898 Expression::Cast(c) => {
5900 matches!(&c.to, DataType::Array { element_type, .. } if matches!(**element_type, DataType::Struct { .. }))
5901 }
5902 _ => false,
5903 }
5904}
5905
5906fn try_wrap_unnest_in_subquery(expr: &mut Expression) {
5909 if let Expression::Alias(ref alias) = expr {
5911 if let Expression::Unnest(ref unnest) = alias.this {
5912 if is_struct_array_unnest_arg(&unnest.this) {
5913 let unnest_clone = (**unnest).clone();
5914 let alias_name = alias.alias.clone();
5915 let new_expr = make_unnest_subquery(unnest_clone, Some(alias_name));
5916 *expr = new_expr;
5917 return;
5918 }
5919 }
5920 }
5921
5922 if let Expression::Unnest(ref unnest) = expr {
5924 if is_struct_array_unnest_arg(&unnest.this) {
5925 let unnest_clone = (**unnest).clone();
5926 let new_expr = make_unnest_subquery(unnest_clone, None);
5927 *expr = new_expr;
5928 }
5929 }
5930}
5931
5932fn make_unnest_subquery(unnest: UnnestFunc, alias: Option<Identifier>) -> Expression {
5934 let max_depth_arg = Expression::NamedArgument(Box::new(NamedArgument {
5936 name: Identifier::new("max_depth".to_string()),
5937 value: Expression::Literal(Box::new(Literal::Number("2".to_string()))),
5938 separator: NamedArgSeparator::DArrow,
5939 }));
5940
5941 let mut unnest_args = vec![unnest.this];
5942 unnest_args.extend(unnest.expressions);
5943 unnest_args.push(max_depth_arg);
5944
5945 let unnest_func =
5946 Expression::Function(Box::new(Function::new("UNNEST".to_string(), unnest_args)));
5947
5948 let mut inner_select = Select::new();
5950 inner_select.expressions = vec![unnest_func];
5951 let inner_select = Expression::Select(Box::new(inner_select));
5952
5953 let subquery = Subquery {
5955 this: inner_select,
5956 alias,
5957 column_aliases: Vec::new(),
5958 alias_explicit_as: false,
5959 alias_keyword: None,
5960 order_by: None,
5961 limit: None,
5962 offset: None,
5963 distribute_by: None,
5964 sort_by: None,
5965 cluster_by: None,
5966 lateral: false,
5967 modifiers_inside: false,
5968 trailing_comments: Vec::new(),
5969 inferred_type: None,
5970 };
5971
5972 Expression::Subquery(Box::new(subquery))
5973}
5974
5975pub fn no_limit_order_by_union(expr: Expression) -> Result<Expression> {
5987 use crate::expressions::{split_set_limit, Limit, Offset as OffsetClause, OrderBy, Star};
5988
5989 match expr {
5990 Expression::Union(mut u) => {
5991 if u.order_by.is_none() && u.limit.is_none() && u.offset.is_none() {
5994 if let Expression::Select(ref mut right_select) = u.right {
5996 if right_select.order_by.is_some()
5997 || right_select.limit.is_some()
5998 || right_select.offset.is_some()
5999 {
6000 u.order_by = right_select.order_by.take();
6002 u.limit = right_select.limit.take().map(Limit::into_set_limit);
6003 u.offset = right_select.offset.take().map(|o| Box::new(o.this));
6004 }
6005 }
6006 }
6007
6008 let has_order_or_limit =
6009 u.order_by.is_some() || u.limit.is_some() || u.offset.is_some();
6010 if has_order_or_limit {
6011 let order_by: Option<OrderBy> = u.order_by.take();
6013 let union_limit: Option<Box<Expression>> = u.limit.take();
6014 let union_offset: Option<Box<Expression>> = u.offset.take();
6015
6016 let (select_limit, select_fetch) = split_set_limit(union_limit);
6017
6018 let select_offset: Option<OffsetClause> = union_offset.map(|o| OffsetClause {
6020 this: *o,
6021 rows: None,
6022 });
6023
6024 let subquery = Subquery {
6026 this: Expression::Union(u),
6027 alias: Some(Identifier::new("_l_0")),
6028 column_aliases: Vec::new(),
6029 alias_explicit_as: true,
6030 alias_keyword: None,
6031 lateral: false,
6032 modifiers_inside: false,
6033 order_by: None,
6034 limit: None,
6035 offset: None,
6036 distribute_by: None,
6037 sort_by: None,
6038 cluster_by: None,
6039 trailing_comments: Vec::new(),
6040 inferred_type: None,
6041 };
6042
6043 let mut select = Select::default();
6045 select.expressions = vec![Expression::Star(Star {
6046 table: None,
6047 except: None,
6048 replace: None,
6049 rename: None,
6050 trailing_comments: Vec::new(),
6051 span: None,
6052 })];
6053 select.from = Some(From {
6054 expressions: vec![Expression::Subquery(Box::new(subquery))],
6055 });
6056 select.order_by = order_by;
6057 select.limit = select_limit;
6058 select.fetch = select_fetch;
6059 select.offset = select_offset;
6060
6061 Ok(Expression::Select(Box::new(select)))
6062 } else {
6063 Ok(Expression::Union(u))
6064 }
6065 }
6066 _ => Ok(expr),
6067 }
6068}
6069
6070pub fn expand_like_any(expr: Expression) -> Result<Expression> {
6078 use crate::expressions::{BinaryOp, LikeOp, Paren};
6079
6080 const LIKE_ALL_MARKER: &str = "__LIKE_ALL_EXPANSION__";
6083
6084 fn unwrap_parens(e: &Expression) -> &Expression {
6085 match e {
6086 Expression::Paren(p) => unwrap_parens(&p.this),
6087 _ => e,
6088 }
6089 }
6090
6091 fn extract_tuple_values(e: &Expression) -> Option<Vec<Expression>> {
6092 let inner = unwrap_parens(e);
6093 match inner {
6094 Expression::Tuple(t) => Some(t.expressions.clone()),
6095 _ if !matches!(e, Expression::Tuple(_)) => Some(vec![inner.clone()]),
6097 _ => None,
6098 }
6099 }
6100
6101 fn expand_like_quantifier(
6103 op: &LikeOp,
6104 values: Vec<Expression>,
6105 is_ilike: bool,
6106 combiner: fn(Expression, Expression) -> Expression,
6107 wrap_marker: bool,
6108 ) -> Expression {
6109 let num_values = values.len();
6110 let mut result: Option<Expression> = None;
6111 for val in values {
6112 let like = if is_ilike {
6113 Expression::ILike(Box::new(LikeOp {
6114 left: op.left.clone(),
6115 right: val,
6116 escape: op.escape.clone(),
6117 quantifier: None,
6118 inferred_type: None,
6119 }))
6120 } else {
6121 Expression::Like(Box::new(LikeOp {
6122 left: op.left.clone(),
6123 right: val,
6124 escape: op.escape.clone(),
6125 quantifier: None,
6126 inferred_type: None,
6127 }))
6128 };
6129 result = Some(match result {
6130 None => like,
6131 Some(prev) => combiner(prev, like),
6132 });
6133 }
6134 let expanded = result.unwrap_or_else(|| unreachable!("values is non-empty"));
6135 if wrap_marker && num_values > 1 {
6139 Expression::Paren(Box::new(Paren {
6140 this: expanded,
6141 trailing_comments: vec![LIKE_ALL_MARKER.to_string()],
6142 }))
6143 } else {
6144 expanded
6145 }
6146 }
6147
6148 fn or_combiner(a: Expression, b: Expression) -> Expression {
6149 Expression::Or(Box::new(BinaryOp::new(a, b)))
6150 }
6151
6152 fn and_combiner(a: Expression, b: Expression) -> Expression {
6153 Expression::And(Box::new(BinaryOp::new(a, b)))
6154 }
6155
6156 fn is_like_all_marker(p: &Paren) -> bool {
6157 p.trailing_comments.len() == 1 && p.trailing_comments[0] == LIKE_ALL_MARKER
6158 }
6159
6160 let result = transform_recursive(expr, &|e| {
6168 match e {
6169 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ANY") => {
6171 if let Some(values) = extract_tuple_values(&op.right) {
6172 if values.is_empty() {
6173 return Ok(e);
6174 }
6175 Ok(expand_like_quantifier(
6176 op,
6177 values,
6178 false,
6179 or_combiner,
6180 false,
6181 ))
6182 } else {
6183 Ok(e)
6184 }
6185 }
6186 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ALL") => {
6188 if let Some(values) = extract_tuple_values(&op.right) {
6189 if values.is_empty() {
6190 return Ok(e);
6191 }
6192 Ok(expand_like_quantifier(
6193 op,
6194 values,
6195 false,
6196 and_combiner,
6197 true,
6198 ))
6199 } else {
6200 Ok(e)
6201 }
6202 }
6203 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ANY") => {
6205 if let Some(values) = extract_tuple_values(&op.right) {
6206 if values.is_empty() {
6207 return Ok(e);
6208 }
6209 Ok(expand_like_quantifier(op, values, true, or_combiner, false))
6210 } else {
6211 Ok(e)
6212 }
6213 }
6214 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ALL") => {
6216 if let Some(values) = extract_tuple_values(&op.right) {
6217 if values.is_empty() {
6218 return Ok(e);
6219 }
6220 Ok(expand_like_quantifier(op, values, true, and_combiner, true))
6221 } else {
6222 Ok(e)
6223 }
6224 }
6225 Expression::And(mut op) => {
6230 if matches!(&op.left, Expression::Or(_)) {
6231 op.left = Expression::Paren(Box::new(Paren {
6232 this: op.left,
6233 trailing_comments: vec![],
6234 }));
6235 }
6236 if matches!(&op.right, Expression::Or(_)) {
6237 op.right = Expression::Paren(Box::new(Paren {
6238 this: op.right,
6239 trailing_comments: vec![],
6240 }));
6241 }
6242 Ok(Expression::And(op))
6243 }
6244 Expression::Or(mut op) => {
6247 if let Expression::Paren(ref mut p) = op.left {
6248 if is_like_all_marker(p) {
6249 p.trailing_comments.clear();
6250 }
6251 }
6252 if let Expression::Paren(ref mut p) = op.right {
6253 if is_like_all_marker(p) {
6254 p.trailing_comments.clear();
6255 }
6256 }
6257 Ok(Expression::Or(op))
6258 }
6259 _ => Ok(e),
6260 }
6261 })?;
6262
6263 transform_recursive(result, &|e| {
6267 if let Expression::Paren(p) = &e {
6268 if is_like_all_marker(p) {
6269 let Expression::Paren(p) = e else {
6270 unreachable!()
6271 };
6272 return Ok(p.this);
6273 }
6274 }
6275 Ok(e)
6276 })
6277}
6278
6279pub fn qualify_derived_table_outputs(expr: Expression) -> Result<Expression> {
6287 use crate::expressions::Alias;
6288
6289 fn add_self_aliases_to_select(select: &mut Select) {
6290 let new_expressions: Vec<Expression> = select
6291 .expressions
6292 .iter()
6293 .map(|e| {
6294 match e {
6295 Expression::Column(col) => {
6297 let alias_name = col.name.clone();
6298 Expression::Alias(Box::new(Alias {
6299 this: e.clone(),
6300 alias: alias_name,
6301 column_aliases: Vec::new(),
6302 alias_explicit_as: false,
6303 alias_keyword: None,
6304 pre_alias_comments: Vec::new(),
6305 trailing_comments: Vec::new(),
6306 inferred_type: None,
6307 }))
6308 }
6309 _ => e.clone(),
6311 }
6312 })
6313 .collect();
6314 select.expressions = new_expressions;
6315 }
6316
6317 fn walk_and_qualify(expr: &mut Expression) {
6318 match expr {
6319 Expression::Select(ref mut select) => {
6320 if let Some(ref mut from) = select.from {
6322 for e in from.expressions.iter_mut() {
6323 qualify_subquery_expr(e);
6324 walk_and_qualify(e);
6325 }
6326 }
6327 for join in select.joins.iter_mut() {
6329 qualify_subquery_expr(&mut join.this);
6330 walk_and_qualify(&mut join.this);
6331 }
6332 for e in select.expressions.iter_mut() {
6334 walk_and_qualify(e);
6335 }
6336 if let Some(ref mut w) = select.where_clause {
6338 walk_and_qualify(&mut w.this);
6339 }
6340 }
6341 Expression::Subquery(ref mut subquery) => {
6342 walk_and_qualify(&mut subquery.this);
6343 }
6344 Expression::Union(ref mut u) => {
6345 walk_and_qualify(&mut u.left);
6346 walk_and_qualify(&mut u.right);
6347 }
6348 Expression::Intersect(ref mut i) => {
6349 walk_and_qualify(&mut i.left);
6350 walk_and_qualify(&mut i.right);
6351 }
6352 Expression::Except(ref mut e) => {
6353 walk_and_qualify(&mut e.left);
6354 walk_and_qualify(&mut e.right);
6355 }
6356 Expression::Cte(ref mut cte) => {
6357 walk_and_qualify(&mut cte.this);
6358 }
6359 _ => {}
6360 }
6361 }
6362
6363 fn qualify_subquery_expr(expr: &mut Expression) {
6364 match expr {
6365 Expression::Subquery(ref mut subquery) => {
6366 if subquery.alias.is_some() && subquery.column_aliases.is_empty() {
6368 if let Expression::Select(ref mut inner_select) = subquery.this {
6369 let has_star = inner_select
6371 .expressions
6372 .iter()
6373 .any(|e| matches!(e, Expression::Star(_)));
6374 if !has_star {
6375 add_self_aliases_to_select(inner_select);
6376 }
6377 }
6378 }
6379 walk_and_qualify(&mut subquery.this);
6381 }
6382 Expression::Alias(ref mut alias) => {
6383 qualify_subquery_expr(&mut alias.this);
6384 }
6385 _ => {}
6386 }
6387 }
6388
6389 let mut result = expr;
6390 walk_and_qualify(&mut result);
6391
6392 if let Expression::Select(ref mut select) = result {
6394 if let Some(ref mut with) = select.with {
6395 for cte in with.ctes.iter_mut() {
6396 if cte.columns.is_empty() {
6398 walk_and_qualify(&mut cte.this);
6400 }
6401 }
6402 }
6403 }
6404
6405 Ok(result)
6406}
6407
6408#[cfg(test)]
6409mod tests {
6410 use super::*;
6411 use crate::dialects::{Dialect, DialectType};
6412 use crate::expressions::Column;
6413
6414 fn gen(expr: &Expression) -> String {
6415 let dialect = Dialect::get(DialectType::Generic);
6416 dialect.generate(expr).unwrap()
6417 }
6418
6419 #[test]
6420 fn test_preprocess() {
6421 let expr = Expression::Boolean(BooleanLiteral { value: true });
6422 let result = preprocess(expr, &[replace_bool_with_int]).unwrap();
6423 assert!(
6424 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
6425 );
6426 }
6427
6428 #[test]
6429 fn test_preprocess_chain() {
6430 let expr = Expression::Boolean(BooleanLiteral { value: true });
6432 let transforms: Vec<fn(Expression) -> Result<Expression>> =
6434 vec![replace_bool_with_int, replace_int_with_bool];
6435 let result = preprocess(expr, &transforms).unwrap();
6436 if let Expression::Boolean(b) = result {
6439 assert!(b.value);
6440 } else {
6441 panic!("Expected boolean literal");
6442 }
6443 }
6444
6445 #[test]
6446 fn test_unnest_to_explode() {
6447 let unnest = Expression::Unnest(Box::new(UnnestFunc {
6448 this: Expression::boxed_column(Column {
6449 name: Identifier::new("arr".to_string()),
6450 table: None,
6451 join_mark: false,
6452 trailing_comments: vec![],
6453 span: None,
6454 inferred_type: None,
6455 }),
6456 expressions: Vec::new(),
6457 with_ordinality: false,
6458 alias: None,
6459 offset_alias: None,
6460 inferred_type: None,
6461 }));
6462
6463 let result = unnest_to_explode(unnest).unwrap();
6464 assert!(matches!(result, Expression::Explode(_)));
6465 }
6466
6467 #[test]
6468 fn test_explode_to_unnest() {
6469 let explode = Expression::Explode(Box::new(UnaryFunc {
6470 this: Expression::boxed_column(Column {
6471 name: Identifier::new("arr".to_string()),
6472 table: None,
6473 join_mark: false,
6474 trailing_comments: vec![],
6475 span: None,
6476 inferred_type: None,
6477 }),
6478 original_name: None,
6479 inferred_type: None,
6480 }));
6481
6482 let result = explode_to_unnest(explode).unwrap();
6483 assert!(matches!(result, Expression::Unnest(_)));
6484 }
6485
6486 #[test]
6487 fn test_replace_bool_with_int() {
6488 let true_expr = Expression::Boolean(BooleanLiteral { value: true });
6489 let result = replace_bool_with_int(true_expr).unwrap();
6490 if let Expression::Literal(lit) = result {
6491 if let Literal::Number(n) = lit.as_ref() {
6492 assert_eq!(n, "1");
6493 }
6494 } else {
6495 panic!("Expected number literal");
6496 }
6497
6498 let false_expr = Expression::Boolean(BooleanLiteral { value: false });
6499 let result = replace_bool_with_int(false_expr).unwrap();
6500 if let Expression::Literal(lit) = result {
6501 if let Literal::Number(n) = lit.as_ref() {
6502 assert_eq!(n, "0");
6503 }
6504 } else {
6505 panic!("Expected number literal");
6506 }
6507 }
6508
6509 #[test]
6510 fn test_replace_int_with_bool() {
6511 let one_expr = Expression::Literal(Box::new(Literal::Number("1".to_string())));
6512 let result = replace_int_with_bool(one_expr).unwrap();
6513 if let Expression::Boolean(b) = result {
6514 assert!(b.value);
6515 } else {
6516 panic!("Expected boolean true");
6517 }
6518
6519 let zero_expr = Expression::Literal(Box::new(Literal::Number("0".to_string())));
6520 let result = replace_int_with_bool(zero_expr).unwrap();
6521 if let Expression::Boolean(b) = result {
6522 assert!(!b.value);
6523 } else {
6524 panic!("Expected boolean false");
6525 }
6526
6527 let two_expr = Expression::Literal(Box::new(Literal::Number("2".to_string())));
6529 let result = replace_int_with_bool(two_expr).unwrap();
6530 assert!(
6531 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
6532 );
6533 }
6534
6535 #[test]
6536 fn test_strip_data_type_params() {
6537 let decimal = DataType::Decimal {
6539 precision: Some(10),
6540 scale: Some(2),
6541 };
6542 let stripped = strip_data_type_params(decimal);
6543 assert_eq!(
6544 stripped,
6545 DataType::Decimal {
6546 precision: None,
6547 scale: None
6548 }
6549 );
6550
6551 let varchar = DataType::VarChar {
6553 length: Some(255),
6554 parenthesized_length: false,
6555 };
6556 let stripped = strip_data_type_params(varchar);
6557 assert_eq!(
6558 stripped,
6559 DataType::VarChar {
6560 length: None,
6561 parenthesized_length: false
6562 }
6563 );
6564
6565 let char_type = DataType::Char { length: Some(10) };
6567 let stripped = strip_data_type_params(char_type);
6568 assert_eq!(stripped, DataType::Char { length: None });
6569
6570 let timestamp = DataType::Timestamp {
6572 precision: Some(6),
6573 timezone: true,
6574 };
6575 let stripped = strip_data_type_params(timestamp);
6576 assert_eq!(
6577 stripped,
6578 DataType::Timestamp {
6579 precision: None,
6580 timezone: true
6581 }
6582 );
6583
6584 let array = DataType::Array {
6586 element_type: Box::new(DataType::VarChar {
6587 length: Some(100),
6588 parenthesized_length: false,
6589 }),
6590 dimension: None,
6591 };
6592 let stripped = strip_data_type_params(array);
6593 assert_eq!(
6594 stripped,
6595 DataType::Array {
6596 element_type: Box::new(DataType::VarChar {
6597 length: None,
6598 parenthesized_length: false
6599 }),
6600 dimension: None,
6601 }
6602 );
6603
6604 let text = DataType::Text;
6606 let stripped = strip_data_type_params(text);
6607 assert_eq!(stripped, DataType::Text);
6608 }
6609
6610 #[test]
6611 fn test_remove_precision_parameterized_types_cast() {
6612 let cast_expr = Expression::Cast(Box::new(Cast {
6614 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
6615 to: DataType::Decimal {
6616 precision: Some(10),
6617 scale: Some(2),
6618 },
6619 trailing_comments: vec![],
6620 double_colon_syntax: false,
6621 format: None,
6622 default: None,
6623 inferred_type: None,
6624 }));
6625
6626 let result = remove_precision_parameterized_types(cast_expr).unwrap();
6627 if let Expression::Cast(cast) = result {
6628 assert_eq!(
6629 cast.to,
6630 DataType::Decimal {
6631 precision: None,
6632 scale: None
6633 }
6634 );
6635 } else {
6636 panic!("Expected Cast expression");
6637 }
6638 }
6639
6640 #[test]
6641 fn test_remove_precision_parameterized_types_varchar() {
6642 let cast_expr = Expression::Cast(Box::new(Cast {
6644 this: Expression::Literal(Box::new(Literal::String("hello".to_string()))),
6645 to: DataType::VarChar {
6646 length: Some(10),
6647 parenthesized_length: false,
6648 },
6649 trailing_comments: vec![],
6650 double_colon_syntax: false,
6651 format: None,
6652 default: None,
6653 inferred_type: None,
6654 }));
6655
6656 let result = remove_precision_parameterized_types(cast_expr).unwrap();
6657 if let Expression::Cast(cast) = result {
6658 assert_eq!(
6659 cast.to,
6660 DataType::VarChar {
6661 length: None,
6662 parenthesized_length: false
6663 }
6664 );
6665 } else {
6666 panic!("Expected Cast expression");
6667 }
6668 }
6669
6670 #[test]
6671 fn test_remove_precision_direct_cast() {
6672 let cast = Expression::Cast(Box::new(Cast {
6676 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
6677 to: DataType::Decimal {
6678 precision: Some(10),
6679 scale: Some(2),
6680 },
6681 trailing_comments: vec![],
6682 double_colon_syntax: false,
6683 format: None,
6684 default: None,
6685 inferred_type: None,
6686 }));
6687
6688 let transformed = remove_precision_parameterized_types(cast).unwrap();
6689 let generated = gen(&transformed);
6690
6691 assert!(generated.contains("DECIMAL"));
6693 assert!(!generated.contains("(10"));
6694 }
6695
6696 #[test]
6697 fn test_epoch_cast_to_ts() {
6698 let cast_expr = Expression::Cast(Box::new(Cast {
6700 this: Expression::Literal(Box::new(Literal::String("epoch".to_string()))),
6701 to: DataType::Timestamp {
6702 precision: None,
6703 timezone: false,
6704 },
6705 trailing_comments: vec![],
6706 double_colon_syntax: false,
6707 format: None,
6708 default: None,
6709 inferred_type: None,
6710 }));
6711
6712 let result = epoch_cast_to_ts(cast_expr).unwrap();
6713 if let Expression::Cast(cast) = result {
6714 if let Expression::Literal(lit) = cast.this {
6715 if let Literal::String(s) = lit.as_ref() {
6716 assert_eq!(s, "1970-01-01 00:00:00");
6717 }
6718 } else {
6719 panic!("Expected string literal");
6720 }
6721 } else {
6722 panic!("Expected Cast expression");
6723 }
6724 }
6725
6726 #[test]
6727 fn test_epoch_cast_to_ts_preserves_non_epoch() {
6728 let cast_expr = Expression::Cast(Box::new(Cast {
6730 this: Expression::Literal(Box::new(Literal::String("2024-01-15".to_string()))),
6731 to: DataType::Timestamp {
6732 precision: None,
6733 timezone: false,
6734 },
6735 trailing_comments: vec![],
6736 double_colon_syntax: false,
6737 format: None,
6738 default: None,
6739 inferred_type: None,
6740 }));
6741
6742 let result = epoch_cast_to_ts(cast_expr).unwrap();
6743 if let Expression::Cast(cast) = result {
6744 if let Expression::Literal(lit) = cast.this {
6745 if let Literal::String(s) = lit.as_ref() {
6746 assert_eq!(s, "2024-01-15");
6747 }
6748 } else {
6749 panic!("Expected string literal");
6750 }
6751 } else {
6752 panic!("Expected Cast expression");
6753 }
6754 }
6755
6756 #[test]
6757 fn test_unqualify_columns() {
6758 let col = Expression::boxed_column(Column {
6760 name: Identifier::new("id".to_string()),
6761 table: Some(Identifier::new("users".to_string())),
6762 join_mark: false,
6763 trailing_comments: vec![],
6764 span: None,
6765 inferred_type: None,
6766 });
6767
6768 let result = unqualify_columns(col).unwrap();
6769 if let Expression::Column(c) = result {
6770 assert!(c.table.is_none());
6771 assert_eq!(c.name.name, "id");
6772 } else {
6773 panic!("Expected Column expression");
6774 }
6775 }
6776
6777 #[test]
6778 fn test_is_temporal_type() {
6779 assert!(is_temporal_type(&DataType::Date));
6780 assert!(is_temporal_type(&DataType::Timestamp {
6781 precision: None,
6782 timezone: false
6783 }));
6784 assert!(is_temporal_type(&DataType::Time {
6785 precision: None,
6786 timezone: false
6787 }));
6788 assert!(!is_temporal_type(&DataType::Int {
6789 length: None,
6790 integer_spelling: false
6791 }));
6792 assert!(!is_temporal_type(&DataType::VarChar {
6793 length: None,
6794 parenthesized_length: false
6795 }));
6796 }
6797
6798 #[test]
6799 fn test_eliminate_semi_join_basic() {
6800 use crate::expressions::{Join, TableRef};
6801
6802 let select = Expression::Select(Box::new(Select {
6804 vertica: None,
6805 expressions: vec![Expression::boxed_column(Column {
6806 name: Identifier::new("a".to_string()),
6807 table: None,
6808 join_mark: false,
6809 trailing_comments: vec![],
6810 span: None,
6811 inferred_type: None,
6812 })],
6813 from: Some(From {
6814 expressions: vec![Expression::Table(Box::new(TableRef::new("t1")))],
6815 }),
6816 joins: vec![Join {
6817 this: Expression::Table(Box::new(TableRef::new("t2"))),
6818 kind: JoinKind::Semi,
6819 on: Some(Expression::Eq(Box::new(BinaryOp {
6820 left: Expression::boxed_column(Column {
6821 name: Identifier::new("x".to_string()),
6822 table: None,
6823 join_mark: false,
6824 trailing_comments: vec![],
6825 span: None,
6826 inferred_type: None,
6827 }),
6828 right: Expression::boxed_column(Column {
6829 name: Identifier::new("y".to_string()),
6830 table: None,
6831 join_mark: false,
6832 trailing_comments: vec![],
6833 span: None,
6834 inferred_type: None,
6835 }),
6836 left_comments: vec![],
6837 operator_comments: vec![],
6838 trailing_comments: vec![],
6839 inferred_type: None,
6840 }))),
6841 using: vec![],
6842 use_inner_keyword: false,
6843 use_outer_keyword: false,
6844 deferred_condition: false,
6845 join_hint: None,
6846 match_condition: None,
6847 pivots: Vec::new(),
6848 comments: Vec::new(),
6849 nesting_group: 0,
6850 directed: false,
6851 }],
6852 ..Select::new()
6853 }));
6854
6855 let result = eliminate_semi_and_anti_joins(select).unwrap();
6856 if let Expression::Select(s) = result {
6857 assert!(s.joins.is_empty());
6859 assert!(s.where_clause.is_some());
6861 } else {
6862 panic!("Expected Select expression");
6863 }
6864 }
6865
6866 #[test]
6867 fn test_no_ilike_sql() {
6868 use crate::expressions::LikeOp;
6869
6870 let ilike_expr = Expression::ILike(Box::new(LikeOp {
6872 left: Expression::boxed_column(Column {
6873 name: Identifier::new("name".to_string()),
6874 table: None,
6875 join_mark: false,
6876 trailing_comments: vec![],
6877 span: None,
6878 inferred_type: None,
6879 }),
6880 right: Expression::Literal(Box::new(Literal::String("%test%".to_string()))),
6881 escape: None,
6882 quantifier: None,
6883 inferred_type: None,
6884 }));
6885
6886 let result = no_ilike_sql(ilike_expr).unwrap();
6887 if let Expression::Like(like) = result {
6888 if let Expression::Function(f) = &like.left {
6890 assert_eq!(f.name, "LOWER");
6891 } else {
6892 panic!("Expected LOWER function on left");
6893 }
6894 if let Expression::Function(f) = &like.right {
6896 assert_eq!(f.name, "LOWER");
6897 } else {
6898 panic!("Expected LOWER function on right");
6899 }
6900 } else {
6901 panic!("Expected Like expression");
6902 }
6903 }
6904
6905 #[test]
6906 fn test_no_trycast_sql() {
6907 let trycast_expr = Expression::TryCast(Box::new(Cast {
6909 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
6910 to: DataType::Int {
6911 length: None,
6912 integer_spelling: false,
6913 },
6914 trailing_comments: vec![],
6915 double_colon_syntax: false,
6916 format: None,
6917 default: None,
6918 inferred_type: None,
6919 }));
6920
6921 let result = no_trycast_sql(trycast_expr).unwrap();
6922 assert!(matches!(result, Expression::Cast(_)));
6923 }
6924
6925 #[test]
6926 fn test_no_safe_cast_sql() {
6927 let safe_cast_expr = Expression::SafeCast(Box::new(Cast {
6929 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
6930 to: DataType::Int {
6931 length: None,
6932 integer_spelling: false,
6933 },
6934 trailing_comments: vec![],
6935 double_colon_syntax: false,
6936 format: None,
6937 default: None,
6938 inferred_type: None,
6939 }));
6940
6941 let result = no_safe_cast_sql(safe_cast_expr).unwrap();
6942 assert!(matches!(result, Expression::Cast(_)));
6943 }
6944
6945 #[test]
6946 fn test_explode_to_unnest_presto() {
6947 let spark = Dialect::get(DialectType::Spark);
6948 let result = spark
6949 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::Presto)
6950 .unwrap();
6951 assert_eq!(
6952 result[0],
6953 "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))"
6954 );
6955 }
6956
6957 #[test]
6958 fn test_explode_to_unnest_bigquery() {
6959 let spark = Dialect::get(DialectType::Spark);
6960 let result = spark
6961 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::BigQuery)
6962 .unwrap();
6963 assert_eq!(
6964 result[0],
6965 "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))"
6966 );
6967 }
6968}