1use crate::dialects::transform_recursive;
10use crate::dialects::{Dialect, DialectType};
11use crate::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, UnaryFunc, UnnestFunc, Where,
16};
17use std::cell::RefCell;
18
19pub fn preprocess<F>(expr: Expression, transforms: &[F]) -> Result<Expression>
28where
29 F: Fn(Expression) -> Result<Expression>,
30{
31 let mut result = expr;
32 for transform in transforms {
33 result = transform(result)?;
34 }
35 Ok(result)
36}
37
38pub fn unnest_to_explode(expr: Expression) -> Result<Expression> {
42 match expr {
43 Expression::Unnest(unnest) => {
44 Ok(Expression::Explode(Box::new(UnaryFunc::new(unnest.this))))
45 }
46 _ => Ok(expr),
47 }
48}
49
50pub fn unnest_to_explode_select(expr: Expression) -> Result<Expression> {
60 transform_recursive(expr, &unnest_to_explode_select_inner)
61}
62
63fn make_udtf_expr(unnest: &UnnestFunc) -> Expression {
66 let has_multi_expr = !unnest.expressions.is_empty();
67 if has_multi_expr {
68 let mut all_args = vec![unnest.this.clone()];
70 all_args.extend(unnest.expressions.iter().cloned());
71 let arrays_zip =
72 Expression::Function(Box::new(Function::new("ARRAYS_ZIP".to_string(), all_args)));
73 Expression::Function(Box::new(Function::new(
74 "INLINE".to_string(),
75 vec![arrays_zip],
76 )))
77 } else {
78 Expression::Explode(Box::new(UnaryFunc::new(unnest.this.clone())))
80 }
81}
82
83fn unnest_to_explode_select_inner(expr: Expression) -> Result<Expression> {
84 let Expression::Select(mut select) = expr else {
85 return Ok(expr);
86 };
87
88 if let Some(ref mut from) = select.from {
90 if from.expressions.len() >= 1 {
91 let mut new_from_exprs = Vec::new();
92 let mut new_lateral_views = Vec::new();
93 let first_is_unnest = is_unnest_expr(&from.expressions[0]);
94
95 for (idx, from_item) in from.expressions.drain(..).enumerate() {
96 if idx == 0 && first_is_unnest {
97 let replaced = replace_from_unnest(from_item);
100 new_from_exprs.push(replaced);
101 } else if idx > 0 && is_unnest_expr(&from_item) {
102 let (alias_name, column_aliases, unnest_func) = extract_unnest_info(from_item);
104 let udtf = make_udtf_expr(&unnest_func);
105 new_lateral_views.push(LateralView {
106 this: udtf,
107 table_alias: alias_name,
108 column_aliases,
109 outer: false,
110 });
111 } else {
112 new_from_exprs.push(from_item);
113 }
114 }
115
116 from.expressions = new_from_exprs;
117 select.lateral_views.extend(new_lateral_views);
119 }
120 }
121
122 let mut remaining_joins = Vec::new();
124 for join in select.joins.drain(..) {
125 if matches!(join.kind, JoinKind::Cross | JoinKind::Inner) {
126 let (is_unnest, is_lateral) = check_join_unnest(&join.this);
127 if is_unnest {
128 let (lateral_alias, lateral_col_aliases, join_expr) = if is_lateral {
130 if let Expression::Lateral(lat) = join.this {
131 let alias = lat.alias.map(|s| Identifier::new(&s));
133 let col_aliases: Vec<Identifier> = lat
134 .column_aliases
135 .iter()
136 .map(|s| Identifier::new(s))
137 .collect();
138 (alias, col_aliases, *lat.this)
139 } else {
140 (None, Vec::new(), join.this)
141 }
142 } else {
143 (None, Vec::new(), join.this)
144 };
145
146 let (alias_name, column_aliases, unnest_func) = extract_unnest_info(join_expr);
147
148 let final_alias = lateral_alias.or(alias_name);
150 let final_col_aliases = if !lateral_col_aliases.is_empty() {
151 lateral_col_aliases
152 } else {
153 column_aliases
154 };
155
156 let table_alias = final_alias.or_else(|| Some(Identifier::new("unnest")));
158 let col_aliases = if final_col_aliases.is_empty() {
159 vec![Identifier::new("unnest")]
160 } else {
161 final_col_aliases
162 };
163
164 let udtf = make_udtf_expr(&unnest_func);
165 select.lateral_views.push(LateralView {
166 this: udtf,
167 table_alias,
168 column_aliases: col_aliases,
169 outer: false,
170 });
171 } else {
172 remaining_joins.push(join);
173 }
174 } else {
175 remaining_joins.push(join);
176 }
177 }
178 select.joins = remaining_joins;
179
180 Ok(Expression::Select(select))
181}
182
183fn is_unnest_expr(expr: &Expression) -> bool {
185 match expr {
186 Expression::Unnest(_) => true,
187 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
188 _ => false,
189 }
190}
191
192fn check_join_unnest(expr: &Expression) -> (bool, bool) {
194 match expr {
195 Expression::Unnest(_) => (true, false),
196 Expression::Alias(a) => {
197 if matches!(a.this, Expression::Unnest(_)) {
198 (true, false)
199 } else {
200 (false, false)
201 }
202 }
203 Expression::Lateral(lat) => match &*lat.this {
204 Expression::Unnest(_) => (true, true),
205 Expression::Alias(a) => {
206 if matches!(a.this, Expression::Unnest(_)) {
207 (true, true)
208 } else {
209 (false, true)
210 }
211 }
212 _ => (false, true),
213 },
214 _ => (false, false),
215 }
216}
217
218fn replace_from_unnest(from_item: Expression) -> Expression {
220 match from_item {
221 Expression::Alias(mut a) => {
222 if let Expression::Unnest(unnest) = a.this {
223 a.this = make_udtf_expr(&unnest);
224 }
225 Expression::Alias(a)
226 }
227 Expression::Unnest(unnest) => make_udtf_expr(&unnest),
228 other => other,
229 }
230}
231
232fn extract_unnest_info(expr: Expression) -> (Option<Identifier>, Vec<Identifier>, UnnestFunc) {
234 match expr {
235 Expression::Alias(a) => {
236 if let Expression::Unnest(unnest) = a.this {
237 (Some(a.alias), a.column_aliases, *unnest)
238 } else {
239 (
241 Some(a.alias),
242 a.column_aliases,
243 UnnestFunc {
244 this: a.this,
245 expressions: Vec::new(),
246 with_ordinality: false,
247 alias: None,
248 offset_alias: None,
249 },
250 )
251 }
252 }
253 Expression::Unnest(unnest) => {
254 let alias = unnest.alias.clone();
255 (alias, Vec::new(), *unnest)
256 }
257 _ => (
258 None,
259 Vec::new(),
260 UnnestFunc {
261 this: expr,
262 expressions: Vec::new(),
263 with_ordinality: false,
264 alias: None,
265 offset_alias: None,
266 },
267 ),
268 }
269}
270
271pub fn explode_to_unnest(expr: Expression) -> Result<Expression> {
273 match expr {
274 Expression::Explode(explode) => Ok(Expression::Unnest(Box::new(UnnestFunc {
275 this: explode.this,
276 expressions: Vec::new(),
277 with_ordinality: false,
278 alias: None,
279 offset_alias: None,
280 }))),
281 _ => Ok(expr),
282 }
283}
284
285pub fn replace_bool_with_int(expr: Expression) -> Result<Expression> {
289 match expr {
290 Expression::Boolean(b) => {
291 let value = if b.value { "1" } else { "0" };
292 Ok(Expression::Literal(Literal::Number(value.to_string())))
293 }
294 _ => Ok(expr),
295 }
296}
297
298pub fn replace_int_with_bool(expr: Expression) -> Result<Expression> {
302 match expr {
303 Expression::Literal(Literal::Number(n)) if n == "1" || n == "0" => {
304 Ok(Expression::Boolean(BooleanLiteral { value: n == "1" }))
305 }
306 _ => Ok(expr),
307 }
308}
309
310pub fn remove_precision_parameterized_types(expr: Expression) -> Result<Expression> {
315 Ok(strip_type_params_recursive(expr))
316}
317
318fn strip_type_params_recursive(expr: Expression) -> Expression {
320 match expr {
321 Expression::Cast(mut cast) => {
323 cast.to = strip_data_type_params(cast.to);
324 cast.this = strip_type_params_recursive(cast.this);
326 Expression::Cast(cast)
327 }
328 Expression::TryCast(mut try_cast) => {
330 try_cast.to = strip_data_type_params(try_cast.to);
331 try_cast.this = strip_type_params_recursive(try_cast.this);
332 Expression::TryCast(try_cast)
333 }
334 Expression::SafeCast(mut safe_cast) => {
336 safe_cast.to = strip_data_type_params(safe_cast.to);
337 safe_cast.this = strip_type_params_recursive(safe_cast.this);
338 Expression::SafeCast(safe_cast)
339 }
340 _ => expr,
343 }
344}
345
346fn strip_data_type_params(dt: DataType) -> DataType {
348 match dt {
349 DataType::Decimal { .. } => DataType::Decimal {
351 precision: None,
352 scale: None,
353 },
354 DataType::TinyInt { .. } => DataType::TinyInt { length: None },
355 DataType::SmallInt { .. } => DataType::SmallInt { length: None },
356 DataType::Int { .. } => DataType::Int {
357 length: None,
358 integer_spelling: false,
359 },
360 DataType::BigInt { .. } => DataType::BigInt { length: None },
361
362 DataType::Char { .. } => DataType::Char { length: None },
364 DataType::VarChar { .. } => DataType::VarChar {
365 length: None,
366 parenthesized_length: false,
367 },
368
369 DataType::Binary { .. } => DataType::Binary { length: None },
371 DataType::VarBinary { .. } => DataType::VarBinary { length: None },
372
373 DataType::Bit { .. } => DataType::Bit { length: None },
375 DataType::VarBit { .. } => DataType::VarBit { length: None },
376
377 DataType::Time { .. } => DataType::Time {
379 precision: None,
380 timezone: false,
381 },
382 DataType::Timestamp { timezone, .. } => DataType::Timestamp {
383 precision: None,
384 timezone,
385 },
386
387 DataType::Array {
389 element_type,
390 dimension,
391 } => DataType::Array {
392 element_type: Box::new(strip_data_type_params(*element_type)),
393 dimension,
394 },
395
396 DataType::Map {
398 key_type,
399 value_type,
400 } => DataType::Map {
401 key_type: Box::new(strip_data_type_params(*key_type)),
402 value_type: Box::new(strip_data_type_params(*value_type)),
403 },
404
405 DataType::Struct { fields, nested } => DataType::Struct {
407 fields: fields
408 .into_iter()
409 .map(|f| {
410 StructField::with_options(
411 f.name,
412 strip_data_type_params(f.data_type),
413 f.options,
414 )
415 })
416 .collect(),
417 nested,
418 },
419
420 DataType::Vector { element_type, .. } => DataType::Vector {
422 element_type: element_type.map(|et| Box::new(strip_data_type_params(*et))),
423 dimension: None,
424 },
425
426 DataType::Object { fields, modifier } => DataType::Object {
428 fields: fields
429 .into_iter()
430 .map(|(name, ty, not_null)| (name, strip_data_type_params(ty), not_null))
431 .collect(),
432 modifier,
433 },
434
435 other => other,
437 }
438}
439
440pub fn eliminate_qualify(expr: Expression) -> Result<Expression> {
455 match expr {
456 Expression::Select(mut select) => {
457 if let Some(qualify) = select.qualify.take() {
458 let qualify_filter = qualify.this;
465 let window_alias_name = "_w".to_string();
466 let window_alias_ident = Identifier::new(window_alias_name.clone());
467
468 let (window_expr, outer_where) =
471 extract_window_from_condition(qualify_filter.clone(), &window_alias_ident);
472
473 if let Some(win_expr) = window_expr {
474 let window_alias_expr =
476 Expression::Alias(Box::new(crate::expressions::Alias {
477 this: win_expr,
478 alias: window_alias_ident.clone(),
479 column_aliases: vec![],
480 pre_alias_comments: vec![],
481 trailing_comments: vec![],
482 inferred_type: None,
483 }));
484
485 let outer_exprs: Vec<Expression> = select
489 .expressions
490 .iter()
491 .map(|expr| {
492 if let Expression::Alias(a) = expr {
493 Expression::Column(crate::expressions::Column {
495 name: a.alias.clone(),
496 table: None,
497 join_mark: false,
498 trailing_comments: vec![],
499 span: None,
500 inferred_type: None,
501 })
502 } else {
503 expr.clone()
504 }
505 })
506 .collect();
507 select.expressions.push(window_alias_expr);
508
509 let inner_select = Expression::Select(select);
511 let subquery = Subquery {
512 this: inner_select,
513 alias: Some(Identifier::new("_t".to_string())),
514 column_aliases: vec![],
515 order_by: None,
516 limit: None,
517 offset: None,
518 distribute_by: None,
519 sort_by: None,
520 cluster_by: None,
521 lateral: false,
522 modifiers_inside: false,
523 trailing_comments: vec![],
524 inferred_type: None,
525 };
526
527 let outer_select = Select {
529 expressions: outer_exprs,
530 from: Some(From {
531 expressions: vec![Expression::Subquery(Box::new(subquery))],
532 }),
533 where_clause: Some(Where { this: outer_where }),
534 ..Select::new()
535 };
536
537 return Ok(Expression::Select(Box::new(outer_select)));
538 } else {
539 let qualify_alias = Expression::Alias(Box::new(crate::expressions::Alias {
541 this: qualify_filter.clone(),
542 alias: window_alias_ident.clone(),
543 column_aliases: vec![],
544 pre_alias_comments: vec![],
545 trailing_comments: vec![],
546 inferred_type: None,
547 }));
548
549 let original_exprs = select.expressions.clone();
550 select.expressions.push(qualify_alias);
551
552 let inner_select = Expression::Select(select);
553 let subquery = Subquery {
554 this: inner_select,
555 alias: Some(Identifier::new("_t".to_string())),
556 column_aliases: vec![],
557 order_by: None,
558 limit: None,
559 offset: None,
560 distribute_by: None,
561 sort_by: None,
562 cluster_by: None,
563 lateral: false,
564 modifiers_inside: false,
565 trailing_comments: vec![],
566 inferred_type: None,
567 };
568
569 let outer_select = Select {
570 expressions: original_exprs,
571 from: Some(From {
572 expressions: vec![Expression::Subquery(Box::new(subquery))],
573 }),
574 where_clause: Some(Where {
575 this: Expression::Column(crate::expressions::Column {
576 name: window_alias_ident,
577 table: None,
578 join_mark: false,
579 trailing_comments: vec![],
580 span: None,
581 inferred_type: None,
582 }),
583 }),
584 ..Select::new()
585 };
586
587 return Ok(Expression::Select(Box::new(outer_select)));
588 }
589 }
590 Ok(Expression::Select(select))
591 }
592 other => Ok(other),
593 }
594}
595
596fn extract_window_from_condition(
600 condition: Expression,
601 alias: &Identifier,
602) -> (Option<Expression>, Expression) {
603 let alias_col = Expression::Column(crate::expressions::Column {
604 name: alias.clone(),
605 table: None,
606 join_mark: false,
607 trailing_comments: vec![],
608 span: None,
609 inferred_type: None,
610 });
611
612 match condition {
614 Expression::Eq(ref op) => {
616 if is_window_expr(&op.left) {
617 (
618 Some(op.left.clone()),
619 Expression::Eq(Box::new(BinaryOp {
620 left: alias_col,
621 right: op.right.clone(),
622 ..(**op).clone()
623 })),
624 )
625 } else if is_window_expr(&op.right) {
626 (
627 Some(op.right.clone()),
628 Expression::Eq(Box::new(BinaryOp {
629 left: op.left.clone(),
630 right: alias_col,
631 ..(**op).clone()
632 })),
633 )
634 } else {
635 (None, condition)
636 }
637 }
638 Expression::Neq(ref op) => {
639 if is_window_expr(&op.left) {
640 (
641 Some(op.left.clone()),
642 Expression::Neq(Box::new(BinaryOp {
643 left: alias_col,
644 right: op.right.clone(),
645 ..(**op).clone()
646 })),
647 )
648 } else if is_window_expr(&op.right) {
649 (
650 Some(op.right.clone()),
651 Expression::Neq(Box::new(BinaryOp {
652 left: op.left.clone(),
653 right: alias_col,
654 ..(**op).clone()
655 })),
656 )
657 } else {
658 (None, condition)
659 }
660 }
661 Expression::Lt(ref op) => {
662 if is_window_expr(&op.left) {
663 (
664 Some(op.left.clone()),
665 Expression::Lt(Box::new(BinaryOp {
666 left: alias_col,
667 right: op.right.clone(),
668 ..(**op).clone()
669 })),
670 )
671 } else if is_window_expr(&op.right) {
672 (
673 Some(op.right.clone()),
674 Expression::Lt(Box::new(BinaryOp {
675 left: op.left.clone(),
676 right: alias_col,
677 ..(**op).clone()
678 })),
679 )
680 } else {
681 (None, condition)
682 }
683 }
684 Expression::Lte(ref op) => {
685 if is_window_expr(&op.left) {
686 (
687 Some(op.left.clone()),
688 Expression::Lte(Box::new(BinaryOp {
689 left: alias_col,
690 right: op.right.clone(),
691 ..(**op).clone()
692 })),
693 )
694 } else if is_window_expr(&op.right) {
695 (
696 Some(op.right.clone()),
697 Expression::Lte(Box::new(BinaryOp {
698 left: op.left.clone(),
699 right: alias_col,
700 ..(**op).clone()
701 })),
702 )
703 } else {
704 (None, condition)
705 }
706 }
707 Expression::Gt(ref op) => {
708 if is_window_expr(&op.left) {
709 (
710 Some(op.left.clone()),
711 Expression::Gt(Box::new(BinaryOp {
712 left: alias_col,
713 right: op.right.clone(),
714 ..(**op).clone()
715 })),
716 )
717 } else if is_window_expr(&op.right) {
718 (
719 Some(op.right.clone()),
720 Expression::Gt(Box::new(BinaryOp {
721 left: op.left.clone(),
722 right: alias_col,
723 ..(**op).clone()
724 })),
725 )
726 } else {
727 (None, condition)
728 }
729 }
730 Expression::Gte(ref op) => {
731 if is_window_expr(&op.left) {
732 (
733 Some(op.left.clone()),
734 Expression::Gte(Box::new(BinaryOp {
735 left: alias_col,
736 right: op.right.clone(),
737 ..(**op).clone()
738 })),
739 )
740 } else if is_window_expr(&op.right) {
741 (
742 Some(op.right.clone()),
743 Expression::Gte(Box::new(BinaryOp {
744 left: op.left.clone(),
745 right: alias_col,
746 ..(**op).clone()
747 })),
748 )
749 } else {
750 (None, condition)
751 }
752 }
753 _ if is_window_expr(&condition) => (Some(condition), alias_col),
755 _ => (None, condition),
757 }
758}
759
760fn is_window_expr(expr: &Expression) -> bool {
762 matches!(expr, Expression::Window(_) | Expression::WindowFunction(_))
763}
764
765pub fn eliminate_distinct_on(expr: Expression) -> Result<Expression> {
784 eliminate_distinct_on_for_dialect(expr, None)
785}
786
787pub fn eliminate_distinct_on_for_dialect(
792 expr: Expression,
793 target: Option<DialectType>,
794) -> Result<Expression> {
795 use crate::expressions::Case;
796
797 if matches!(
799 target,
800 Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB)
801 ) {
802 return Ok(expr);
803 }
804
805 enum NullsMode {
810 None, NullsFirst, CaseExpr, }
814
815 let nulls_mode = match target {
816 Some(DialectType::MySQL)
817 | Some(DialectType::StarRocks)
818 | Some(DialectType::SingleStore)
819 | Some(DialectType::TSQL)
820 | Some(DialectType::Fabric) => NullsMode::CaseExpr,
821 Some(DialectType::Oracle) | Some(DialectType::Redshift) | Some(DialectType::Snowflake) => {
822 NullsMode::None
823 }
824 _ => NullsMode::NullsFirst,
826 };
827
828 match expr {
829 Expression::Select(mut select) => {
830 if let Some(distinct_cols) = select.distinct_on.take() {
831 if !distinct_cols.is_empty() {
832 let row_number_alias = Identifier::new("_row_number".to_string());
834
835 let order_exprs = if let Some(ref order_by) = select.order_by {
837 let mut exprs = order_by.expressions.clone();
838 match nulls_mode {
840 NullsMode::NullsFirst => {
841 for ord in &mut exprs {
842 if ord.desc && ord.nulls_first.is_none() {
843 ord.nulls_first = Some(true);
844 }
845 }
846 }
847 NullsMode::CaseExpr => {
848 let mut new_exprs = Vec::new();
851 for ord in &exprs {
852 if ord.desc && ord.nulls_first.is_none() {
853 let null_check = Expression::Case(Box::new(Case {
855 operand: None,
856 whens: vec![(
857 Expression::IsNull(Box::new(
858 crate::expressions::IsNull {
859 this: ord.this.clone(),
860 not: false,
861 postfix_form: false,
862 },
863 )),
864 Expression::Literal(Literal::Number(
865 "1".to_string(),
866 )),
867 )],
868 else_: Some(Expression::Literal(Literal::Number(
869 "0".to_string(),
870 ))),
871 comments: Vec::new(),
872 inferred_type: None,
873 }));
874 new_exprs.push(crate::expressions::Ordered {
875 this: null_check,
876 desc: true,
877 nulls_first: None,
878 explicit_asc: false,
879 with_fill: None,
880 });
881 }
882 new_exprs.push(ord.clone());
883 }
884 exprs = new_exprs;
885 }
886 NullsMode::None => {}
887 }
888 exprs
889 } else {
890 distinct_cols
891 .iter()
892 .map(|e| crate::expressions::Ordered {
893 this: e.clone(),
894 desc: false,
895 nulls_first: None,
896 explicit_asc: false,
897 with_fill: None,
898 })
899 .collect()
900 };
901
902 let row_number_func =
904 Expression::WindowFunction(Box::new(crate::expressions::WindowFunction {
905 this: Expression::RowNumber(crate::expressions::RowNumber),
906 over: Over {
907 partition_by: distinct_cols,
908 order_by: order_exprs,
909 frame: None,
910 window_name: None,
911 alias: None,
912 },
913 keep: None,
914 inferred_type: None,
915 }));
916
917 let mut inner_aliased_exprs = Vec::new();
921 let mut outer_select_exprs = Vec::new();
922 for orig_expr in &select.expressions {
923 match orig_expr {
924 Expression::Alias(alias) => {
925 inner_aliased_exprs.push(orig_expr.clone());
927 outer_select_exprs.push(Expression::Column(
928 crate::expressions::Column {
929 name: alias.alias.clone(),
930 table: None,
931 join_mark: false,
932 trailing_comments: vec![],
933 span: None,
934 inferred_type: None,
935 },
936 ));
937 }
938 Expression::Column(col) => {
939 inner_aliased_exprs.push(Expression::Alias(Box::new(
941 crate::expressions::Alias {
942 this: orig_expr.clone(),
943 alias: col.name.clone(),
944 column_aliases: vec![],
945 pre_alias_comments: vec![],
946 trailing_comments: vec![],
947 inferred_type: None,
948 },
949 )));
950 outer_select_exprs.push(Expression::Column(
951 crate::expressions::Column {
952 name: col.name.clone(),
953 table: None,
954 join_mark: false,
955 trailing_comments: vec![],
956 span: None,
957 inferred_type: None,
958 },
959 ));
960 }
961 _ => {
962 inner_aliased_exprs.push(orig_expr.clone());
964 outer_select_exprs.push(orig_expr.clone());
965 }
966 }
967 }
968
969 let row_number_alias_expr =
971 Expression::Alias(Box::new(crate::expressions::Alias {
972 this: row_number_func,
973 alias: row_number_alias.clone(),
974 column_aliases: vec![],
975 pre_alias_comments: vec![],
976 trailing_comments: vec![],
977 inferred_type: None,
978 }));
979 inner_aliased_exprs.push(row_number_alias_expr);
980
981 select.expressions = inner_aliased_exprs;
983
984 let _inner_order_by = select.order_by.take();
986
987 select.distinct = false;
989
990 let inner_select = Expression::Select(select);
992 let subquery = Subquery {
993 this: inner_select,
994 alias: Some(Identifier::new("_t".to_string())),
995 column_aliases: vec![],
996 order_by: None,
997 limit: None,
998 offset: None,
999 distribute_by: None,
1000 sort_by: None,
1001 cluster_by: None,
1002 lateral: false,
1003 modifiers_inside: false,
1004 trailing_comments: vec![],
1005 inferred_type: None,
1006 };
1007
1008 let outer_select = Select {
1011 expressions: outer_select_exprs,
1012 from: Some(From {
1013 expressions: vec![Expression::Subquery(Box::new(subquery))],
1014 }),
1015 where_clause: Some(Where {
1016 this: Expression::Eq(Box::new(BinaryOp {
1017 left: Expression::Column(crate::expressions::Column {
1018 name: row_number_alias,
1019 table: None,
1020 join_mark: false,
1021 trailing_comments: vec![],
1022 span: None,
1023 inferred_type: None,
1024 }),
1025 right: Expression::Literal(Literal::Number("1".to_string())),
1026 left_comments: vec![],
1027 operator_comments: vec![],
1028 trailing_comments: vec![],
1029 inferred_type: None,
1030 })),
1031 }),
1032 ..Select::new()
1033 };
1034
1035 return Ok(Expression::Select(Box::new(outer_select)));
1036 }
1037 }
1038 Ok(Expression::Select(select))
1039 }
1040 other => Ok(other),
1041 }
1042}
1043
1044pub fn eliminate_semi_and_anti_joins(expr: Expression) -> Result<Expression> {
1052 match expr {
1053 Expression::Select(mut select) => {
1054 let mut new_joins = Vec::new();
1055 let mut extra_where_conditions = Vec::new();
1056
1057 for join in select.joins.drain(..) {
1058 match join.kind {
1059 JoinKind::Semi | JoinKind::LeftSemi => {
1060 if let Some(on_condition) = join.on {
1061 let subquery_select = Select {
1063 expressions: vec![Expression::Literal(Literal::Number(
1064 "1".to_string(),
1065 ))],
1066 from: Some(From {
1067 expressions: vec![join.this],
1068 }),
1069 where_clause: Some(Where { this: on_condition }),
1070 ..Select::new()
1071 };
1072
1073 let exists = Expression::Exists(Box::new(Exists {
1074 this: Expression::Subquery(Box::new(Subquery {
1075 this: Expression::Select(Box::new(subquery_select)),
1076 alias: None,
1077 column_aliases: vec![],
1078 order_by: None,
1079 limit: None,
1080 offset: None,
1081 distribute_by: None,
1082 sort_by: None,
1083 cluster_by: None,
1084 lateral: false,
1085 modifiers_inside: false,
1086 trailing_comments: vec![],
1087 inferred_type: None,
1088 })),
1089 not: false,
1090 }));
1091
1092 extra_where_conditions.push(exists);
1093 }
1094 }
1095 JoinKind::Anti | JoinKind::LeftAnti => {
1096 if let Some(on_condition) = join.on {
1097 let subquery_select = Select {
1099 expressions: vec![Expression::Literal(Literal::Number(
1100 "1".to_string(),
1101 ))],
1102 from: Some(From {
1103 expressions: vec![join.this],
1104 }),
1105 where_clause: Some(Where { this: on_condition }),
1106 ..Select::new()
1107 };
1108
1109 let not_exists = Expression::Exists(Box::new(Exists {
1111 this: Expression::Subquery(Box::new(Subquery {
1112 this: Expression::Select(Box::new(subquery_select)),
1113 alias: None,
1114 column_aliases: vec![],
1115 order_by: None,
1116 limit: None,
1117 offset: None,
1118 distribute_by: None,
1119 sort_by: None,
1120 cluster_by: None,
1121 lateral: false,
1122 modifiers_inside: false,
1123 trailing_comments: vec![],
1124 inferred_type: None,
1125 })),
1126 not: true,
1127 }));
1128
1129 extra_where_conditions.push(not_exists);
1130 }
1131 }
1132 _ => {
1133 new_joins.push(join);
1135 }
1136 }
1137 }
1138
1139 select.joins = new_joins;
1140
1141 if !extra_where_conditions.is_empty() {
1143 let combined = extra_where_conditions
1144 .into_iter()
1145 .reduce(|acc, cond| {
1146 Expression::And(Box::new(BinaryOp {
1147 left: acc,
1148 right: cond,
1149 left_comments: vec![],
1150 operator_comments: vec![],
1151 trailing_comments: vec![],
1152 inferred_type: None,
1153 }))
1154 })
1155 .unwrap();
1156
1157 select.where_clause = match select.where_clause {
1158 Some(Where { this: existing }) => Some(Where {
1159 this: Expression::And(Box::new(BinaryOp {
1160 left: existing,
1161 right: combined,
1162 left_comments: vec![],
1163 operator_comments: vec![],
1164 trailing_comments: vec![],
1165 inferred_type: None,
1166 })),
1167 }),
1168 None => Some(Where { this: combined }),
1169 };
1170 }
1171
1172 Ok(Expression::Select(select))
1173 }
1174 other => Ok(other),
1175 }
1176}
1177
1178pub fn eliminate_full_outer_join(expr: Expression) -> Result<Expression> {
1196 match expr {
1197 Expression::Select(mut select) => {
1198 let full_outer_join_idx = select.joins.iter().position(|j| j.kind == JoinKind::Full);
1200
1201 if let Some(idx) = full_outer_join_idx {
1202 let full_join_count = select
1204 .joins
1205 .iter()
1206 .filter(|j| j.kind == JoinKind::Full)
1207 .count();
1208 if full_join_count != 1 {
1209 return Ok(Expression::Select(select));
1210 }
1211
1212 let mut right_select = select.clone();
1214
1215 let full_join = &select.joins[idx];
1217 let join_condition = full_join.on.clone();
1218
1219 select.joins[idx].kind = JoinKind::Left;
1221
1222 right_select.joins[idx].kind = JoinKind::Right;
1224
1225 if let (Some(ref from), Some(ref join_cond)) = (&select.from, &join_condition) {
1227 if !from.expressions.is_empty() {
1228 let anti_subquery = Expression::Select(Box::new(Select {
1229 expressions: vec![Expression::Literal(Literal::Number(
1230 "1".to_string(),
1231 ))],
1232 from: Some(from.clone()),
1233 where_clause: Some(Where {
1234 this: join_cond.clone(),
1235 }),
1236 ..Select::new()
1237 }));
1238
1239 let not_exists = Expression::Not(Box::new(crate::expressions::UnaryOp {
1240 inferred_type: None,
1241 this: Expression::Exists(Box::new(Exists {
1242 this: Expression::Subquery(Box::new(Subquery {
1243 this: anti_subquery,
1244 alias: None,
1245 column_aliases: vec![],
1246 order_by: None,
1247 limit: None,
1248 offset: None,
1249 distribute_by: None,
1250 sort_by: None,
1251 cluster_by: None,
1252 lateral: false,
1253 modifiers_inside: false,
1254 trailing_comments: vec![],
1255 inferred_type: None,
1256 })),
1257 not: false,
1258 })),
1259 }));
1260
1261 right_select.where_clause = Some(Where {
1263 this: match right_select.where_clause {
1264 Some(w) => Expression::And(Box::new(BinaryOp {
1265 left: w.this,
1266 right: not_exists,
1267 left_comments: vec![],
1268 operator_comments: vec![],
1269 trailing_comments: vec![],
1270 inferred_type: None,
1271 })),
1272 None => not_exists,
1273 },
1274 });
1275 }
1276 }
1277
1278 right_select.with = None;
1280
1281 let order_by = select.order_by.take();
1283
1284 let union = crate::expressions::Union {
1286 left: Expression::Select(select),
1287 right: Expression::Select(right_select),
1288 all: true, distinct: false,
1290 with: None,
1291 order_by,
1292 limit: None,
1293 offset: None,
1294 distribute_by: None,
1295 sort_by: None,
1296 cluster_by: None,
1297 by_name: false,
1298 side: None,
1299 kind: None,
1300 corresponding: false,
1301 strict: false,
1302 on_columns: Vec::new(),
1303 };
1304
1305 return Ok(Expression::Union(Box::new(union)));
1306 }
1307
1308 Ok(Expression::Select(select))
1309 }
1310 other => Ok(other),
1311 }
1312}
1313
1314pub fn move_ctes_to_top_level(expr: Expression) -> Result<Expression> {
1327 match expr {
1328 Expression::Select(mut select) => {
1329 let mut collected_ctes: Vec<crate::expressions::Cte> = Vec::new();
1331 let mut has_recursive = false;
1332
1333 collect_nested_ctes(
1334 &Expression::Select(select.clone()),
1335 &mut collected_ctes,
1336 &mut has_recursive,
1337 true,
1338 );
1339
1340 let mut cte_body_collected: Vec<(String, Vec<crate::expressions::Cte>)> = Vec::new();
1343 if let Some(ref with) = select.with {
1344 for cte in &with.ctes {
1345 let mut body_ctes: Vec<crate::expressions::Cte> = Vec::new();
1346 collect_ctes_from_cte_body(&cte.this, &mut body_ctes, &mut has_recursive);
1347 if !body_ctes.is_empty() {
1348 cte_body_collected.push((cte.alias.name.clone(), body_ctes));
1349 }
1350 }
1351 }
1352
1353 let has_subquery_ctes = !collected_ctes.is_empty();
1354 let has_body_ctes = !cte_body_collected.is_empty();
1355
1356 if has_subquery_ctes || has_body_ctes {
1357 strip_nested_with_clauses(&mut select, true);
1359
1360 if has_body_ctes {
1362 if let Some(ref mut with) = select.with {
1363 for cte in with.ctes.iter_mut() {
1364 strip_with_from_cte_body(&mut cte.this);
1365 }
1366 }
1367 }
1368
1369 let top_with = select.with.get_or_insert_with(|| crate::expressions::With {
1370 ctes: Vec::new(),
1371 recursive: false,
1372 leading_comments: vec![],
1373 search: None,
1374 });
1375
1376 if has_recursive {
1377 top_with.recursive = true;
1378 }
1379
1380 if has_body_ctes {
1382 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
1383 for mut cte in top_with.ctes.drain(..) {
1384 if let Some(pos) = cte_body_collected
1386 .iter()
1387 .position(|(name, _)| *name == cte.alias.name)
1388 {
1389 let (_, mut nested) = cte_body_collected.remove(pos);
1390 for nested_cte in nested.iter_mut() {
1392 strip_with_from_cte_body(&mut nested_cte.this);
1393 }
1394 new_ctes.extend(nested);
1395 }
1396 strip_with_from_cte_body(&mut cte.this);
1398 new_ctes.push(cte);
1399 }
1400 top_with.ctes = new_ctes;
1401 }
1402
1403 top_with.ctes.extend(collected_ctes);
1405 }
1406
1407 Ok(Expression::Select(select))
1408 }
1409 other => Ok(other),
1410 }
1411}
1412
1413fn collect_ctes_from_cte_body(
1415 expr: &Expression,
1416 collected: &mut Vec<crate::expressions::Cte>,
1417 has_recursive: &mut bool,
1418) {
1419 if let Expression::Select(select) = expr {
1420 if let Some(ref with) = select.with {
1421 if with.recursive {
1422 *has_recursive = true;
1423 }
1424 for cte in &with.ctes {
1425 collect_ctes_from_cte_body(&cte.this, collected, has_recursive);
1427 collected.push(cte.clone());
1429 }
1430 }
1431 }
1432}
1433
1434fn strip_with_from_cte_body(expr: &mut Expression) {
1436 if let Expression::Select(ref mut select) = expr {
1437 select.with = None;
1438 }
1439}
1440
1441fn strip_nested_with_clauses(select: &mut Select, _is_top_level: bool) {
1443 if let Some(ref mut from) = select.from {
1445 for expr in from.expressions.iter_mut() {
1446 strip_with_from_expr(expr);
1447 }
1448 }
1449 for join in select.joins.iter_mut() {
1451 strip_with_from_expr(&mut join.this);
1452 }
1453 for expr in select.expressions.iter_mut() {
1455 strip_with_from_expr(expr);
1456 }
1457 if let Some(ref mut w) = select.where_clause {
1459 strip_with_from_expr(&mut w.this);
1460 }
1461}
1462
1463fn strip_with_from_expr(expr: &mut Expression) {
1464 match expr {
1465 Expression::Subquery(ref mut subquery) => {
1466 strip_with_from_inner_query(&mut subquery.this);
1467 }
1468 Expression::Alias(ref mut alias) => {
1469 strip_with_from_expr(&mut alias.this);
1470 }
1471 Expression::Select(ref mut select) => {
1472 select.with = None;
1474 strip_nested_with_clauses(select, false);
1476 }
1477 _ => {}
1478 }
1479}
1480
1481fn strip_with_from_inner_query(expr: &mut Expression) {
1482 if let Expression::Select(ref mut select) = expr {
1483 select.with = None;
1484 strip_nested_with_clauses(select, false);
1485 }
1486}
1487
1488fn collect_nested_ctes(
1490 expr: &Expression,
1491 collected: &mut Vec<crate::expressions::Cte>,
1492 has_recursive: &mut bool,
1493 is_top_level: bool,
1494) {
1495 match expr {
1496 Expression::Select(select) => {
1497 if !is_top_level {
1499 if let Some(ref with) = select.with {
1500 if with.recursive {
1501 *has_recursive = true;
1502 }
1503 collected.extend(with.ctes.clone());
1504 }
1505 }
1506
1507 if let Some(ref from) = select.from {
1509 for expr in &from.expressions {
1510 collect_nested_ctes(expr, collected, has_recursive, false);
1511 }
1512 }
1513
1514 for join in &select.joins {
1516 collect_nested_ctes(&join.this, collected, has_recursive, false);
1517 }
1518
1519 for sel_expr in &select.expressions {
1521 collect_nested_ctes(sel_expr, collected, has_recursive, false);
1522 }
1523
1524 if let Some(ref where_clause) = select.where_clause {
1526 collect_nested_ctes(&where_clause.this, collected, has_recursive, false);
1527 }
1528 }
1529 Expression::Subquery(subquery) => {
1530 collect_nested_ctes(&subquery.this, collected, has_recursive, false);
1532 }
1533 Expression::Alias(alias) => {
1534 collect_nested_ctes(&alias.this, collected, has_recursive, false);
1535 }
1536 _ => {}
1538 }
1539}
1540
1541pub fn eliminate_window_clause(expr: Expression) -> Result<Expression> {
1557 match expr {
1558 Expression::Select(mut select) => {
1559 if let Some(named_windows) = select.windows.take() {
1560 let window_map: std::collections::HashMap<String, &Over> = named_windows
1562 .iter()
1563 .map(|nw| (nw.name.name.to_lowercase(), &nw.spec))
1564 .collect();
1565
1566 select.expressions = select
1568 .expressions
1569 .into_iter()
1570 .map(|e| inline_window_refs(e, &window_map))
1571 .collect();
1572 }
1573 Ok(Expression::Select(select))
1574 }
1575 other => Ok(other),
1576 }
1577}
1578
1579fn inline_window_refs(
1581 expr: Expression,
1582 window_map: &std::collections::HashMap<String, &Over>,
1583) -> Expression {
1584 match expr {
1585 Expression::WindowFunction(mut wf) => {
1586 if let Some(ref name) = wf.over.window_name {
1588 let key = name.name.to_lowercase();
1589 if let Some(named_spec) = window_map.get(&key) {
1590 if wf.over.partition_by.is_empty() && !named_spec.partition_by.is_empty() {
1592 wf.over.partition_by = named_spec.partition_by.clone();
1593 }
1594 if wf.over.order_by.is_empty() && !named_spec.order_by.is_empty() {
1595 wf.over.order_by = named_spec.order_by.clone();
1596 }
1597 if wf.over.frame.is_none() && named_spec.frame.is_some() {
1598 wf.over.frame = named_spec.frame.clone();
1599 }
1600 wf.over.window_name = None;
1602 }
1603 }
1604 Expression::WindowFunction(wf)
1605 }
1606 Expression::Alias(mut alias) => {
1607 alias.this = inline_window_refs(alias.this, window_map);
1609 Expression::Alias(alias)
1610 }
1611 other => other,
1614 }
1615}
1616
1617pub fn eliminate_join_marks(expr: Expression) -> Result<Expression> {
1631 match expr {
1632 Expression::Select(mut select) => {
1633 let has_join_marks = select
1635 .where_clause
1636 .as_ref()
1637 .map_or(false, |w| contains_join_mark(&w.this));
1638
1639 if !has_join_marks {
1640 return Ok(Expression::Select(select));
1641 }
1642
1643 let from_tables: Vec<String> = select
1645 .from
1646 .as_ref()
1647 .map(|f| {
1648 f.expressions
1649 .iter()
1650 .filter_map(|e| get_table_name(e))
1651 .collect()
1652 })
1653 .unwrap_or_default();
1654
1655 let mut join_conditions: std::collections::HashMap<String, Vec<Expression>> =
1657 std::collections::HashMap::new();
1658 let mut remaining_conditions: Vec<Expression> = Vec::new();
1659
1660 if let Some(ref where_clause) = select.where_clause {
1661 extract_join_mark_conditions(
1662 &where_clause.this,
1663 &mut join_conditions,
1664 &mut remaining_conditions,
1665 );
1666 }
1667
1668 let mut new_joins = select.joins.clone();
1670 for (table_name, conditions) in join_conditions {
1671 let table_in_from = from_tables.contains(&table_name);
1673
1674 if table_in_from && !conditions.is_empty() {
1675 let combined_condition = conditions.into_iter().reduce(|a, b| {
1677 Expression::And(Box::new(BinaryOp {
1678 left: a,
1679 right: b,
1680 left_comments: vec![],
1681 operator_comments: vec![],
1682 trailing_comments: vec![],
1683 inferred_type: None,
1684 }))
1685 });
1686
1687 if let Some(ref mut from) = select.from {
1689 if let Some(pos) = from
1690 .expressions
1691 .iter()
1692 .position(|e| get_table_name(e).map_or(false, |n| n == table_name))
1693 {
1694 if from.expressions.len() > 1 {
1695 let join_table = from.expressions.remove(pos);
1696 new_joins.push(crate::expressions::Join {
1697 this: join_table,
1698 kind: JoinKind::Left,
1699 on: combined_condition,
1700 using: vec![],
1701 use_inner_keyword: false,
1702 use_outer_keyword: true,
1703 deferred_condition: false,
1704 join_hint: None,
1705 match_condition: None,
1706 pivots: Vec::new(),
1707 comments: Vec::new(),
1708 nesting_group: 0,
1709 directed: false,
1710 });
1711 }
1712 }
1713 }
1714 }
1715 }
1716
1717 select.joins = new_joins;
1718
1719 if remaining_conditions.is_empty() {
1721 select.where_clause = None;
1722 } else {
1723 let combined = remaining_conditions.into_iter().reduce(|a, b| {
1724 Expression::And(Box::new(BinaryOp {
1725 left: a,
1726 right: b,
1727 left_comments: vec![],
1728 operator_comments: vec![],
1729 trailing_comments: vec![],
1730 inferred_type: None,
1731 }))
1732 });
1733 select.where_clause = combined.map(|c| Where { this: c });
1734 }
1735
1736 clear_join_marks(&mut Expression::Select(select.clone()));
1738
1739 Ok(Expression::Select(select))
1740 }
1741 other => Ok(other),
1742 }
1743}
1744
1745fn contains_join_mark(expr: &Expression) -> bool {
1747 match expr {
1748 Expression::Column(col) => col.join_mark,
1749 Expression::And(op) | Expression::Or(op) => {
1750 contains_join_mark(&op.left) || contains_join_mark(&op.right)
1751 }
1752 Expression::Eq(op)
1753 | Expression::Neq(op)
1754 | Expression::Lt(op)
1755 | Expression::Lte(op)
1756 | Expression::Gt(op)
1757 | Expression::Gte(op) => contains_join_mark(&op.left) || contains_join_mark(&op.right),
1758 Expression::Not(op) => contains_join_mark(&op.this),
1759 _ => false,
1760 }
1761}
1762
1763fn get_table_name(expr: &Expression) -> Option<String> {
1765 match expr {
1766 Expression::Table(t) => Some(t.name.name.clone()),
1767 Expression::Alias(a) => Some(a.alias.name.clone()),
1768 _ => None,
1769 }
1770}
1771
1772fn extract_join_mark_conditions(
1774 expr: &Expression,
1775 join_conditions: &mut std::collections::HashMap<String, Vec<Expression>>,
1776 remaining: &mut Vec<Expression>,
1777) {
1778 match expr {
1779 Expression::And(op) => {
1780 extract_join_mark_conditions(&op.left, join_conditions, remaining);
1781 extract_join_mark_conditions(&op.right, join_conditions, remaining);
1782 }
1783 _ => {
1784 if let Some(table) = get_join_mark_table(expr) {
1785 join_conditions
1786 .entry(table)
1787 .or_insert_with(Vec::new)
1788 .push(expr.clone());
1789 } else {
1790 remaining.push(expr.clone());
1791 }
1792 }
1793 }
1794}
1795
1796fn get_join_mark_table(expr: &Expression) -> Option<String> {
1798 match expr {
1799 Expression::Eq(op)
1800 | Expression::Neq(op)
1801 | Expression::Lt(op)
1802 | Expression::Lte(op)
1803 | Expression::Gt(op)
1804 | Expression::Gte(op) => {
1805 if let Expression::Column(col) = &op.left {
1807 if col.join_mark {
1808 return col.table.as_ref().map(|t| t.name.clone());
1809 }
1810 }
1811 if let Expression::Column(col) = &op.right {
1812 if col.join_mark {
1813 return col.table.as_ref().map(|t| t.name.clone());
1814 }
1815 }
1816 None
1817 }
1818 _ => None,
1819 }
1820}
1821
1822fn clear_join_marks(expr: &mut Expression) {
1824 match expr {
1825 Expression::Column(col) => col.join_mark = false,
1826 Expression::Select(select) => {
1827 if let Some(ref mut w) = select.where_clause {
1828 clear_join_marks(&mut w.this);
1829 }
1830 for sel_expr in &mut select.expressions {
1831 clear_join_marks(sel_expr);
1832 }
1833 }
1834 Expression::And(op) | Expression::Or(op) => {
1835 clear_join_marks(&mut op.left);
1836 clear_join_marks(&mut op.right);
1837 }
1838 Expression::Eq(op)
1839 | Expression::Neq(op)
1840 | Expression::Lt(op)
1841 | Expression::Lte(op)
1842 | Expression::Gt(op)
1843 | Expression::Gte(op) => {
1844 clear_join_marks(&mut op.left);
1845 clear_join_marks(&mut op.right);
1846 }
1847 _ => {}
1848 }
1849}
1850
1851pub fn add_recursive_cte_column_names(expr: Expression) -> Result<Expression> {
1858 match expr {
1859 Expression::Select(mut select) => {
1860 if let Some(ref mut with) = select.with {
1861 if with.recursive {
1862 let mut counter = 0;
1863 for cte in &mut with.ctes {
1864 if cte.columns.is_empty() {
1865 if let Expression::Select(ref cte_select) = cte.this {
1867 let names: Vec<Identifier> = cte_select
1868 .expressions
1869 .iter()
1870 .map(|e| match e {
1871 Expression::Alias(a) => a.alias.clone(),
1872 Expression::Column(c) => c.name.clone(),
1873 _ => {
1874 counter += 1;
1875 Identifier::new(format!("_c_{}", counter))
1876 }
1877 })
1878 .collect();
1879 cte.columns = names;
1880 }
1881 }
1882 }
1883 }
1884 }
1885 Ok(Expression::Select(select))
1886 }
1887 other => Ok(other),
1888 }
1889}
1890
1891pub fn epoch_cast_to_ts(expr: Expression) -> Result<Expression> {
1898 match expr {
1899 Expression::Cast(mut cast) => {
1900 if let Expression::Literal(Literal::String(ref s)) = cast.this {
1901 if s.to_lowercase() == "epoch" {
1902 if is_temporal_type(&cast.to) {
1903 cast.this =
1904 Expression::Literal(Literal::String("1970-01-01 00:00:00".to_string()));
1905 }
1906 }
1907 }
1908 Ok(Expression::Cast(cast))
1909 }
1910 Expression::TryCast(mut try_cast) => {
1911 if let Expression::Literal(Literal::String(ref s)) = try_cast.this {
1912 if s.to_lowercase() == "epoch" {
1913 if is_temporal_type(&try_cast.to) {
1914 try_cast.this =
1915 Expression::Literal(Literal::String("1970-01-01 00:00:00".to_string()));
1916 }
1917 }
1918 }
1919 Ok(Expression::TryCast(try_cast))
1920 }
1921 other => Ok(other),
1922 }
1923}
1924
1925fn is_temporal_type(dt: &DataType) -> bool {
1927 matches!(
1928 dt,
1929 DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. }
1930 )
1931}
1932
1933pub fn ensure_bools(expr: Expression) -> Result<Expression> {
1958 let expr = ensure_bools_in_case(expr);
1960 match expr {
1961 Expression::Select(mut select) => {
1962 if let Some(ref mut where_clause) = select.where_clause {
1964 where_clause.this = ensure_bool_condition(where_clause.this.clone());
1965 }
1966 if let Some(ref mut having) = select.having {
1968 having.this = ensure_bool_condition(having.this.clone());
1969 }
1970 Ok(Expression::Select(select))
1971 }
1972 Expression::And(_) | Expression::Or(_) | Expression::Not(_) => {
1974 Ok(ensure_bool_condition(expr))
1975 }
1976 other => Ok(other),
1977 }
1978}
1979
1980fn ensure_bools_in_case(expr: Expression) -> Expression {
1984 match expr {
1985 Expression::Case(mut case) => {
1986 case.whens = case
1987 .whens
1988 .into_iter()
1989 .map(|(condition, result)| {
1990 let new_condition = ensure_bool_condition(ensure_bools_in_case(condition));
1991 let new_result = ensure_bools_in_case(result);
1992 (new_condition, new_result)
1993 })
1994 .collect();
1995 if let Some(else_expr) = case.else_ {
1996 case.else_ = Some(ensure_bools_in_case(else_expr));
1997 }
1998 Expression::Case(Box::new(*case))
1999 }
2000 Expression::Select(mut select) => {
2001 select.expressions = select
2003 .expressions
2004 .into_iter()
2005 .map(ensure_bools_in_case)
2006 .collect();
2007 Expression::Select(select)
2009 }
2010 Expression::Alias(mut alias) => {
2011 alias.this = ensure_bools_in_case(alias.this);
2012 Expression::Alias(alias)
2013 }
2014 Expression::Paren(mut paren) => {
2015 paren.this = ensure_bools_in_case(paren.this);
2016 Expression::Paren(paren)
2017 }
2018 other => other,
2019 }
2020}
2021
2022fn is_boolean_expression(expr: &Expression) -> bool {
2025 matches!(
2026 expr,
2027 Expression::Eq(_)
2028 | Expression::Neq(_)
2029 | Expression::Lt(_)
2030 | Expression::Lte(_)
2031 | Expression::Gt(_)
2032 | Expression::Gte(_)
2033 | Expression::Is(_)
2034 | Expression::IsNull(_)
2035 | Expression::IsTrue(_)
2036 | Expression::IsFalse(_)
2037 | Expression::Like(_)
2038 | Expression::ILike(_)
2039 | Expression::SimilarTo(_)
2040 | Expression::Glob(_)
2041 | Expression::RegexpLike(_)
2042 | Expression::In(_)
2043 | Expression::Between(_)
2044 | Expression::Exists(_)
2045 | Expression::And(_)
2046 | Expression::Or(_)
2047 | Expression::Not(_)
2048 | Expression::Any(_)
2049 | Expression::All(_)
2050 | Expression::EqualNull(_)
2051 )
2052}
2053
2054fn wrap_neq_zero(expr: Expression) -> Expression {
2056 Expression::Neq(Box::new(BinaryOp {
2057 left: expr,
2058 right: Expression::Literal(Literal::Number("0".to_string())),
2059 left_comments: vec![],
2060 operator_comments: vec![],
2061 trailing_comments: vec![],
2062 inferred_type: None,
2063 }))
2064}
2065
2066fn ensure_bool_condition(expr: Expression) -> Expression {
2072 match expr {
2073 Expression::And(op) => {
2075 let new_op = BinaryOp {
2076 left: ensure_bool_condition(op.left.clone()),
2077 right: ensure_bool_condition(op.right.clone()),
2078 left_comments: op.left_comments.clone(),
2079 operator_comments: op.operator_comments.clone(),
2080 trailing_comments: op.trailing_comments.clone(),
2081 inferred_type: None,
2082 };
2083 Expression::And(Box::new(new_op))
2084 }
2085 Expression::Or(op) => {
2086 let new_op = BinaryOp {
2087 left: ensure_bool_condition(op.left.clone()),
2088 right: ensure_bool_condition(op.right.clone()),
2089 left_comments: op.left_comments.clone(),
2090 operator_comments: op.operator_comments.clone(),
2091 trailing_comments: op.trailing_comments.clone(),
2092 inferred_type: None,
2093 };
2094 Expression::Or(Box::new(new_op))
2095 }
2096 Expression::Not(op) => Expression::Not(Box::new(crate::expressions::UnaryOp {
2098 this: ensure_bool_condition(op.this.clone()),
2099 inferred_type: None,
2100 })),
2101 Expression::Paren(paren) => Expression::Paren(Box::new(crate::expressions::Paren {
2103 this: ensure_bool_condition(paren.this.clone()),
2104 trailing_comments: paren.trailing_comments.clone(),
2105 })),
2106 Expression::Boolean(BooleanLiteral { value: true }) => {
2108 Expression::Paren(Box::new(crate::expressions::Paren {
2109 this: Expression::Eq(Box::new(BinaryOp {
2110 left: Expression::Literal(Literal::Number("1".to_string())),
2111 right: Expression::Literal(Literal::Number("1".to_string())),
2112 left_comments: vec![],
2113 operator_comments: vec![],
2114 trailing_comments: vec![],
2115 inferred_type: None,
2116 })),
2117 trailing_comments: vec![],
2118 }))
2119 }
2120 Expression::Boolean(BooleanLiteral { value: false }) => {
2121 Expression::Paren(Box::new(crate::expressions::Paren {
2122 this: Expression::Eq(Box::new(BinaryOp {
2123 left: Expression::Literal(Literal::Number("1".to_string())),
2124 right: Expression::Literal(Literal::Number("0".to_string())),
2125 left_comments: vec![],
2126 operator_comments: vec![],
2127 trailing_comments: vec![],
2128 inferred_type: None,
2129 })),
2130 trailing_comments: vec![],
2131 }))
2132 }
2133 ref e if is_boolean_expression(e) => expr,
2135 _ => wrap_neq_zero(expr),
2138 }
2139}
2140
2141pub fn unqualify_columns(expr: Expression) -> Result<Expression> {
2147 Ok(unqualify_columns_recursive(expr))
2148}
2149
2150fn unqualify_columns_recursive(expr: Expression) -> Expression {
2152 match expr {
2153 Expression::Column(mut col) => {
2154 col.table = None;
2155 Expression::Column(col)
2156 }
2157 Expression::Select(mut select) => {
2158 select.expressions = select
2159 .expressions
2160 .into_iter()
2161 .map(unqualify_columns_recursive)
2162 .collect();
2163 if let Some(ref mut where_clause) = select.where_clause {
2164 where_clause.this = unqualify_columns_recursive(where_clause.this.clone());
2165 }
2166 if let Some(ref mut having) = select.having {
2167 having.this = unqualify_columns_recursive(having.this.clone());
2168 }
2169 if let Some(ref mut group_by) = select.group_by {
2170 group_by.expressions = group_by
2171 .expressions
2172 .iter()
2173 .cloned()
2174 .map(unqualify_columns_recursive)
2175 .collect();
2176 }
2177 if let Some(ref mut order_by) = select.order_by {
2178 order_by.expressions = order_by
2179 .expressions
2180 .iter()
2181 .map(|o| crate::expressions::Ordered {
2182 this: unqualify_columns_recursive(o.this.clone()),
2183 desc: o.desc,
2184 nulls_first: o.nulls_first,
2185 explicit_asc: o.explicit_asc,
2186 with_fill: o.with_fill.clone(),
2187 })
2188 .collect();
2189 }
2190 for join in &mut select.joins {
2191 if let Some(ref mut on) = join.on {
2192 *on = unqualify_columns_recursive(on.clone());
2193 }
2194 }
2195 Expression::Select(select)
2196 }
2197 Expression::Alias(mut alias) => {
2198 alias.this = unqualify_columns_recursive(alias.this);
2199 Expression::Alias(alias)
2200 }
2201 Expression::And(op) => Expression::And(Box::new(unqualify_binary_op(*op))),
2203 Expression::Or(op) => Expression::Or(Box::new(unqualify_binary_op(*op))),
2204 Expression::Eq(op) => Expression::Eq(Box::new(unqualify_binary_op(*op))),
2205 Expression::Neq(op) => Expression::Neq(Box::new(unqualify_binary_op(*op))),
2206 Expression::Lt(op) => Expression::Lt(Box::new(unqualify_binary_op(*op))),
2207 Expression::Lte(op) => Expression::Lte(Box::new(unqualify_binary_op(*op))),
2208 Expression::Gt(op) => Expression::Gt(Box::new(unqualify_binary_op(*op))),
2209 Expression::Gte(op) => Expression::Gte(Box::new(unqualify_binary_op(*op))),
2210 Expression::Add(op) => Expression::Add(Box::new(unqualify_binary_op(*op))),
2211 Expression::Sub(op) => Expression::Sub(Box::new(unqualify_binary_op(*op))),
2212 Expression::Mul(op) => Expression::Mul(Box::new(unqualify_binary_op(*op))),
2213 Expression::Div(op) => Expression::Div(Box::new(unqualify_binary_op(*op))),
2214 Expression::Function(mut func) => {
2216 func.args = func
2217 .args
2218 .into_iter()
2219 .map(unqualify_columns_recursive)
2220 .collect();
2221 Expression::Function(func)
2222 }
2223 Expression::AggregateFunction(mut func) => {
2224 func.args = func
2225 .args
2226 .into_iter()
2227 .map(unqualify_columns_recursive)
2228 .collect();
2229 Expression::AggregateFunction(func)
2230 }
2231 Expression::Case(mut case) => {
2232 case.whens = case
2233 .whens
2234 .into_iter()
2235 .map(|(cond, result)| {
2236 (
2237 unqualify_columns_recursive(cond),
2238 unqualify_columns_recursive(result),
2239 )
2240 })
2241 .collect();
2242 if let Some(else_expr) = case.else_ {
2243 case.else_ = Some(unqualify_columns_recursive(else_expr));
2244 }
2245 Expression::Case(case)
2246 }
2247 other => other,
2249 }
2250}
2251
2252fn unqualify_binary_op(mut op: BinaryOp) -> BinaryOp {
2254 op.left = unqualify_columns_recursive(op.left);
2255 op.right = unqualify_columns_recursive(op.right);
2256 op
2257}
2258
2259pub fn unnest_generate_date_array_using_recursive_cte(expr: Expression) -> Result<Expression> {
2279 match expr {
2280 Expression::Select(mut select) => {
2281 let mut cte_count = 0;
2282 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
2283
2284 if let Some(ref mut with) = select.with {
2286 for cte in &mut with.ctes {
2287 process_expression_for_gda(&mut cte.this, &mut cte_count, &mut new_ctes);
2288 }
2289 }
2290
2291 if let Some(ref mut from) = select.from {
2293 for table_expr in &mut from.expressions {
2294 if let Some((cte, replacement)) =
2295 try_convert_generate_date_array(table_expr, &mut cte_count)
2296 {
2297 new_ctes.push(cte);
2298 *table_expr = replacement;
2299 }
2300 }
2301 }
2302
2303 for join in &mut select.joins {
2305 if let Some((cte, replacement)) =
2306 try_convert_generate_date_array(&join.this, &mut cte_count)
2307 {
2308 new_ctes.push(cte);
2309 join.this = replacement;
2310 }
2311 }
2312
2313 if !new_ctes.is_empty() {
2315 let with_clause = select.with.get_or_insert_with(|| crate::expressions::With {
2316 ctes: Vec::new(),
2317 recursive: true, leading_comments: vec![],
2319 search: None,
2320 });
2321 with_clause.recursive = true;
2322
2323 let mut all_ctes = new_ctes;
2325 all_ctes.append(&mut with_clause.ctes);
2326 with_clause.ctes = all_ctes;
2327 }
2328
2329 Ok(Expression::Select(select))
2330 }
2331 other => Ok(other),
2332 }
2333}
2334
2335fn process_expression_for_gda(
2338 expr: &mut Expression,
2339 cte_count: &mut usize,
2340 new_ctes: &mut Vec<crate::expressions::Cte>,
2341) {
2342 match expr {
2343 Expression::Select(ref mut select) => {
2344 if let Some(ref mut from) = select.from {
2346 for table_expr in &mut from.expressions {
2347 if let Some((cte, replacement)) =
2348 try_convert_generate_date_array(table_expr, cte_count)
2349 {
2350 new_ctes.push(cte);
2351 *table_expr = replacement;
2352 }
2353 }
2354 }
2355 for join in &mut select.joins {
2357 if let Some((cte, replacement)) =
2358 try_convert_generate_date_array(&join.this, cte_count)
2359 {
2360 new_ctes.push(cte);
2361 join.this = replacement;
2362 }
2363 }
2364 }
2365 Expression::Union(ref mut u) => {
2366 process_expression_for_gda(&mut u.left, cte_count, new_ctes);
2367 process_expression_for_gda(&mut u.right, cte_count, new_ctes);
2368 }
2369 Expression::Subquery(ref mut sq) => {
2370 process_expression_for_gda(&mut sq.this, cte_count, new_ctes);
2371 }
2372 _ => {}
2373 }
2374}
2375
2376fn try_convert_generate_date_array(
2379 expr: &Expression,
2380 cte_count: &mut usize,
2381) -> Option<(crate::expressions::Cte, Expression)> {
2382 try_convert_generate_date_array_with_name(expr, cte_count, None)
2383}
2384
2385fn try_convert_generate_date_array_with_name(
2386 expr: &Expression,
2387 cte_count: &mut usize,
2388 column_name_override: Option<&str>,
2389) -> Option<(crate::expressions::Cte, Expression)> {
2390 fn extract_gda_args(
2392 inner: &Expression,
2393 ) -> Option<(&Expression, &Expression, Option<&Expression>)> {
2394 match inner {
2395 Expression::GenerateDateArray(gda) => {
2396 let start = gda.start.as_ref()?;
2397 let end = gda.end.as_ref()?;
2398 let step = gda.step.as_deref();
2399 Some((start, end, step))
2400 }
2401 Expression::GenerateSeries(gs) => {
2402 let start = gs.start.as_deref()?;
2403 let end = gs.end.as_deref()?;
2404 let step = gs.step.as_deref();
2405 Some((start, end, step))
2406 }
2407 Expression::Function(f) if f.name.eq_ignore_ascii_case("GENERATE_DATE_ARRAY") => {
2408 if f.args.len() >= 2 {
2409 let start = &f.args[0];
2410 let end = &f.args[1];
2411 let step = f.args.get(2);
2412 Some((start, end, step))
2413 } else {
2414 None
2415 }
2416 }
2417 _ => None,
2418 }
2419 }
2420
2421 if let Expression::Unnest(unnest) = expr {
2423 if let Some((start, end, step_opt)) = extract_gda_args(&unnest.this) {
2424 let start = start;
2425 let end = end;
2426 let step: Option<&Expression> = step_opt;
2427
2428 let cte_name = if *cte_count == 0 {
2430 "_generated_dates".to_string()
2431 } else {
2432 format!("_generated_dates_{}", cte_count)
2433 };
2434 *cte_count += 1;
2435
2436 let column_name =
2437 Identifier::new(column_name_override.unwrap_or("date_value").to_string());
2438
2439 let cast_to_date = |expr: &Expression| -> Expression {
2441 match expr {
2442 Expression::Literal(Literal::Date(_)) => {
2443 if let Expression::Literal(Literal::Date(d)) = expr {
2445 Expression::Cast(Box::new(Cast {
2446 this: Expression::Literal(Literal::String(d.clone())),
2447 to: DataType::Date,
2448 trailing_comments: vec![],
2449 double_colon_syntax: false,
2450 format: None,
2451 default: None,
2452 inferred_type: None,
2453 }))
2454 } else {
2455 unreachable!()
2456 }
2457 }
2458 Expression::Cast(c) if matches!(c.to, DataType::Date) => expr.clone(),
2459 _ => Expression::Cast(Box::new(Cast {
2460 this: expr.clone(),
2461 to: DataType::Date,
2462 trailing_comments: vec![],
2463 double_colon_syntax: false,
2464 format: None,
2465 default: None,
2466 inferred_type: None,
2467 })),
2468 }
2469 };
2470
2471 let base_select = Select {
2473 expressions: vec![Expression::Alias(Box::new(crate::expressions::Alias {
2474 this: cast_to_date(start),
2475 alias: column_name.clone(),
2476 column_aliases: vec![],
2477 pre_alias_comments: vec![],
2478 trailing_comments: vec![],
2479 inferred_type: None,
2480 }))],
2481 ..Select::new()
2482 };
2483
2484 let normalize_interval = |expr: &Expression| -> Expression {
2486 if let Expression::Interval(ref iv) = expr {
2487 let mut iv_clone = iv.as_ref().clone();
2488 if let Some(Expression::Literal(Literal::String(ref s))) = iv_clone.this {
2489 if s.parse::<f64>().is_ok() {
2491 iv_clone.this = Some(Expression::Literal(Literal::Number(s.clone())));
2492 }
2493 }
2494 Expression::Interval(Box::new(iv_clone))
2495 } else {
2496 expr.clone()
2497 }
2498 };
2499
2500 let normalized_step = step.map(|s| normalize_interval(s)).unwrap_or_else(|| {
2503 Expression::Interval(Box::new(crate::expressions::Interval {
2504 this: Some(Expression::Literal(Literal::Number("1".to_string()))),
2505 unit: Some(crate::expressions::IntervalUnitSpec::Simple {
2506 unit: crate::expressions::IntervalUnit::Day,
2507 use_plural: false,
2508 }),
2509 }))
2510 });
2511
2512 let (add_unit, add_count) = extract_interval_unit_and_count(&normalized_step);
2514
2515 let date_add_expr = Expression::DateAdd(Box::new(crate::expressions::DateAddFunc {
2516 this: Expression::Column(crate::expressions::Column {
2517 name: column_name.clone(),
2518 table: None,
2519 join_mark: false,
2520 trailing_comments: vec![],
2521 span: None,
2522 inferred_type: None,
2523 }),
2524 interval: add_count,
2525 unit: add_unit,
2526 }));
2527
2528 let cast_date_add = Expression::Cast(Box::new(Cast {
2529 this: date_add_expr.clone(),
2530 to: DataType::Date,
2531 trailing_comments: vec![],
2532 double_colon_syntax: false,
2533 format: None,
2534 default: None,
2535 inferred_type: None,
2536 }));
2537
2538 let recursive_select = Select {
2539 expressions: vec![cast_date_add.clone()],
2540 from: Some(From {
2541 expressions: vec![Expression::Table(crate::expressions::TableRef::new(
2542 &cte_name,
2543 ))],
2544 }),
2545 where_clause: Some(Where {
2546 this: Expression::Lte(Box::new(BinaryOp {
2547 left: cast_date_add,
2548 right: cast_to_date(end),
2549 left_comments: vec![],
2550 operator_comments: vec![],
2551 trailing_comments: vec![],
2552 inferred_type: None,
2553 })),
2554 }),
2555 ..Select::new()
2556 };
2557
2558 let union = crate::expressions::Union {
2560 left: Expression::Select(Box::new(base_select)),
2561 right: Expression::Select(Box::new(recursive_select)),
2562 all: true, distinct: false,
2564 with: None,
2565 order_by: None,
2566 limit: None,
2567 offset: None,
2568 distribute_by: None,
2569 sort_by: None,
2570 cluster_by: None,
2571 by_name: false,
2572 side: None,
2573 kind: None,
2574 corresponding: false,
2575 strict: false,
2576 on_columns: Vec::new(),
2577 };
2578
2579 let cte = crate::expressions::Cte {
2581 this: Expression::Union(Box::new(union)),
2582 alias: Identifier::new(cte_name.clone()),
2583 columns: vec![column_name.clone()],
2584 materialized: None,
2585 key_expressions: Vec::new(),
2586 alias_first: true,
2587 comments: Vec::new(),
2588 };
2589
2590 let replacement_select = Select {
2592 expressions: vec![Expression::Column(crate::expressions::Column {
2593 name: column_name,
2594 table: None,
2595 join_mark: false,
2596 trailing_comments: vec![],
2597 span: None,
2598 inferred_type: None,
2599 })],
2600 from: Some(From {
2601 expressions: vec![Expression::Table(crate::expressions::TableRef::new(
2602 &cte_name,
2603 ))],
2604 }),
2605 ..Select::new()
2606 };
2607
2608 let replacement = Expression::Subquery(Box::new(Subquery {
2609 this: Expression::Select(Box::new(replacement_select)),
2610 alias: Some(Identifier::new(cte_name)),
2611 column_aliases: vec![],
2612 order_by: None,
2613 limit: None,
2614 offset: None,
2615 distribute_by: None,
2616 sort_by: None,
2617 cluster_by: None,
2618 lateral: false,
2619 modifiers_inside: false,
2620 trailing_comments: vec![],
2621 inferred_type: None,
2622 }));
2623
2624 return Some((cte, replacement));
2625 }
2626 }
2627
2628 if let Expression::Alias(alias) = expr {
2630 let col_name = alias.column_aliases.first().map(|id| id.name.as_str());
2632 if let Some((cte, replacement)) =
2633 try_convert_generate_date_array_with_name(&alias.this, cte_count, col_name)
2634 {
2635 if col_name.is_some() {
2638 return Some((cte, replacement));
2639 }
2640 let new_alias = Expression::Alias(Box::new(crate::expressions::Alias {
2641 this: replacement,
2642 alias: alias.alias.clone(),
2643 column_aliases: alias.column_aliases.clone(),
2644 pre_alias_comments: alias.pre_alias_comments.clone(),
2645 trailing_comments: alias.trailing_comments.clone(),
2646 inferred_type: None,
2647 }));
2648 return Some((cte, new_alias));
2649 }
2650 }
2651
2652 None
2653}
2654
2655fn extract_interval_unit_and_count(
2660 expr: &Expression,
2661) -> (crate::expressions::IntervalUnit, Expression) {
2662 use crate::expressions::{IntervalUnit, IntervalUnitSpec, Literal};
2663
2664 if let Expression::Interval(ref iv) = expr {
2665 if let Some(ref unit_spec) = iv.unit {
2667 if let IntervalUnitSpec::Simple { unit, .. } = unit_spec {
2668 let count = match &iv.this {
2669 Some(e) => e.clone(),
2670 None => Expression::Literal(Literal::Number("1".to_string())),
2671 };
2672 return (unit.clone(), count);
2673 }
2674 }
2675
2676 if let Some(ref val_expr) = iv.this {
2678 match val_expr {
2679 Expression::Literal(Literal::String(s))
2680 | Expression::Literal(Literal::Number(s)) => {
2681 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
2683 if parts.len() == 2 {
2684 let count_str = parts[0].trim();
2685 let unit_str = parts[1].trim().to_uppercase();
2686 let unit = match unit_str.as_str() {
2687 "YEAR" | "YEARS" => IntervalUnit::Year,
2688 "QUARTER" | "QUARTERS" => IntervalUnit::Quarter,
2689 "MONTH" | "MONTHS" => IntervalUnit::Month,
2690 "WEEK" | "WEEKS" => IntervalUnit::Week,
2691 "DAY" | "DAYS" => IntervalUnit::Day,
2692 "HOUR" | "HOURS" => IntervalUnit::Hour,
2693 "MINUTE" | "MINUTES" => IntervalUnit::Minute,
2694 "SECOND" | "SECONDS" => IntervalUnit::Second,
2695 "MILLISECOND" | "MILLISECONDS" => IntervalUnit::Millisecond,
2696 "MICROSECOND" | "MICROSECONDS" => IntervalUnit::Microsecond,
2697 _ => IntervalUnit::Day,
2698 };
2699 return (
2700 unit,
2701 Expression::Literal(Literal::Number(count_str.to_string())),
2702 );
2703 }
2704 if s.parse::<f64>().is_ok() {
2706 return (
2707 IntervalUnit::Day,
2708 Expression::Literal(Literal::Number(s.clone())),
2709 );
2710 }
2711 }
2712 _ => {}
2713 }
2714 }
2715
2716 (
2718 IntervalUnit::Day,
2719 Expression::Literal(Literal::Number("1".to_string())),
2720 )
2721 } else {
2722 (
2723 IntervalUnit::Day,
2724 Expression::Literal(Literal::Number("1".to_string())),
2725 )
2726 }
2727}
2728
2729pub fn no_ilike_sql(expr: Expression) -> Result<Expression> {
2742 match expr {
2743 Expression::ILike(ilike) => {
2744 let lower_left = Expression::Function(Box::new(crate::expressions::Function {
2746 name: "LOWER".to_string(),
2747 args: vec![ilike.left],
2748 distinct: false,
2749 trailing_comments: vec![],
2750 use_bracket_syntax: false,
2751 no_parens: false,
2752 quoted: false,
2753 span: None,
2754 inferred_type: None,
2755 }));
2756
2757 let lower_right = Expression::Function(Box::new(crate::expressions::Function {
2758 name: "LOWER".to_string(),
2759 args: vec![ilike.right],
2760 distinct: false,
2761 trailing_comments: vec![],
2762 use_bracket_syntax: false,
2763 no_parens: false,
2764 quoted: false,
2765 span: None,
2766 inferred_type: None,
2767 }));
2768
2769 Ok(Expression::Like(Box::new(crate::expressions::LikeOp {
2770 left: lower_left,
2771 right: lower_right,
2772 escape: ilike.escape,
2773 quantifier: ilike.quantifier,
2774 inferred_type: None,
2775 })))
2776 }
2777 other => Ok(other),
2778 }
2779}
2780
2781pub fn no_trycast_sql(expr: Expression) -> Result<Expression> {
2789 match expr {
2790 Expression::TryCast(try_cast) => Ok(Expression::Cast(try_cast)),
2791 other => Ok(other),
2792 }
2793}
2794
2795pub fn no_safe_cast_sql(expr: Expression) -> Result<Expression> {
2800 match expr {
2801 Expression::SafeCast(safe_cast) => Ok(Expression::Cast(safe_cast)),
2802 other => Ok(other),
2803 }
2804}
2805
2806pub fn no_comment_column_constraint(expr: Expression) -> Result<Expression> {
2813 Ok(expr)
2815}
2816
2817pub fn unnest_generate_series(expr: Expression) -> Result<Expression> {
2831 match expr {
2834 Expression::Table(ref table) => {
2835 if table.name.name.to_uppercase() == "GENERATE_SERIES" {
2838 let unnest = Expression::Unnest(Box::new(UnnestFunc {
2840 this: expr.clone(),
2841 expressions: Vec::new(),
2842 with_ordinality: false,
2843 alias: None,
2844 offset_alias: None,
2845 }));
2846
2847 return Ok(Expression::Alias(Box::new(crate::expressions::Alias {
2849 this: unnest,
2850 alias: Identifier::new("_u".to_string()),
2851 column_aliases: vec![],
2852 pre_alias_comments: vec![],
2853 trailing_comments: vec![],
2854 inferred_type: None,
2855 })));
2856 }
2857 Ok(expr)
2858 }
2859 Expression::GenerateSeries(gs) => {
2860 let unnest = Expression::Unnest(Box::new(UnnestFunc {
2862 this: Expression::GenerateSeries(gs),
2863 expressions: Vec::new(),
2864 with_ordinality: false,
2865 alias: None,
2866 offset_alias: None,
2867 }));
2868 Ok(unnest)
2869 }
2870 other => Ok(other),
2871 }
2872}
2873
2874pub fn unwrap_unnest_generate_series_for_postgres(expr: Expression) -> Result<Expression> {
2885 use crate::dialects::transform_recursive;
2886 transform_recursive(expr, &unwrap_unnest_generate_series_single)
2887}
2888
2889fn unwrap_unnest_generate_series_single(expr: Expression) -> Result<Expression> {
2890 use crate::expressions::*;
2891 match expr {
2893 Expression::Select(mut select) => {
2894 if let Some(ref mut from) = select.from {
2896 for table_expr in &mut from.expressions {
2897 if let Some(replacement) = try_unwrap_unnest_gen_series(table_expr) {
2898 *table_expr = replacement;
2899 }
2900 }
2901 }
2902 for join in &mut select.joins {
2904 if let Some(replacement) = try_unwrap_unnest_gen_series(&join.this) {
2905 join.this = replacement;
2906 }
2907 }
2908 Ok(Expression::Select(select))
2909 }
2910 other => Ok(other),
2911 }
2912}
2913
2914fn try_unwrap_unnest_gen_series(expr: &Expression) -> Option<Expression> {
2917 use crate::expressions::*;
2918
2919 let gen_series = match expr {
2921 Expression::Unnest(unnest) => {
2922 if let Expression::GenerateSeries(ref gs) = unnest.this {
2923 Some(gs.as_ref().clone())
2924 } else {
2925 None
2926 }
2927 }
2928 Expression::Alias(alias) => {
2929 if let Expression::Unnest(ref unnest) = alias.this {
2930 if let Expression::GenerateSeries(ref gs) = unnest.this {
2931 Some(gs.as_ref().clone())
2932 } else {
2933 None
2934 }
2935 } else {
2936 None
2937 }
2938 }
2939 _ => None,
2940 };
2941
2942 let gs = gen_series?;
2943
2944 let value_col = Expression::Column(Column {
2946 name: Identifier::new("value".to_string()),
2947 table: None,
2948 join_mark: false,
2949 trailing_comments: vec![],
2950 span: None,
2951 inferred_type: None,
2952 });
2953
2954 let cast_value = Expression::Cast(Box::new(Cast {
2955 this: value_col,
2956 to: DataType::Date,
2957 trailing_comments: vec![],
2958 double_colon_syntax: false,
2959 format: None,
2960 default: None,
2961 inferred_type: None,
2962 }));
2963
2964 let gen_series_expr = Expression::GenerateSeries(Box::new(gs));
2965
2966 let gen_series_aliased = Expression::Alias(Box::new(Alias {
2968 this: gen_series_expr,
2969 alias: Identifier::new("_t".to_string()),
2970 column_aliases: vec![Identifier::new("value".to_string())],
2971 pre_alias_comments: vec![],
2972 trailing_comments: vec![],
2973 inferred_type: None,
2974 }));
2975
2976 let mut inner_select = Select::new();
2977 inner_select.expressions = vec![cast_value];
2978 inner_select.from = Some(From {
2979 expressions: vec![gen_series_aliased],
2980 });
2981
2982 let inner_select_expr = Expression::Select(Box::new(inner_select));
2983
2984 let subquery = Expression::Subquery(Box::new(Subquery {
2985 this: inner_select_expr,
2986 alias: None,
2987 column_aliases: vec![],
2988 order_by: None,
2989 limit: None,
2990 offset: None,
2991 distribute_by: None,
2992 sort_by: None,
2993 cluster_by: None,
2994 lateral: false,
2995 modifiers_inside: false,
2996 trailing_comments: vec![],
2997 inferred_type: None,
2998 }));
2999
3000 Some(Expression::Alias(Box::new(Alias {
3002 this: subquery,
3003 alias: Identifier::new("_unnested_generate_series".to_string()),
3004 column_aliases: vec![],
3005 pre_alias_comments: vec![],
3006 trailing_comments: vec![],
3007 inferred_type: None,
3008 })))
3009}
3010
3011pub fn expand_between_in_delete(expr: Expression) -> Result<Expression> {
3019 match expr {
3020 Expression::Delete(mut delete) => {
3021 if let Some(ref mut where_clause) = delete.where_clause {
3023 where_clause.this = expand_between_recursive(where_clause.this.clone());
3024 }
3025 Ok(Expression::Delete(delete))
3026 }
3027 other => Ok(other),
3028 }
3029}
3030
3031fn expand_between_recursive(expr: Expression) -> Expression {
3033 match expr {
3034 Expression::Between(between) => {
3037 let this = expand_between_recursive(between.this.clone());
3038 let low = expand_between_recursive(between.low);
3039 let high = expand_between_recursive(between.high);
3040
3041 if between.not {
3042 Expression::Or(Box::new(BinaryOp::new(
3044 Expression::Lt(Box::new(BinaryOp::new(this.clone(), low))),
3045 Expression::Gt(Box::new(BinaryOp::new(this, high))),
3046 )))
3047 } else {
3048 Expression::And(Box::new(BinaryOp::new(
3050 Expression::Gte(Box::new(BinaryOp::new(this.clone(), low))),
3051 Expression::Lte(Box::new(BinaryOp::new(this, high))),
3052 )))
3053 }
3054 }
3055
3056 Expression::And(mut op) => {
3058 op.left = expand_between_recursive(op.left);
3059 op.right = expand_between_recursive(op.right);
3060 Expression::And(op)
3061 }
3062 Expression::Or(mut op) => {
3063 op.left = expand_between_recursive(op.left);
3064 op.right = expand_between_recursive(op.right);
3065 Expression::Or(op)
3066 }
3067 Expression::Not(mut op) => {
3068 op.this = expand_between_recursive(op.this);
3069 Expression::Not(op)
3070 }
3071
3072 Expression::Paren(mut paren) => {
3074 paren.this = expand_between_recursive(paren.this);
3075 Expression::Paren(paren)
3076 }
3077
3078 other => other,
3080 }
3081}
3082
3083pub fn pushdown_cte_column_names(expr: Expression) -> Result<Expression> {
3092 match expr {
3093 Expression::Select(mut select) => {
3094 if let Some(ref mut with) = select.with {
3095 for cte in &mut with.ctes {
3096 if !cte.columns.is_empty() {
3097 let is_star = matches!(&cte.this, Expression::Select(s) if
3099 s.expressions.len() == 1 && matches!(&s.expressions[0], Expression::Star(_)));
3100
3101 if is_star {
3102 cte.columns.clear();
3104 continue;
3105 }
3106
3107 let column_names: Vec<Identifier> = cte.columns.drain(..).collect();
3109
3110 if let Expression::Select(ref mut inner_select) = cte.this {
3112 let new_exprs: Vec<Expression> = inner_select
3113 .expressions
3114 .drain(..)
3115 .zip(
3116 column_names
3117 .into_iter()
3118 .chain(std::iter::repeat_with(|| Identifier::new(""))),
3119 )
3120 .map(|(expr, col_name)| {
3121 if col_name.name.is_empty() {
3122 return expr;
3123 }
3124 match expr {
3126 Expression::Alias(mut a) => {
3127 a.alias = col_name;
3128 Expression::Alias(a)
3129 }
3130 other => {
3131 Expression::Alias(Box::new(crate::expressions::Alias {
3132 this: other,
3133 alias: col_name,
3134 column_aliases: Vec::new(),
3135 pre_alias_comments: Vec::new(),
3136 trailing_comments: Vec::new(),
3137 inferred_type: None,
3138 }))
3139 }
3140 }
3141 })
3142 .collect();
3143 inner_select.expressions = new_exprs;
3144 }
3145 }
3146 }
3147 }
3148 Ok(Expression::Select(select))
3149 }
3150 other => Ok(other),
3151 }
3152}
3153
3154pub fn simplify_nested_paren_values(expr: Expression) -> Result<Expression> {
3158 match expr {
3159 Expression::Select(mut select) => {
3160 if let Some(ref mut from) = select.from {
3161 for from_item in from.expressions.iter_mut() {
3162 simplify_paren_values_in_from(from_item);
3163 }
3164 }
3165 Ok(Expression::Select(select))
3166 }
3167 other => Ok(other),
3168 }
3169}
3170
3171fn simplify_paren_values_in_from(expr: &mut Expression) {
3172 let replacement = match expr {
3174 Expression::Subquery(ref subquery) => {
3176 if let Expression::Paren(ref paren) = subquery.this {
3177 if matches!(&paren.this, Expression::Values(_)) {
3178 let mut new_sub = subquery.as_ref().clone();
3179 new_sub.this = paren.this.clone();
3180 Some(Expression::Subquery(Box::new(new_sub)))
3181 } else {
3182 None
3183 }
3184 } else {
3185 None
3186 }
3187 }
3188 Expression::Paren(ref outer_paren) => {
3191 if let Expression::Subquery(ref subquery) = outer_paren.this {
3192 if matches!(&subquery.this, Expression::Values(_)) {
3194 Some(outer_paren.this.clone())
3195 }
3196 else if let Expression::Paren(ref paren) = subquery.this {
3198 if matches!(&paren.this, Expression::Values(_)) {
3199 let mut new_sub = subquery.as_ref().clone();
3200 new_sub.this = paren.this.clone();
3201 Some(Expression::Subquery(Box::new(new_sub)))
3202 } else {
3203 None
3204 }
3205 } else {
3206 None
3207 }
3208 } else if let Expression::Paren(ref inner_paren) = outer_paren.this {
3209 if matches!(&inner_paren.this, Expression::Values(_)) {
3210 Some(outer_paren.this.clone())
3211 } else {
3212 None
3213 }
3214 } else {
3215 None
3216 }
3217 }
3218 _ => None,
3219 };
3220 if let Some(new_expr) = replacement {
3221 *expr = new_expr;
3222 }
3223}
3224
3225pub fn add_auto_table_alias(expr: Expression) -> Result<Expression> {
3229 match expr {
3230 Expression::Select(mut select) => {
3231 if let Some(ref mut from) = select.from {
3233 let mut counter = 0usize;
3234 for from_item in from.expressions.iter_mut() {
3235 add_auto_alias_to_from_item(from_item, &mut counter);
3236 }
3237 }
3238 Ok(Expression::Select(select))
3239 }
3240 other => Ok(other),
3241 }
3242}
3243
3244fn add_auto_alias_to_from_item(expr: &mut Expression, counter: &mut usize) {
3245 use crate::expressions::Identifier;
3246
3247 match expr {
3248 Expression::Alias(ref mut alias) => {
3249 if alias.alias.name.is_empty() && !alias.column_aliases.is_empty() {
3251 alias.alias = Identifier::new(format!("_t{}", counter));
3252 *counter += 1;
3253 }
3254 }
3255 _ => {}
3256 }
3257}
3258
3259pub fn propagate_struct_field_names(expr: Expression) -> Result<Expression> {
3269 use crate::dialects::transform_recursive;
3270 transform_recursive(expr, &propagate_struct_names_in_expr)
3271}
3272
3273fn propagate_struct_names_in_expr(expr: Expression) -> Result<Expression> {
3274 use crate::expressions::{Alias, ArrayConstructor, Function, Identifier};
3275
3276 fn propagate_in_elements(elements: &[Expression]) -> Option<Vec<Expression>> {
3278 if elements.len() <= 1 {
3279 return None;
3280 }
3281 if let Some(Expression::Function(ref first_struct)) = elements.first() {
3283 if first_struct.name.eq_ignore_ascii_case("STRUCT") {
3284 let field_names: Vec<Option<String>> = first_struct
3286 .args
3287 .iter()
3288 .map(|arg| {
3289 if let Expression::Alias(a) = arg {
3290 Some(a.alias.name.clone())
3291 } else {
3292 None
3293 }
3294 })
3295 .collect();
3296
3297 if field_names.iter().any(|n| n.is_some()) {
3299 let mut new_elements = Vec::with_capacity(elements.len());
3300 new_elements.push(elements[0].clone());
3301
3302 for elem in &elements[1..] {
3303 if let Expression::Function(ref s) = elem {
3304 if s.name.eq_ignore_ascii_case("STRUCT")
3305 && s.args.len() == field_names.len()
3306 {
3307 let all_unnamed =
3309 s.args.iter().all(|a| !matches!(a, Expression::Alias(_)));
3310 if all_unnamed {
3311 let new_args: Vec<Expression> = s
3313 .args
3314 .iter()
3315 .zip(field_names.iter())
3316 .map(|(val, name)| {
3317 if let Some(n) = name {
3318 Expression::Alias(Box::new(Alias::new(
3319 val.clone(),
3320 Identifier::new(n.clone()),
3321 )))
3322 } else {
3323 val.clone()
3324 }
3325 })
3326 .collect();
3327 new_elements.push(Expression::Function(Box::new(
3328 Function::new("STRUCT".to_string(), new_args),
3329 )));
3330 continue;
3331 }
3332 }
3333 }
3334 new_elements.push(elem.clone());
3335 }
3336
3337 return Some(new_elements);
3338 }
3339 }
3340 }
3341 None
3342 }
3343
3344 if let Expression::Array(ref arr) = expr {
3346 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
3347 return Ok(Expression::Array(Box::new(crate::expressions::Array {
3348 expressions: new_elements,
3349 })));
3350 }
3351 }
3352
3353 if let Expression::ArrayFunc(ref arr) = expr {
3355 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
3356 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
3357 expressions: new_elements,
3358 bracket_notation: arr.bracket_notation,
3359 use_list_keyword: arr.use_list_keyword,
3360 })));
3361 }
3362 }
3363
3364 Ok(expr)
3365}
3366
3367pub fn unnest_alias_to_column_alias(expr: Expression) -> Result<Expression> {
3370 use crate::dialects::transform_recursive;
3371 transform_recursive(expr, &unnest_alias_transform_single_select)
3372}
3373
3374pub fn unnest_from_to_cross_join(expr: Expression) -> Result<Expression> {
3377 use crate::dialects::transform_recursive;
3378 transform_recursive(expr, &unnest_from_to_cross_join_single_select)
3379}
3380
3381fn unnest_from_to_cross_join_single_select(expr: Expression) -> Result<Expression> {
3382 if let Expression::Select(mut select) = expr {
3383 if let Some(ref mut from) = select.from {
3384 if from.expressions.len() > 1 {
3385 let mut new_from_exprs = Vec::new();
3386 let mut new_cross_joins = Vec::new();
3387
3388 for (idx, from_item) in from.expressions.drain(..).enumerate() {
3389 if idx == 0 {
3390 new_from_exprs.push(from_item);
3391 } else {
3392 let is_unnest = match &from_item {
3393 Expression::Unnest(_) => true,
3394 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
3395 _ => false,
3396 };
3397
3398 if is_unnest {
3399 new_cross_joins.push(crate::expressions::Join {
3400 this: from_item,
3401 on: None,
3402 using: Vec::new(),
3403 kind: JoinKind::Cross,
3404 use_inner_keyword: false,
3405 use_outer_keyword: false,
3406 deferred_condition: false,
3407 join_hint: None,
3408 match_condition: None,
3409 pivots: Vec::new(),
3410 comments: Vec::new(),
3411 nesting_group: 0,
3412 directed: false,
3413 });
3414 } else {
3415 new_from_exprs.push(from_item);
3416 }
3417 }
3418 }
3419
3420 from.expressions = new_from_exprs;
3421 new_cross_joins.append(&mut select.joins);
3422 select.joins = new_cross_joins;
3423 }
3424 }
3425
3426 Ok(Expression::Select(select))
3427 } else {
3428 Ok(expr)
3429 }
3430}
3431
3432pub fn wrap_unnest_join_aliases(expr: Expression) -> Result<Expression> {
3436 use crate::dialects::transform_recursive;
3437 transform_recursive(expr, &wrap_unnest_join_aliases_single)
3438}
3439
3440fn wrap_unnest_join_aliases_single(expr: Expression) -> Result<Expression> {
3441 if let Expression::Select(mut select) = expr {
3442 for join in &mut select.joins {
3444 wrap_unnest_alias_in_join_item(&mut join.this);
3445 }
3446 Ok(Expression::Select(select))
3447 } else {
3448 Ok(expr)
3449 }
3450}
3451
3452fn wrap_unnest_alias_in_join_item(expr: &mut Expression) {
3454 use crate::expressions::Identifier;
3455 if let Expression::Alias(alias) = expr {
3456 let is_unnest = match &alias.this {
3458 Expression::Function(f) => f.name.eq_ignore_ascii_case("UNNEST"),
3459 _ => false,
3460 };
3461
3462 if is_unnest && alias.column_aliases.is_empty() {
3463 let original_alias_name = alias.alias.name.clone();
3465 alias.alias = Identifier {
3466 name: "_u".to_string(),
3467 quoted: false,
3468 trailing_comments: Vec::new(),
3469 span: None,
3470 };
3471 alias.column_aliases = vec![Identifier {
3472 name: original_alias_name,
3473 quoted: false,
3474 trailing_comments: Vec::new(),
3475 span: None,
3476 }];
3477 }
3478 }
3479}
3480
3481fn unnest_alias_transform_single_select(expr: Expression) -> Result<Expression> {
3482 if let Expression::Select(mut select) = expr {
3483 let mut counter = 0usize;
3484
3485 if let Some(ref mut from) = select.from {
3487 for from_item in from.expressions.iter_mut() {
3489 convert_unnest_alias_in_from(from_item, &mut counter);
3490 }
3491
3492 if from.expressions.len() > 1 {
3494 let mut new_from_exprs = Vec::new();
3495 let mut new_cross_joins = Vec::new();
3496
3497 for (idx, from_item) in from.expressions.drain(..).enumerate() {
3498 if idx == 0 {
3499 new_from_exprs.push(from_item);
3501 } else {
3502 let is_unnest = match &from_item {
3504 Expression::Unnest(_) => true,
3505 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
3506 _ => false,
3507 };
3508
3509 if is_unnest {
3510 new_cross_joins.push(crate::expressions::Join {
3512 this: from_item,
3513 on: None,
3514 using: Vec::new(),
3515 kind: JoinKind::Cross,
3516 use_inner_keyword: false,
3517 use_outer_keyword: false,
3518 deferred_condition: false,
3519 join_hint: None,
3520 match_condition: None,
3521 pivots: Vec::new(),
3522 comments: Vec::new(),
3523 nesting_group: 0,
3524 directed: false,
3525 });
3526 } else {
3527 new_from_exprs.push(from_item);
3529 }
3530 }
3531 }
3532
3533 from.expressions = new_from_exprs;
3534 new_cross_joins.append(&mut select.joins);
3536 select.joins = new_cross_joins;
3537 }
3538 }
3539
3540 for join in select.joins.iter_mut() {
3542 convert_unnest_alias_in_from(&mut join.this, &mut counter);
3543 }
3544
3545 Ok(Expression::Select(select))
3546 } else {
3547 Ok(expr)
3548 }
3549}
3550
3551fn convert_unnest_alias_in_from(expr: &mut Expression, counter: &mut usize) {
3552 use crate::expressions::Identifier;
3553
3554 if let Expression::Alias(ref mut alias) = expr {
3555 let is_unnest = matches!(&alias.this, Expression::Unnest(_))
3557 || matches!(&alias.this, Expression::Function(f) if f.name.eq_ignore_ascii_case("EXPLODE"));
3558
3559 if is_unnest && alias.column_aliases.is_empty() {
3560 let col_alias = alias.alias.clone();
3562 alias.column_aliases = vec![col_alias];
3563 alias.alias = Identifier::new(format!("_t{}", counter));
3564 *counter += 1;
3565 }
3566 }
3567}
3568
3569pub fn expand_posexplode_duckdb(expr: Expression) -> Result<Expression> {
3576 use crate::expressions::{Alias, Function};
3577
3578 match expr {
3579 Expression::Select(mut select) => {
3580 let mut new_expressions = Vec::new();
3582 let mut changed = false;
3583
3584 for sel_expr in select.expressions.drain(..) {
3585 if let Expression::Alias(ref alias_box) = sel_expr {
3587 if let Expression::Function(ref func) = alias_box.this {
3588 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3589 let arg = func.args[0].clone();
3590 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
3592 (
3593 alias_box.column_aliases[0].name.clone(),
3594 alias_box.column_aliases[1].name.clone(),
3595 )
3596 } else if !alias_box.alias.is_empty() {
3597 ("pos".to_string(), alias_box.alias.name.clone())
3599 } else {
3600 ("pos".to_string(), "col".to_string())
3601 };
3602
3603 let gen_subscripts = Expression::Function(Box::new(Function::new(
3605 "GENERATE_SUBSCRIPTS".to_string(),
3606 vec![
3607 arg.clone(),
3608 Expression::Literal(Literal::Number("1".to_string())),
3609 ],
3610 )));
3611 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3612 gen_subscripts,
3613 Expression::Literal(Literal::Number("1".to_string())),
3614 )));
3615 let pos_alias = Expression::Alias(Box::new(Alias {
3616 this: sub_one,
3617 alias: Identifier::new(pos_name),
3618 column_aliases: Vec::new(),
3619 pre_alias_comments: Vec::new(),
3620 trailing_comments: Vec::new(),
3621 inferred_type: None,
3622 }));
3623
3624 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3626 this: arg,
3627 expressions: Vec::new(),
3628 with_ordinality: false,
3629 alias: None,
3630 offset_alias: None,
3631 }));
3632 let col_alias = Expression::Alias(Box::new(Alias {
3633 this: unnest,
3634 alias: Identifier::new(col_name),
3635 column_aliases: Vec::new(),
3636 pre_alias_comments: Vec::new(),
3637 trailing_comments: Vec::new(),
3638 inferred_type: None,
3639 }));
3640
3641 new_expressions.push(pos_alias);
3642 new_expressions.push(col_alias);
3643 changed = true;
3644 continue;
3645 }
3646 }
3647 }
3648
3649 if let Expression::Function(ref func) = sel_expr {
3651 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3652 let arg = func.args[0].clone();
3653 let pos_name = "pos";
3654 let col_name = "col";
3655
3656 let gen_subscripts = Expression::Function(Box::new(Function::new(
3658 "GENERATE_SUBSCRIPTS".to_string(),
3659 vec![
3660 arg.clone(),
3661 Expression::Literal(Literal::Number("1".to_string())),
3662 ],
3663 )));
3664 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3665 gen_subscripts,
3666 Expression::Literal(Literal::Number("1".to_string())),
3667 )));
3668 let pos_alias = Expression::Alias(Box::new(Alias {
3669 this: sub_one,
3670 alias: Identifier::new(pos_name),
3671 column_aliases: Vec::new(),
3672 pre_alias_comments: Vec::new(),
3673 trailing_comments: Vec::new(),
3674 inferred_type: None,
3675 }));
3676
3677 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3679 this: arg,
3680 expressions: Vec::new(),
3681 with_ordinality: false,
3682 alias: None,
3683 offset_alias: None,
3684 }));
3685 let col_alias = Expression::Alias(Box::new(Alias {
3686 this: unnest,
3687 alias: Identifier::new(col_name),
3688 column_aliases: Vec::new(),
3689 pre_alias_comments: Vec::new(),
3690 trailing_comments: Vec::new(),
3691 inferred_type: None,
3692 }));
3693
3694 new_expressions.push(pos_alias);
3695 new_expressions.push(col_alias);
3696 changed = true;
3697 continue;
3698 }
3699 }
3700
3701 new_expressions.push(sel_expr);
3703 }
3704
3705 if changed {
3706 select.expressions = new_expressions;
3707 } else {
3708 select.expressions = new_expressions;
3709 }
3710
3711 if let Some(ref mut from) = select.from {
3714 expand_posexplode_in_from_duckdb(from)?;
3715 }
3716
3717 Ok(Expression::Select(select))
3718 }
3719 other => Ok(other),
3720 }
3721}
3722
3723fn expand_posexplode_in_from_duckdb(from: &mut From) -> Result<()> {
3725 use crate::expressions::{Alias, Function};
3726
3727 let mut new_expressions = Vec::new();
3728 let mut _changed = false;
3729
3730 for table_expr in from.expressions.drain(..) {
3731 if let Expression::Alias(ref alias_box) = table_expr {
3733 if let Expression::Function(ref func) = alias_box.this {
3734 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3735 let arg = func.args[0].clone();
3736 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
3737 (
3738 alias_box.column_aliases[0].name.clone(),
3739 alias_box.column_aliases[1].name.clone(),
3740 )
3741 } else {
3742 ("pos".to_string(), "col".to_string())
3743 };
3744
3745 let gen_subscripts = Expression::Function(Box::new(Function::new(
3747 "GENERATE_SUBSCRIPTS".to_string(),
3748 vec![
3749 arg.clone(),
3750 Expression::Literal(Literal::Number("1".to_string())),
3751 ],
3752 )));
3753 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3754 gen_subscripts,
3755 Expression::Literal(Literal::Number("1".to_string())),
3756 )));
3757 let pos_alias = Expression::Alias(Box::new(Alias {
3758 this: sub_one,
3759 alias: Identifier::new(&pos_name),
3760 column_aliases: Vec::new(),
3761 pre_alias_comments: Vec::new(),
3762 trailing_comments: Vec::new(),
3763 inferred_type: None,
3764 }));
3765 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3766 this: arg,
3767 expressions: Vec::new(),
3768 with_ordinality: false,
3769 alias: None,
3770 offset_alias: None,
3771 }));
3772 let col_alias = Expression::Alias(Box::new(Alias {
3773 this: unnest,
3774 alias: Identifier::new(&col_name),
3775 column_aliases: Vec::new(),
3776 pre_alias_comments: Vec::new(),
3777 trailing_comments: Vec::new(),
3778 inferred_type: None,
3779 }));
3780
3781 let mut inner_select = Select::new();
3782 inner_select.expressions = vec![pos_alias, col_alias];
3783
3784 let subquery = Expression::Subquery(Box::new(Subquery {
3785 this: Expression::Select(Box::new(inner_select)),
3786 alias: None,
3787 column_aliases: Vec::new(),
3788 order_by: None,
3789 limit: None,
3790 offset: None,
3791 distribute_by: None,
3792 sort_by: None,
3793 cluster_by: None,
3794 lateral: false,
3795 modifiers_inside: false,
3796 trailing_comments: Vec::new(),
3797 inferred_type: None,
3798 }));
3799 new_expressions.push(subquery);
3800 _changed = true;
3801 continue;
3802 }
3803 }
3804 }
3805
3806 if let Expression::Function(ref func) = table_expr {
3808 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3809 let arg = func.args[0].clone();
3810
3811 let gen_subscripts = Expression::Function(Box::new(Function::new(
3813 "GENERATE_SUBSCRIPTS".to_string(),
3814 vec![
3815 arg.clone(),
3816 Expression::Literal(Literal::Number("1".to_string())),
3817 ],
3818 )));
3819 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3820 gen_subscripts,
3821 Expression::Literal(Literal::Number("1".to_string())),
3822 )));
3823 let pos_alias = Expression::Alias(Box::new(Alias {
3824 this: sub_one,
3825 alias: Identifier::new("pos"),
3826 column_aliases: Vec::new(),
3827 pre_alias_comments: Vec::new(),
3828 trailing_comments: Vec::new(),
3829 inferred_type: None,
3830 }));
3831 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3832 this: arg,
3833 expressions: Vec::new(),
3834 with_ordinality: false,
3835 alias: None,
3836 offset_alias: None,
3837 }));
3838 let col_alias = Expression::Alias(Box::new(Alias {
3839 this: unnest,
3840 alias: Identifier::new("col"),
3841 column_aliases: Vec::new(),
3842 pre_alias_comments: Vec::new(),
3843 trailing_comments: Vec::new(),
3844 inferred_type: None,
3845 }));
3846
3847 let mut inner_select = Select::new();
3848 inner_select.expressions = vec![pos_alias, col_alias];
3849
3850 let subquery = Expression::Subquery(Box::new(Subquery {
3851 this: Expression::Select(Box::new(inner_select)),
3852 alias: None,
3853 column_aliases: Vec::new(),
3854 order_by: None,
3855 limit: None,
3856 offset: None,
3857 distribute_by: None,
3858 sort_by: None,
3859 cluster_by: None,
3860 lateral: false,
3861 modifiers_inside: false,
3862 trailing_comments: Vec::new(),
3863 inferred_type: None,
3864 }));
3865 new_expressions.push(subquery);
3866 _changed = true;
3867 continue;
3868 }
3869 }
3870
3871 new_expressions.push(table_expr);
3872 }
3873
3874 from.expressions = new_expressions;
3875 Ok(())
3876}
3877
3878pub fn explode_projection_to_unnest(expr: Expression, target: DialectType) -> Result<Expression> {
3893 match expr {
3894 Expression::Select(select) => explode_projection_to_unnest_impl(*select, target),
3895 other => Ok(other),
3896 }
3897}
3898
3899pub fn snowflake_flatten_projection_to_unnest(expr: Expression) -> Result<Expression> {
3909 match expr {
3910 Expression::Select(select) => snowflake_flatten_projection_to_unnest_impl(*select),
3911 other => Ok(other),
3912 }
3913}
3914
3915fn snowflake_flatten_projection_to_unnest_impl(mut select: Select) -> Result<Expression> {
3916 let mut flattened_inputs: Vec<Expression> = Vec::new();
3917 let mut new_selects: Vec<Expression> = Vec::with_capacity(select.expressions.len());
3918
3919 for sel_expr in select.expressions.into_iter() {
3920 let found_input: RefCell<Option<Expression>> = RefCell::new(None);
3921
3922 let rewritten = transform_recursive(sel_expr, &|e| {
3923 if let Expression::Lateral(lat) = e {
3924 if let Some(input_expr) = extract_flatten_input(&lat) {
3925 if found_input.borrow().is_none() {
3926 *found_input.borrow_mut() = Some(input_expr);
3927 }
3928 return Ok(Expression::Lateral(Box::new(rewrite_flatten_lateral(*lat))));
3929 }
3930 return Ok(Expression::Lateral(lat));
3931 }
3932 Ok(e)
3933 })?;
3934
3935 if let Some(input) = found_input.into_inner() {
3936 flattened_inputs.push(input);
3937 }
3938 new_selects.push(rewritten);
3939 }
3940
3941 if flattened_inputs.is_empty() {
3942 select.expressions = new_selects;
3943 return Ok(Expression::Select(Box::new(select)));
3944 }
3945
3946 select.expressions = new_selects;
3947
3948 for (idx, input_expr) in flattened_inputs.into_iter().enumerate() {
3949 let is_first = idx == 0;
3951 let series_alias = if is_first {
3952 "pos".to_string()
3953 } else {
3954 format!("pos_{}", idx + 1)
3955 };
3956 let series_source_alias = if is_first {
3957 "_u".to_string()
3958 } else {
3959 format!("_u_{}", idx * 2 + 1)
3960 };
3961 let unnest_source_alias = if is_first {
3962 "_u_2".to_string()
3963 } else {
3964 format!("_u_{}", idx * 2 + 2)
3965 };
3966 let pos2_alias = if is_first {
3967 "pos_2".to_string()
3968 } else {
3969 format!("{}_2", series_alias)
3970 };
3971 let entity_alias = if is_first {
3972 "entity".to_string()
3973 } else {
3974 format!("entity_{}", idx + 1)
3975 };
3976
3977 let array_size_call = Expression::Function(Box::new(Function::new(
3978 "ARRAY_SIZE".to_string(),
3979 vec![Expression::NamedArgument(Box::new(NamedArgument {
3980 name: Identifier::new("INPUT"),
3981 value: input_expr.clone(),
3982 separator: NamedArgSeparator::DArrow,
3983 }))],
3984 )));
3985
3986 let greatest = Expression::Function(Box::new(Function::new(
3987 "GREATEST".to_string(),
3988 vec![array_size_call.clone()],
3989 )));
3990
3991 let series_end = Expression::Add(Box::new(BinaryOp::new(
3992 Expression::Paren(Box::new(crate::expressions::Paren {
3993 this: Expression::Sub(Box::new(BinaryOp::new(
3994 greatest,
3995 Expression::Literal(Literal::Number("1".to_string())),
3996 ))),
3997 trailing_comments: Vec::new(),
3998 })),
3999 Expression::Literal(Literal::Number("1".to_string())),
4000 )));
4001
4002 let series_range = Expression::Function(Box::new(Function::new(
4003 "ARRAY_GENERATE_RANGE".to_string(),
4004 vec![
4005 Expression::Literal(Literal::Number("0".to_string())),
4006 series_end,
4007 ],
4008 )));
4009
4010 let series_flatten = Expression::Function(Box::new(Function::new(
4011 "FLATTEN".to_string(),
4012 vec![Expression::NamedArgument(Box::new(NamedArgument {
4013 name: Identifier::new("INPUT"),
4014 value: series_range,
4015 separator: NamedArgSeparator::DArrow,
4016 }))],
4017 )));
4018
4019 let series_table = Expression::Function(Box::new(Function::new(
4020 "TABLE".to_string(),
4021 vec![series_flatten],
4022 )));
4023
4024 let series_alias_expr = Expression::Alias(Box::new(Alias {
4025 this: series_table,
4026 alias: Identifier::new(series_source_alias.clone()),
4027 column_aliases: vec![
4028 Identifier::new("seq"),
4029 Identifier::new("key"),
4030 Identifier::new("path"),
4031 Identifier::new("index"),
4032 Identifier::new(series_alias.clone()),
4033 Identifier::new("this"),
4034 ],
4035 pre_alias_comments: Vec::new(),
4036 trailing_comments: Vec::new(),
4037 inferred_type: None,
4038 }));
4039
4040 select.joins.push(Join {
4041 this: series_alias_expr,
4042 on: None,
4043 using: Vec::new(),
4044 kind: JoinKind::Cross,
4045 use_inner_keyword: false,
4046 use_outer_keyword: false,
4047 deferred_condition: false,
4048 join_hint: None,
4049 match_condition: None,
4050 pivots: Vec::new(),
4051 comments: Vec::new(),
4052 nesting_group: 0,
4053 directed: false,
4054 });
4055
4056 let entity_flatten = Expression::Function(Box::new(Function::new(
4057 "FLATTEN".to_string(),
4058 vec![Expression::NamedArgument(Box::new(NamedArgument {
4059 name: Identifier::new("INPUT"),
4060 value: input_expr.clone(),
4061 separator: NamedArgSeparator::DArrow,
4062 }))],
4063 )));
4064
4065 let entity_table = Expression::Function(Box::new(Function::new(
4066 "TABLE".to_string(),
4067 vec![entity_flatten],
4068 )));
4069
4070 let entity_alias_expr = Expression::Alias(Box::new(Alias {
4071 this: entity_table,
4072 alias: Identifier::new(unnest_source_alias.clone()),
4073 column_aliases: vec![
4074 Identifier::new("seq"),
4075 Identifier::new("key"),
4076 Identifier::new("path"),
4077 Identifier::new(pos2_alias.clone()),
4078 Identifier::new(entity_alias.clone()),
4079 Identifier::new("this"),
4080 ],
4081 pre_alias_comments: Vec::new(),
4082 trailing_comments: Vec::new(),
4083 inferred_type: None,
4084 }));
4085
4086 select.joins.push(Join {
4087 this: entity_alias_expr,
4088 on: None,
4089 using: Vec::new(),
4090 kind: JoinKind::Cross,
4091 use_inner_keyword: false,
4092 use_outer_keyword: false,
4093 deferred_condition: false,
4094 join_hint: None,
4095 match_condition: None,
4096 pivots: Vec::new(),
4097 comments: Vec::new(),
4098 nesting_group: 0,
4099 directed: false,
4100 });
4101
4102 let pos_col =
4103 Expression::qualified_column(series_source_alias.clone(), series_alias.clone());
4104 let pos2_col =
4105 Expression::qualified_column(unnest_source_alias.clone(), pos2_alias.clone());
4106
4107 let eq = Expression::Eq(Box::new(BinaryOp::new(pos_col.clone(), pos2_col.clone())));
4108 let size_minus_1 = Expression::Paren(Box::new(crate::expressions::Paren {
4109 this: Expression::Sub(Box::new(BinaryOp::new(
4110 array_size_call,
4111 Expression::Literal(Literal::Number("1".to_string())),
4112 ))),
4113 trailing_comments: Vec::new(),
4114 }));
4115 let gt = Expression::Gt(Box::new(BinaryOp::new(pos_col, size_minus_1.clone())));
4116 let pos2_eq_size = Expression::Eq(Box::new(BinaryOp::new(pos2_col, size_minus_1)));
4117 let and_cond = Expression::And(Box::new(BinaryOp::new(gt, pos2_eq_size)));
4118 let or_cond = Expression::Or(Box::new(BinaryOp::new(
4119 eq,
4120 Expression::Paren(Box::new(crate::expressions::Paren {
4121 this: and_cond,
4122 trailing_comments: Vec::new(),
4123 })),
4124 )));
4125
4126 select.where_clause = Some(match select.where_clause.take() {
4127 Some(existing) => Where {
4128 this: Expression::And(Box::new(BinaryOp::new(existing.this, or_cond))),
4129 },
4130 None => Where { this: or_cond },
4131 });
4132 }
4133
4134 Ok(Expression::Select(Box::new(select)))
4135}
4136
4137fn extract_flatten_input(lat: &Lateral) -> Option<Expression> {
4138 let Expression::Function(f) = lat.this.as_ref() else {
4139 return None;
4140 };
4141 if !f.name.eq_ignore_ascii_case("FLATTEN") {
4142 return None;
4143 }
4144
4145 for arg in &f.args {
4146 if let Expression::NamedArgument(na) = arg {
4147 if na.name.name.eq_ignore_ascii_case("INPUT") {
4148 return Some(na.value.clone());
4149 }
4150 }
4151 }
4152 f.args.first().cloned()
4153}
4154
4155fn rewrite_flatten_lateral(mut lat: Lateral) -> Lateral {
4156 let cond = Expression::Eq(Box::new(BinaryOp::new(
4157 Expression::qualified_column("_u", "pos"),
4158 Expression::qualified_column("_u_2", "pos_2"),
4159 )));
4160 let true_expr = Expression::qualified_column("_u_2", "entity");
4161 let iff_expr = Expression::Function(Box::new(Function::new(
4162 "IFF".to_string(),
4163 vec![cond, true_expr, Expression::Null(crate::expressions::Null)],
4164 )));
4165
4166 lat.this = Box::new(iff_expr);
4167 if lat.column_aliases.is_empty() {
4168 lat.column_aliases = vec![
4169 "SEQ".to_string(),
4170 "KEY".to_string(),
4171 "PATH".to_string(),
4172 "INDEX".to_string(),
4173 "VALUE".to_string(),
4174 "THIS".to_string(),
4175 ];
4176 }
4177 lat
4178}
4179
4180struct ExplodeInfo {
4182 arg_sql: String,
4184 explode_alias: String,
4186 pos_alias: String,
4188 unnest_source_alias: String,
4190}
4191
4192fn explode_projection_to_unnest_impl(select: Select, target: DialectType) -> Result<Expression> {
4193 let is_presto = matches!(
4194 target,
4195 DialectType::Presto | DialectType::Trino | DialectType::Athena
4196 );
4197 let is_bigquery = matches!(target, DialectType::BigQuery);
4198
4199 if !is_presto && !is_bigquery {
4200 return Ok(Expression::Select(Box::new(select)));
4201 }
4202
4203 let has_explode = select.expressions.iter().any(|e| expr_contains_explode(e));
4205 if !has_explode {
4206 return Ok(Expression::Select(Box::new(select)));
4207 }
4208
4209 let mut taken_select_names = std::collections::HashSet::new();
4211 let mut taken_source_names = std::collections::HashSet::new();
4212
4213 for sel in &select.expressions {
4215 if let Some(name) = get_output_name(sel) {
4216 taken_select_names.insert(name);
4217 }
4218 }
4219
4220 for sel in &select.expressions {
4222 let explode_expr = find_explode_in_expr(sel);
4223 if let Some(arg) = explode_expr {
4224 if let Some(name) = get_output_name(&arg) {
4225 taken_select_names.insert(name);
4226 }
4227 }
4228 }
4229
4230 if let Some(ref from) = select.from {
4232 for from_expr in &from.expressions {
4233 collect_source_names(from_expr, &mut taken_source_names);
4234 }
4235 }
4236 for join in &select.joins {
4238 collect_source_names(&join.this, &mut taken_source_names);
4239 }
4240
4241 let series_alias = new_name(&mut taken_select_names, "pos");
4243
4244 let series_source_alias = new_name(&mut taken_source_names, "_u");
4246
4247 let target_dialect = Dialect::get(target);
4249
4250 let mut explode_infos: Vec<ExplodeInfo> = Vec::new();
4252 let mut new_projections: Vec<String> = Vec::new();
4253
4254 for (_idx, sel_expr) in select.expressions.iter().enumerate() {
4255 let explode_data = extract_explode_data(sel_expr);
4256
4257 if let Some((is_posexplode, arg_expr, explicit_alias, explicit_pos_alias)) = explode_data {
4258 let arg_sql = target_dialect
4260 .generate(&arg_expr)
4261 .unwrap_or_else(|_| "NULL".to_string());
4262
4263 let unnest_source_alias = new_name(&mut taken_source_names, "_u");
4264
4265 let explode_alias = if let Some(ref ea) = explicit_alias {
4266 taken_select_names.remove(ea.as_str());
4269 let name = new_name(&mut taken_select_names, ea);
4271 name
4272 } else {
4273 new_name(&mut taken_select_names, "col")
4274 };
4275
4276 let pos_alias = if let Some(ref pa) = explicit_pos_alias {
4277 taken_select_names.remove(pa.as_str());
4279 let name = new_name(&mut taken_select_names, pa);
4280 name
4281 } else {
4282 new_name(&mut taken_select_names, "pos")
4283 };
4284
4285 if is_presto {
4287 let if_col = format!(
4289 "IF({}.{} = {}.{}, {}.{}) AS {}",
4290 series_source_alias,
4291 series_alias,
4292 unnest_source_alias,
4293 pos_alias,
4294 unnest_source_alias,
4295 explode_alias,
4296 explode_alias
4297 );
4298 new_projections.push(if_col);
4299
4300 if is_posexplode {
4302 let if_pos = format!(
4303 "IF({}.{} = {}.{}, {}.{}) AS {}",
4304 series_source_alias,
4305 series_alias,
4306 unnest_source_alias,
4307 pos_alias,
4308 unnest_source_alias,
4309 pos_alias,
4310 pos_alias
4311 );
4312 new_projections.push(if_pos);
4313 }
4314 } else {
4315 let if_col = format!(
4317 "IF({} = {}, {}, NULL) AS {}",
4318 series_alias, pos_alias, explode_alias, explode_alias
4319 );
4320 new_projections.push(if_col);
4321
4322 if is_posexplode {
4324 let if_pos = format!(
4325 "IF({} = {}, {}, NULL) AS {}",
4326 series_alias, pos_alias, pos_alias, pos_alias
4327 );
4328 new_projections.push(if_pos);
4329 }
4330 }
4331
4332 explode_infos.push(ExplodeInfo {
4333 arg_sql,
4334 explode_alias,
4335 pos_alias,
4336 unnest_source_alias,
4337 });
4338 } else {
4339 let sel_sql = target_dialect
4341 .generate(sel_expr)
4342 .unwrap_or_else(|_| "*".to_string());
4343 new_projections.push(sel_sql);
4344 }
4345 }
4346
4347 if explode_infos.is_empty() {
4348 return Ok(Expression::Select(Box::new(select)));
4349 }
4350
4351 let mut from_parts: Vec<String> = Vec::new();
4353
4354 if let Some(ref from) = select.from {
4356 for from_expr in &from.expressions {
4357 let from_sql = target_dialect.generate(from_expr).unwrap_or_default();
4358 from_parts.push(from_sql);
4359 }
4360 }
4361
4362 let size_exprs: Vec<String> = explode_infos
4364 .iter()
4365 .map(|info| {
4366 if is_presto {
4367 format!("CARDINALITY({})", info.arg_sql)
4368 } else {
4369 format!("ARRAY_LENGTH({})", info.arg_sql)
4370 }
4371 })
4372 .collect();
4373
4374 let greatest_arg = if size_exprs.len() == 1 {
4375 size_exprs[0].clone()
4376 } else {
4377 format!("GREATEST({})", size_exprs.join(", "))
4378 };
4379
4380 let series_sql = if is_presto {
4383 if size_exprs.len() == 1 {
4385 format!(
4386 "UNNEST(SEQUENCE(1, GREATEST({}))) AS {}({})",
4387 greatest_arg, series_source_alias, series_alias
4388 )
4389 } else {
4390 format!(
4392 "UNNEST(SEQUENCE(1, {})) AS {}({})",
4393 greatest_arg, series_source_alias, series_alias
4394 )
4395 }
4396 } else {
4397 if size_exprs.len() == 1 {
4399 format!(
4400 "UNNEST(GENERATE_ARRAY(0, GREATEST({}) - 1)) AS {}",
4401 greatest_arg, series_alias
4402 )
4403 } else {
4404 format!(
4406 "UNNEST(GENERATE_ARRAY(0, {} - 1)) AS {}",
4407 greatest_arg, series_alias
4408 )
4409 }
4410 };
4411
4412 let mut cross_joins: Vec<String> = Vec::new();
4416
4417 for info in &explode_infos {
4418 cross_joins.push(format!(
4420 "CROSS JOIN UNNEST({}) WITH ORDINALITY AS {}({}, {})",
4421 info.arg_sql, info.unnest_source_alias, info.explode_alias, info.pos_alias
4422 ));
4423 }
4424
4425 let mut where_conditions: Vec<String> = Vec::new();
4427
4428 for info in &explode_infos {
4429 let size_expr = if is_presto {
4430 format!("CARDINALITY({})", info.arg_sql)
4431 } else {
4432 format!("ARRAY_LENGTH({})", info.arg_sql)
4433 };
4434
4435 let cond = if is_presto {
4436 format!(
4437 "{series_src}.{series_al} = {unnest_src}.{pos_al} OR ({series_src}.{series_al} > {size} AND {unnest_src}.{pos_al} = {size})",
4438 series_src = series_source_alias,
4439 series_al = series_alias,
4440 unnest_src = info.unnest_source_alias,
4441 pos_al = info.pos_alias,
4442 size = size_expr
4443 )
4444 } else {
4445 format!(
4446 "{series_al} = {pos_al} OR ({series_al} > ({size} - 1) AND {pos_al} = ({size} - 1))",
4447 series_al = series_alias,
4448 pos_al = info.pos_alias,
4449 size = size_expr
4450 )
4451 };
4452
4453 where_conditions.push(cond);
4454 }
4455
4456 let where_sql = if where_conditions.len() == 1 {
4458 where_conditions[0].clone()
4459 } else {
4460 where_conditions
4461 .iter()
4462 .map(|c| format!("({})", c))
4463 .collect::<Vec<_>>()
4464 .join(" AND ")
4465 };
4466
4467 let select_part = new_projections.join(", ");
4469
4470 let from_and_joins = if from_parts.is_empty() {
4472 format!("FROM {} {}", series_sql, cross_joins.join(" "))
4474 } else {
4475 format!(
4476 "FROM {} {} {}",
4477 from_parts.join(", "),
4478 format!("CROSS JOIN {}", series_sql),
4479 cross_joins.join(" ")
4480 )
4481 };
4482
4483 let full_sql = format!(
4484 "SELECT {} {} WHERE {}",
4485 select_part, from_and_joins, where_sql
4486 );
4487
4488 let generic_dialect = Dialect::get(DialectType::Generic);
4491 let parsed = generic_dialect.parse(&full_sql);
4492 match parsed {
4493 Ok(mut stmts) if !stmts.is_empty() => {
4494 let mut result = stmts.remove(0);
4495
4496 if is_bigquery {
4500 convert_unnest_presto_to_bigquery(&mut result);
4501 }
4502
4503 Ok(result)
4504 }
4505 _ => {
4506 Ok(Expression::Select(Box::new(select)))
4508 }
4509 }
4510}
4511
4512fn convert_unnest_presto_to_bigquery(expr: &mut Expression) {
4516 match expr {
4517 Expression::Select(ref mut select) => {
4518 if let Some(ref mut from) = select.from {
4520 for from_item in from.expressions.iter_mut() {
4521 convert_unnest_presto_to_bigquery(from_item);
4522 }
4523 }
4524 for join in select.joins.iter_mut() {
4526 convert_unnest_presto_to_bigquery(&mut join.this);
4527 }
4528 }
4529 Expression::Alias(ref alias) => {
4530 if let Expression::Unnest(ref unnest) = alias.this {
4532 if unnest.with_ordinality && alias.column_aliases.len() >= 2 {
4533 let col_alias = alias.column_aliases[0].clone();
4534 let pos_alias = alias.column_aliases[1].clone();
4535 let mut new_unnest = unnest.as_ref().clone();
4536 new_unnest.alias = Some(col_alias);
4537 new_unnest.offset_alias = Some(pos_alias);
4538 *expr = Expression::Unnest(Box::new(new_unnest));
4540 }
4541 }
4542 }
4543 _ => {}
4544 }
4545}
4546
4547fn new_name(names: &mut std::collections::HashSet<String>, base: &str) -> String {
4550 if !names.contains(base) {
4551 names.insert(base.to_string());
4552 return base.to_string();
4553 }
4554 let mut i = 2;
4555 loop {
4556 let candidate = format!("{}_{}", base, i);
4557 if !names.contains(&candidate) {
4558 names.insert(candidate.clone());
4559 return candidate;
4560 }
4561 i += 1;
4562 }
4563}
4564
4565fn expr_contains_explode(expr: &Expression) -> bool {
4567 match expr {
4568 Expression::Explode(_) => true,
4569 Expression::ExplodeOuter(_) => true,
4570 Expression::Function(f) => {
4571 let name = f.name.to_uppercase();
4572 name == "POSEXPLODE" || name == "POSEXPLODE_OUTER"
4573 }
4574 Expression::Alias(a) => expr_contains_explode(&a.this),
4575 _ => false,
4576 }
4577}
4578
4579fn find_explode_in_expr(expr: &Expression) -> Option<Expression> {
4581 match expr {
4582 Expression::Explode(uf) => Some(uf.this.clone()),
4583 Expression::ExplodeOuter(uf) => Some(uf.this.clone()),
4584 Expression::Function(f) => {
4585 let name = f.name.to_uppercase();
4586 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
4587 Some(f.args[0].clone())
4588 } else {
4589 None
4590 }
4591 }
4592 Expression::Alias(a) => find_explode_in_expr(&a.this),
4593 _ => None,
4594 }
4595}
4596
4597fn extract_explode_data(
4600 expr: &Expression,
4601) -> Option<(bool, Expression, Option<String>, Option<String>)> {
4602 match expr {
4603 Expression::Explode(uf) => Some((false, uf.this.clone(), None, None)),
4605 Expression::ExplodeOuter(uf) => Some((false, uf.this.clone(), None, None)),
4606 Expression::Function(f) => {
4608 let name = f.name.to_uppercase();
4609 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
4610 Some((true, f.args[0].clone(), None, None))
4611 } else {
4612 None
4613 }
4614 }
4615 Expression::Alias(a) => {
4617 match &a.this {
4618 Expression::Explode(uf) => {
4619 let alias = if !a.alias.is_empty() {
4620 Some(a.alias.name.clone())
4621 } else {
4622 None
4623 };
4624 Some((false, uf.this.clone(), alias, None))
4625 }
4626 Expression::ExplodeOuter(uf) => {
4627 let alias = if !a.alias.is_empty() {
4628 Some(a.alias.name.clone())
4629 } else {
4630 None
4631 };
4632 Some((false, uf.this.clone(), alias, None))
4633 }
4634 Expression::Function(f) => {
4635 let name = f.name.to_uppercase();
4636 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
4637 if a.column_aliases.len() == 2 {
4639 let pos_alias = a.column_aliases[0].name.clone();
4640 let col_alias = a.column_aliases[1].name.clone();
4641 Some((true, f.args[0].clone(), Some(col_alias), Some(pos_alias)))
4642 } else if !a.alias.is_empty() {
4643 Some((true, f.args[0].clone(), Some(a.alias.name.clone()), None))
4645 } else {
4646 Some((true, f.args[0].clone(), None, None))
4647 }
4648 } else {
4649 None
4650 }
4651 }
4652 _ => None,
4653 }
4654 }
4655 _ => None,
4656 }
4657}
4658
4659fn get_output_name(expr: &Expression) -> Option<String> {
4661 match expr {
4662 Expression::Alias(a) => {
4663 if !a.alias.is_empty() {
4664 Some(a.alias.name.clone())
4665 } else {
4666 None
4667 }
4668 }
4669 Expression::Column(c) => Some(c.name.name.clone()),
4670 Expression::Identifier(id) => Some(id.name.clone()),
4671 _ => None,
4672 }
4673}
4674
4675fn collect_source_names(expr: &Expression, names: &mut std::collections::HashSet<String>) {
4677 match expr {
4678 Expression::Alias(a) => {
4679 if !a.alias.is_empty() {
4680 names.insert(a.alias.name.clone());
4681 }
4682 }
4683 Expression::Subquery(s) => {
4684 if let Some(ref alias) = s.alias {
4685 names.insert(alias.name.clone());
4686 }
4687 }
4688 Expression::Table(t) => {
4689 if let Some(ref alias) = t.alias {
4690 names.insert(alias.name.clone());
4691 } else {
4692 names.insert(t.name.name.clone());
4693 }
4694 }
4695 Expression::Column(c) => {
4696 names.insert(c.name.name.clone());
4697 }
4698 Expression::Identifier(id) => {
4699 names.insert(id.name.clone());
4700 }
4701 _ => {}
4702 }
4703}
4704
4705pub fn strip_unnest_column_refs(expr: Expression) -> Result<Expression> {
4708 use crate::dialects::transform_recursive;
4709 transform_recursive(expr, &strip_unnest_column_refs_single)
4710}
4711
4712fn strip_unnest_column_refs_single(expr: Expression) -> Result<Expression> {
4713 if let Expression::Select(mut select) = expr {
4714 for join in select.joins.iter_mut() {
4716 strip_unnest_from_expr(&mut join.this);
4717 }
4718 if let Some(ref mut from) = select.from {
4720 for from_item in from.expressions.iter_mut() {
4721 strip_unnest_from_expr(from_item);
4722 }
4723 }
4724 Ok(Expression::Select(select))
4725 } else {
4726 Ok(expr)
4727 }
4728}
4729
4730fn strip_unnest_from_expr(expr: &mut Expression) {
4733 if let Expression::Alias(ref mut alias) = expr {
4734 if let Expression::Unnest(ref unnest) = alias.this {
4735 let is_column_ref = matches!(&unnest.this, Expression::Column(_) | Expression::Dot(_));
4736 if is_column_ref {
4737 let inner = unnest.this.clone();
4739 alias.this = inner;
4740 }
4741 }
4742 }
4743}
4744
4745pub fn wrap_duckdb_unnest_struct(expr: Expression) -> Result<Expression> {
4748 use crate::dialects::transform_recursive;
4749 transform_recursive(expr, &wrap_duckdb_unnest_struct_single)
4750}
4751
4752fn wrap_duckdb_unnest_struct_single(expr: Expression) -> Result<Expression> {
4753 if let Expression::Select(mut select) = expr {
4754 if let Some(ref mut from) = select.from {
4756 for from_item in from.expressions.iter_mut() {
4757 try_wrap_unnest_in_subquery(from_item);
4758 }
4759 }
4760
4761 for join in select.joins.iter_mut() {
4763 try_wrap_unnest_in_subquery(&mut join.this);
4764 }
4765
4766 Ok(Expression::Select(select))
4767 } else {
4768 Ok(expr)
4769 }
4770}
4771
4772fn is_struct_array_unnest_arg(expr: &Expression) -> bool {
4774 match expr {
4775 Expression::Array(arr) => arr
4777 .expressions
4778 .iter()
4779 .any(|e| matches!(e, Expression::Struct(_))),
4780 Expression::ArrayFunc(arr) => arr
4781 .expressions
4782 .iter()
4783 .any(|e| matches!(e, Expression::Struct(_))),
4784 Expression::Cast(c) => {
4786 matches!(&c.to, DataType::Array { element_type, .. } if matches!(**element_type, DataType::Struct { .. }))
4787 }
4788 _ => false,
4789 }
4790}
4791
4792fn try_wrap_unnest_in_subquery(expr: &mut Expression) {
4795 if let Expression::Alias(ref alias) = expr {
4797 if let Expression::Unnest(ref unnest) = alias.this {
4798 if is_struct_array_unnest_arg(&unnest.this) {
4799 let unnest_clone = (**unnest).clone();
4800 let alias_name = alias.alias.clone();
4801 let new_expr = make_unnest_subquery(unnest_clone, Some(alias_name));
4802 *expr = new_expr;
4803 return;
4804 }
4805 }
4806 }
4807
4808 if let Expression::Unnest(ref unnest) = expr {
4810 if is_struct_array_unnest_arg(&unnest.this) {
4811 let unnest_clone = (**unnest).clone();
4812 let new_expr = make_unnest_subquery(unnest_clone, None);
4813 *expr = new_expr;
4814 }
4815 }
4816}
4817
4818fn make_unnest_subquery(unnest: UnnestFunc, alias: Option<Identifier>) -> Expression {
4820 let max_depth_arg = Expression::NamedArgument(Box::new(NamedArgument {
4822 name: Identifier::new("max_depth".to_string()),
4823 value: Expression::Literal(Literal::Number("2".to_string())),
4824 separator: NamedArgSeparator::DArrow,
4825 }));
4826
4827 let mut unnest_args = vec![unnest.this];
4828 unnest_args.extend(unnest.expressions);
4829 unnest_args.push(max_depth_arg);
4830
4831 let unnest_func =
4832 Expression::Function(Box::new(Function::new("UNNEST".to_string(), unnest_args)));
4833
4834 let mut inner_select = Select::new();
4836 inner_select.expressions = vec![unnest_func];
4837 let inner_select = Expression::Select(Box::new(inner_select));
4838
4839 let subquery = Subquery {
4841 this: inner_select,
4842 alias,
4843 column_aliases: Vec::new(),
4844 order_by: None,
4845 limit: None,
4846 offset: None,
4847 distribute_by: None,
4848 sort_by: None,
4849 cluster_by: None,
4850 lateral: false,
4851 modifiers_inside: false,
4852 trailing_comments: Vec::new(),
4853 inferred_type: None,
4854 };
4855
4856 Expression::Subquery(Box::new(subquery))
4857}
4858
4859pub fn no_limit_order_by_union(expr: Expression) -> Result<Expression> {
4871 use crate::expressions::{Limit as LimitClause, Offset as OffsetClause, OrderBy, Star};
4872
4873 match expr {
4874 Expression::Union(mut u) => {
4875 if u.order_by.is_none() && u.limit.is_none() && u.offset.is_none() {
4878 if let Expression::Select(ref mut right_select) = u.right {
4880 if right_select.order_by.is_some()
4881 || right_select.limit.is_some()
4882 || right_select.offset.is_some()
4883 {
4884 u.order_by = right_select.order_by.take();
4886 u.limit = right_select.limit.take().map(|l| Box::new(l.this));
4887 u.offset = right_select.offset.take().map(|o| Box::new(o.this));
4888 }
4889 }
4890 }
4891
4892 let has_order_or_limit =
4893 u.order_by.is_some() || u.limit.is_some() || u.offset.is_some();
4894 if has_order_or_limit {
4895 let order_by: Option<OrderBy> = u.order_by.take();
4897 let union_limit: Option<Box<Expression>> = u.limit.take();
4898 let union_offset: Option<Box<Expression>> = u.offset.take();
4899
4900 let select_limit: Option<LimitClause> = union_limit.map(|l| LimitClause {
4902 this: *l,
4903 percent: false,
4904 comments: Vec::new(),
4905 });
4906
4907 let select_offset: Option<OffsetClause> = union_offset.map(|o| OffsetClause {
4909 this: *o,
4910 rows: None,
4911 });
4912
4913 let subquery = Subquery {
4915 this: Expression::Union(u),
4916 alias: Some(Identifier::new("_l_0")),
4917 column_aliases: Vec::new(),
4918 lateral: false,
4919 modifiers_inside: false,
4920 order_by: None,
4921 limit: None,
4922 offset: None,
4923 distribute_by: None,
4924 sort_by: None,
4925 cluster_by: None,
4926 trailing_comments: Vec::new(),
4927 inferred_type: None,
4928 };
4929
4930 let mut select = Select::default();
4932 select.expressions = vec![Expression::Star(Star {
4933 table: None,
4934 except: None,
4935 replace: None,
4936 rename: None,
4937 trailing_comments: Vec::new(),
4938 span: None,
4939 })];
4940 select.from = Some(From {
4941 expressions: vec![Expression::Subquery(Box::new(subquery))],
4942 });
4943 select.order_by = order_by;
4944 select.limit = select_limit;
4945 select.offset = select_offset;
4946
4947 Ok(Expression::Select(Box::new(select)))
4948 } else {
4949 Ok(Expression::Union(u))
4950 }
4951 }
4952 _ => Ok(expr),
4953 }
4954}
4955
4956pub fn expand_like_any(expr: Expression) -> Result<Expression> {
4961 use crate::expressions::{BinaryOp, LikeOp};
4962
4963 fn unwrap_parens(e: &Expression) -> &Expression {
4964 match e {
4965 Expression::Paren(p) => unwrap_parens(&p.this),
4966 _ => e,
4967 }
4968 }
4969
4970 fn extract_tuple_values(e: &Expression) -> Option<Vec<Expression>> {
4971 let inner = unwrap_parens(e);
4972 match inner {
4973 Expression::Tuple(t) => Some(t.expressions.clone()),
4974 _ => None,
4975 }
4976 }
4977
4978 transform_recursive(expr, &|e| {
4979 match e {
4980 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ANY") => {
4981 if let Some(values) = extract_tuple_values(&op.right) {
4982 if values.is_empty() {
4983 return Ok(e);
4984 }
4985 let mut result: Option<Expression> = None;
4987 for val in values {
4988 let like = Expression::Like(Box::new(LikeOp {
4989 left: op.left.clone(),
4990 right: val,
4991 escape: op.escape.clone(),
4992 quantifier: None,
4993 inferred_type: None,
4994 }));
4995 result = Some(match result {
4996 None => like,
4997 Some(prev) => Expression::Or(Box::new(BinaryOp::new(prev, like))),
4998 });
4999 }
5000 Ok(result.unwrap_or(e))
5001 } else {
5002 Ok(e)
5003 }
5004 }
5005 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ANY") => {
5006 if let Some(values) = extract_tuple_values(&op.right) {
5007 if values.is_empty() {
5008 return Ok(e);
5009 }
5010 let mut result: Option<Expression> = None;
5011 for val in values {
5012 let ilike = Expression::ILike(Box::new(LikeOp {
5013 left: op.left.clone(),
5014 right: val,
5015 escape: op.escape.clone(),
5016 quantifier: None,
5017 inferred_type: None,
5018 }));
5019 result = Some(match result {
5020 None => ilike,
5021 Some(prev) => Expression::Or(Box::new(BinaryOp::new(prev, ilike))),
5022 });
5023 }
5024 Ok(result.unwrap_or(e))
5025 } else {
5026 Ok(e)
5027 }
5028 }
5029 _ => Ok(e),
5030 }
5031 })
5032}
5033
5034pub fn qualify_derived_table_outputs(expr: Expression) -> Result<Expression> {
5042 use crate::expressions::Alias;
5043
5044 fn add_self_aliases_to_select(select: &mut Select) {
5045 let new_expressions: Vec<Expression> = select
5046 .expressions
5047 .iter()
5048 .map(|e| {
5049 match e {
5050 Expression::Column(col) => {
5052 let alias_name = col.name.clone();
5053 Expression::Alias(Box::new(Alias {
5054 this: e.clone(),
5055 alias: alias_name,
5056 column_aliases: Vec::new(),
5057 pre_alias_comments: Vec::new(),
5058 trailing_comments: Vec::new(),
5059 inferred_type: None,
5060 }))
5061 }
5062 _ => e.clone(),
5064 }
5065 })
5066 .collect();
5067 select.expressions = new_expressions;
5068 }
5069
5070 fn walk_and_qualify(expr: &mut Expression) {
5071 match expr {
5072 Expression::Select(ref mut select) => {
5073 if let Some(ref mut from) = select.from {
5075 for e in from.expressions.iter_mut() {
5076 qualify_subquery_expr(e);
5077 walk_and_qualify(e);
5078 }
5079 }
5080 for join in select.joins.iter_mut() {
5082 qualify_subquery_expr(&mut join.this);
5083 walk_and_qualify(&mut join.this);
5084 }
5085 for e in select.expressions.iter_mut() {
5087 walk_and_qualify(e);
5088 }
5089 if let Some(ref mut w) = select.where_clause {
5091 walk_and_qualify(&mut w.this);
5092 }
5093 }
5094 Expression::Subquery(ref mut subquery) => {
5095 walk_and_qualify(&mut subquery.this);
5096 }
5097 Expression::Union(ref mut u) => {
5098 walk_and_qualify(&mut u.left);
5099 walk_and_qualify(&mut u.right);
5100 }
5101 Expression::Intersect(ref mut i) => {
5102 walk_and_qualify(&mut i.left);
5103 walk_and_qualify(&mut i.right);
5104 }
5105 Expression::Except(ref mut e) => {
5106 walk_and_qualify(&mut e.left);
5107 walk_and_qualify(&mut e.right);
5108 }
5109 Expression::Cte(ref mut cte) => {
5110 walk_and_qualify(&mut cte.this);
5111 }
5112 _ => {}
5113 }
5114 }
5115
5116 fn qualify_subquery_expr(expr: &mut Expression) {
5117 match expr {
5118 Expression::Subquery(ref mut subquery) => {
5119 if subquery.alias.is_some() && subquery.column_aliases.is_empty() {
5121 if let Expression::Select(ref mut inner_select) = subquery.this {
5122 let has_star = inner_select
5124 .expressions
5125 .iter()
5126 .any(|e| matches!(e, Expression::Star(_)));
5127 if !has_star {
5128 add_self_aliases_to_select(inner_select);
5129 }
5130 }
5131 }
5132 walk_and_qualify(&mut subquery.this);
5134 }
5135 Expression::Alias(ref mut alias) => {
5136 qualify_subquery_expr(&mut alias.this);
5137 }
5138 _ => {}
5139 }
5140 }
5141
5142 let mut result = expr;
5143 walk_and_qualify(&mut result);
5144
5145 if let Expression::Select(ref mut select) = result {
5147 if let Some(ref mut with) = select.with {
5148 for cte in with.ctes.iter_mut() {
5149 if cte.columns.is_empty() {
5151 walk_and_qualify(&mut cte.this);
5153 }
5154 }
5155 }
5156 }
5157
5158 Ok(result)
5159}
5160
5161#[cfg(test)]
5162mod tests {
5163 use super::*;
5164 use crate::dialects::{Dialect, DialectType};
5165 use crate::expressions::Column;
5166
5167 fn gen(expr: &Expression) -> String {
5168 let dialect = Dialect::get(DialectType::Generic);
5169 dialect.generate(expr).unwrap()
5170 }
5171
5172 #[test]
5173 fn test_preprocess() {
5174 let expr = Expression::Boolean(BooleanLiteral { value: true });
5175 let result = preprocess(expr, &[replace_bool_with_int]).unwrap();
5176 assert!(matches!(result, Expression::Literal(Literal::Number(_))));
5177 }
5178
5179 #[test]
5180 fn test_preprocess_chain() {
5181 let expr = Expression::Boolean(BooleanLiteral { value: true });
5183 let transforms: Vec<fn(Expression) -> Result<Expression>> =
5185 vec![replace_bool_with_int, replace_int_with_bool];
5186 let result = preprocess(expr, &transforms).unwrap();
5187 if let Expression::Boolean(b) = result {
5190 assert!(b.value);
5191 } else {
5192 panic!("Expected boolean literal");
5193 }
5194 }
5195
5196 #[test]
5197 fn test_unnest_to_explode() {
5198 let unnest = Expression::Unnest(Box::new(UnnestFunc {
5199 this: Expression::Column(Column {
5200 name: Identifier::new("arr".to_string()),
5201 table: None,
5202 join_mark: false,
5203 trailing_comments: vec![],
5204 span: None,
5205 inferred_type: None,
5206 }),
5207 expressions: Vec::new(),
5208 with_ordinality: false,
5209 alias: None,
5210 offset_alias: None,
5211 }));
5212
5213 let result = unnest_to_explode(unnest).unwrap();
5214 assert!(matches!(result, Expression::Explode(_)));
5215 }
5216
5217 #[test]
5218 fn test_explode_to_unnest() {
5219 let explode = Expression::Explode(Box::new(UnaryFunc {
5220 this: Expression::Column(Column {
5221 name: Identifier::new("arr".to_string()),
5222 table: None,
5223 join_mark: false,
5224 trailing_comments: vec![],
5225 span: None,
5226 inferred_type: None,
5227 }),
5228 original_name: None,
5229 inferred_type: None,
5230 }));
5231
5232 let result = explode_to_unnest(explode).unwrap();
5233 assert!(matches!(result, Expression::Unnest(_)));
5234 }
5235
5236 #[test]
5237 fn test_replace_bool_with_int() {
5238 let true_expr = Expression::Boolean(BooleanLiteral { value: true });
5239 let result = replace_bool_with_int(true_expr).unwrap();
5240 if let Expression::Literal(Literal::Number(n)) = result {
5241 assert_eq!(n, "1");
5242 } else {
5243 panic!("Expected number literal");
5244 }
5245
5246 let false_expr = Expression::Boolean(BooleanLiteral { value: false });
5247 let result = replace_bool_with_int(false_expr).unwrap();
5248 if let Expression::Literal(Literal::Number(n)) = result {
5249 assert_eq!(n, "0");
5250 } else {
5251 panic!("Expected number literal");
5252 }
5253 }
5254
5255 #[test]
5256 fn test_replace_int_with_bool() {
5257 let one_expr = Expression::Literal(Literal::Number("1".to_string()));
5258 let result = replace_int_with_bool(one_expr).unwrap();
5259 if let Expression::Boolean(b) = result {
5260 assert!(b.value);
5261 } else {
5262 panic!("Expected boolean true");
5263 }
5264
5265 let zero_expr = Expression::Literal(Literal::Number("0".to_string()));
5266 let result = replace_int_with_bool(zero_expr).unwrap();
5267 if let Expression::Boolean(b) = result {
5268 assert!(!b.value);
5269 } else {
5270 panic!("Expected boolean false");
5271 }
5272
5273 let two_expr = Expression::Literal(Literal::Number("2".to_string()));
5275 let result = replace_int_with_bool(two_expr).unwrap();
5276 assert!(matches!(result, Expression::Literal(Literal::Number(_))));
5277 }
5278
5279 #[test]
5280 fn test_strip_data_type_params() {
5281 let decimal = DataType::Decimal {
5283 precision: Some(10),
5284 scale: Some(2),
5285 };
5286 let stripped = strip_data_type_params(decimal);
5287 assert_eq!(
5288 stripped,
5289 DataType::Decimal {
5290 precision: None,
5291 scale: None
5292 }
5293 );
5294
5295 let varchar = DataType::VarChar {
5297 length: Some(255),
5298 parenthesized_length: false,
5299 };
5300 let stripped = strip_data_type_params(varchar);
5301 assert_eq!(
5302 stripped,
5303 DataType::VarChar {
5304 length: None,
5305 parenthesized_length: false
5306 }
5307 );
5308
5309 let char_type = DataType::Char { length: Some(10) };
5311 let stripped = strip_data_type_params(char_type);
5312 assert_eq!(stripped, DataType::Char { length: None });
5313
5314 let timestamp = DataType::Timestamp {
5316 precision: Some(6),
5317 timezone: true,
5318 };
5319 let stripped = strip_data_type_params(timestamp);
5320 assert_eq!(
5321 stripped,
5322 DataType::Timestamp {
5323 precision: None,
5324 timezone: true
5325 }
5326 );
5327
5328 let array = DataType::Array {
5330 element_type: Box::new(DataType::VarChar {
5331 length: Some(100),
5332 parenthesized_length: false,
5333 }),
5334 dimension: None,
5335 };
5336 let stripped = strip_data_type_params(array);
5337 assert_eq!(
5338 stripped,
5339 DataType::Array {
5340 element_type: Box::new(DataType::VarChar {
5341 length: None,
5342 parenthesized_length: false
5343 }),
5344 dimension: None,
5345 }
5346 );
5347
5348 let text = DataType::Text;
5350 let stripped = strip_data_type_params(text);
5351 assert_eq!(stripped, DataType::Text);
5352 }
5353
5354 #[test]
5355 fn test_remove_precision_parameterized_types_cast() {
5356 let cast_expr = Expression::Cast(Box::new(Cast {
5358 this: Expression::Literal(Literal::Number("1".to_string())),
5359 to: DataType::Decimal {
5360 precision: Some(10),
5361 scale: Some(2),
5362 },
5363 trailing_comments: vec![],
5364 double_colon_syntax: false,
5365 format: None,
5366 default: None,
5367 inferred_type: None,
5368 }));
5369
5370 let result = remove_precision_parameterized_types(cast_expr).unwrap();
5371 if let Expression::Cast(cast) = result {
5372 assert_eq!(
5373 cast.to,
5374 DataType::Decimal {
5375 precision: None,
5376 scale: None
5377 }
5378 );
5379 } else {
5380 panic!("Expected Cast expression");
5381 }
5382 }
5383
5384 #[test]
5385 fn test_remove_precision_parameterized_types_varchar() {
5386 let cast_expr = Expression::Cast(Box::new(Cast {
5388 this: Expression::Literal(Literal::String("hello".to_string())),
5389 to: DataType::VarChar {
5390 length: Some(10),
5391 parenthesized_length: false,
5392 },
5393 trailing_comments: vec![],
5394 double_colon_syntax: false,
5395 format: None,
5396 default: None,
5397 inferred_type: None,
5398 }));
5399
5400 let result = remove_precision_parameterized_types(cast_expr).unwrap();
5401 if let Expression::Cast(cast) = result {
5402 assert_eq!(
5403 cast.to,
5404 DataType::VarChar {
5405 length: None,
5406 parenthesized_length: false
5407 }
5408 );
5409 } else {
5410 panic!("Expected Cast expression");
5411 }
5412 }
5413
5414 #[test]
5415 fn test_remove_precision_direct_cast() {
5416 let cast = Expression::Cast(Box::new(Cast {
5420 this: Expression::Literal(Literal::Number("1".to_string())),
5421 to: DataType::Decimal {
5422 precision: Some(10),
5423 scale: Some(2),
5424 },
5425 trailing_comments: vec![],
5426 double_colon_syntax: false,
5427 format: None,
5428 default: None,
5429 inferred_type: None,
5430 }));
5431
5432 let transformed = remove_precision_parameterized_types(cast).unwrap();
5433 let generated = gen(&transformed);
5434
5435 assert!(generated.contains("DECIMAL"));
5437 assert!(!generated.contains("(10"));
5438 }
5439
5440 #[test]
5441 fn test_epoch_cast_to_ts() {
5442 let cast_expr = Expression::Cast(Box::new(Cast {
5444 this: Expression::Literal(Literal::String("epoch".to_string())),
5445 to: DataType::Timestamp {
5446 precision: None,
5447 timezone: false,
5448 },
5449 trailing_comments: vec![],
5450 double_colon_syntax: false,
5451 format: None,
5452 default: None,
5453 inferred_type: None,
5454 }));
5455
5456 let result = epoch_cast_to_ts(cast_expr).unwrap();
5457 if let Expression::Cast(cast) = result {
5458 if let Expression::Literal(Literal::String(s)) = cast.this {
5459 assert_eq!(s, "1970-01-01 00:00:00");
5460 } else {
5461 panic!("Expected string literal");
5462 }
5463 } else {
5464 panic!("Expected Cast expression");
5465 }
5466 }
5467
5468 #[test]
5469 fn test_epoch_cast_to_ts_preserves_non_epoch() {
5470 let cast_expr = Expression::Cast(Box::new(Cast {
5472 this: Expression::Literal(Literal::String("2024-01-15".to_string())),
5473 to: DataType::Timestamp {
5474 precision: None,
5475 timezone: false,
5476 },
5477 trailing_comments: vec![],
5478 double_colon_syntax: false,
5479 format: None,
5480 default: None,
5481 inferred_type: None,
5482 }));
5483
5484 let result = epoch_cast_to_ts(cast_expr).unwrap();
5485 if let Expression::Cast(cast) = result {
5486 if let Expression::Literal(Literal::String(s)) = cast.this {
5487 assert_eq!(s, "2024-01-15");
5488 } else {
5489 panic!("Expected string literal");
5490 }
5491 } else {
5492 panic!("Expected Cast expression");
5493 }
5494 }
5495
5496 #[test]
5497 fn test_unqualify_columns() {
5498 let col = Expression::Column(Column {
5500 name: Identifier::new("id".to_string()),
5501 table: Some(Identifier::new("users".to_string())),
5502 join_mark: false,
5503 trailing_comments: vec![],
5504 span: None,
5505 inferred_type: None,
5506 });
5507
5508 let result = unqualify_columns(col).unwrap();
5509 if let Expression::Column(c) = result {
5510 assert!(c.table.is_none());
5511 assert_eq!(c.name.name, "id");
5512 } else {
5513 panic!("Expected Column expression");
5514 }
5515 }
5516
5517 #[test]
5518 fn test_is_temporal_type() {
5519 assert!(is_temporal_type(&DataType::Date));
5520 assert!(is_temporal_type(&DataType::Timestamp {
5521 precision: None,
5522 timezone: false
5523 }));
5524 assert!(is_temporal_type(&DataType::Time {
5525 precision: None,
5526 timezone: false
5527 }));
5528 assert!(!is_temporal_type(&DataType::Int {
5529 length: None,
5530 integer_spelling: false
5531 }));
5532 assert!(!is_temporal_type(&DataType::VarChar {
5533 length: None,
5534 parenthesized_length: false
5535 }));
5536 }
5537
5538 #[test]
5539 fn test_eliminate_semi_join_basic() {
5540 use crate::expressions::{Join, TableRef};
5541
5542 let select = Expression::Select(Box::new(Select {
5544 expressions: vec![Expression::Column(Column {
5545 name: Identifier::new("a".to_string()),
5546 table: None,
5547 join_mark: false,
5548 trailing_comments: vec![],
5549 span: None,
5550 inferred_type: None,
5551 })],
5552 from: Some(From {
5553 expressions: vec![Expression::Table(TableRef::new("t1"))],
5554 }),
5555 joins: vec![Join {
5556 this: Expression::Table(TableRef::new("t2")),
5557 kind: JoinKind::Semi,
5558 on: Some(Expression::Eq(Box::new(BinaryOp {
5559 left: Expression::Column(Column {
5560 name: Identifier::new("x".to_string()),
5561 table: None,
5562 join_mark: false,
5563 trailing_comments: vec![],
5564 span: None,
5565 inferred_type: None,
5566 }),
5567 right: Expression::Column(Column {
5568 name: Identifier::new("y".to_string()),
5569 table: None,
5570 join_mark: false,
5571 trailing_comments: vec![],
5572 span: None,
5573 inferred_type: None,
5574 }),
5575 left_comments: vec![],
5576 operator_comments: vec![],
5577 trailing_comments: vec![],
5578 inferred_type: None,
5579 }))),
5580 using: vec![],
5581 use_inner_keyword: false,
5582 use_outer_keyword: false,
5583 deferred_condition: false,
5584 join_hint: None,
5585 match_condition: None,
5586 pivots: Vec::new(),
5587 comments: Vec::new(),
5588 nesting_group: 0,
5589 directed: false,
5590 }],
5591 ..Select::new()
5592 }));
5593
5594 let result = eliminate_semi_and_anti_joins(select).unwrap();
5595 if let Expression::Select(s) = result {
5596 assert!(s.joins.is_empty());
5598 assert!(s.where_clause.is_some());
5600 } else {
5601 panic!("Expected Select expression");
5602 }
5603 }
5604
5605 #[test]
5606 fn test_no_ilike_sql() {
5607 use crate::expressions::LikeOp;
5608
5609 let ilike_expr = Expression::ILike(Box::new(LikeOp {
5611 left: Expression::Column(Column {
5612 name: Identifier::new("name".to_string()),
5613 table: None,
5614 join_mark: false,
5615 trailing_comments: vec![],
5616 span: None,
5617 inferred_type: None,
5618 }),
5619 right: Expression::Literal(Literal::String("%test%".to_string())),
5620 escape: None,
5621 quantifier: None,
5622 inferred_type: None,
5623 }));
5624
5625 let result = no_ilike_sql(ilike_expr).unwrap();
5626 if let Expression::Like(like) = result {
5627 if let Expression::Function(f) = &like.left {
5629 assert_eq!(f.name, "LOWER");
5630 } else {
5631 panic!("Expected LOWER function on left");
5632 }
5633 if let Expression::Function(f) = &like.right {
5635 assert_eq!(f.name, "LOWER");
5636 } else {
5637 panic!("Expected LOWER function on right");
5638 }
5639 } else {
5640 panic!("Expected Like expression");
5641 }
5642 }
5643
5644 #[test]
5645 fn test_no_trycast_sql() {
5646 let trycast_expr = Expression::TryCast(Box::new(Cast {
5648 this: Expression::Literal(Literal::String("123".to_string())),
5649 to: DataType::Int {
5650 length: None,
5651 integer_spelling: false,
5652 },
5653 trailing_comments: vec![],
5654 double_colon_syntax: false,
5655 format: None,
5656 default: None,
5657 inferred_type: None,
5658 }));
5659
5660 let result = no_trycast_sql(trycast_expr).unwrap();
5661 assert!(matches!(result, Expression::Cast(_)));
5662 }
5663
5664 #[test]
5665 fn test_no_safe_cast_sql() {
5666 let safe_cast_expr = Expression::SafeCast(Box::new(Cast {
5668 this: Expression::Literal(Literal::String("123".to_string())),
5669 to: DataType::Int {
5670 length: None,
5671 integer_spelling: false,
5672 },
5673 trailing_comments: vec![],
5674 double_colon_syntax: false,
5675 format: None,
5676 default: None,
5677 inferred_type: None,
5678 }));
5679
5680 let result = no_safe_cast_sql(safe_cast_expr).unwrap();
5681 assert!(matches!(result, Expression::Cast(_)));
5682 }
5683
5684 #[test]
5685 fn test_explode_to_unnest_presto() {
5686 let spark = Dialect::get(DialectType::Spark);
5687 let result = spark
5688 .transpile_to("SELECT EXPLODE(x) FROM tbl", DialectType::Presto)
5689 .unwrap();
5690 assert_eq!(
5691 result[0],
5692 "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))"
5693 );
5694 }
5695
5696 #[test]
5697 fn test_explode_to_unnest_bigquery() {
5698 let spark = Dialect::get(DialectType::Spark);
5699 let result = spark
5700 .transpile_to("SELECT EXPLODE(x) FROM tbl", DialectType::BigQuery)
5701 .unwrap();
5702 assert_eq!(
5703 result[0],
5704 "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))"
5705 );
5706 }
5707}