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, With,
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(Box::new(Literal::Number(
293 value.to_string(),
294 ))))
295 }
296 _ => Ok(expr),
297 }
298}
299
300pub fn replace_int_with_bool(expr: Expression) -> Result<Expression> {
304 match expr {
305 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(n) if n == "1" || n == "0") =>
306 {
307 let Literal::Number(n) = lit.as_ref() else {
308 unreachable!()
309 };
310 Ok(Expression::Boolean(BooleanLiteral { value: n == "1" }))
311 }
312 _ => Ok(expr),
313 }
314}
315
316pub fn remove_precision_parameterized_types(expr: Expression) -> Result<Expression> {
321 Ok(strip_type_params_recursive(expr))
322}
323
324fn strip_type_params_recursive(expr: Expression) -> Expression {
326 match expr {
327 Expression::Cast(mut cast) => {
329 cast.to = strip_data_type_params(cast.to);
330 cast.this = strip_type_params_recursive(cast.this);
332 Expression::Cast(cast)
333 }
334 Expression::TryCast(mut try_cast) => {
336 try_cast.to = strip_data_type_params(try_cast.to);
337 try_cast.this = strip_type_params_recursive(try_cast.this);
338 Expression::TryCast(try_cast)
339 }
340 Expression::SafeCast(mut safe_cast) => {
342 safe_cast.to = strip_data_type_params(safe_cast.to);
343 safe_cast.this = strip_type_params_recursive(safe_cast.this);
344 Expression::SafeCast(safe_cast)
345 }
346 _ => expr,
349 }
350}
351
352fn strip_data_type_params(dt: DataType) -> DataType {
354 match dt {
355 DataType::Decimal { .. } => DataType::Decimal {
357 precision: None,
358 scale: None,
359 },
360 DataType::TinyInt { .. } => DataType::TinyInt { length: None },
361 DataType::SmallInt { .. } => DataType::SmallInt { length: None },
362 DataType::Int { .. } => DataType::Int {
363 length: None,
364 integer_spelling: false,
365 },
366 DataType::BigInt { .. } => DataType::BigInt { length: None },
367
368 DataType::Char { .. } => DataType::Char { length: None },
370 DataType::VarChar { .. } => DataType::VarChar {
371 length: None,
372 parenthesized_length: false,
373 },
374
375 DataType::Binary { .. } => DataType::Binary { length: None },
377 DataType::VarBinary { .. } => DataType::VarBinary { length: None },
378
379 DataType::Bit { .. } => DataType::Bit { length: None },
381 DataType::VarBit { .. } => DataType::VarBit { length: None },
382
383 DataType::Time { .. } => DataType::Time {
385 precision: None,
386 timezone: false,
387 },
388 DataType::Timestamp { timezone, .. } => DataType::Timestamp {
389 precision: None,
390 timezone,
391 },
392
393 DataType::Array {
395 element_type,
396 dimension,
397 } => DataType::Array {
398 element_type: Box::new(strip_data_type_params(*element_type)),
399 dimension,
400 },
401
402 DataType::Map {
404 key_type,
405 value_type,
406 } => DataType::Map {
407 key_type: Box::new(strip_data_type_params(*key_type)),
408 value_type: Box::new(strip_data_type_params(*value_type)),
409 },
410
411 DataType::Struct { fields, nested } => DataType::Struct {
413 fields: fields
414 .into_iter()
415 .map(|f| {
416 StructField::with_options(
417 f.name,
418 strip_data_type_params(f.data_type),
419 f.options,
420 )
421 })
422 .collect(),
423 nested,
424 },
425
426 DataType::Vector { element_type, .. } => DataType::Vector {
428 element_type: element_type.map(|et| Box::new(strip_data_type_params(*et))),
429 dimension: None,
430 },
431
432 DataType::Object { fields, modifier } => DataType::Object {
434 fields: fields
435 .into_iter()
436 .map(|(name, ty, not_null)| (name, strip_data_type_params(ty), not_null))
437 .collect(),
438 modifier,
439 },
440
441 other => other,
443 }
444}
445
446pub fn eliminate_qualify(expr: Expression) -> Result<Expression> {
461 match expr {
462 Expression::Select(mut select) => {
463 if let Some(qualify) = select.qualify.take() {
464 let qualify_filter = qualify.this;
471 let window_alias_name = "_w".to_string();
472 let window_alias_ident = Identifier::new(window_alias_name.clone());
473
474 let (window_expr, outer_where) =
477 extract_window_from_condition(qualify_filter.clone(), &window_alias_ident);
478
479 if let Some(win_expr) = window_expr {
480 let window_alias_expr =
482 Expression::Alias(Box::new(crate::expressions::Alias {
483 this: win_expr,
484 alias: window_alias_ident.clone(),
485 column_aliases: vec![],
486 alias_explicit_as: false,
487 alias_keyword: None,
488 pre_alias_comments: vec![],
489 trailing_comments: vec![],
490 inferred_type: None,
491 }));
492
493 let outer_exprs: Vec<Expression> = select
497 .expressions
498 .iter()
499 .map(|expr| {
500 if let Expression::Alias(a) = expr {
501 Expression::Column(Box::new(crate::expressions::Column {
503 name: a.alias.clone(),
504 table: None,
505 join_mark: false,
506 trailing_comments: vec![],
507 span: None,
508 inferred_type: None,
509 }))
510 } else {
511 expr.clone()
512 }
513 })
514 .collect();
515 select.expressions.push(window_alias_expr);
516
517 let inner_select = Expression::Select(select);
519 let subquery = Subquery {
520 this: inner_select,
521 alias: Some(Identifier::new("_t".to_string())),
522 column_aliases: vec![],
523 alias_explicit_as: false,
524 alias_keyword: None,
525 order_by: None,
526 limit: None,
527 offset: None,
528 distribute_by: None,
529 sort_by: None,
530 cluster_by: None,
531 lateral: false,
532 modifiers_inside: false,
533 trailing_comments: vec![],
534 inferred_type: None,
535 };
536
537 let outer_select = Select {
539 expressions: outer_exprs,
540 from: Some(From {
541 expressions: vec![Expression::Subquery(Box::new(subquery))],
542 }),
543 where_clause: Some(Where { this: outer_where }),
544 ..Select::new()
545 };
546
547 return Ok(Expression::Select(Box::new(outer_select)));
548 } else {
549 let qualify_alias = Expression::Alias(Box::new(crate::expressions::Alias {
551 this: qualify_filter.clone(),
552 alias: window_alias_ident.clone(),
553 column_aliases: vec![],
554 alias_explicit_as: false,
555 alias_keyword: None,
556 pre_alias_comments: vec![],
557 trailing_comments: vec![],
558 inferred_type: None,
559 }));
560
561 let original_exprs = select.expressions.clone();
562 select.expressions.push(qualify_alias);
563
564 let inner_select = Expression::Select(select);
565 let subquery = Subquery {
566 this: inner_select,
567 alias: Some(Identifier::new("_t".to_string())),
568 column_aliases: vec![],
569 alias_explicit_as: false,
570 alias_keyword: None,
571 order_by: None,
572 limit: None,
573 offset: None,
574 distribute_by: None,
575 sort_by: None,
576 cluster_by: None,
577 lateral: false,
578 modifiers_inside: false,
579 trailing_comments: vec![],
580 inferred_type: None,
581 };
582
583 let outer_select = Select {
584 expressions: original_exprs,
585 from: Some(From {
586 expressions: vec![Expression::Subquery(Box::new(subquery))],
587 }),
588 where_clause: Some(Where {
589 this: Expression::Column(Box::new(crate::expressions::Column {
590 name: window_alias_ident,
591 table: None,
592 join_mark: false,
593 trailing_comments: vec![],
594 span: None,
595 inferred_type: None,
596 })),
597 }),
598 ..Select::new()
599 };
600
601 return Ok(Expression::Select(Box::new(outer_select)));
602 }
603 }
604 Ok(Expression::Select(select))
605 }
606 other => Ok(other),
607 }
608}
609
610fn extract_window_from_condition(
614 condition: Expression,
615 alias: &Identifier,
616) -> (Option<Expression>, Expression) {
617 let alias_col = Expression::Column(Box::new(crate::expressions::Column {
618 name: alias.clone(),
619 table: None,
620 join_mark: false,
621 trailing_comments: vec![],
622 span: None,
623 inferred_type: None,
624 }));
625
626 match condition {
628 Expression::Eq(ref op) => {
630 if is_window_expr(&op.left) {
631 (
632 Some(op.left.clone()),
633 Expression::Eq(Box::new(BinaryOp {
634 left: alias_col,
635 right: op.right.clone(),
636 ..(**op).clone()
637 })),
638 )
639 } else if is_window_expr(&op.right) {
640 (
641 Some(op.right.clone()),
642 Expression::Eq(Box::new(BinaryOp {
643 left: op.left.clone(),
644 right: alias_col,
645 ..(**op).clone()
646 })),
647 )
648 } else {
649 (None, condition)
650 }
651 }
652 Expression::Neq(ref op) => {
653 if is_window_expr(&op.left) {
654 (
655 Some(op.left.clone()),
656 Expression::Neq(Box::new(BinaryOp {
657 left: alias_col,
658 right: op.right.clone(),
659 ..(**op).clone()
660 })),
661 )
662 } else if is_window_expr(&op.right) {
663 (
664 Some(op.right.clone()),
665 Expression::Neq(Box::new(BinaryOp {
666 left: op.left.clone(),
667 right: alias_col,
668 ..(**op).clone()
669 })),
670 )
671 } else {
672 (None, condition)
673 }
674 }
675 Expression::Lt(ref op) => {
676 if is_window_expr(&op.left) {
677 (
678 Some(op.left.clone()),
679 Expression::Lt(Box::new(BinaryOp {
680 left: alias_col,
681 right: op.right.clone(),
682 ..(**op).clone()
683 })),
684 )
685 } else if is_window_expr(&op.right) {
686 (
687 Some(op.right.clone()),
688 Expression::Lt(Box::new(BinaryOp {
689 left: op.left.clone(),
690 right: alias_col,
691 ..(**op).clone()
692 })),
693 )
694 } else {
695 (None, condition)
696 }
697 }
698 Expression::Lte(ref op) => {
699 if is_window_expr(&op.left) {
700 (
701 Some(op.left.clone()),
702 Expression::Lte(Box::new(BinaryOp {
703 left: alias_col,
704 right: op.right.clone(),
705 ..(**op).clone()
706 })),
707 )
708 } else if is_window_expr(&op.right) {
709 (
710 Some(op.right.clone()),
711 Expression::Lte(Box::new(BinaryOp {
712 left: op.left.clone(),
713 right: alias_col,
714 ..(**op).clone()
715 })),
716 )
717 } else {
718 (None, condition)
719 }
720 }
721 Expression::Gt(ref op) => {
722 if is_window_expr(&op.left) {
723 (
724 Some(op.left.clone()),
725 Expression::Gt(Box::new(BinaryOp {
726 left: alias_col,
727 right: op.right.clone(),
728 ..(**op).clone()
729 })),
730 )
731 } else if is_window_expr(&op.right) {
732 (
733 Some(op.right.clone()),
734 Expression::Gt(Box::new(BinaryOp {
735 left: op.left.clone(),
736 right: alias_col,
737 ..(**op).clone()
738 })),
739 )
740 } else {
741 (None, condition)
742 }
743 }
744 Expression::Gte(ref op) => {
745 if is_window_expr(&op.left) {
746 (
747 Some(op.left.clone()),
748 Expression::Gte(Box::new(BinaryOp {
749 left: alias_col,
750 right: op.right.clone(),
751 ..(**op).clone()
752 })),
753 )
754 } else if is_window_expr(&op.right) {
755 (
756 Some(op.right.clone()),
757 Expression::Gte(Box::new(BinaryOp {
758 left: op.left.clone(),
759 right: alias_col,
760 ..(**op).clone()
761 })),
762 )
763 } else {
764 (None, condition)
765 }
766 }
767 _ if is_window_expr(&condition) => (Some(condition), alias_col),
769 _ => (None, condition),
771 }
772}
773
774fn is_window_expr(expr: &Expression) -> bool {
776 matches!(expr, Expression::Window(_) | Expression::WindowFunction(_))
777}
778
779pub fn eliminate_distinct_on(expr: Expression) -> Result<Expression> {
798 eliminate_distinct_on_for_dialect(expr, None, None)
799}
800
801pub fn eliminate_distinct_on_for_dialect(
806 expr: Expression,
807 target: Option<DialectType>,
808 source: Option<DialectType>,
809) -> Result<Expression> {
810 use crate::expressions::Case;
811
812 if matches!(
814 target,
815 Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB)
816 ) {
817 return Ok(expr);
818 }
819
820 enum NullsMode {
825 None, NullsFirst, CaseExpr, }
829
830 let nulls_mode = match target {
831 Some(DialectType::MySQL)
832 | Some(DialectType::SingleStore)
833 | Some(DialectType::TSQL)
834 | Some(DialectType::Fabric) => NullsMode::CaseExpr,
835 Some(DialectType::Oracle) | Some(DialectType::Redshift) | Some(DialectType::Snowflake) => {
836 NullsMode::None
837 }
838 Some(DialectType::StarRocks) => {
839 if matches!(source, Some(DialectType::Redshift)) {
840 NullsMode::CaseExpr
841 } else {
842 NullsMode::None
843 }
844 }
845 _ => NullsMode::NullsFirst,
847 };
848
849 match expr {
850 Expression::Select(mut select) => {
851 if let Some(distinct_cols) = select.distinct_on.take() {
852 if !distinct_cols.is_empty() {
853 let row_number_alias = Identifier::new("_row_number".to_string());
855
856 let order_exprs = if let Some(ref order_by) = select.order_by {
858 let mut exprs = order_by.expressions.clone();
859 match nulls_mode {
861 NullsMode::NullsFirst => {
862 for ord in &mut exprs {
863 if ord.desc && ord.nulls_first.is_none() {
864 ord.nulls_first = Some(true);
865 }
866 }
867 }
868 NullsMode::CaseExpr => {
869 let mut new_exprs = Vec::new();
872 for ord in &exprs {
873 if ord.desc && ord.nulls_first.is_none() {
874 let null_check = Expression::Case(Box::new(Case {
876 operand: None,
877 whens: vec![(
878 Expression::IsNull(Box::new(
879 crate::expressions::IsNull {
880 this: ord.this.clone(),
881 not: false,
882 postfix_form: false,
883 },
884 )),
885 Expression::Literal(Box::new(Literal::Number(
886 "1".to_string(),
887 ))),
888 )],
889 else_: Some(Expression::Literal(Box::new(
890 Literal::Number("0".to_string()),
891 ))),
892 comments: Vec::new(),
893 inferred_type: None,
894 }));
895 new_exprs.push(crate::expressions::Ordered {
896 this: null_check,
897 desc: true,
898 nulls_first: None,
899 explicit_asc: false,
900 with_fill: None,
901 });
902 }
903 new_exprs.push(ord.clone());
904 }
905 exprs = new_exprs;
906 }
907 NullsMode::None => {}
908 }
909 exprs
910 } else {
911 distinct_cols
912 .iter()
913 .map(|e| crate::expressions::Ordered {
914 this: e.clone(),
915 desc: false,
916 nulls_first: None,
917 explicit_asc: false,
918 with_fill: None,
919 })
920 .collect()
921 };
922
923 let row_number_func =
925 Expression::WindowFunction(Box::new(crate::expressions::WindowFunction {
926 this: Expression::RowNumber(crate::expressions::RowNumber),
927 over: Over {
928 partition_by: distinct_cols,
929 order_by: order_exprs,
930 frame: None,
931 window_name: None,
932 alias: None,
933 },
934 keep: None,
935 inferred_type: None,
936 }));
937
938 let mut inner_aliased_exprs = Vec::new();
942 let mut outer_select_exprs = Vec::new();
943 for orig_expr in &select.expressions {
944 match orig_expr {
945 Expression::Alias(alias) => {
946 inner_aliased_exprs.push(orig_expr.clone());
948 outer_select_exprs.push(Expression::Column(Box::new(
949 crate::expressions::Column {
950 name: alias.alias.clone(),
951 table: None,
952 join_mark: false,
953 trailing_comments: vec![],
954 span: None,
955 inferred_type: None,
956 },
957 )));
958 }
959 Expression::Column(col) => {
960 inner_aliased_exprs.push(Expression::Alias(Box::new(
962 crate::expressions::Alias {
963 this: orig_expr.clone(),
964 alias: col.name.clone(),
965 column_aliases: vec![],
966 alias_explicit_as: false,
967 alias_keyword: None,
968 pre_alias_comments: vec![],
969 trailing_comments: vec![],
970 inferred_type: None,
971 },
972 )));
973 outer_select_exprs.push(Expression::Column(Box::new(
974 crate::expressions::Column {
975 name: col.name.clone(),
976 table: None,
977 join_mark: false,
978 trailing_comments: vec![],
979 span: None,
980 inferred_type: None,
981 },
982 )));
983 }
984 _ => {
985 inner_aliased_exprs.push(orig_expr.clone());
987 outer_select_exprs.push(orig_expr.clone());
988 }
989 }
990 }
991
992 let row_number_alias_expr =
994 Expression::Alias(Box::new(crate::expressions::Alias {
995 this: row_number_func,
996 alias: row_number_alias.clone(),
997 column_aliases: vec![],
998 alias_explicit_as: false,
999 alias_keyword: None,
1000 pre_alias_comments: vec![],
1001 trailing_comments: vec![],
1002 inferred_type: None,
1003 }));
1004 inner_aliased_exprs.push(row_number_alias_expr);
1005
1006 select.expressions = inner_aliased_exprs;
1008
1009 let _inner_order_by = select.order_by.take();
1011
1012 select.distinct = false;
1014
1015 let inner_select = Expression::Select(select);
1017 let subquery = Subquery {
1018 this: inner_select,
1019 alias: Some(Identifier::new("_t".to_string())),
1020 column_aliases: vec![],
1021 alias_explicit_as: false,
1022 alias_keyword: None,
1023 order_by: None,
1024 limit: None,
1025 offset: None,
1026 distribute_by: None,
1027 sort_by: None,
1028 cluster_by: None,
1029 lateral: false,
1030 modifiers_inside: false,
1031 trailing_comments: vec![],
1032 inferred_type: None,
1033 };
1034
1035 let outer_select = Select {
1038 expressions: outer_select_exprs,
1039 from: Some(From {
1040 expressions: vec![Expression::Subquery(Box::new(subquery))],
1041 }),
1042 where_clause: Some(Where {
1043 this: Expression::Eq(Box::new(BinaryOp {
1044 left: Expression::Column(Box::new(crate::expressions::Column {
1045 name: row_number_alias,
1046 table: None,
1047 join_mark: false,
1048 trailing_comments: vec![],
1049 span: None,
1050 inferred_type: None,
1051 })),
1052 right: Expression::Literal(Box::new(Literal::Number(
1053 "1".to_string(),
1054 ))),
1055 left_comments: vec![],
1056 operator_comments: vec![],
1057 trailing_comments: vec![],
1058 inferred_type: None,
1059 })),
1060 }),
1061 ..Select::new()
1062 };
1063
1064 return Ok(Expression::Select(Box::new(outer_select)));
1065 }
1066 }
1067 Ok(Expression::Select(select))
1068 }
1069 other => Ok(other),
1070 }
1071}
1072
1073pub fn eliminate_semi_and_anti_joins(expr: Expression) -> Result<Expression> {
1081 match expr {
1082 Expression::Select(mut select) => {
1083 let mut new_joins = Vec::new();
1084 let mut extra_where_conditions = Vec::new();
1085
1086 for join in select.joins.drain(..) {
1087 match join.kind {
1088 JoinKind::Semi | JoinKind::LeftSemi => {
1089 if let Some(on_condition) = join.on {
1090 let subquery_select = Select {
1092 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1093 "1".to_string(),
1094 )))],
1095 from: Some(From {
1096 expressions: vec![join.this],
1097 }),
1098 where_clause: Some(Where { this: on_condition }),
1099 ..Select::new()
1100 };
1101
1102 let exists = Expression::Exists(Box::new(Exists {
1103 this: Expression::Subquery(Box::new(Subquery {
1104 this: Expression::Select(Box::new(subquery_select)),
1105 alias: None,
1106 column_aliases: vec![],
1107 alias_explicit_as: false,
1108 alias_keyword: None,
1109 order_by: None,
1110 limit: None,
1111 offset: None,
1112 distribute_by: None,
1113 sort_by: None,
1114 cluster_by: None,
1115 lateral: false,
1116 modifiers_inside: false,
1117 trailing_comments: vec![],
1118 inferred_type: None,
1119 })),
1120 not: false,
1121 }));
1122
1123 extra_where_conditions.push(exists);
1124 }
1125 }
1126 JoinKind::Anti | JoinKind::LeftAnti => {
1127 if let Some(on_condition) = join.on {
1128 let subquery_select = Select {
1130 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1131 "1".to_string(),
1132 )))],
1133 from: Some(From {
1134 expressions: vec![join.this],
1135 }),
1136 where_clause: Some(Where { this: on_condition }),
1137 ..Select::new()
1138 };
1139
1140 let not_exists = Expression::Exists(Box::new(Exists {
1142 this: Expression::Subquery(Box::new(Subquery {
1143 this: Expression::Select(Box::new(subquery_select)),
1144 alias: None,
1145 column_aliases: vec![],
1146 alias_explicit_as: false,
1147 alias_keyword: None,
1148 order_by: None,
1149 limit: None,
1150 offset: None,
1151 distribute_by: None,
1152 sort_by: None,
1153 cluster_by: None,
1154 lateral: false,
1155 modifiers_inside: false,
1156 trailing_comments: vec![],
1157 inferred_type: None,
1158 })),
1159 not: true,
1160 }));
1161
1162 extra_where_conditions.push(not_exists);
1163 }
1164 }
1165 _ => {
1166 new_joins.push(join);
1168 }
1169 }
1170 }
1171
1172 select.joins = new_joins;
1173
1174 if !extra_where_conditions.is_empty() {
1176 let combined = extra_where_conditions
1177 .into_iter()
1178 .reduce(|acc, cond| {
1179 Expression::And(Box::new(BinaryOp {
1180 left: acc,
1181 right: cond,
1182 left_comments: vec![],
1183 operator_comments: vec![],
1184 trailing_comments: vec![],
1185 inferred_type: None,
1186 }))
1187 })
1188 .unwrap();
1189
1190 select.where_clause = match select.where_clause {
1191 Some(Where { this: existing }) => Some(Where {
1192 this: Expression::And(Box::new(BinaryOp {
1193 left: existing,
1194 right: combined,
1195 left_comments: vec![],
1196 operator_comments: vec![],
1197 trailing_comments: vec![],
1198 inferred_type: None,
1199 })),
1200 }),
1201 None => Some(Where { this: combined }),
1202 };
1203 }
1204
1205 Ok(Expression::Select(select))
1206 }
1207 other => Ok(other),
1208 }
1209}
1210
1211pub fn eliminate_full_outer_join(expr: Expression) -> Result<Expression> {
1229 match expr {
1230 Expression::Select(mut select) => {
1231 let full_outer_join_idx = select.joins.iter().position(|j| j.kind == JoinKind::Full);
1233
1234 if let Some(idx) = full_outer_join_idx {
1235 let full_join_count = select
1237 .joins
1238 .iter()
1239 .filter(|j| j.kind == JoinKind::Full)
1240 .count();
1241 if full_join_count != 1 {
1242 return Ok(Expression::Select(select));
1243 }
1244
1245 let mut right_select = select.clone();
1247
1248 let full_join = &select.joins[idx];
1250 let join_condition = full_join.on.clone();
1251
1252 select.joins[idx].kind = JoinKind::Left;
1254
1255 right_select.joins[idx].kind = JoinKind::Right;
1257
1258 if let (Some(ref from), Some(ref join_cond)) = (&select.from, &join_condition) {
1260 if !from.expressions.is_empty() {
1261 let anti_subquery = Expression::Select(Box::new(Select {
1262 expressions: vec![Expression::Literal(Box::new(Literal::Number(
1263 "1".to_string(),
1264 )))],
1265 from: Some(from.clone()),
1266 where_clause: Some(Where {
1267 this: join_cond.clone(),
1268 }),
1269 ..Select::new()
1270 }));
1271
1272 let not_exists = Expression::Not(Box::new(crate::expressions::UnaryOp {
1273 inferred_type: None,
1274 this: Expression::Exists(Box::new(Exists {
1275 this: Expression::Subquery(Box::new(Subquery {
1276 this: anti_subquery,
1277 alias: None,
1278 column_aliases: vec![],
1279 alias_explicit_as: false,
1280 alias_keyword: None,
1281 order_by: None,
1282 limit: None,
1283 offset: None,
1284 distribute_by: None,
1285 sort_by: None,
1286 cluster_by: None,
1287 lateral: false,
1288 modifiers_inside: false,
1289 trailing_comments: vec![],
1290 inferred_type: None,
1291 })),
1292 not: false,
1293 })),
1294 }));
1295
1296 right_select.where_clause = Some(Where {
1298 this: match right_select.where_clause {
1299 Some(w) => Expression::And(Box::new(BinaryOp {
1300 left: w.this,
1301 right: not_exists,
1302 left_comments: vec![],
1303 operator_comments: vec![],
1304 trailing_comments: vec![],
1305 inferred_type: None,
1306 })),
1307 None => not_exists,
1308 },
1309 });
1310 }
1311 }
1312
1313 right_select.with = None;
1315
1316 let order_by = select.order_by.take();
1318
1319 let union = crate::expressions::Union {
1321 left: Expression::Select(select),
1322 right: Expression::Select(right_select),
1323 all: true, distinct: false,
1325 with: None,
1326 order_by,
1327 limit: None,
1328 offset: None,
1329 distribute_by: None,
1330 sort_by: None,
1331 cluster_by: None,
1332 by_name: false,
1333 side: None,
1334 kind: None,
1335 corresponding: false,
1336 strict: false,
1337 on_columns: Vec::new(),
1338 };
1339
1340 return Ok(Expression::Union(Box::new(union)));
1341 }
1342
1343 Ok(Expression::Select(select))
1344 }
1345 other => Ok(other),
1346 }
1347}
1348
1349pub fn move_ctes_to_top_level(expr: Expression) -> Result<Expression> {
1362 match expr {
1363 Expression::Select(mut select) => {
1364 let mut collected_ctes: Vec<crate::expressions::Cte> = Vec::new();
1366 let mut has_recursive = false;
1367
1368 collect_nested_ctes(
1369 &Expression::Select(select.clone()),
1370 &mut collected_ctes,
1371 &mut has_recursive,
1372 true,
1373 );
1374
1375 let mut cte_body_collected: Vec<(String, Vec<crate::expressions::Cte>)> = Vec::new();
1378 if let Some(ref with) = select.with {
1379 for cte in &with.ctes {
1380 let mut body_ctes: Vec<crate::expressions::Cte> = Vec::new();
1381 collect_ctes_from_cte_body(&cte.this, &mut body_ctes, &mut has_recursive);
1382 if !body_ctes.is_empty() {
1383 cte_body_collected.push((cte.alias.name.clone(), body_ctes));
1384 }
1385 }
1386 }
1387
1388 let has_subquery_ctes = !collected_ctes.is_empty();
1389 let has_body_ctes = !cte_body_collected.is_empty();
1390
1391 if has_subquery_ctes || has_body_ctes {
1392 strip_nested_with_clauses(&mut select, true);
1394
1395 if has_body_ctes {
1397 if let Some(ref mut with) = select.with {
1398 for cte in with.ctes.iter_mut() {
1399 strip_with_from_cte_body(&mut cte.this);
1400 }
1401 }
1402 }
1403
1404 let top_with = select.with.get_or_insert_with(|| crate::expressions::With {
1405 ctes: Vec::new(),
1406 recursive: false,
1407 leading_comments: vec![],
1408 search: None,
1409 });
1410
1411 if has_recursive {
1412 top_with.recursive = true;
1413 }
1414
1415 if has_body_ctes {
1417 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
1418 for mut cte in top_with.ctes.drain(..) {
1419 if let Some(pos) = cte_body_collected
1421 .iter()
1422 .position(|(name, _)| *name == cte.alias.name)
1423 {
1424 let (_, mut nested) = cte_body_collected.remove(pos);
1425 for nested_cte in nested.iter_mut() {
1427 strip_with_from_cte_body(&mut nested_cte.this);
1428 }
1429 new_ctes.extend(nested);
1430 }
1431 strip_with_from_cte_body(&mut cte.this);
1433 new_ctes.push(cte);
1434 }
1435 top_with.ctes = new_ctes;
1436 }
1437
1438 top_with.ctes.extend(collected_ctes);
1440 }
1441
1442 Ok(Expression::Select(select))
1443 }
1444 other => Ok(other),
1445 }
1446}
1447
1448fn collect_ctes_from_cte_body(
1450 expr: &Expression,
1451 collected: &mut Vec<crate::expressions::Cte>,
1452 has_recursive: &mut bool,
1453) {
1454 if let Expression::Select(select) = expr {
1455 if let Some(ref with) = select.with {
1456 if with.recursive {
1457 *has_recursive = true;
1458 }
1459 for cte in &with.ctes {
1460 collect_ctes_from_cte_body(&cte.this, collected, has_recursive);
1462 collected.push(cte.clone());
1464 }
1465 }
1466 }
1467}
1468
1469fn strip_with_from_cte_body(expr: &mut Expression) {
1471 if let Expression::Select(ref mut select) = expr {
1472 select.with = None;
1473 }
1474}
1475
1476fn strip_nested_with_clauses(select: &mut Select, _is_top_level: bool) {
1478 if let Some(ref mut from) = select.from {
1480 for expr in from.expressions.iter_mut() {
1481 strip_with_from_expr(expr);
1482 }
1483 }
1484 for join in select.joins.iter_mut() {
1486 strip_with_from_expr(&mut join.this);
1487 }
1488 for expr in select.expressions.iter_mut() {
1490 strip_with_from_expr(expr);
1491 }
1492 if let Some(ref mut w) = select.where_clause {
1494 strip_with_from_expr(&mut w.this);
1495 }
1496}
1497
1498fn strip_with_from_expr(expr: &mut Expression) {
1499 match expr {
1500 Expression::Subquery(ref mut subquery) => {
1501 strip_with_from_inner_query(&mut subquery.this);
1502 }
1503 Expression::Alias(ref mut alias) => {
1504 strip_with_from_expr(&mut alias.this);
1505 }
1506 Expression::Select(ref mut select) => {
1507 select.with = None;
1509 strip_nested_with_clauses(select, false);
1511 }
1512 _ => {}
1513 }
1514}
1515
1516fn strip_with_from_inner_query(expr: &mut Expression) {
1517 if let Expression::Select(ref mut select) = expr {
1518 select.with = None;
1519 strip_nested_with_clauses(select, false);
1520 }
1521}
1522
1523fn collect_nested_ctes(
1525 expr: &Expression,
1526 collected: &mut Vec<crate::expressions::Cte>,
1527 has_recursive: &mut bool,
1528 is_top_level: bool,
1529) {
1530 match expr {
1531 Expression::Select(select) => {
1532 if !is_top_level {
1534 if let Some(ref with) = select.with {
1535 if with.recursive {
1536 *has_recursive = true;
1537 }
1538 collected.extend(with.ctes.clone());
1539 }
1540 }
1541
1542 if let Some(ref from) = select.from {
1544 for expr in &from.expressions {
1545 collect_nested_ctes(expr, collected, has_recursive, false);
1546 }
1547 }
1548
1549 for join in &select.joins {
1551 collect_nested_ctes(&join.this, collected, has_recursive, false);
1552 }
1553
1554 for sel_expr in &select.expressions {
1556 collect_nested_ctes(sel_expr, collected, has_recursive, false);
1557 }
1558
1559 if let Some(ref where_clause) = select.where_clause {
1561 collect_nested_ctes(&where_clause.this, collected, has_recursive, false);
1562 }
1563 }
1564 Expression::Subquery(subquery) => {
1565 collect_nested_ctes(&subquery.this, collected, has_recursive, false);
1567 }
1568 Expression::Alias(alias) => {
1569 collect_nested_ctes(&alias.this, collected, has_recursive, false);
1570 }
1571 _ => {}
1573 }
1574}
1575
1576pub fn eliminate_window_clause(expr: Expression) -> Result<Expression> {
1592 match expr {
1593 Expression::Select(mut select) => {
1594 if let Some(named_windows) = select.windows.take() {
1595 let window_map: std::collections::HashMap<String, &Over> = named_windows
1597 .iter()
1598 .map(|nw| (nw.name.name.to_lowercase(), &nw.spec))
1599 .collect();
1600
1601 select.expressions = select
1603 .expressions
1604 .into_iter()
1605 .map(|e| inline_window_refs(e, &window_map))
1606 .collect();
1607 }
1608 Ok(Expression::Select(select))
1609 }
1610 other => Ok(other),
1611 }
1612}
1613
1614fn inline_window_refs(
1616 expr: Expression,
1617 window_map: &std::collections::HashMap<String, &Over>,
1618) -> Expression {
1619 match expr {
1620 Expression::WindowFunction(mut wf) => {
1621 if let Some(ref name) = wf.over.window_name {
1623 let key = name.name.to_lowercase();
1624 if let Some(named_spec) = window_map.get(&key) {
1625 if wf.over.partition_by.is_empty() && !named_spec.partition_by.is_empty() {
1627 wf.over.partition_by = named_spec.partition_by.clone();
1628 }
1629 if wf.over.order_by.is_empty() && !named_spec.order_by.is_empty() {
1630 wf.over.order_by = named_spec.order_by.clone();
1631 }
1632 if wf.over.frame.is_none() && named_spec.frame.is_some() {
1633 wf.over.frame = named_spec.frame.clone();
1634 }
1635 wf.over.window_name = None;
1637 }
1638 }
1639 Expression::WindowFunction(wf)
1640 }
1641 Expression::Alias(mut alias) => {
1642 alias.this = inline_window_refs(alias.this, window_map);
1644 Expression::Alias(alias)
1645 }
1646 other => other,
1649 }
1650}
1651
1652pub fn eliminate_join_marks(expr: Expression) -> Result<Expression> {
1666 match expr {
1667 Expression::Select(mut select) => {
1668 let has_join_marks = select
1670 .where_clause
1671 .as_ref()
1672 .map_or(false, |w| contains_join_mark(&w.this));
1673
1674 if !has_join_marks {
1675 return Ok(Expression::Select(select));
1676 }
1677
1678 let from_tables: Vec<String> = select
1680 .from
1681 .as_ref()
1682 .map(|f| {
1683 f.expressions
1684 .iter()
1685 .filter_map(|e| get_table_name(e))
1686 .collect()
1687 })
1688 .unwrap_or_default();
1689
1690 let mut join_conditions: std::collections::HashMap<String, Vec<Expression>> =
1692 std::collections::HashMap::new();
1693 let mut remaining_conditions: Vec<Expression> = Vec::new();
1694
1695 if let Some(ref where_clause) = select.where_clause {
1696 extract_join_mark_conditions(
1697 &where_clause.this,
1698 &mut join_conditions,
1699 &mut remaining_conditions,
1700 );
1701 }
1702
1703 let mut new_joins = select.joins.clone();
1705 for (table_name, conditions) in join_conditions {
1706 let table_in_from = from_tables.contains(&table_name);
1708
1709 if table_in_from && !conditions.is_empty() {
1710 let combined_condition = conditions.into_iter().reduce(|a, b| {
1712 Expression::And(Box::new(BinaryOp {
1713 left: a,
1714 right: b,
1715 left_comments: vec![],
1716 operator_comments: vec![],
1717 trailing_comments: vec![],
1718 inferred_type: None,
1719 }))
1720 });
1721
1722 if let Some(ref mut from) = select.from {
1724 if let Some(pos) = from
1725 .expressions
1726 .iter()
1727 .position(|e| get_table_name(e).map_or(false, |n| n == table_name))
1728 {
1729 if from.expressions.len() > 1 {
1730 let join_table = from.expressions.remove(pos);
1731 new_joins.push(crate::expressions::Join {
1732 this: join_table,
1733 kind: JoinKind::Left,
1734 on: combined_condition,
1735 using: vec![],
1736 use_inner_keyword: false,
1737 use_outer_keyword: true,
1738 deferred_condition: false,
1739 join_hint: None,
1740 match_condition: None,
1741 pivots: Vec::new(),
1742 comments: Vec::new(),
1743 nesting_group: 0,
1744 directed: false,
1745 });
1746 }
1747 }
1748 }
1749 }
1750 }
1751
1752 select.joins = new_joins;
1753
1754 if remaining_conditions.is_empty() {
1756 select.where_clause = None;
1757 } else {
1758 let combined = remaining_conditions.into_iter().reduce(|a, b| {
1759 Expression::And(Box::new(BinaryOp {
1760 left: a,
1761 right: b,
1762 left_comments: vec![],
1763 operator_comments: vec![],
1764 trailing_comments: vec![],
1765 inferred_type: None,
1766 }))
1767 });
1768 select.where_clause = combined.map(|c| Where { this: c });
1769 }
1770
1771 clear_join_marks(&mut Expression::Select(select.clone()));
1773
1774 Ok(Expression::Select(select))
1775 }
1776 other => Ok(other),
1777 }
1778}
1779
1780fn contains_join_mark(expr: &Expression) -> bool {
1782 match expr {
1783 Expression::Column(col) => col.join_mark,
1784 Expression::And(op) | Expression::Or(op) => {
1785 contains_join_mark(&op.left) || contains_join_mark(&op.right)
1786 }
1787 Expression::Eq(op)
1788 | Expression::Neq(op)
1789 | Expression::Lt(op)
1790 | Expression::Lte(op)
1791 | Expression::Gt(op)
1792 | Expression::Gte(op) => contains_join_mark(&op.left) || contains_join_mark(&op.right),
1793 Expression::Not(op) => contains_join_mark(&op.this),
1794 _ => false,
1795 }
1796}
1797
1798fn get_table_name(expr: &Expression) -> Option<String> {
1800 match expr {
1801 Expression::Table(t) => Some(t.name.name.clone()),
1802 Expression::Alias(a) => Some(a.alias.name.clone()),
1803 _ => None,
1804 }
1805}
1806
1807fn extract_join_mark_conditions(
1809 expr: &Expression,
1810 join_conditions: &mut std::collections::HashMap<String, Vec<Expression>>,
1811 remaining: &mut Vec<Expression>,
1812) {
1813 match expr {
1814 Expression::And(op) => {
1815 extract_join_mark_conditions(&op.left, join_conditions, remaining);
1816 extract_join_mark_conditions(&op.right, join_conditions, remaining);
1817 }
1818 _ => {
1819 if let Some(table) = get_join_mark_table(expr) {
1820 join_conditions
1821 .entry(table)
1822 .or_insert_with(Vec::new)
1823 .push(expr.clone());
1824 } else {
1825 remaining.push(expr.clone());
1826 }
1827 }
1828 }
1829}
1830
1831fn get_join_mark_table(expr: &Expression) -> Option<String> {
1833 match expr {
1834 Expression::Eq(op)
1835 | Expression::Neq(op)
1836 | Expression::Lt(op)
1837 | Expression::Lte(op)
1838 | Expression::Gt(op)
1839 | Expression::Gte(op) => {
1840 if let Expression::Column(col) = &op.left {
1842 if col.join_mark {
1843 return col.table.as_ref().map(|t| t.name.clone());
1844 }
1845 }
1846 if let Expression::Column(col) = &op.right {
1847 if col.join_mark {
1848 return col.table.as_ref().map(|t| t.name.clone());
1849 }
1850 }
1851 None
1852 }
1853 _ => None,
1854 }
1855}
1856
1857fn clear_join_marks(expr: &mut Expression) {
1859 match expr {
1860 Expression::Column(col) => col.join_mark = false,
1861 Expression::Select(select) => {
1862 if let Some(ref mut w) = select.where_clause {
1863 clear_join_marks(&mut w.this);
1864 }
1865 for sel_expr in &mut select.expressions {
1866 clear_join_marks(sel_expr);
1867 }
1868 }
1869 Expression::And(op) | Expression::Or(op) => {
1870 clear_join_marks(&mut op.left);
1871 clear_join_marks(&mut op.right);
1872 }
1873 Expression::Eq(op)
1874 | Expression::Neq(op)
1875 | Expression::Lt(op)
1876 | Expression::Lte(op)
1877 | Expression::Gt(op)
1878 | Expression::Gte(op) => {
1879 clear_join_marks(&mut op.left);
1880 clear_join_marks(&mut op.right);
1881 }
1882 _ => {}
1883 }
1884}
1885
1886pub fn add_recursive_cte_column_names(expr: Expression) -> Result<Expression> {
1893 match expr {
1894 Expression::Select(mut select) => {
1895 if let Some(ref mut with) = select.with {
1896 if with.recursive {
1897 let mut counter = 0;
1898 for cte in &mut with.ctes {
1899 if cte.columns.is_empty() {
1900 if let Expression::Select(ref cte_select) = cte.this {
1902 let names: Vec<Identifier> = cte_select
1903 .expressions
1904 .iter()
1905 .map(|e| match e {
1906 Expression::Alias(a) => a.alias.clone(),
1907 Expression::Column(c) => c.name.clone(),
1908 _ => {
1909 counter += 1;
1910 Identifier::new(format!("_c_{}", counter))
1911 }
1912 })
1913 .collect();
1914 cte.columns = names;
1915 }
1916 }
1917 }
1918 }
1919 }
1920 Ok(Expression::Select(select))
1921 }
1922 other => Ok(other),
1923 }
1924}
1925
1926pub fn epoch_cast_to_ts(expr: Expression) -> Result<Expression> {
1933 match expr {
1934 Expression::Cast(mut cast) => {
1935 if let Expression::Literal(ref lit) = cast.this {
1936 if let Literal::String(ref s) = lit.as_ref() {
1937 if s.to_lowercase() == "epoch" {
1938 if is_temporal_type(&cast.to) {
1939 cast.this = Expression::Literal(Box::new(Literal::String(
1940 "1970-01-01 00:00:00".to_string(),
1941 )));
1942 }
1943 }
1944 }
1945 }
1946 Ok(Expression::Cast(cast))
1947 }
1948 Expression::TryCast(mut try_cast) => {
1949 if let Expression::Literal(ref lit) = try_cast.this {
1950 if let Literal::String(ref s) = lit.as_ref() {
1951 if s.to_lowercase() == "epoch" {
1952 if is_temporal_type(&try_cast.to) {
1953 try_cast.this = Expression::Literal(Box::new(Literal::String(
1954 "1970-01-01 00:00:00".to_string(),
1955 )));
1956 }
1957 }
1958 }
1959 }
1960 Ok(Expression::TryCast(try_cast))
1961 }
1962 other => Ok(other),
1963 }
1964}
1965
1966fn is_temporal_type(dt: &DataType) -> bool {
1968 matches!(
1969 dt,
1970 DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. }
1971 )
1972}
1973
1974pub fn ensure_bools(expr: Expression) -> Result<Expression> {
1999 let expr = ensure_bools_in_value_context(expr);
2000
2001 Ok(match expr {
2002 Expression::And(_) | Expression::Or(_) | Expression::Not(_) => ensure_bool_condition(expr),
2004 other => other,
2005 })
2006}
2007
2008fn ensure_bools_in_value_context(expr: Expression) -> Expression {
2012 match expr {
2013 Expression::Case(mut case) => {
2014 case.whens = case
2015 .whens
2016 .into_iter()
2017 .map(|(condition, result)| {
2018 let new_condition =
2019 ensure_bool_condition(ensure_bools_in_value_context(condition));
2020 let new_result = ensure_bools_in_value_context(result);
2021 (new_condition, new_result)
2022 })
2023 .collect();
2024 if let Some(else_expr) = case.else_ {
2025 case.else_ = Some(ensure_bools_in_value_context(else_expr));
2026 }
2027 Expression::Case(Box::new(*case))
2028 }
2029 Expression::Select(select) => Expression::Select(Box::new(ensure_bools_in_select(*select))),
2030 Expression::Subquery(mut subquery) => {
2031 subquery.this = ensure_bools_in_value_context(subquery.this);
2032 Expression::Subquery(subquery)
2033 }
2034 Expression::Union(mut union) => {
2035 let left = std::mem::replace(&mut union.left, Expression::null());
2036 let right = std::mem::replace(&mut union.right, Expression::null());
2037 union.left = ensure_bools_in_value_context(left);
2038 union.right = ensure_bools_in_value_context(right);
2039 if let Some(with) = union.with.take() {
2040 union.with = Some(ensure_bools_in_with(with));
2041 }
2042 Expression::Union(union)
2043 }
2044 Expression::Intersect(mut intersect) => {
2045 let left = std::mem::replace(&mut intersect.left, Expression::null());
2046 let right = std::mem::replace(&mut intersect.right, Expression::null());
2047 intersect.left = ensure_bools_in_value_context(left);
2048 intersect.right = ensure_bools_in_value_context(right);
2049 if let Some(with) = intersect.with.take() {
2050 intersect.with = Some(ensure_bools_in_with(with));
2051 }
2052 Expression::Intersect(intersect)
2053 }
2054 Expression::Except(mut except) => {
2055 let left = std::mem::replace(&mut except.left, Expression::null());
2056 let right = std::mem::replace(&mut except.right, Expression::null());
2057 except.left = ensure_bools_in_value_context(left);
2058 except.right = ensure_bools_in_value_context(right);
2059 if let Some(with) = except.with.take() {
2060 except.with = Some(ensure_bools_in_with(with));
2061 }
2062 Expression::Except(except)
2063 }
2064 Expression::Alias(mut alias) => {
2065 alias.this = ensure_bools_in_value_context(alias.this);
2066 Expression::Alias(alias)
2067 }
2068 Expression::Paren(mut paren) => {
2069 paren.this = ensure_bools_in_value_context(paren.this);
2070 Expression::Paren(paren)
2071 }
2072 other => other,
2073 }
2074}
2075
2076fn ensure_bools_in_select(mut select: Select) -> Select {
2077 select.expressions = select
2078 .expressions
2079 .into_iter()
2080 .map(ensure_bools_in_value_context)
2081 .collect();
2082
2083 if let Some(from) = select.from.take() {
2084 select.from = Some(crate::expressions::From {
2085 expressions: from
2086 .expressions
2087 .into_iter()
2088 .map(ensure_bools_in_value_context)
2089 .collect(),
2090 });
2091 }
2092
2093 select.joins = select.joins.into_iter().map(ensure_bools_in_join).collect();
2094
2095 if let Some(mut where_clause) = select.where_clause.take() {
2096 where_clause.this = ensure_bool_condition(ensure_bools_in_value_context(where_clause.this));
2097 select.where_clause = Some(where_clause);
2098 }
2099
2100 if let Some(mut having) = select.having.take() {
2101 having.this = ensure_bool_condition(ensure_bools_in_value_context(having.this));
2102 select.having = Some(having);
2103 }
2104
2105 if let Some(with) = select.with.take() {
2106 select.with = Some(ensure_bools_in_with(with));
2107 }
2108
2109 select
2110}
2111
2112fn ensure_bools_in_join(mut join: Join) -> Join {
2113 join.this = ensure_bools_in_value_context(join.this);
2114
2115 if let Some(on) = join.on.take() {
2116 join.on = Some(ensure_bool_condition(ensure_bools_in_value_context(on)));
2117 }
2118
2119 join.pivots = join
2120 .pivots
2121 .into_iter()
2122 .map(ensure_bools_in_value_context)
2123 .collect();
2124
2125 join
2126}
2127
2128fn ensure_bools_in_with(mut with: With) -> With {
2129 with.ctes = with
2130 .ctes
2131 .into_iter()
2132 .map(|mut cte| {
2133 cte.this = ensure_bools_in_value_context(cte.this);
2134 cte
2135 })
2136 .collect();
2137 with
2138}
2139
2140fn is_boolean_expression(expr: &Expression) -> bool {
2143 matches!(
2144 expr,
2145 Expression::Eq(_)
2146 | Expression::Neq(_)
2147 | Expression::Lt(_)
2148 | Expression::Lte(_)
2149 | Expression::Gt(_)
2150 | Expression::Gte(_)
2151 | Expression::Is(_)
2152 | Expression::IsNull(_)
2153 | Expression::IsTrue(_)
2154 | Expression::IsFalse(_)
2155 | Expression::Like(_)
2156 | Expression::ILike(_)
2157 | Expression::SimilarTo(_)
2158 | Expression::Glob(_)
2159 | Expression::RegexpLike(_)
2160 | Expression::In(_)
2161 | Expression::Between(_)
2162 | Expression::Exists(_)
2163 | Expression::And(_)
2164 | Expression::Or(_)
2165 | Expression::Not(_)
2166 | Expression::Any(_)
2167 | Expression::All(_)
2168 | Expression::EqualNull(_)
2169 )
2170}
2171
2172fn wrap_neq_zero(expr: Expression) -> Expression {
2174 Expression::Neq(Box::new(BinaryOp {
2175 left: expr,
2176 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
2177 left_comments: vec![],
2178 operator_comments: vec![],
2179 trailing_comments: vec![],
2180 inferred_type: None,
2181 }))
2182}
2183
2184fn ensure_bool_condition(expr: Expression) -> Expression {
2190 match expr {
2191 Expression::And(op) => {
2193 let new_op = BinaryOp {
2194 left: ensure_bool_condition(op.left.clone()),
2195 right: ensure_bool_condition(op.right.clone()),
2196 left_comments: op.left_comments.clone(),
2197 operator_comments: op.operator_comments.clone(),
2198 trailing_comments: op.trailing_comments.clone(),
2199 inferred_type: None,
2200 };
2201 Expression::And(Box::new(new_op))
2202 }
2203 Expression::Or(op) => {
2204 let new_op = BinaryOp {
2205 left: ensure_bool_condition(op.left.clone()),
2206 right: ensure_bool_condition(op.right.clone()),
2207 left_comments: op.left_comments.clone(),
2208 operator_comments: op.operator_comments.clone(),
2209 trailing_comments: op.trailing_comments.clone(),
2210 inferred_type: None,
2211 };
2212 Expression::Or(Box::new(new_op))
2213 }
2214 Expression::Not(op) => Expression::Not(Box::new(crate::expressions::UnaryOp {
2216 this: ensure_bool_condition(op.this.clone()),
2217 inferred_type: None,
2218 })),
2219 Expression::Paren(paren) => Expression::Paren(Box::new(crate::expressions::Paren {
2221 this: ensure_bool_condition(paren.this.clone()),
2222 trailing_comments: paren.trailing_comments.clone(),
2223 })),
2224 Expression::Boolean(BooleanLiteral { value: true }) => {
2226 Expression::Paren(Box::new(crate::expressions::Paren {
2227 this: Expression::Eq(Box::new(BinaryOp {
2228 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2229 right: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2230 left_comments: vec![],
2231 operator_comments: vec![],
2232 trailing_comments: vec![],
2233 inferred_type: None,
2234 })),
2235 trailing_comments: vec![],
2236 }))
2237 }
2238 Expression::Boolean(BooleanLiteral { value: false }) => {
2239 Expression::Paren(Box::new(crate::expressions::Paren {
2240 this: Expression::Eq(Box::new(BinaryOp {
2241 left: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2242 right: Expression::Literal(Box::new(Literal::Number("0".to_string()))),
2243 left_comments: vec![],
2244 operator_comments: vec![],
2245 trailing_comments: vec![],
2246 inferred_type: None,
2247 })),
2248 trailing_comments: vec![],
2249 }))
2250 }
2251 ref e if is_boolean_expression(e) => expr,
2253 _ => wrap_neq_zero(expr),
2256 }
2257}
2258
2259pub fn unqualify_columns(expr: Expression) -> Result<Expression> {
2265 Ok(unqualify_columns_recursive(expr))
2266}
2267
2268fn unqualify_columns_recursive(expr: Expression) -> Expression {
2270 match expr {
2271 Expression::Column(mut col) => {
2272 col.table = None;
2273 Expression::Column(col)
2274 }
2275 Expression::Select(mut select) => {
2276 select.expressions = select
2277 .expressions
2278 .into_iter()
2279 .map(unqualify_columns_recursive)
2280 .collect();
2281 if let Some(ref mut where_clause) = select.where_clause {
2282 where_clause.this = unqualify_columns_recursive(where_clause.this.clone());
2283 }
2284 if let Some(ref mut having) = select.having {
2285 having.this = unqualify_columns_recursive(having.this.clone());
2286 }
2287 if let Some(ref mut group_by) = select.group_by {
2288 group_by.expressions = group_by
2289 .expressions
2290 .iter()
2291 .cloned()
2292 .map(unqualify_columns_recursive)
2293 .collect();
2294 }
2295 if let Some(ref mut order_by) = select.order_by {
2296 order_by.expressions = order_by
2297 .expressions
2298 .iter()
2299 .map(|o| crate::expressions::Ordered {
2300 this: unqualify_columns_recursive(o.this.clone()),
2301 desc: o.desc,
2302 nulls_first: o.nulls_first,
2303 explicit_asc: o.explicit_asc,
2304 with_fill: o.with_fill.clone(),
2305 })
2306 .collect();
2307 }
2308 for join in &mut select.joins {
2309 if let Some(ref mut on) = join.on {
2310 *on = unqualify_columns_recursive(on.clone());
2311 }
2312 }
2313 Expression::Select(select)
2314 }
2315 Expression::Alias(mut alias) => {
2316 alias.this = unqualify_columns_recursive(alias.this);
2317 Expression::Alias(alias)
2318 }
2319 Expression::And(op) => Expression::And(Box::new(unqualify_binary_op(*op))),
2321 Expression::Or(op) => Expression::Or(Box::new(unqualify_binary_op(*op))),
2322 Expression::Eq(op) => Expression::Eq(Box::new(unqualify_binary_op(*op))),
2323 Expression::Neq(op) => Expression::Neq(Box::new(unqualify_binary_op(*op))),
2324 Expression::Lt(op) => Expression::Lt(Box::new(unqualify_binary_op(*op))),
2325 Expression::Lte(op) => Expression::Lte(Box::new(unqualify_binary_op(*op))),
2326 Expression::Gt(op) => Expression::Gt(Box::new(unqualify_binary_op(*op))),
2327 Expression::Gte(op) => Expression::Gte(Box::new(unqualify_binary_op(*op))),
2328 Expression::Add(op) => Expression::Add(Box::new(unqualify_binary_op(*op))),
2329 Expression::Sub(op) => Expression::Sub(Box::new(unqualify_binary_op(*op))),
2330 Expression::Mul(op) => Expression::Mul(Box::new(unqualify_binary_op(*op))),
2331 Expression::Div(op) => Expression::Div(Box::new(unqualify_binary_op(*op))),
2332 Expression::Function(mut func) => {
2334 func.args = func
2335 .args
2336 .into_iter()
2337 .map(unqualify_columns_recursive)
2338 .collect();
2339 Expression::Function(func)
2340 }
2341 Expression::AggregateFunction(mut func) => {
2342 func.args = func
2343 .args
2344 .into_iter()
2345 .map(unqualify_columns_recursive)
2346 .collect();
2347 Expression::AggregateFunction(func)
2348 }
2349 Expression::Case(mut case) => {
2350 case.whens = case
2351 .whens
2352 .into_iter()
2353 .map(|(cond, result)| {
2354 (
2355 unqualify_columns_recursive(cond),
2356 unqualify_columns_recursive(result),
2357 )
2358 })
2359 .collect();
2360 if let Some(else_expr) = case.else_ {
2361 case.else_ = Some(unqualify_columns_recursive(else_expr));
2362 }
2363 Expression::Case(case)
2364 }
2365 other => other,
2367 }
2368}
2369
2370fn unqualify_binary_op(mut op: BinaryOp) -> BinaryOp {
2372 op.left = unqualify_columns_recursive(op.left);
2373 op.right = unqualify_columns_recursive(op.right);
2374 op
2375}
2376
2377pub fn unnest_generate_date_array_using_recursive_cte(expr: Expression) -> Result<Expression> {
2397 match expr {
2398 Expression::Select(mut select) => {
2399 let mut cte_count = 0;
2400 let mut new_ctes: Vec<crate::expressions::Cte> = Vec::new();
2401
2402 if let Some(ref mut with) = select.with {
2404 for cte in &mut with.ctes {
2405 process_expression_for_gda(&mut cte.this, &mut cte_count, &mut new_ctes);
2406 }
2407 }
2408
2409 if let Some(ref mut from) = select.from {
2411 for table_expr in &mut from.expressions {
2412 if let Some((cte, replacement)) =
2413 try_convert_generate_date_array(table_expr, &mut cte_count)
2414 {
2415 new_ctes.push(cte);
2416 *table_expr = replacement;
2417 }
2418 }
2419 }
2420
2421 for join in &mut select.joins {
2423 if let Some((cte, replacement)) =
2424 try_convert_generate_date_array(&join.this, &mut cte_count)
2425 {
2426 new_ctes.push(cte);
2427 join.this = replacement;
2428 }
2429 }
2430
2431 if !new_ctes.is_empty() {
2433 let with_clause = select.with.get_or_insert_with(|| crate::expressions::With {
2434 ctes: Vec::new(),
2435 recursive: true, leading_comments: vec![],
2437 search: None,
2438 });
2439 with_clause.recursive = true;
2440
2441 let mut all_ctes = new_ctes;
2443 all_ctes.append(&mut with_clause.ctes);
2444 with_clause.ctes = all_ctes;
2445 }
2446
2447 Ok(Expression::Select(select))
2448 }
2449 other => Ok(other),
2450 }
2451}
2452
2453fn process_expression_for_gda(
2456 expr: &mut Expression,
2457 cte_count: &mut usize,
2458 new_ctes: &mut Vec<crate::expressions::Cte>,
2459) {
2460 match expr {
2461 Expression::Select(ref mut select) => {
2462 if let Some(ref mut from) = select.from {
2464 for table_expr in &mut from.expressions {
2465 if let Some((cte, replacement)) =
2466 try_convert_generate_date_array(table_expr, cte_count)
2467 {
2468 new_ctes.push(cte);
2469 *table_expr = replacement;
2470 }
2471 }
2472 }
2473 for join in &mut select.joins {
2475 if let Some((cte, replacement)) =
2476 try_convert_generate_date_array(&join.this, cte_count)
2477 {
2478 new_ctes.push(cte);
2479 join.this = replacement;
2480 }
2481 }
2482 }
2483 Expression::Union(ref mut u) => {
2484 process_expression_for_gda(&mut u.left, cte_count, new_ctes);
2485 process_expression_for_gda(&mut u.right, cte_count, new_ctes);
2486 }
2487 Expression::Subquery(ref mut sq) => {
2488 process_expression_for_gda(&mut sq.this, cte_count, new_ctes);
2489 }
2490 _ => {}
2491 }
2492}
2493
2494fn try_convert_generate_date_array(
2497 expr: &Expression,
2498 cte_count: &mut usize,
2499) -> Option<(crate::expressions::Cte, Expression)> {
2500 try_convert_generate_date_array_with_name(expr, cte_count, None)
2501}
2502
2503fn try_convert_generate_date_array_with_name(
2504 expr: &Expression,
2505 cte_count: &mut usize,
2506 column_name_override: Option<&str>,
2507) -> Option<(crate::expressions::Cte, Expression)> {
2508 fn extract_gda_args(
2510 inner: &Expression,
2511 ) -> Option<(&Expression, &Expression, Option<&Expression>)> {
2512 match inner {
2513 Expression::GenerateDateArray(gda) => {
2514 let start = gda.start.as_ref()?;
2515 let end = gda.end.as_ref()?;
2516 let step = gda.step.as_deref();
2517 Some((start, end, step))
2518 }
2519 Expression::GenerateSeries(gs) => {
2520 let start = gs.start.as_deref()?;
2521 let end = gs.end.as_deref()?;
2522 let step = gs.step.as_deref();
2523 Some((start, end, step))
2524 }
2525 Expression::Function(f) if f.name.eq_ignore_ascii_case("GENERATE_DATE_ARRAY") => {
2526 if f.args.len() >= 2 {
2527 let start = &f.args[0];
2528 let end = &f.args[1];
2529 let step = f.args.get(2);
2530 Some((start, end, step))
2531 } else {
2532 None
2533 }
2534 }
2535 _ => None,
2536 }
2537 }
2538
2539 if let Expression::Unnest(unnest) = expr {
2541 if let Some((start, end, step_opt)) = extract_gda_args(&unnest.this) {
2542 let start = start;
2543 let end = end;
2544 let step: Option<&Expression> = step_opt;
2545
2546 let cte_name = if *cte_count == 0 {
2548 "_generated_dates".to_string()
2549 } else {
2550 format!("_generated_dates_{}", cte_count)
2551 };
2552 *cte_count += 1;
2553
2554 let column_name =
2555 Identifier::new(column_name_override.unwrap_or("date_value").to_string());
2556
2557 let cast_to_date = |expr: &Expression| -> Expression {
2559 match expr {
2560 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
2561 if let Expression::Literal(lit) = expr {
2563 if let Literal::Date(d) = lit.as_ref() {
2564 Expression::Cast(Box::new(Cast {
2565 this: Expression::Literal(Box::new(Literal::String(d.clone()))),
2566 to: DataType::Date,
2567 trailing_comments: vec![],
2568 double_colon_syntax: false,
2569 format: None,
2570 default: None,
2571 inferred_type: None,
2572 }))
2573 } else {
2574 expr.clone()
2575 }
2576 } else {
2577 unreachable!()
2578 }
2579 }
2580 Expression::Cast(c) if matches!(c.to, DataType::Date) => expr.clone(),
2581 _ => Expression::Cast(Box::new(Cast {
2582 this: expr.clone(),
2583 to: DataType::Date,
2584 trailing_comments: vec![],
2585 double_colon_syntax: false,
2586 format: None,
2587 default: None,
2588 inferred_type: None,
2589 })),
2590 }
2591 };
2592
2593 let base_select = Select {
2595 expressions: vec![Expression::Alias(Box::new(crate::expressions::Alias {
2596 this: cast_to_date(start),
2597 alias: column_name.clone(),
2598 column_aliases: vec![],
2599 alias_explicit_as: false,
2600 alias_keyword: None,
2601 pre_alias_comments: vec![],
2602 trailing_comments: vec![],
2603 inferred_type: None,
2604 }))],
2605 ..Select::new()
2606 };
2607
2608 let normalize_interval = |expr: &Expression| -> Expression {
2610 if let Expression::Interval(ref iv) = expr {
2611 let mut iv_clone = iv.as_ref().clone();
2612 if let Some(Expression::Literal(ref lit)) = iv_clone.this {
2613 if let Literal::String(ref s) = lit.as_ref() {
2614 if s.parse::<f64>().is_ok() {
2616 iv_clone.this =
2617 Some(Expression::Literal(Box::new(Literal::Number(s.clone()))));
2618 }
2619 }
2620 }
2621 Expression::Interval(Box::new(iv_clone))
2622 } else {
2623 expr.clone()
2624 }
2625 };
2626
2627 let normalized_step = step.map(|s| normalize_interval(s)).unwrap_or_else(|| {
2630 Expression::Interval(Box::new(crate::expressions::Interval {
2631 this: Some(Expression::Literal(Box::new(Literal::Number(
2632 "1".to_string(),
2633 )))),
2634 unit: Some(crate::expressions::IntervalUnitSpec::Simple {
2635 unit: crate::expressions::IntervalUnit::Day,
2636 use_plural: false,
2637 }),
2638 }))
2639 });
2640
2641 let (add_unit, add_count) = extract_interval_unit_and_count(&normalized_step);
2643
2644 let date_add_expr = Expression::DateAdd(Box::new(crate::expressions::DateAddFunc {
2645 this: Expression::Column(Box::new(crate::expressions::Column {
2646 name: column_name.clone(),
2647 table: None,
2648 join_mark: false,
2649 trailing_comments: vec![],
2650 span: None,
2651 inferred_type: None,
2652 })),
2653 interval: add_count,
2654 unit: add_unit,
2655 }));
2656
2657 let cast_date_add = Expression::Cast(Box::new(Cast {
2658 this: date_add_expr.clone(),
2659 to: DataType::Date,
2660 trailing_comments: vec![],
2661 double_colon_syntax: false,
2662 format: None,
2663 default: None,
2664 inferred_type: None,
2665 }));
2666
2667 let recursive_select = Select {
2668 expressions: vec![cast_date_add.clone()],
2669 from: Some(From {
2670 expressions: vec![Expression::Table(Box::new(
2671 crate::expressions::TableRef::new(&cte_name),
2672 ))],
2673 }),
2674 where_clause: Some(Where {
2675 this: Expression::Lte(Box::new(BinaryOp {
2676 left: cast_date_add,
2677 right: cast_to_date(end),
2678 left_comments: vec![],
2679 operator_comments: vec![],
2680 trailing_comments: vec![],
2681 inferred_type: None,
2682 })),
2683 }),
2684 ..Select::new()
2685 };
2686
2687 let union = crate::expressions::Union {
2689 left: Expression::Select(Box::new(base_select)),
2690 right: Expression::Select(Box::new(recursive_select)),
2691 all: true, distinct: false,
2693 with: None,
2694 order_by: None,
2695 limit: None,
2696 offset: None,
2697 distribute_by: None,
2698 sort_by: None,
2699 cluster_by: None,
2700 by_name: false,
2701 side: None,
2702 kind: None,
2703 corresponding: false,
2704 strict: false,
2705 on_columns: Vec::new(),
2706 };
2707
2708 let cte = crate::expressions::Cte {
2710 this: Expression::Union(Box::new(union)),
2711 alias: Identifier::new(cte_name.clone()),
2712 columns: vec![column_name.clone()],
2713 materialized: None,
2714 key_expressions: Vec::new(),
2715 alias_first: true,
2716 comments: Vec::new(),
2717 };
2718
2719 let replacement_select = Select {
2721 expressions: vec![Expression::Column(Box::new(crate::expressions::Column {
2722 name: column_name,
2723 table: None,
2724 join_mark: false,
2725 trailing_comments: vec![],
2726 span: None,
2727 inferred_type: None,
2728 }))],
2729 from: Some(From {
2730 expressions: vec![Expression::Table(Box::new(
2731 crate::expressions::TableRef::new(&cte_name),
2732 ))],
2733 }),
2734 ..Select::new()
2735 };
2736
2737 let replacement = Expression::Subquery(Box::new(Subquery {
2738 this: Expression::Select(Box::new(replacement_select)),
2739 alias: Some(Identifier::new(cte_name)),
2740 column_aliases: vec![],
2741 alias_explicit_as: false,
2742 alias_keyword: None,
2743 order_by: None,
2744 limit: None,
2745 offset: None,
2746 distribute_by: None,
2747 sort_by: None,
2748 cluster_by: None,
2749 lateral: false,
2750 modifiers_inside: false,
2751 trailing_comments: vec![],
2752 inferred_type: None,
2753 }));
2754
2755 return Some((cte, replacement));
2756 }
2757 }
2758
2759 if let Expression::Alias(alias) = expr {
2761 let col_name = alias.column_aliases.first().map(|id| id.name.as_str());
2763 if let Some((cte, replacement)) =
2764 try_convert_generate_date_array_with_name(&alias.this, cte_count, col_name)
2765 {
2766 if col_name.is_some() {
2769 return Some((cte, replacement));
2770 }
2771 let new_alias = Expression::Alias(Box::new(crate::expressions::Alias {
2772 this: replacement,
2773 alias: alias.alias.clone(),
2774 column_aliases: alias.column_aliases.clone(),
2775 alias_explicit_as: false,
2776 alias_keyword: None,
2777 pre_alias_comments: alias.pre_alias_comments.clone(),
2778 trailing_comments: alias.trailing_comments.clone(),
2779 inferred_type: None,
2780 }));
2781 return Some((cte, new_alias));
2782 }
2783 }
2784
2785 None
2786}
2787
2788fn extract_interval_unit_and_count(
2793 expr: &Expression,
2794) -> (crate::expressions::IntervalUnit, Expression) {
2795 use crate::expressions::{IntervalUnit, IntervalUnitSpec, Literal};
2796
2797 if let Expression::Interval(ref iv) = expr {
2798 if let Some(ref unit_spec) = iv.unit {
2800 if let IntervalUnitSpec::Simple { unit, .. } = unit_spec {
2801 let count = match &iv.this {
2802 Some(e) => e.clone(),
2803 None => Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2804 };
2805 return (unit.clone(), count);
2806 }
2807 }
2808
2809 if let Some(ref val_expr) = iv.this {
2811 match val_expr {
2812 Expression::Literal(lit)
2813 if matches!(lit.as_ref(), Literal::String(_) | Literal::Number(_)) =>
2814 {
2815 let s = match lit.as_ref() {
2816 Literal::String(s) | Literal::Number(s) => s,
2817 _ => unreachable!(),
2818 };
2819 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
2821 if parts.len() == 2 {
2822 let count_str = parts[0].trim();
2823 let unit_str = parts[1].trim().to_uppercase();
2824 let unit = match unit_str.as_str() {
2825 "YEAR" | "YEARS" => IntervalUnit::Year,
2826 "QUARTER" | "QUARTERS" => IntervalUnit::Quarter,
2827 "MONTH" | "MONTHS" => IntervalUnit::Month,
2828 "WEEK" | "WEEKS" => IntervalUnit::Week,
2829 "DAY" | "DAYS" => IntervalUnit::Day,
2830 "HOUR" | "HOURS" => IntervalUnit::Hour,
2831 "MINUTE" | "MINUTES" => IntervalUnit::Minute,
2832 "SECOND" | "SECONDS" => IntervalUnit::Second,
2833 "MILLISECOND" | "MILLISECONDS" => IntervalUnit::Millisecond,
2834 "MICROSECOND" | "MICROSECONDS" => IntervalUnit::Microsecond,
2835 _ => IntervalUnit::Day,
2836 };
2837 return (
2838 unit,
2839 Expression::Literal(Box::new(Literal::Number(count_str.to_string()))),
2840 );
2841 }
2842 if s.parse::<f64>().is_ok() {
2844 return (
2845 IntervalUnit::Day,
2846 Expression::Literal(Box::new(Literal::Number(s.clone()))),
2847 );
2848 }
2849 }
2850 _ => {}
2851 }
2852 }
2853
2854 (
2856 IntervalUnit::Day,
2857 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2858 )
2859 } else {
2860 (
2861 IntervalUnit::Day,
2862 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
2863 )
2864 }
2865}
2866
2867pub fn no_ilike_sql(expr: Expression) -> Result<Expression> {
2880 match expr {
2881 Expression::ILike(ilike) => {
2882 let lower_left = Expression::Function(Box::new(crate::expressions::Function {
2884 name: "LOWER".to_string(),
2885 args: vec![ilike.left],
2886 distinct: false,
2887 trailing_comments: vec![],
2888 use_bracket_syntax: false,
2889 no_parens: false,
2890 quoted: false,
2891 span: None,
2892 inferred_type: None,
2893 }));
2894
2895 let lower_right = Expression::Function(Box::new(crate::expressions::Function {
2896 name: "LOWER".to_string(),
2897 args: vec![ilike.right],
2898 distinct: false,
2899 trailing_comments: vec![],
2900 use_bracket_syntax: false,
2901 no_parens: false,
2902 quoted: false,
2903 span: None,
2904 inferred_type: None,
2905 }));
2906
2907 Ok(Expression::Like(Box::new(crate::expressions::LikeOp {
2908 left: lower_left,
2909 right: lower_right,
2910 escape: ilike.escape,
2911 quantifier: ilike.quantifier,
2912 inferred_type: None,
2913 })))
2914 }
2915 other => Ok(other),
2916 }
2917}
2918
2919pub fn no_trycast_sql(expr: Expression) -> Result<Expression> {
2927 match expr {
2928 Expression::TryCast(try_cast) => Ok(Expression::Cast(try_cast)),
2929 other => Ok(other),
2930 }
2931}
2932
2933pub fn no_safe_cast_sql(expr: Expression) -> Result<Expression> {
2938 match expr {
2939 Expression::SafeCast(safe_cast) => Ok(Expression::Cast(safe_cast)),
2940 other => Ok(other),
2941 }
2942}
2943
2944pub fn no_comment_column_constraint(expr: Expression) -> Result<Expression> {
2951 Ok(expr)
2953}
2954
2955pub fn unnest_generate_series(expr: Expression) -> Result<Expression> {
2969 match expr {
2972 Expression::Table(ref table) => {
2973 if table.name.name.to_uppercase() == "GENERATE_SERIES" {
2976 let unnest = Expression::Unnest(Box::new(UnnestFunc {
2978 this: expr.clone(),
2979 expressions: Vec::new(),
2980 with_ordinality: false,
2981 alias: None,
2982 offset_alias: None,
2983 }));
2984
2985 return Ok(Expression::Alias(Box::new(crate::expressions::Alias {
2987 this: unnest,
2988 alias: Identifier::new("_u".to_string()),
2989 column_aliases: vec![],
2990 alias_explicit_as: false,
2991 alias_keyword: None,
2992 pre_alias_comments: vec![],
2993 trailing_comments: vec![],
2994 inferred_type: None,
2995 })));
2996 }
2997 Ok(expr)
2998 }
2999 Expression::GenerateSeries(gs) => {
3000 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3002 this: Expression::GenerateSeries(gs),
3003 expressions: Vec::new(),
3004 with_ordinality: false,
3005 alias: None,
3006 offset_alias: None,
3007 }));
3008 Ok(unnest)
3009 }
3010 other => Ok(other),
3011 }
3012}
3013
3014pub fn unwrap_unnest_generate_series_for_postgres(expr: Expression) -> Result<Expression> {
3025 use crate::dialects::transform_recursive;
3026 transform_recursive(expr, &unwrap_unnest_generate_series_single)
3027}
3028
3029fn unwrap_unnest_generate_series_single(expr: Expression) -> Result<Expression> {
3030 use crate::expressions::*;
3031 match expr {
3033 Expression::Select(mut select) => {
3034 if let Some(ref mut from) = select.from {
3036 for table_expr in &mut from.expressions {
3037 if let Some(replacement) = try_unwrap_unnest_gen_series(table_expr) {
3038 *table_expr = replacement;
3039 }
3040 }
3041 }
3042 for join in &mut select.joins {
3044 if let Some(replacement) = try_unwrap_unnest_gen_series(&join.this) {
3045 join.this = replacement;
3046 }
3047 }
3048 Ok(Expression::Select(select))
3049 }
3050 other => Ok(other),
3051 }
3052}
3053
3054fn try_unwrap_unnest_gen_series(expr: &Expression) -> Option<Expression> {
3057 use crate::expressions::*;
3058
3059 let gen_series = match expr {
3061 Expression::Unnest(unnest) => {
3062 if let Expression::GenerateSeries(ref gs) = unnest.this {
3063 Some(gs.as_ref().clone())
3064 } else {
3065 None
3066 }
3067 }
3068 Expression::Alias(alias) => {
3069 if let Expression::Unnest(ref unnest) = alias.this {
3070 if let Expression::GenerateSeries(ref gs) = unnest.this {
3071 Some(gs.as_ref().clone())
3072 } else {
3073 None
3074 }
3075 } else {
3076 None
3077 }
3078 }
3079 _ => None,
3080 };
3081
3082 let gs = gen_series?;
3083
3084 let value_col = Expression::boxed_column(Column {
3086 name: Identifier::new("value".to_string()),
3087 table: None,
3088 join_mark: false,
3089 trailing_comments: vec![],
3090 span: None,
3091 inferred_type: None,
3092 });
3093
3094 let cast_value = Expression::Cast(Box::new(Cast {
3095 this: value_col,
3096 to: DataType::Date,
3097 trailing_comments: vec![],
3098 double_colon_syntax: false,
3099 format: None,
3100 default: None,
3101 inferred_type: None,
3102 }));
3103
3104 let gen_series_expr = Expression::GenerateSeries(Box::new(gs));
3105
3106 let gen_series_aliased = Expression::Alias(Box::new(Alias {
3108 this: gen_series_expr,
3109 alias: Identifier::new("_t".to_string()),
3110 column_aliases: vec![Identifier::new("value".to_string())],
3111 alias_explicit_as: false,
3112 alias_keyword: None,
3113 pre_alias_comments: vec![],
3114 trailing_comments: vec![],
3115 inferred_type: None,
3116 }));
3117
3118 let mut inner_select = Select::new();
3119 inner_select.expressions = vec![cast_value];
3120 inner_select.from = Some(From {
3121 expressions: vec![gen_series_aliased],
3122 });
3123
3124 let inner_select_expr = Expression::Select(Box::new(inner_select));
3125
3126 let subquery = Expression::Subquery(Box::new(Subquery {
3127 this: inner_select_expr,
3128 alias: None,
3129 column_aliases: vec![],
3130 alias_explicit_as: false,
3131 alias_keyword: None,
3132 order_by: None,
3133 limit: None,
3134 offset: None,
3135 distribute_by: None,
3136 sort_by: None,
3137 cluster_by: None,
3138 lateral: false,
3139 modifiers_inside: false,
3140 trailing_comments: vec![],
3141 inferred_type: None,
3142 }));
3143
3144 Some(Expression::Alias(Box::new(Alias {
3146 this: subquery,
3147 alias: Identifier::new("_unnested_generate_series".to_string()),
3148 column_aliases: vec![],
3149 alias_explicit_as: false,
3150 alias_keyword: None,
3151 pre_alias_comments: vec![],
3152 trailing_comments: vec![],
3153 inferred_type: None,
3154 })))
3155}
3156
3157pub fn expand_between_in_delete(expr: Expression) -> Result<Expression> {
3165 match expr {
3166 Expression::Delete(mut delete) => {
3167 if let Some(ref mut where_clause) = delete.where_clause {
3169 where_clause.this = expand_between_recursive(where_clause.this.clone());
3170 }
3171 Ok(Expression::Delete(delete))
3172 }
3173 other => Ok(other),
3174 }
3175}
3176
3177fn expand_between_recursive(expr: Expression) -> Expression {
3179 match expr {
3180 Expression::Between(between) => {
3183 let this = expand_between_recursive(between.this.clone());
3184 let low = expand_between_recursive(between.low);
3185 let high = expand_between_recursive(between.high);
3186
3187 if between.not {
3188 Expression::Or(Box::new(BinaryOp::new(
3190 Expression::Lt(Box::new(BinaryOp::new(this.clone(), low))),
3191 Expression::Gt(Box::new(BinaryOp::new(this, high))),
3192 )))
3193 } else {
3194 Expression::And(Box::new(BinaryOp::new(
3196 Expression::Gte(Box::new(BinaryOp::new(this.clone(), low))),
3197 Expression::Lte(Box::new(BinaryOp::new(this, high))),
3198 )))
3199 }
3200 }
3201
3202 Expression::And(mut op) => {
3204 op.left = expand_between_recursive(op.left);
3205 op.right = expand_between_recursive(op.right);
3206 Expression::And(op)
3207 }
3208 Expression::Or(mut op) => {
3209 op.left = expand_between_recursive(op.left);
3210 op.right = expand_between_recursive(op.right);
3211 Expression::Or(op)
3212 }
3213 Expression::Not(mut op) => {
3214 op.this = expand_between_recursive(op.this);
3215 Expression::Not(op)
3216 }
3217
3218 Expression::Paren(mut paren) => {
3220 paren.this = expand_between_recursive(paren.this);
3221 Expression::Paren(paren)
3222 }
3223
3224 other => other,
3226 }
3227}
3228
3229pub fn pushdown_cte_column_names(expr: Expression) -> Result<Expression> {
3238 match expr {
3239 Expression::Select(mut select) => {
3240 if let Some(ref mut with) = select.with {
3241 for cte in &mut with.ctes {
3242 if !cte.columns.is_empty() {
3243 let is_star = matches!(&cte.this, Expression::Select(s) if
3245 s.expressions.len() == 1 && matches!(&s.expressions[0], Expression::Star(_)));
3246
3247 if is_star {
3248 cte.columns.clear();
3250 continue;
3251 }
3252
3253 let column_names: Vec<Identifier> = cte.columns.drain(..).collect();
3255
3256 if let Expression::Select(ref mut inner_select) = cte.this {
3258 let new_exprs: Vec<Expression> = inner_select
3259 .expressions
3260 .drain(..)
3261 .zip(
3262 column_names
3263 .into_iter()
3264 .chain(std::iter::repeat_with(|| Identifier::new(""))),
3265 )
3266 .map(|(expr, col_name)| {
3267 if col_name.name.is_empty() {
3268 return expr;
3269 }
3270 match expr {
3272 Expression::Alias(mut a) => {
3273 a.alias = col_name;
3274 Expression::Alias(a)
3275 }
3276 other => {
3277 Expression::Alias(Box::new(crate::expressions::Alias {
3278 this: other,
3279 alias: col_name,
3280 column_aliases: Vec::new(),
3281 alias_explicit_as: false,
3282 alias_keyword: None,
3283 pre_alias_comments: Vec::new(),
3284 trailing_comments: Vec::new(),
3285 inferred_type: None,
3286 }))
3287 }
3288 }
3289 })
3290 .collect();
3291 inner_select.expressions = new_exprs;
3292 }
3293 }
3294 }
3295 }
3296 Ok(Expression::Select(select))
3297 }
3298 other => Ok(other),
3299 }
3300}
3301
3302pub fn simplify_nested_paren_values(expr: Expression) -> Result<Expression> {
3306 match expr {
3307 Expression::Select(mut select) => {
3308 if let Some(ref mut from) = select.from {
3309 for from_item in from.expressions.iter_mut() {
3310 simplify_paren_values_in_from(from_item);
3311 }
3312 }
3313 Ok(Expression::Select(select))
3314 }
3315 other => Ok(other),
3316 }
3317}
3318
3319fn simplify_paren_values_in_from(expr: &mut Expression) {
3320 let replacement = match expr {
3322 Expression::Subquery(ref subquery) => {
3324 if let Expression::Paren(ref paren) = subquery.this {
3325 if matches!(&paren.this, Expression::Values(_)) {
3326 let mut new_sub = subquery.as_ref().clone();
3327 new_sub.this = paren.this.clone();
3328 Some(Expression::Subquery(Box::new(new_sub)))
3329 } else {
3330 None
3331 }
3332 } else {
3333 None
3334 }
3335 }
3336 Expression::Paren(ref outer_paren) => {
3339 if let Expression::Subquery(ref subquery) = outer_paren.this {
3340 if matches!(&subquery.this, Expression::Values(_)) {
3342 Some(outer_paren.this.clone())
3343 }
3344 else if let Expression::Paren(ref paren) = subquery.this {
3346 if matches!(&paren.this, Expression::Values(_)) {
3347 let mut new_sub = subquery.as_ref().clone();
3348 new_sub.this = paren.this.clone();
3349 Some(Expression::Subquery(Box::new(new_sub)))
3350 } else {
3351 None
3352 }
3353 } else {
3354 None
3355 }
3356 } else if let Expression::Paren(ref inner_paren) = outer_paren.this {
3357 if matches!(&inner_paren.this, Expression::Values(_)) {
3358 Some(outer_paren.this.clone())
3359 } else {
3360 None
3361 }
3362 } else {
3363 None
3364 }
3365 }
3366 _ => None,
3367 };
3368 if let Some(new_expr) = replacement {
3369 *expr = new_expr;
3370 }
3371}
3372
3373pub fn add_auto_table_alias(expr: Expression) -> Result<Expression> {
3377 match expr {
3378 Expression::Select(mut select) => {
3379 if let Some(ref mut from) = select.from {
3381 let mut counter = 0usize;
3382 for from_item in from.expressions.iter_mut() {
3383 add_auto_alias_to_from_item(from_item, &mut counter);
3384 }
3385 }
3386 Ok(Expression::Select(select))
3387 }
3388 other => Ok(other),
3389 }
3390}
3391
3392fn add_auto_alias_to_from_item(expr: &mut Expression, counter: &mut usize) {
3393 use crate::expressions::Identifier;
3394
3395 match expr {
3396 Expression::Alias(ref mut alias) => {
3397 if alias.alias.name.is_empty() && !alias.column_aliases.is_empty() {
3399 alias.alias = Identifier::new(format!("_t{}", counter));
3400 *counter += 1;
3401 }
3402 }
3403 _ => {}
3404 }
3405}
3406
3407pub fn propagate_struct_field_names(expr: Expression) -> Result<Expression> {
3417 use crate::dialects::transform_recursive;
3418 transform_recursive(expr, &propagate_struct_names_in_expr)
3419}
3420
3421fn propagate_struct_names_in_expr(expr: Expression) -> Result<Expression> {
3422 use crate::expressions::{Alias, ArrayConstructor, Function, Identifier};
3423
3424 fn propagate_in_elements(elements: &[Expression]) -> Option<Vec<Expression>> {
3426 if elements.len() <= 1 {
3427 return None;
3428 }
3429 if let Some(Expression::Function(ref first_struct)) = elements.first() {
3431 if first_struct.name.eq_ignore_ascii_case("STRUCT") {
3432 let field_names: Vec<Option<String>> = first_struct
3434 .args
3435 .iter()
3436 .map(|arg| {
3437 if let Expression::Alias(a) = arg {
3438 Some(a.alias.name.clone())
3439 } else {
3440 None
3441 }
3442 })
3443 .collect();
3444
3445 if field_names.iter().any(|n| n.is_some()) {
3447 let mut new_elements = Vec::with_capacity(elements.len());
3448 new_elements.push(elements[0].clone());
3449
3450 for elem in &elements[1..] {
3451 if let Expression::Function(ref s) = elem {
3452 if s.name.eq_ignore_ascii_case("STRUCT")
3453 && s.args.len() == field_names.len()
3454 {
3455 let all_unnamed =
3457 s.args.iter().all(|a| !matches!(a, Expression::Alias(_)));
3458 if all_unnamed {
3459 let new_args: Vec<Expression> = s
3461 .args
3462 .iter()
3463 .zip(field_names.iter())
3464 .map(|(val, name)| {
3465 if let Some(n) = name {
3466 Expression::Alias(Box::new(Alias::new(
3467 val.clone(),
3468 Identifier::new(n.clone()),
3469 )))
3470 } else {
3471 val.clone()
3472 }
3473 })
3474 .collect();
3475 new_elements.push(Expression::Function(Box::new(
3476 Function::new("STRUCT".to_string(), new_args),
3477 )));
3478 continue;
3479 }
3480 }
3481 }
3482 new_elements.push(elem.clone());
3483 }
3484
3485 return Some(new_elements);
3486 }
3487 }
3488 }
3489 None
3490 }
3491
3492 if let Expression::Array(ref arr) = expr {
3494 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
3495 return Ok(Expression::Array(Box::new(crate::expressions::Array {
3496 expressions: new_elements,
3497 })));
3498 }
3499 }
3500
3501 if let Expression::ArrayFunc(ref arr) = expr {
3503 if let Some(new_elements) = propagate_in_elements(&arr.expressions) {
3504 return Ok(Expression::ArrayFunc(Box::new(ArrayConstructor {
3505 expressions: new_elements,
3506 bracket_notation: arr.bracket_notation,
3507 use_list_keyword: arr.use_list_keyword,
3508 })));
3509 }
3510 }
3511
3512 Ok(expr)
3513}
3514
3515pub fn unnest_alias_to_column_alias(expr: Expression) -> Result<Expression> {
3518 use crate::dialects::transform_recursive;
3519 transform_recursive(expr, &unnest_alias_transform_single_select)
3520}
3521
3522pub fn unnest_from_to_cross_join(expr: Expression) -> Result<Expression> {
3525 use crate::dialects::transform_recursive;
3526 transform_recursive(expr, &unnest_from_to_cross_join_single_select)
3527}
3528
3529fn unnest_from_to_cross_join_single_select(expr: Expression) -> Result<Expression> {
3530 if let Expression::Select(mut select) = expr {
3531 if let Some(ref mut from) = select.from {
3532 if from.expressions.len() > 1 {
3533 let mut new_from_exprs = Vec::new();
3534 let mut new_cross_joins = Vec::new();
3535
3536 for (idx, from_item) in from.expressions.drain(..).enumerate() {
3537 if idx == 0 {
3538 new_from_exprs.push(from_item);
3539 } else {
3540 let is_unnest = match &from_item {
3541 Expression::Unnest(_) => true,
3542 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
3543 _ => false,
3544 };
3545
3546 if is_unnest {
3547 new_cross_joins.push(crate::expressions::Join {
3548 this: from_item,
3549 on: None,
3550 using: Vec::new(),
3551 kind: JoinKind::Cross,
3552 use_inner_keyword: false,
3553 use_outer_keyword: false,
3554 deferred_condition: false,
3555 join_hint: None,
3556 match_condition: None,
3557 pivots: Vec::new(),
3558 comments: Vec::new(),
3559 nesting_group: 0,
3560 directed: false,
3561 });
3562 } else {
3563 new_from_exprs.push(from_item);
3564 }
3565 }
3566 }
3567
3568 from.expressions = new_from_exprs;
3569 new_cross_joins.append(&mut select.joins);
3570 select.joins = new_cross_joins;
3571 }
3572 }
3573
3574 Ok(Expression::Select(select))
3575 } else {
3576 Ok(expr)
3577 }
3578}
3579
3580pub fn wrap_unnest_join_aliases(expr: Expression) -> Result<Expression> {
3584 use crate::dialects::transform_recursive;
3585 transform_recursive(expr, &wrap_unnest_join_aliases_single)
3586}
3587
3588fn wrap_unnest_join_aliases_single(expr: Expression) -> Result<Expression> {
3589 if let Expression::Select(mut select) = expr {
3590 for join in &mut select.joins {
3592 wrap_unnest_alias_in_join_item(&mut join.this);
3593 }
3594 Ok(Expression::Select(select))
3595 } else {
3596 Ok(expr)
3597 }
3598}
3599
3600fn wrap_unnest_alias_in_join_item(expr: &mut Expression) {
3602 use crate::expressions::Identifier;
3603 if let Expression::Alias(alias) = expr {
3604 let is_unnest = match &alias.this {
3606 Expression::Function(f) => f.name.eq_ignore_ascii_case("UNNEST"),
3607 _ => false,
3608 };
3609
3610 if is_unnest && alias.column_aliases.is_empty() {
3611 let original_alias_name = alias.alias.name.clone();
3613 alias.alias = Identifier {
3614 name: "_u".to_string(),
3615 quoted: false,
3616 trailing_comments: Vec::new(),
3617 span: None,
3618 };
3619 alias.column_aliases = vec![Identifier {
3620 name: original_alias_name,
3621 quoted: false,
3622 trailing_comments: Vec::new(),
3623 span: None,
3624 }];
3625 }
3626 }
3627}
3628
3629fn unnest_alias_transform_single_select(expr: Expression) -> Result<Expression> {
3630 if let Expression::Select(mut select) = expr {
3631 let mut counter = 0usize;
3632
3633 if let Some(ref mut from) = select.from {
3635 for from_item in from.expressions.iter_mut() {
3637 convert_unnest_alias_in_from(from_item, &mut counter);
3638 }
3639
3640 if from.expressions.len() > 1 {
3642 let mut new_from_exprs = Vec::new();
3643 let mut new_cross_joins = Vec::new();
3644
3645 for (idx, from_item) in from.expressions.drain(..).enumerate() {
3646 if idx == 0 {
3647 new_from_exprs.push(from_item);
3649 } else {
3650 let is_unnest = match &from_item {
3652 Expression::Unnest(_) => true,
3653 Expression::Alias(a) => matches!(a.this, Expression::Unnest(_)),
3654 _ => false,
3655 };
3656
3657 if is_unnest {
3658 new_cross_joins.push(crate::expressions::Join {
3660 this: from_item,
3661 on: None,
3662 using: Vec::new(),
3663 kind: JoinKind::Cross,
3664 use_inner_keyword: false,
3665 use_outer_keyword: false,
3666 deferred_condition: false,
3667 join_hint: None,
3668 match_condition: None,
3669 pivots: Vec::new(),
3670 comments: Vec::new(),
3671 nesting_group: 0,
3672 directed: false,
3673 });
3674 } else {
3675 new_from_exprs.push(from_item);
3677 }
3678 }
3679 }
3680
3681 from.expressions = new_from_exprs;
3682 new_cross_joins.append(&mut select.joins);
3684 select.joins = new_cross_joins;
3685 }
3686 }
3687
3688 for join in select.joins.iter_mut() {
3690 convert_unnest_alias_in_from(&mut join.this, &mut counter);
3691 }
3692
3693 Ok(Expression::Select(select))
3694 } else {
3695 Ok(expr)
3696 }
3697}
3698
3699fn convert_unnest_alias_in_from(expr: &mut Expression, counter: &mut usize) {
3700 use crate::expressions::Identifier;
3701
3702 if let Expression::Alias(ref mut alias) = expr {
3703 let is_unnest = matches!(&alias.this, Expression::Unnest(_))
3705 || matches!(&alias.this, Expression::Function(f) if f.name.eq_ignore_ascii_case("EXPLODE"));
3706
3707 if is_unnest && alias.column_aliases.is_empty() {
3708 let col_alias = alias.alias.clone();
3710 alias.column_aliases = vec![col_alias];
3711 alias.alias = Identifier::new(format!("_t{}", counter));
3712 *counter += 1;
3713 }
3714 }
3715}
3716
3717pub fn expand_posexplode_duckdb(expr: Expression) -> Result<Expression> {
3724 use crate::expressions::{Alias, Function};
3725
3726 match expr {
3727 Expression::Select(mut select) => {
3728 let mut new_expressions = Vec::new();
3730 let mut changed = false;
3731
3732 for sel_expr in select.expressions.drain(..) {
3733 if let Expression::Alias(ref alias_box) = sel_expr {
3735 if let Expression::Function(ref func) = alias_box.this {
3736 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3737 let arg = func.args[0].clone();
3738 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
3740 (
3741 alias_box.column_aliases[0].name.clone(),
3742 alias_box.column_aliases[1].name.clone(),
3743 )
3744 } else if !alias_box.alias.is_empty() {
3745 ("pos".to_string(), alias_box.alias.name.clone())
3747 } else {
3748 ("pos".to_string(), "col".to_string())
3749 };
3750
3751 let gen_subscripts = Expression::Function(Box::new(Function::new(
3753 "GENERATE_SUBSCRIPTS".to_string(),
3754 vec![
3755 arg.clone(),
3756 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3757 ],
3758 )));
3759 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3760 gen_subscripts,
3761 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3762 )));
3763 let pos_alias = Expression::Alias(Box::new(Alias {
3764 this: sub_one,
3765 alias: Identifier::new(pos_name),
3766 column_aliases: Vec::new(),
3767 alias_explicit_as: false,
3768 alias_keyword: None,
3769 pre_alias_comments: Vec::new(),
3770 trailing_comments: Vec::new(),
3771 inferred_type: None,
3772 }));
3773
3774 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3776 this: arg,
3777 expressions: Vec::new(),
3778 with_ordinality: false,
3779 alias: None,
3780 offset_alias: None,
3781 }));
3782 let col_alias = Expression::Alias(Box::new(Alias {
3783 this: unnest,
3784 alias: Identifier::new(col_name),
3785 column_aliases: Vec::new(),
3786 alias_explicit_as: false,
3787 alias_keyword: None,
3788 pre_alias_comments: Vec::new(),
3789 trailing_comments: Vec::new(),
3790 inferred_type: None,
3791 }));
3792
3793 new_expressions.push(pos_alias);
3794 new_expressions.push(col_alias);
3795 changed = true;
3796 continue;
3797 }
3798 }
3799 }
3800
3801 if let Expression::Function(ref func) = sel_expr {
3803 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3804 let arg = func.args[0].clone();
3805 let pos_name = "pos";
3806 let col_name = "col";
3807
3808 let gen_subscripts = Expression::Function(Box::new(Function::new(
3810 "GENERATE_SUBSCRIPTS".to_string(),
3811 vec![
3812 arg.clone(),
3813 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3814 ],
3815 )));
3816 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3817 gen_subscripts,
3818 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3819 )));
3820 let pos_alias = Expression::Alias(Box::new(Alias {
3821 this: sub_one,
3822 alias: Identifier::new(pos_name),
3823 column_aliases: Vec::new(),
3824 alias_explicit_as: false,
3825 alias_keyword: None,
3826 pre_alias_comments: Vec::new(),
3827 trailing_comments: Vec::new(),
3828 inferred_type: None,
3829 }));
3830
3831 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3833 this: arg,
3834 expressions: Vec::new(),
3835 with_ordinality: false,
3836 alias: None,
3837 offset_alias: None,
3838 }));
3839 let col_alias = Expression::Alias(Box::new(Alias {
3840 this: unnest,
3841 alias: Identifier::new(col_name),
3842 column_aliases: Vec::new(),
3843 alias_explicit_as: false,
3844 alias_keyword: None,
3845 pre_alias_comments: Vec::new(),
3846 trailing_comments: Vec::new(),
3847 inferred_type: None,
3848 }));
3849
3850 new_expressions.push(pos_alias);
3851 new_expressions.push(col_alias);
3852 changed = true;
3853 continue;
3854 }
3855 }
3856
3857 new_expressions.push(sel_expr);
3859 }
3860
3861 if changed {
3862 select.expressions = new_expressions;
3863 } else {
3864 select.expressions = new_expressions;
3865 }
3866
3867 if let Some(ref mut from) = select.from {
3870 expand_posexplode_in_from_duckdb(from)?;
3871 }
3872
3873 Ok(Expression::Select(select))
3874 }
3875 other => Ok(other),
3876 }
3877}
3878
3879fn expand_posexplode_in_from_duckdb(from: &mut From) -> Result<()> {
3881 use crate::expressions::{Alias, Function};
3882
3883 let mut new_expressions = Vec::new();
3884 let mut _changed = false;
3885
3886 for table_expr in from.expressions.drain(..) {
3887 if let Expression::Alias(ref alias_box) = table_expr {
3889 if let Expression::Function(ref func) = alias_box.this {
3890 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3891 let arg = func.args[0].clone();
3892 let (pos_name, col_name) = if alias_box.column_aliases.len() == 2 {
3893 (
3894 alias_box.column_aliases[0].name.clone(),
3895 alias_box.column_aliases[1].name.clone(),
3896 )
3897 } else {
3898 ("pos".to_string(), "col".to_string())
3899 };
3900
3901 let gen_subscripts = Expression::Function(Box::new(Function::new(
3903 "GENERATE_SUBSCRIPTS".to_string(),
3904 vec![
3905 arg.clone(),
3906 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3907 ],
3908 )));
3909 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3910 gen_subscripts,
3911 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3912 )));
3913 let pos_alias = Expression::Alias(Box::new(Alias {
3914 this: sub_one,
3915 alias: Identifier::new(&pos_name),
3916 column_aliases: Vec::new(),
3917 alias_explicit_as: false,
3918 alias_keyword: None,
3919 pre_alias_comments: Vec::new(),
3920 trailing_comments: Vec::new(),
3921 inferred_type: None,
3922 }));
3923 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3924 this: arg,
3925 expressions: Vec::new(),
3926 with_ordinality: false,
3927 alias: None,
3928 offset_alias: None,
3929 }));
3930 let col_alias = Expression::Alias(Box::new(Alias {
3931 this: unnest,
3932 alias: Identifier::new(&col_name),
3933 column_aliases: Vec::new(),
3934 alias_explicit_as: false,
3935 alias_keyword: None,
3936 pre_alias_comments: Vec::new(),
3937 trailing_comments: Vec::new(),
3938 inferred_type: None,
3939 }));
3940
3941 let mut inner_select = Select::new();
3942 inner_select.expressions = vec![pos_alias, col_alias];
3943
3944 let subquery = Expression::Subquery(Box::new(Subquery {
3945 this: Expression::Select(Box::new(inner_select)),
3946 alias: None,
3947 column_aliases: Vec::new(),
3948 alias_explicit_as: false,
3949 alias_keyword: None,
3950 order_by: None,
3951 limit: None,
3952 offset: None,
3953 distribute_by: None,
3954 sort_by: None,
3955 cluster_by: None,
3956 lateral: false,
3957 modifiers_inside: false,
3958 trailing_comments: Vec::new(),
3959 inferred_type: None,
3960 }));
3961 new_expressions.push(subquery);
3962 _changed = true;
3963 continue;
3964 }
3965 }
3966 }
3967
3968 if let Expression::Function(ref func) = table_expr {
3970 if func.name.eq_ignore_ascii_case("POSEXPLODE") && func.args.len() == 1 {
3971 let arg = func.args[0].clone();
3972
3973 let gen_subscripts = Expression::Function(Box::new(Function::new(
3975 "GENERATE_SUBSCRIPTS".to_string(),
3976 vec![
3977 arg.clone(),
3978 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3979 ],
3980 )));
3981 let sub_one = Expression::Sub(Box::new(BinaryOp::new(
3982 gen_subscripts,
3983 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
3984 )));
3985 let pos_alias = Expression::Alias(Box::new(Alias {
3986 this: sub_one,
3987 alias: Identifier::new("pos"),
3988 column_aliases: Vec::new(),
3989 alias_explicit_as: false,
3990 alias_keyword: None,
3991 pre_alias_comments: Vec::new(),
3992 trailing_comments: Vec::new(),
3993 inferred_type: None,
3994 }));
3995 let unnest = Expression::Unnest(Box::new(UnnestFunc {
3996 this: arg,
3997 expressions: Vec::new(),
3998 with_ordinality: false,
3999 alias: None,
4000 offset_alias: None,
4001 }));
4002 let col_alias = Expression::Alias(Box::new(Alias {
4003 this: unnest,
4004 alias: Identifier::new("col"),
4005 column_aliases: Vec::new(),
4006 alias_explicit_as: false,
4007 alias_keyword: None,
4008 pre_alias_comments: Vec::new(),
4009 trailing_comments: Vec::new(),
4010 inferred_type: None,
4011 }));
4012
4013 let mut inner_select = Select::new();
4014 inner_select.expressions = vec![pos_alias, col_alias];
4015
4016 let subquery = Expression::Subquery(Box::new(Subquery {
4017 this: Expression::Select(Box::new(inner_select)),
4018 alias: None,
4019 column_aliases: Vec::new(),
4020 alias_explicit_as: false,
4021 alias_keyword: None,
4022 order_by: None,
4023 limit: None,
4024 offset: None,
4025 distribute_by: None,
4026 sort_by: None,
4027 cluster_by: None,
4028 lateral: false,
4029 modifiers_inside: false,
4030 trailing_comments: Vec::new(),
4031 inferred_type: None,
4032 }));
4033 new_expressions.push(subquery);
4034 _changed = true;
4035 continue;
4036 }
4037 }
4038
4039 new_expressions.push(table_expr);
4040 }
4041
4042 from.expressions = new_expressions;
4043 Ok(())
4044}
4045
4046pub fn explode_projection_to_unnest(expr: Expression, target: DialectType) -> Result<Expression> {
4061 match expr {
4062 Expression::Select(select) => explode_projection_to_unnest_impl(*select, target),
4063 other => Ok(other),
4064 }
4065}
4066
4067pub fn snowflake_flatten_projection_to_unnest(expr: Expression) -> Result<Expression> {
4077 match expr {
4078 Expression::Select(select) => snowflake_flatten_projection_to_unnest_impl(*select),
4079 other => Ok(other),
4080 }
4081}
4082
4083fn snowflake_flatten_projection_to_unnest_impl(mut select: Select) -> Result<Expression> {
4084 let mut flattened_inputs: Vec<Expression> = Vec::new();
4085 let mut new_selects: Vec<Expression> = Vec::with_capacity(select.expressions.len());
4086
4087 for sel_expr in select.expressions.into_iter() {
4088 let found_input: RefCell<Option<Expression>> = RefCell::new(None);
4089
4090 let rewritten = transform_recursive(sel_expr, &|e| {
4091 if let Expression::Lateral(lat) = e {
4092 if let Some(input_expr) = extract_flatten_input(&lat) {
4093 if found_input.borrow().is_none() {
4094 *found_input.borrow_mut() = Some(input_expr);
4095 }
4096 return Ok(Expression::Lateral(Box::new(rewrite_flatten_lateral(*lat))));
4097 }
4098 return Ok(Expression::Lateral(lat));
4099 }
4100 Ok(e)
4101 })?;
4102
4103 if let Some(input) = found_input.into_inner() {
4104 flattened_inputs.push(input);
4105 }
4106 new_selects.push(rewritten);
4107 }
4108
4109 if flattened_inputs.is_empty() {
4110 select.expressions = new_selects;
4111 return Ok(Expression::Select(Box::new(select)));
4112 }
4113
4114 select.expressions = new_selects;
4115
4116 for (idx, input_expr) in flattened_inputs.into_iter().enumerate() {
4117 let is_first = idx == 0;
4119 let series_alias = if is_first {
4120 "pos".to_string()
4121 } else {
4122 format!("pos_{}", idx + 1)
4123 };
4124 let series_source_alias = if is_first {
4125 "_u".to_string()
4126 } else {
4127 format!("_u_{}", idx * 2 + 1)
4128 };
4129 let unnest_source_alias = if is_first {
4130 "_u_2".to_string()
4131 } else {
4132 format!("_u_{}", idx * 2 + 2)
4133 };
4134 let pos2_alias = if is_first {
4135 "pos_2".to_string()
4136 } else {
4137 format!("{}_2", series_alias)
4138 };
4139 let entity_alias = if is_first {
4140 "entity".to_string()
4141 } else {
4142 format!("entity_{}", idx + 1)
4143 };
4144
4145 let array_size_call = Expression::Function(Box::new(Function::new(
4146 "ARRAY_SIZE".to_string(),
4147 vec![Expression::NamedArgument(Box::new(NamedArgument {
4148 name: Identifier::new("INPUT"),
4149 value: input_expr.clone(),
4150 separator: NamedArgSeparator::DArrow,
4151 }))],
4152 )));
4153
4154 let greatest = Expression::Function(Box::new(Function::new(
4155 "GREATEST".to_string(),
4156 vec![array_size_call.clone()],
4157 )));
4158
4159 let series_end = Expression::Add(Box::new(BinaryOp::new(
4160 Expression::Paren(Box::new(crate::expressions::Paren {
4161 this: Expression::Sub(Box::new(BinaryOp::new(
4162 greatest,
4163 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4164 ))),
4165 trailing_comments: Vec::new(),
4166 })),
4167 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4168 )));
4169
4170 let series_range = Expression::Function(Box::new(Function::new(
4171 "ARRAY_GENERATE_RANGE".to_string(),
4172 vec![
4173 Expression::Literal(Box::new(Literal::Number("0".to_string()))),
4174 series_end,
4175 ],
4176 )));
4177
4178 let series_flatten = Expression::Function(Box::new(Function::new(
4179 "FLATTEN".to_string(),
4180 vec![Expression::NamedArgument(Box::new(NamedArgument {
4181 name: Identifier::new("INPUT"),
4182 value: series_range,
4183 separator: NamedArgSeparator::DArrow,
4184 }))],
4185 )));
4186
4187 let series_table = Expression::Function(Box::new(Function::new(
4188 "TABLE".to_string(),
4189 vec![series_flatten],
4190 )));
4191
4192 let series_alias_expr = Expression::Alias(Box::new(Alias {
4193 this: series_table,
4194 alias: Identifier::new(series_source_alias.clone()),
4195 column_aliases: vec![
4196 Identifier::new("seq"),
4197 Identifier::new("key"),
4198 Identifier::new("path"),
4199 Identifier::new("index"),
4200 Identifier::new(series_alias.clone()),
4201 Identifier::new("this"),
4202 ],
4203 alias_explicit_as: false,
4204 alias_keyword: None,
4205 pre_alias_comments: Vec::new(),
4206 trailing_comments: Vec::new(),
4207 inferred_type: None,
4208 }));
4209
4210 select.joins.push(Join {
4211 this: series_alias_expr,
4212 on: None,
4213 using: Vec::new(),
4214 kind: JoinKind::Cross,
4215 use_inner_keyword: false,
4216 use_outer_keyword: false,
4217 deferred_condition: false,
4218 join_hint: None,
4219 match_condition: None,
4220 pivots: Vec::new(),
4221 comments: Vec::new(),
4222 nesting_group: 0,
4223 directed: false,
4224 });
4225
4226 let entity_flatten = Expression::Function(Box::new(Function::new(
4227 "FLATTEN".to_string(),
4228 vec![Expression::NamedArgument(Box::new(NamedArgument {
4229 name: Identifier::new("INPUT"),
4230 value: input_expr.clone(),
4231 separator: NamedArgSeparator::DArrow,
4232 }))],
4233 )));
4234
4235 let entity_table = Expression::Function(Box::new(Function::new(
4236 "TABLE".to_string(),
4237 vec![entity_flatten],
4238 )));
4239
4240 let entity_alias_expr = Expression::Alias(Box::new(Alias {
4241 this: entity_table,
4242 alias: Identifier::new(unnest_source_alias.clone()),
4243 column_aliases: vec![
4244 Identifier::new("seq"),
4245 Identifier::new("key"),
4246 Identifier::new("path"),
4247 Identifier::new(pos2_alias.clone()),
4248 Identifier::new(entity_alias.clone()),
4249 Identifier::new("this"),
4250 ],
4251 alias_explicit_as: false,
4252 alias_keyword: None,
4253 pre_alias_comments: Vec::new(),
4254 trailing_comments: Vec::new(),
4255 inferred_type: None,
4256 }));
4257
4258 select.joins.push(Join {
4259 this: entity_alias_expr,
4260 on: None,
4261 using: Vec::new(),
4262 kind: JoinKind::Cross,
4263 use_inner_keyword: false,
4264 use_outer_keyword: false,
4265 deferred_condition: false,
4266 join_hint: None,
4267 match_condition: None,
4268 pivots: Vec::new(),
4269 comments: Vec::new(),
4270 nesting_group: 0,
4271 directed: false,
4272 });
4273
4274 let pos_col =
4275 Expression::qualified_column(series_source_alias.clone(), series_alias.clone());
4276 let pos2_col =
4277 Expression::qualified_column(unnest_source_alias.clone(), pos2_alias.clone());
4278
4279 let eq = Expression::Eq(Box::new(BinaryOp::new(pos_col.clone(), pos2_col.clone())));
4280 let size_minus_1 = Expression::Paren(Box::new(crate::expressions::Paren {
4281 this: Expression::Sub(Box::new(BinaryOp::new(
4282 array_size_call,
4283 Expression::Literal(Box::new(Literal::Number("1".to_string()))),
4284 ))),
4285 trailing_comments: Vec::new(),
4286 }));
4287 let gt = Expression::Gt(Box::new(BinaryOp::new(pos_col, size_minus_1.clone())));
4288 let pos2_eq_size = Expression::Eq(Box::new(BinaryOp::new(pos2_col, size_minus_1)));
4289 let and_cond = Expression::And(Box::new(BinaryOp::new(gt, pos2_eq_size)));
4290 let or_cond = Expression::Or(Box::new(BinaryOp::new(
4291 eq,
4292 Expression::Paren(Box::new(crate::expressions::Paren {
4293 this: and_cond,
4294 trailing_comments: Vec::new(),
4295 })),
4296 )));
4297
4298 select.where_clause = Some(match select.where_clause.take() {
4299 Some(existing) => Where {
4300 this: Expression::And(Box::new(BinaryOp::new(existing.this, or_cond))),
4301 },
4302 None => Where { this: or_cond },
4303 });
4304 }
4305
4306 Ok(Expression::Select(Box::new(select)))
4307}
4308
4309fn extract_flatten_input(lat: &Lateral) -> Option<Expression> {
4310 let Expression::Function(f) = lat.this.as_ref() else {
4311 return None;
4312 };
4313 if !f.name.eq_ignore_ascii_case("FLATTEN") {
4314 return None;
4315 }
4316
4317 for arg in &f.args {
4318 if let Expression::NamedArgument(na) = arg {
4319 if na.name.name.eq_ignore_ascii_case("INPUT") {
4320 return Some(na.value.clone());
4321 }
4322 }
4323 }
4324 f.args.first().cloned()
4325}
4326
4327fn rewrite_flatten_lateral(mut lat: Lateral) -> Lateral {
4328 let cond = Expression::Eq(Box::new(BinaryOp::new(
4329 Expression::qualified_column("_u", "pos"),
4330 Expression::qualified_column("_u_2", "pos_2"),
4331 )));
4332 let true_expr = Expression::qualified_column("_u_2", "entity");
4333 let iff_expr = Expression::Function(Box::new(Function::new(
4334 "IFF".to_string(),
4335 vec![cond, true_expr, Expression::Null(crate::expressions::Null)],
4336 )));
4337
4338 lat.this = Box::new(iff_expr);
4339 if lat.column_aliases.is_empty() {
4340 lat.column_aliases = vec![
4341 "SEQ".to_string(),
4342 "KEY".to_string(),
4343 "PATH".to_string(),
4344 "INDEX".to_string(),
4345 "VALUE".to_string(),
4346 "THIS".to_string(),
4347 ];
4348 }
4349 lat
4350}
4351
4352struct ExplodeInfo {
4354 arg_sql: String,
4356 explode_alias: String,
4358 pos_alias: String,
4360 unnest_source_alias: String,
4362}
4363
4364fn explode_projection_to_unnest_impl(select: Select, target: DialectType) -> Result<Expression> {
4365 let is_presto = matches!(
4366 target,
4367 DialectType::Presto | DialectType::Trino | DialectType::Athena
4368 );
4369 let is_bigquery = matches!(target, DialectType::BigQuery);
4370
4371 if !is_presto && !is_bigquery {
4372 return Ok(Expression::Select(Box::new(select)));
4373 }
4374
4375 let has_explode = select.expressions.iter().any(|e| expr_contains_explode(e));
4377 if !has_explode {
4378 return Ok(Expression::Select(Box::new(select)));
4379 }
4380
4381 let mut taken_select_names = std::collections::HashSet::new();
4383 let mut taken_source_names = std::collections::HashSet::new();
4384
4385 for sel in &select.expressions {
4387 if let Some(name) = get_output_name(sel) {
4388 taken_select_names.insert(name);
4389 }
4390 }
4391
4392 for sel in &select.expressions {
4394 let explode_expr = find_explode_in_expr(sel);
4395 if let Some(arg) = explode_expr {
4396 if let Some(name) = get_output_name(&arg) {
4397 taken_select_names.insert(name);
4398 }
4399 }
4400 }
4401
4402 if let Some(ref from) = select.from {
4404 for from_expr in &from.expressions {
4405 collect_source_names(from_expr, &mut taken_source_names);
4406 }
4407 }
4408 for join in &select.joins {
4410 collect_source_names(&join.this, &mut taken_source_names);
4411 }
4412
4413 let series_alias = new_name(&mut taken_select_names, "pos");
4415
4416 let series_source_alias = new_name(&mut taken_source_names, "_u");
4418
4419 let target_dialect = Dialect::get(target);
4421
4422 let mut explode_infos: Vec<ExplodeInfo> = Vec::new();
4424 let mut new_projections: Vec<String> = Vec::new();
4425
4426 for (_idx, sel_expr) in select.expressions.iter().enumerate() {
4427 let explode_data = extract_explode_data(sel_expr);
4428
4429 if let Some((is_posexplode, arg_expr, explicit_alias, explicit_pos_alias)) = explode_data {
4430 let arg_sql = target_dialect
4432 .generate(&arg_expr)
4433 .unwrap_or_else(|_| "NULL".to_string());
4434
4435 let unnest_source_alias = new_name(&mut taken_source_names, "_u");
4436
4437 let explode_alias = if let Some(ref ea) = explicit_alias {
4438 taken_select_names.remove(ea.as_str());
4441 let name = new_name(&mut taken_select_names, ea);
4443 name
4444 } else {
4445 new_name(&mut taken_select_names, "col")
4446 };
4447
4448 let pos_alias = if let Some(ref pa) = explicit_pos_alias {
4449 taken_select_names.remove(pa.as_str());
4451 let name = new_name(&mut taken_select_names, pa);
4452 name
4453 } else {
4454 new_name(&mut taken_select_names, "pos")
4455 };
4456
4457 if is_presto {
4459 let if_col = format!(
4461 "IF({}.{} = {}.{}, {}.{}) AS {}",
4462 series_source_alias,
4463 series_alias,
4464 unnest_source_alias,
4465 pos_alias,
4466 unnest_source_alias,
4467 explode_alias,
4468 explode_alias
4469 );
4470 new_projections.push(if_col);
4471
4472 if is_posexplode {
4474 let if_pos = format!(
4475 "IF({}.{} = {}.{}, {}.{}) AS {}",
4476 series_source_alias,
4477 series_alias,
4478 unnest_source_alias,
4479 pos_alias,
4480 unnest_source_alias,
4481 pos_alias,
4482 pos_alias
4483 );
4484 new_projections.push(if_pos);
4485 }
4486 } else {
4487 let if_col = format!(
4489 "IF({} = {}, {}, NULL) AS {}",
4490 series_alias, pos_alias, explode_alias, explode_alias
4491 );
4492 new_projections.push(if_col);
4493
4494 if is_posexplode {
4496 let if_pos = format!(
4497 "IF({} = {}, {}, NULL) AS {}",
4498 series_alias, pos_alias, pos_alias, pos_alias
4499 );
4500 new_projections.push(if_pos);
4501 }
4502 }
4503
4504 explode_infos.push(ExplodeInfo {
4505 arg_sql,
4506 explode_alias,
4507 pos_alias,
4508 unnest_source_alias,
4509 });
4510 } else {
4511 let sel_sql = target_dialect
4513 .generate(sel_expr)
4514 .unwrap_or_else(|_| "*".to_string());
4515 new_projections.push(sel_sql);
4516 }
4517 }
4518
4519 if explode_infos.is_empty() {
4520 return Ok(Expression::Select(Box::new(select)));
4521 }
4522
4523 let mut from_parts: Vec<String> = Vec::new();
4525
4526 if let Some(ref from) = select.from {
4528 for from_expr in &from.expressions {
4529 let from_sql = target_dialect.generate(from_expr).unwrap_or_default();
4530 from_parts.push(from_sql);
4531 }
4532 }
4533
4534 let size_exprs: Vec<String> = explode_infos
4536 .iter()
4537 .map(|info| {
4538 if is_presto {
4539 format!("CARDINALITY({})", info.arg_sql)
4540 } else {
4541 format!("ARRAY_LENGTH({})", info.arg_sql)
4542 }
4543 })
4544 .collect();
4545
4546 let greatest_arg = if size_exprs.len() == 1 {
4547 size_exprs[0].clone()
4548 } else {
4549 format!("GREATEST({})", size_exprs.join(", "))
4550 };
4551
4552 let series_sql = if is_presto {
4555 if size_exprs.len() == 1 {
4557 format!(
4558 "UNNEST(SEQUENCE(1, GREATEST({}))) AS {}({})",
4559 greatest_arg, series_source_alias, series_alias
4560 )
4561 } else {
4562 format!(
4564 "UNNEST(SEQUENCE(1, {})) AS {}({})",
4565 greatest_arg, series_source_alias, series_alias
4566 )
4567 }
4568 } else {
4569 if size_exprs.len() == 1 {
4571 format!(
4572 "UNNEST(GENERATE_ARRAY(0, GREATEST({}) - 1)) AS {}",
4573 greatest_arg, series_alias
4574 )
4575 } else {
4576 format!(
4578 "UNNEST(GENERATE_ARRAY(0, {} - 1)) AS {}",
4579 greatest_arg, series_alias
4580 )
4581 }
4582 };
4583
4584 let mut cross_joins: Vec<String> = Vec::new();
4588
4589 for info in &explode_infos {
4590 cross_joins.push(format!(
4592 "CROSS JOIN UNNEST({}) WITH ORDINALITY AS {}({}, {})",
4593 info.arg_sql, info.unnest_source_alias, info.explode_alias, info.pos_alias
4594 ));
4595 }
4596
4597 let mut where_conditions: Vec<String> = Vec::new();
4599
4600 for info in &explode_infos {
4601 let size_expr = if is_presto {
4602 format!("CARDINALITY({})", info.arg_sql)
4603 } else {
4604 format!("ARRAY_LENGTH({})", info.arg_sql)
4605 };
4606
4607 let cond = if is_presto {
4608 format!(
4609 "{series_src}.{series_al} = {unnest_src}.{pos_al} OR ({series_src}.{series_al} > {size} AND {unnest_src}.{pos_al} = {size})",
4610 series_src = series_source_alias,
4611 series_al = series_alias,
4612 unnest_src = info.unnest_source_alias,
4613 pos_al = info.pos_alias,
4614 size = size_expr
4615 )
4616 } else {
4617 format!(
4618 "{series_al} = {pos_al} OR ({series_al} > ({size} - 1) AND {pos_al} = ({size} - 1))",
4619 series_al = series_alias,
4620 pos_al = info.pos_alias,
4621 size = size_expr
4622 )
4623 };
4624
4625 where_conditions.push(cond);
4626 }
4627
4628 let where_sql = if where_conditions.len() == 1 {
4630 where_conditions[0].clone()
4631 } else {
4632 where_conditions
4633 .iter()
4634 .map(|c| format!("({})", c))
4635 .collect::<Vec<_>>()
4636 .join(" AND ")
4637 };
4638
4639 let select_part = new_projections.join(", ");
4641
4642 let from_and_joins = if from_parts.is_empty() {
4644 format!("FROM {} {}", series_sql, cross_joins.join(" "))
4646 } else {
4647 format!(
4648 "FROM {} {} {}",
4649 from_parts.join(", "),
4650 format!("CROSS JOIN {}", series_sql),
4651 cross_joins.join(" ")
4652 )
4653 };
4654
4655 let full_sql = format!(
4656 "SELECT {} {} WHERE {}",
4657 select_part, from_and_joins, where_sql
4658 );
4659
4660 let generic_dialect = Dialect::get(DialectType::Generic);
4663 let parsed = generic_dialect.parse(&full_sql);
4664 match parsed {
4665 Ok(mut stmts) if !stmts.is_empty() => {
4666 let mut result = stmts.remove(0);
4667
4668 if is_bigquery {
4672 convert_unnest_presto_to_bigquery(&mut result);
4673 }
4674
4675 Ok(result)
4676 }
4677 _ => {
4678 Ok(Expression::Select(Box::new(select)))
4680 }
4681 }
4682}
4683
4684fn convert_unnest_presto_to_bigquery(expr: &mut Expression) {
4688 match expr {
4689 Expression::Select(ref mut select) => {
4690 if let Some(ref mut from) = select.from {
4692 for from_item in from.expressions.iter_mut() {
4693 convert_unnest_presto_to_bigquery(from_item);
4694 }
4695 }
4696 for join in select.joins.iter_mut() {
4698 convert_unnest_presto_to_bigquery(&mut join.this);
4699 }
4700 }
4701 Expression::Alias(ref alias) => {
4702 if let Expression::Unnest(ref unnest) = alias.this {
4704 if unnest.with_ordinality && alias.column_aliases.len() >= 2 {
4705 let col_alias = alias.column_aliases[0].clone();
4706 let pos_alias = alias.column_aliases[1].clone();
4707 let mut new_unnest = unnest.as_ref().clone();
4708 new_unnest.alias = Some(col_alias);
4709 new_unnest.offset_alias = Some(pos_alias);
4710 *expr = Expression::Unnest(Box::new(new_unnest));
4712 }
4713 }
4714 }
4715 _ => {}
4716 }
4717}
4718
4719fn new_name(names: &mut std::collections::HashSet<String>, base: &str) -> String {
4722 if !names.contains(base) {
4723 names.insert(base.to_string());
4724 return base.to_string();
4725 }
4726 let mut i = 2;
4727 loop {
4728 let candidate = format!("{}_{}", base, i);
4729 if !names.contains(&candidate) {
4730 names.insert(candidate.clone());
4731 return candidate;
4732 }
4733 i += 1;
4734 }
4735}
4736
4737fn expr_contains_explode(expr: &Expression) -> bool {
4739 match expr {
4740 Expression::Explode(_) => true,
4741 Expression::ExplodeOuter(_) => true,
4742 Expression::Function(f) => {
4743 let name = f.name.to_uppercase();
4744 name == "POSEXPLODE" || name == "POSEXPLODE_OUTER"
4745 }
4746 Expression::Alias(a) => expr_contains_explode(&a.this),
4747 _ => false,
4748 }
4749}
4750
4751fn find_explode_in_expr(expr: &Expression) -> Option<Expression> {
4753 match expr {
4754 Expression::Explode(uf) => Some(uf.this.clone()),
4755 Expression::ExplodeOuter(uf) => Some(uf.this.clone()),
4756 Expression::Function(f) => {
4757 let name = f.name.to_uppercase();
4758 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
4759 Some(f.args[0].clone())
4760 } else {
4761 None
4762 }
4763 }
4764 Expression::Alias(a) => find_explode_in_expr(&a.this),
4765 _ => None,
4766 }
4767}
4768
4769fn extract_explode_data(
4772 expr: &Expression,
4773) -> Option<(bool, Expression, Option<String>, Option<String>)> {
4774 match expr {
4775 Expression::Explode(uf) => Some((false, uf.this.clone(), None, None)),
4777 Expression::ExplodeOuter(uf) => Some((false, uf.this.clone(), None, None)),
4778 Expression::Function(f) => {
4780 let name = f.name.to_uppercase();
4781 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
4782 Some((true, f.args[0].clone(), None, None))
4783 } else {
4784 None
4785 }
4786 }
4787 Expression::Alias(a) => {
4789 match &a.this {
4790 Expression::Explode(uf) => {
4791 let alias = if !a.alias.is_empty() {
4792 Some(a.alias.name.clone())
4793 } else {
4794 None
4795 };
4796 Some((false, uf.this.clone(), alias, None))
4797 }
4798 Expression::ExplodeOuter(uf) => {
4799 let alias = if !a.alias.is_empty() {
4800 Some(a.alias.name.clone())
4801 } else {
4802 None
4803 };
4804 Some((false, uf.this.clone(), alias, None))
4805 }
4806 Expression::Function(f) => {
4807 let name = f.name.to_uppercase();
4808 if (name == "POSEXPLODE" || name == "POSEXPLODE_OUTER") && !f.args.is_empty() {
4809 if a.column_aliases.len() == 2 {
4811 let pos_alias = a.column_aliases[0].name.clone();
4812 let col_alias = a.column_aliases[1].name.clone();
4813 Some((true, f.args[0].clone(), Some(col_alias), Some(pos_alias)))
4814 } else if !a.alias.is_empty() {
4815 Some((true, f.args[0].clone(), Some(a.alias.name.clone()), None))
4817 } else {
4818 Some((true, f.args[0].clone(), None, None))
4819 }
4820 } else {
4821 None
4822 }
4823 }
4824 _ => None,
4825 }
4826 }
4827 _ => None,
4828 }
4829}
4830
4831fn get_output_name(expr: &Expression) -> Option<String> {
4833 match expr {
4834 Expression::Alias(a) => {
4835 if !a.alias.is_empty() {
4836 Some(a.alias.name.clone())
4837 } else {
4838 None
4839 }
4840 }
4841 Expression::Column(c) => Some(c.name.name.clone()),
4842 Expression::Identifier(id) => Some(id.name.clone()),
4843 _ => None,
4844 }
4845}
4846
4847fn collect_source_names(expr: &Expression, names: &mut std::collections::HashSet<String>) {
4849 match expr {
4850 Expression::Alias(a) => {
4851 if !a.alias.is_empty() {
4852 names.insert(a.alias.name.clone());
4853 }
4854 }
4855 Expression::Subquery(s) => {
4856 if let Some(ref alias) = s.alias {
4857 names.insert(alias.name.clone());
4858 }
4859 }
4860 Expression::Table(t) => {
4861 if let Some(ref alias) = t.alias {
4862 names.insert(alias.name.clone());
4863 } else {
4864 names.insert(t.name.name.clone());
4865 }
4866 }
4867 Expression::Column(c) => {
4868 names.insert(c.name.name.clone());
4869 }
4870 Expression::Identifier(id) => {
4871 names.insert(id.name.clone());
4872 }
4873 _ => {}
4874 }
4875}
4876
4877pub fn strip_unnest_column_refs(expr: Expression) -> Result<Expression> {
4880 use crate::dialects::transform_recursive;
4881 transform_recursive(expr, &strip_unnest_column_refs_single)
4882}
4883
4884fn strip_unnest_column_refs_single(expr: Expression) -> Result<Expression> {
4885 if let Expression::Select(mut select) = expr {
4886 for join in select.joins.iter_mut() {
4888 strip_unnest_from_expr(&mut join.this);
4889 }
4890 if let Some(ref mut from) = select.from {
4892 for from_item in from.expressions.iter_mut() {
4893 strip_unnest_from_expr(from_item);
4894 }
4895 }
4896 Ok(Expression::Select(select))
4897 } else {
4898 Ok(expr)
4899 }
4900}
4901
4902fn strip_unnest_from_expr(expr: &mut Expression) {
4905 if let Expression::Alias(ref mut alias) = expr {
4906 if let Expression::Unnest(ref unnest) = alias.this {
4907 let is_column_ref = matches!(&unnest.this, Expression::Column(_) | Expression::Dot(_));
4908 if is_column_ref {
4909 let inner = unnest.this.clone();
4911 alias.this = inner;
4912 }
4913 }
4914 }
4915}
4916
4917pub fn wrap_duckdb_unnest_struct(expr: Expression) -> Result<Expression> {
4920 use crate::dialects::transform_recursive;
4921 transform_recursive(expr, &wrap_duckdb_unnest_struct_single)
4922}
4923
4924fn wrap_duckdb_unnest_struct_single(expr: Expression) -> Result<Expression> {
4925 if let Expression::Select(mut select) = expr {
4926 if let Some(ref mut from) = select.from {
4928 for from_item in from.expressions.iter_mut() {
4929 try_wrap_unnest_in_subquery(from_item);
4930 }
4931 }
4932
4933 for join in select.joins.iter_mut() {
4935 try_wrap_unnest_in_subquery(&mut join.this);
4936 }
4937
4938 Ok(Expression::Select(select))
4939 } else {
4940 Ok(expr)
4941 }
4942}
4943
4944fn is_struct_array_unnest_arg(expr: &Expression) -> bool {
4946 match expr {
4947 Expression::Array(arr) => arr
4949 .expressions
4950 .iter()
4951 .any(|e| matches!(e, Expression::Struct(_))),
4952 Expression::ArrayFunc(arr) => arr
4953 .expressions
4954 .iter()
4955 .any(|e| matches!(e, Expression::Struct(_))),
4956 Expression::Cast(c) => {
4958 matches!(&c.to, DataType::Array { element_type, .. } if matches!(**element_type, DataType::Struct { .. }))
4959 }
4960 _ => false,
4961 }
4962}
4963
4964fn try_wrap_unnest_in_subquery(expr: &mut Expression) {
4967 if let Expression::Alias(ref alias) = expr {
4969 if let Expression::Unnest(ref unnest) = alias.this {
4970 if is_struct_array_unnest_arg(&unnest.this) {
4971 let unnest_clone = (**unnest).clone();
4972 let alias_name = alias.alias.clone();
4973 let new_expr = make_unnest_subquery(unnest_clone, Some(alias_name));
4974 *expr = new_expr;
4975 return;
4976 }
4977 }
4978 }
4979
4980 if let Expression::Unnest(ref unnest) = expr {
4982 if is_struct_array_unnest_arg(&unnest.this) {
4983 let unnest_clone = (**unnest).clone();
4984 let new_expr = make_unnest_subquery(unnest_clone, None);
4985 *expr = new_expr;
4986 }
4987 }
4988}
4989
4990fn make_unnest_subquery(unnest: UnnestFunc, alias: Option<Identifier>) -> Expression {
4992 let max_depth_arg = Expression::NamedArgument(Box::new(NamedArgument {
4994 name: Identifier::new("max_depth".to_string()),
4995 value: Expression::Literal(Box::new(Literal::Number("2".to_string()))),
4996 separator: NamedArgSeparator::DArrow,
4997 }));
4998
4999 let mut unnest_args = vec![unnest.this];
5000 unnest_args.extend(unnest.expressions);
5001 unnest_args.push(max_depth_arg);
5002
5003 let unnest_func =
5004 Expression::Function(Box::new(Function::new("UNNEST".to_string(), unnest_args)));
5005
5006 let mut inner_select = Select::new();
5008 inner_select.expressions = vec![unnest_func];
5009 let inner_select = Expression::Select(Box::new(inner_select));
5010
5011 let subquery = Subquery {
5013 this: inner_select,
5014 alias,
5015 column_aliases: Vec::new(),
5016 alias_explicit_as: false,
5017 alias_keyword: None,
5018 order_by: None,
5019 limit: None,
5020 offset: None,
5021 distribute_by: None,
5022 sort_by: None,
5023 cluster_by: None,
5024 lateral: false,
5025 modifiers_inside: false,
5026 trailing_comments: Vec::new(),
5027 inferred_type: None,
5028 };
5029
5030 Expression::Subquery(Box::new(subquery))
5031}
5032
5033pub fn no_limit_order_by_union(expr: Expression) -> Result<Expression> {
5045 use crate::expressions::{Limit as LimitClause, Offset as OffsetClause, OrderBy, Star};
5046
5047 match expr {
5048 Expression::Union(mut u) => {
5049 if u.order_by.is_none() && u.limit.is_none() && u.offset.is_none() {
5052 if let Expression::Select(ref mut right_select) = u.right {
5054 if right_select.order_by.is_some()
5055 || right_select.limit.is_some()
5056 || right_select.offset.is_some()
5057 {
5058 u.order_by = right_select.order_by.take();
5060 u.limit = right_select.limit.take().map(|l| Box::new(l.this));
5061 u.offset = right_select.offset.take().map(|o| Box::new(o.this));
5062 }
5063 }
5064 }
5065
5066 let has_order_or_limit =
5067 u.order_by.is_some() || u.limit.is_some() || u.offset.is_some();
5068 if has_order_or_limit {
5069 let order_by: Option<OrderBy> = u.order_by.take();
5071 let union_limit: Option<Box<Expression>> = u.limit.take();
5072 let union_offset: Option<Box<Expression>> = u.offset.take();
5073
5074 let select_limit: Option<LimitClause> = union_limit.map(|l| LimitClause {
5076 this: *l,
5077 percent: false,
5078 comments: Vec::new(),
5079 });
5080
5081 let select_offset: Option<OffsetClause> = union_offset.map(|o| OffsetClause {
5083 this: *o,
5084 rows: None,
5085 });
5086
5087 let subquery = Subquery {
5089 this: Expression::Union(u),
5090 alias: Some(Identifier::new("_l_0")),
5091 column_aliases: Vec::new(),
5092 alias_explicit_as: true,
5093 alias_keyword: None,
5094 lateral: false,
5095 modifiers_inside: false,
5096 order_by: None,
5097 limit: None,
5098 offset: None,
5099 distribute_by: None,
5100 sort_by: None,
5101 cluster_by: None,
5102 trailing_comments: Vec::new(),
5103 inferred_type: None,
5104 };
5105
5106 let mut select = Select::default();
5108 select.expressions = vec![Expression::Star(Star {
5109 table: None,
5110 except: None,
5111 replace: None,
5112 rename: None,
5113 trailing_comments: Vec::new(),
5114 span: None,
5115 })];
5116 select.from = Some(From {
5117 expressions: vec![Expression::Subquery(Box::new(subquery))],
5118 });
5119 select.order_by = order_by;
5120 select.limit = select_limit;
5121 select.offset = select_offset;
5122
5123 Ok(Expression::Select(Box::new(select)))
5124 } else {
5125 Ok(Expression::Union(u))
5126 }
5127 }
5128 _ => Ok(expr),
5129 }
5130}
5131
5132pub fn expand_like_any(expr: Expression) -> Result<Expression> {
5140 use crate::expressions::{BinaryOp, LikeOp, Paren};
5141
5142 const LIKE_ALL_MARKER: &str = "__LIKE_ALL_EXPANSION__";
5145
5146 fn unwrap_parens(e: &Expression) -> &Expression {
5147 match e {
5148 Expression::Paren(p) => unwrap_parens(&p.this),
5149 _ => e,
5150 }
5151 }
5152
5153 fn extract_tuple_values(e: &Expression) -> Option<Vec<Expression>> {
5154 let inner = unwrap_parens(e);
5155 match inner {
5156 Expression::Tuple(t) => Some(t.expressions.clone()),
5157 _ if !matches!(e, Expression::Tuple(_)) => Some(vec![inner.clone()]),
5159 _ => None,
5160 }
5161 }
5162
5163 fn expand_like_quantifier(
5165 op: &LikeOp,
5166 values: Vec<Expression>,
5167 is_ilike: bool,
5168 combiner: fn(Expression, Expression) -> Expression,
5169 wrap_marker: bool,
5170 ) -> Expression {
5171 let num_values = values.len();
5172 let mut result: Option<Expression> = None;
5173 for val in values {
5174 let like = if is_ilike {
5175 Expression::ILike(Box::new(LikeOp {
5176 left: op.left.clone(),
5177 right: val,
5178 escape: op.escape.clone(),
5179 quantifier: None,
5180 inferred_type: None,
5181 }))
5182 } else {
5183 Expression::Like(Box::new(LikeOp {
5184 left: op.left.clone(),
5185 right: val,
5186 escape: op.escape.clone(),
5187 quantifier: None,
5188 inferred_type: None,
5189 }))
5190 };
5191 result = Some(match result {
5192 None => like,
5193 Some(prev) => combiner(prev, like),
5194 });
5195 }
5196 let expanded = result.unwrap_or_else(|| unreachable!("values is non-empty"));
5197 if wrap_marker && num_values > 1 {
5201 Expression::Paren(Box::new(Paren {
5202 this: expanded,
5203 trailing_comments: vec![LIKE_ALL_MARKER.to_string()],
5204 }))
5205 } else {
5206 expanded
5207 }
5208 }
5209
5210 fn or_combiner(a: Expression, b: Expression) -> Expression {
5211 Expression::Or(Box::new(BinaryOp::new(a, b)))
5212 }
5213
5214 fn and_combiner(a: Expression, b: Expression) -> Expression {
5215 Expression::And(Box::new(BinaryOp::new(a, b)))
5216 }
5217
5218 fn is_like_all_marker(p: &Paren) -> bool {
5219 p.trailing_comments.len() == 1 && p.trailing_comments[0] == LIKE_ALL_MARKER
5220 }
5221
5222 let result = transform_recursive(expr, &|e| {
5230 match e {
5231 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ANY") => {
5233 if let Some(values) = extract_tuple_values(&op.right) {
5234 if values.is_empty() {
5235 return Ok(e);
5236 }
5237 Ok(expand_like_quantifier(
5238 op,
5239 values,
5240 false,
5241 or_combiner,
5242 false,
5243 ))
5244 } else {
5245 Ok(e)
5246 }
5247 }
5248 Expression::Like(ref op) if op.quantifier.as_deref() == Some("ALL") => {
5250 if let Some(values) = extract_tuple_values(&op.right) {
5251 if values.is_empty() {
5252 return Ok(e);
5253 }
5254 Ok(expand_like_quantifier(
5255 op,
5256 values,
5257 false,
5258 and_combiner,
5259 true,
5260 ))
5261 } else {
5262 Ok(e)
5263 }
5264 }
5265 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ANY") => {
5267 if let Some(values) = extract_tuple_values(&op.right) {
5268 if values.is_empty() {
5269 return Ok(e);
5270 }
5271 Ok(expand_like_quantifier(op, values, true, or_combiner, false))
5272 } else {
5273 Ok(e)
5274 }
5275 }
5276 Expression::ILike(ref op) if op.quantifier.as_deref() == Some("ALL") => {
5278 if let Some(values) = extract_tuple_values(&op.right) {
5279 if values.is_empty() {
5280 return Ok(e);
5281 }
5282 Ok(expand_like_quantifier(op, values, true, and_combiner, true))
5283 } else {
5284 Ok(e)
5285 }
5286 }
5287 Expression::And(mut op) => {
5292 if matches!(&op.left, Expression::Or(_)) {
5293 op.left = Expression::Paren(Box::new(Paren {
5294 this: op.left,
5295 trailing_comments: vec![],
5296 }));
5297 }
5298 if matches!(&op.right, Expression::Or(_)) {
5299 op.right = Expression::Paren(Box::new(Paren {
5300 this: op.right,
5301 trailing_comments: vec![],
5302 }));
5303 }
5304 Ok(Expression::And(op))
5305 }
5306 Expression::Or(mut op) => {
5309 if let Expression::Paren(ref mut p) = op.left {
5310 if is_like_all_marker(p) {
5311 p.trailing_comments.clear();
5312 }
5313 }
5314 if let Expression::Paren(ref mut p) = op.right {
5315 if is_like_all_marker(p) {
5316 p.trailing_comments.clear();
5317 }
5318 }
5319 Ok(Expression::Or(op))
5320 }
5321 _ => Ok(e),
5322 }
5323 })?;
5324
5325 transform_recursive(result, &|e| {
5329 if let Expression::Paren(p) = &e {
5330 if is_like_all_marker(p) {
5331 let Expression::Paren(p) = e else {
5332 unreachable!()
5333 };
5334 return Ok(p.this);
5335 }
5336 }
5337 Ok(e)
5338 })
5339}
5340
5341pub fn qualify_derived_table_outputs(expr: Expression) -> Result<Expression> {
5349 use crate::expressions::Alias;
5350
5351 fn add_self_aliases_to_select(select: &mut Select) {
5352 let new_expressions: Vec<Expression> = select
5353 .expressions
5354 .iter()
5355 .map(|e| {
5356 match e {
5357 Expression::Column(col) => {
5359 let alias_name = col.name.clone();
5360 Expression::Alias(Box::new(Alias {
5361 this: e.clone(),
5362 alias: alias_name,
5363 column_aliases: Vec::new(),
5364 alias_explicit_as: false,
5365 alias_keyword: None,
5366 pre_alias_comments: Vec::new(),
5367 trailing_comments: Vec::new(),
5368 inferred_type: None,
5369 }))
5370 }
5371 _ => e.clone(),
5373 }
5374 })
5375 .collect();
5376 select.expressions = new_expressions;
5377 }
5378
5379 fn walk_and_qualify(expr: &mut Expression) {
5380 match expr {
5381 Expression::Select(ref mut select) => {
5382 if let Some(ref mut from) = select.from {
5384 for e in from.expressions.iter_mut() {
5385 qualify_subquery_expr(e);
5386 walk_and_qualify(e);
5387 }
5388 }
5389 for join in select.joins.iter_mut() {
5391 qualify_subquery_expr(&mut join.this);
5392 walk_and_qualify(&mut join.this);
5393 }
5394 for e in select.expressions.iter_mut() {
5396 walk_and_qualify(e);
5397 }
5398 if let Some(ref mut w) = select.where_clause {
5400 walk_and_qualify(&mut w.this);
5401 }
5402 }
5403 Expression::Subquery(ref mut subquery) => {
5404 walk_and_qualify(&mut subquery.this);
5405 }
5406 Expression::Union(ref mut u) => {
5407 walk_and_qualify(&mut u.left);
5408 walk_and_qualify(&mut u.right);
5409 }
5410 Expression::Intersect(ref mut i) => {
5411 walk_and_qualify(&mut i.left);
5412 walk_and_qualify(&mut i.right);
5413 }
5414 Expression::Except(ref mut e) => {
5415 walk_and_qualify(&mut e.left);
5416 walk_and_qualify(&mut e.right);
5417 }
5418 Expression::Cte(ref mut cte) => {
5419 walk_and_qualify(&mut cte.this);
5420 }
5421 _ => {}
5422 }
5423 }
5424
5425 fn qualify_subquery_expr(expr: &mut Expression) {
5426 match expr {
5427 Expression::Subquery(ref mut subquery) => {
5428 if subquery.alias.is_some() && subquery.column_aliases.is_empty() {
5430 if let Expression::Select(ref mut inner_select) = subquery.this {
5431 let has_star = inner_select
5433 .expressions
5434 .iter()
5435 .any(|e| matches!(e, Expression::Star(_)));
5436 if !has_star {
5437 add_self_aliases_to_select(inner_select);
5438 }
5439 }
5440 }
5441 walk_and_qualify(&mut subquery.this);
5443 }
5444 Expression::Alias(ref mut alias) => {
5445 qualify_subquery_expr(&mut alias.this);
5446 }
5447 _ => {}
5448 }
5449 }
5450
5451 let mut result = expr;
5452 walk_and_qualify(&mut result);
5453
5454 if let Expression::Select(ref mut select) = result {
5456 if let Some(ref mut with) = select.with {
5457 for cte in with.ctes.iter_mut() {
5458 if cte.columns.is_empty() {
5460 walk_and_qualify(&mut cte.this);
5462 }
5463 }
5464 }
5465 }
5466
5467 Ok(result)
5468}
5469
5470#[cfg(test)]
5471mod tests {
5472 use super::*;
5473 use crate::dialects::{Dialect, DialectType};
5474 use crate::expressions::Column;
5475
5476 fn gen(expr: &Expression) -> String {
5477 let dialect = Dialect::get(DialectType::Generic);
5478 dialect.generate(expr).unwrap()
5479 }
5480
5481 #[test]
5482 fn test_preprocess() {
5483 let expr = Expression::Boolean(BooleanLiteral { value: true });
5484 let result = preprocess(expr, &[replace_bool_with_int]).unwrap();
5485 assert!(
5486 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
5487 );
5488 }
5489
5490 #[test]
5491 fn test_preprocess_chain() {
5492 let expr = Expression::Boolean(BooleanLiteral { value: true });
5494 let transforms: Vec<fn(Expression) -> Result<Expression>> =
5496 vec![replace_bool_with_int, replace_int_with_bool];
5497 let result = preprocess(expr, &transforms).unwrap();
5498 if let Expression::Boolean(b) = result {
5501 assert!(b.value);
5502 } else {
5503 panic!("Expected boolean literal");
5504 }
5505 }
5506
5507 #[test]
5508 fn test_unnest_to_explode() {
5509 let unnest = Expression::Unnest(Box::new(UnnestFunc {
5510 this: Expression::boxed_column(Column {
5511 name: Identifier::new("arr".to_string()),
5512 table: None,
5513 join_mark: false,
5514 trailing_comments: vec![],
5515 span: None,
5516 inferred_type: None,
5517 }),
5518 expressions: Vec::new(),
5519 with_ordinality: false,
5520 alias: None,
5521 offset_alias: None,
5522 }));
5523
5524 let result = unnest_to_explode(unnest).unwrap();
5525 assert!(matches!(result, Expression::Explode(_)));
5526 }
5527
5528 #[test]
5529 fn test_explode_to_unnest() {
5530 let explode = Expression::Explode(Box::new(UnaryFunc {
5531 this: Expression::boxed_column(Column {
5532 name: Identifier::new("arr".to_string()),
5533 table: None,
5534 join_mark: false,
5535 trailing_comments: vec![],
5536 span: None,
5537 inferred_type: None,
5538 }),
5539 original_name: None,
5540 inferred_type: None,
5541 }));
5542
5543 let result = explode_to_unnest(explode).unwrap();
5544 assert!(matches!(result, Expression::Unnest(_)));
5545 }
5546
5547 #[test]
5548 fn test_replace_bool_with_int() {
5549 let true_expr = Expression::Boolean(BooleanLiteral { value: true });
5550 let result = replace_bool_with_int(true_expr).unwrap();
5551 if let Expression::Literal(lit) = result {
5552 if let Literal::Number(n) = lit.as_ref() {
5553 assert_eq!(n, "1");
5554 }
5555 } else {
5556 panic!("Expected number literal");
5557 }
5558
5559 let false_expr = Expression::Boolean(BooleanLiteral { value: false });
5560 let result = replace_bool_with_int(false_expr).unwrap();
5561 if let Expression::Literal(lit) = result {
5562 if let Literal::Number(n) = lit.as_ref() {
5563 assert_eq!(n, "0");
5564 }
5565 } else {
5566 panic!("Expected number literal");
5567 }
5568 }
5569
5570 #[test]
5571 fn test_replace_int_with_bool() {
5572 let one_expr = Expression::Literal(Box::new(Literal::Number("1".to_string())));
5573 let result = replace_int_with_bool(one_expr).unwrap();
5574 if let Expression::Boolean(b) = result {
5575 assert!(b.value);
5576 } else {
5577 panic!("Expected boolean true");
5578 }
5579
5580 let zero_expr = Expression::Literal(Box::new(Literal::Number("0".to_string())));
5581 let result = replace_int_with_bool(zero_expr).unwrap();
5582 if let Expression::Boolean(b) = result {
5583 assert!(!b.value);
5584 } else {
5585 panic!("Expected boolean false");
5586 }
5587
5588 let two_expr = Expression::Literal(Box::new(Literal::Number("2".to_string())));
5590 let result = replace_int_with_bool(two_expr).unwrap();
5591 assert!(
5592 matches!(result, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
5593 );
5594 }
5595
5596 #[test]
5597 fn test_strip_data_type_params() {
5598 let decimal = DataType::Decimal {
5600 precision: Some(10),
5601 scale: Some(2),
5602 };
5603 let stripped = strip_data_type_params(decimal);
5604 assert_eq!(
5605 stripped,
5606 DataType::Decimal {
5607 precision: None,
5608 scale: None
5609 }
5610 );
5611
5612 let varchar = DataType::VarChar {
5614 length: Some(255),
5615 parenthesized_length: false,
5616 };
5617 let stripped = strip_data_type_params(varchar);
5618 assert_eq!(
5619 stripped,
5620 DataType::VarChar {
5621 length: None,
5622 parenthesized_length: false
5623 }
5624 );
5625
5626 let char_type = DataType::Char { length: Some(10) };
5628 let stripped = strip_data_type_params(char_type);
5629 assert_eq!(stripped, DataType::Char { length: None });
5630
5631 let timestamp = DataType::Timestamp {
5633 precision: Some(6),
5634 timezone: true,
5635 };
5636 let stripped = strip_data_type_params(timestamp);
5637 assert_eq!(
5638 stripped,
5639 DataType::Timestamp {
5640 precision: None,
5641 timezone: true
5642 }
5643 );
5644
5645 let array = DataType::Array {
5647 element_type: Box::new(DataType::VarChar {
5648 length: Some(100),
5649 parenthesized_length: false,
5650 }),
5651 dimension: None,
5652 };
5653 let stripped = strip_data_type_params(array);
5654 assert_eq!(
5655 stripped,
5656 DataType::Array {
5657 element_type: Box::new(DataType::VarChar {
5658 length: None,
5659 parenthesized_length: false
5660 }),
5661 dimension: None,
5662 }
5663 );
5664
5665 let text = DataType::Text;
5667 let stripped = strip_data_type_params(text);
5668 assert_eq!(stripped, DataType::Text);
5669 }
5670
5671 #[test]
5672 fn test_remove_precision_parameterized_types_cast() {
5673 let cast_expr = Expression::Cast(Box::new(Cast {
5675 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
5676 to: DataType::Decimal {
5677 precision: Some(10),
5678 scale: Some(2),
5679 },
5680 trailing_comments: vec![],
5681 double_colon_syntax: false,
5682 format: None,
5683 default: None,
5684 inferred_type: None,
5685 }));
5686
5687 let result = remove_precision_parameterized_types(cast_expr).unwrap();
5688 if let Expression::Cast(cast) = result {
5689 assert_eq!(
5690 cast.to,
5691 DataType::Decimal {
5692 precision: None,
5693 scale: None
5694 }
5695 );
5696 } else {
5697 panic!("Expected Cast expression");
5698 }
5699 }
5700
5701 #[test]
5702 fn test_remove_precision_parameterized_types_varchar() {
5703 let cast_expr = Expression::Cast(Box::new(Cast {
5705 this: Expression::Literal(Box::new(Literal::String("hello".to_string()))),
5706 to: DataType::VarChar {
5707 length: Some(10),
5708 parenthesized_length: false,
5709 },
5710 trailing_comments: vec![],
5711 double_colon_syntax: false,
5712 format: None,
5713 default: None,
5714 inferred_type: None,
5715 }));
5716
5717 let result = remove_precision_parameterized_types(cast_expr).unwrap();
5718 if let Expression::Cast(cast) = result {
5719 assert_eq!(
5720 cast.to,
5721 DataType::VarChar {
5722 length: None,
5723 parenthesized_length: false
5724 }
5725 );
5726 } else {
5727 panic!("Expected Cast expression");
5728 }
5729 }
5730
5731 #[test]
5732 fn test_remove_precision_direct_cast() {
5733 let cast = Expression::Cast(Box::new(Cast {
5737 this: Expression::Literal(Box::new(Literal::Number("1".to_string()))),
5738 to: DataType::Decimal {
5739 precision: Some(10),
5740 scale: Some(2),
5741 },
5742 trailing_comments: vec![],
5743 double_colon_syntax: false,
5744 format: None,
5745 default: None,
5746 inferred_type: None,
5747 }));
5748
5749 let transformed = remove_precision_parameterized_types(cast).unwrap();
5750 let generated = gen(&transformed);
5751
5752 assert!(generated.contains("DECIMAL"));
5754 assert!(!generated.contains("(10"));
5755 }
5756
5757 #[test]
5758 fn test_epoch_cast_to_ts() {
5759 let cast_expr = Expression::Cast(Box::new(Cast {
5761 this: Expression::Literal(Box::new(Literal::String("epoch".to_string()))),
5762 to: DataType::Timestamp {
5763 precision: None,
5764 timezone: false,
5765 },
5766 trailing_comments: vec![],
5767 double_colon_syntax: false,
5768 format: None,
5769 default: None,
5770 inferred_type: None,
5771 }));
5772
5773 let result = epoch_cast_to_ts(cast_expr).unwrap();
5774 if let Expression::Cast(cast) = result {
5775 if let Expression::Literal(lit) = cast.this {
5776 if let Literal::String(s) = lit.as_ref() {
5777 assert_eq!(s, "1970-01-01 00:00:00");
5778 }
5779 } else {
5780 panic!("Expected string literal");
5781 }
5782 } else {
5783 panic!("Expected Cast expression");
5784 }
5785 }
5786
5787 #[test]
5788 fn test_epoch_cast_to_ts_preserves_non_epoch() {
5789 let cast_expr = Expression::Cast(Box::new(Cast {
5791 this: Expression::Literal(Box::new(Literal::String("2024-01-15".to_string()))),
5792 to: DataType::Timestamp {
5793 precision: None,
5794 timezone: false,
5795 },
5796 trailing_comments: vec![],
5797 double_colon_syntax: false,
5798 format: None,
5799 default: None,
5800 inferred_type: None,
5801 }));
5802
5803 let result = epoch_cast_to_ts(cast_expr).unwrap();
5804 if let Expression::Cast(cast) = result {
5805 if let Expression::Literal(lit) = cast.this {
5806 if let Literal::String(s) = lit.as_ref() {
5807 assert_eq!(s, "2024-01-15");
5808 }
5809 } else {
5810 panic!("Expected string literal");
5811 }
5812 } else {
5813 panic!("Expected Cast expression");
5814 }
5815 }
5816
5817 #[test]
5818 fn test_unqualify_columns() {
5819 let col = Expression::boxed_column(Column {
5821 name: Identifier::new("id".to_string()),
5822 table: Some(Identifier::new("users".to_string())),
5823 join_mark: false,
5824 trailing_comments: vec![],
5825 span: None,
5826 inferred_type: None,
5827 });
5828
5829 let result = unqualify_columns(col).unwrap();
5830 if let Expression::Column(c) = result {
5831 assert!(c.table.is_none());
5832 assert_eq!(c.name.name, "id");
5833 } else {
5834 panic!("Expected Column expression");
5835 }
5836 }
5837
5838 #[test]
5839 fn test_is_temporal_type() {
5840 assert!(is_temporal_type(&DataType::Date));
5841 assert!(is_temporal_type(&DataType::Timestamp {
5842 precision: None,
5843 timezone: false
5844 }));
5845 assert!(is_temporal_type(&DataType::Time {
5846 precision: None,
5847 timezone: false
5848 }));
5849 assert!(!is_temporal_type(&DataType::Int {
5850 length: None,
5851 integer_spelling: false
5852 }));
5853 assert!(!is_temporal_type(&DataType::VarChar {
5854 length: None,
5855 parenthesized_length: false
5856 }));
5857 }
5858
5859 #[test]
5860 fn test_eliminate_semi_join_basic() {
5861 use crate::expressions::{Join, TableRef};
5862
5863 let select = Expression::Select(Box::new(Select {
5865 expressions: vec![Expression::boxed_column(Column {
5866 name: Identifier::new("a".to_string()),
5867 table: None,
5868 join_mark: false,
5869 trailing_comments: vec![],
5870 span: None,
5871 inferred_type: None,
5872 })],
5873 from: Some(From {
5874 expressions: vec![Expression::Table(Box::new(TableRef::new("t1")))],
5875 }),
5876 joins: vec![Join {
5877 this: Expression::Table(Box::new(TableRef::new("t2"))),
5878 kind: JoinKind::Semi,
5879 on: Some(Expression::Eq(Box::new(BinaryOp {
5880 left: Expression::boxed_column(Column {
5881 name: Identifier::new("x".to_string()),
5882 table: None,
5883 join_mark: false,
5884 trailing_comments: vec![],
5885 span: None,
5886 inferred_type: None,
5887 }),
5888 right: Expression::boxed_column(Column {
5889 name: Identifier::new("y".to_string()),
5890 table: None,
5891 join_mark: false,
5892 trailing_comments: vec![],
5893 span: None,
5894 inferred_type: None,
5895 }),
5896 left_comments: vec![],
5897 operator_comments: vec![],
5898 trailing_comments: vec![],
5899 inferred_type: None,
5900 }))),
5901 using: vec![],
5902 use_inner_keyword: false,
5903 use_outer_keyword: false,
5904 deferred_condition: false,
5905 join_hint: None,
5906 match_condition: None,
5907 pivots: Vec::new(),
5908 comments: Vec::new(),
5909 nesting_group: 0,
5910 directed: false,
5911 }],
5912 ..Select::new()
5913 }));
5914
5915 let result = eliminate_semi_and_anti_joins(select).unwrap();
5916 if let Expression::Select(s) = result {
5917 assert!(s.joins.is_empty());
5919 assert!(s.where_clause.is_some());
5921 } else {
5922 panic!("Expected Select expression");
5923 }
5924 }
5925
5926 #[test]
5927 fn test_no_ilike_sql() {
5928 use crate::expressions::LikeOp;
5929
5930 let ilike_expr = Expression::ILike(Box::new(LikeOp {
5932 left: Expression::boxed_column(Column {
5933 name: Identifier::new("name".to_string()),
5934 table: None,
5935 join_mark: false,
5936 trailing_comments: vec![],
5937 span: None,
5938 inferred_type: None,
5939 }),
5940 right: Expression::Literal(Box::new(Literal::String("%test%".to_string()))),
5941 escape: None,
5942 quantifier: None,
5943 inferred_type: None,
5944 }));
5945
5946 let result = no_ilike_sql(ilike_expr).unwrap();
5947 if let Expression::Like(like) = result {
5948 if let Expression::Function(f) = &like.left {
5950 assert_eq!(f.name, "LOWER");
5951 } else {
5952 panic!("Expected LOWER function on left");
5953 }
5954 if let Expression::Function(f) = &like.right {
5956 assert_eq!(f.name, "LOWER");
5957 } else {
5958 panic!("Expected LOWER function on right");
5959 }
5960 } else {
5961 panic!("Expected Like expression");
5962 }
5963 }
5964
5965 #[test]
5966 fn test_no_trycast_sql() {
5967 let trycast_expr = Expression::TryCast(Box::new(Cast {
5969 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
5970 to: DataType::Int {
5971 length: None,
5972 integer_spelling: false,
5973 },
5974 trailing_comments: vec![],
5975 double_colon_syntax: false,
5976 format: None,
5977 default: None,
5978 inferred_type: None,
5979 }));
5980
5981 let result = no_trycast_sql(trycast_expr).unwrap();
5982 assert!(matches!(result, Expression::Cast(_)));
5983 }
5984
5985 #[test]
5986 fn test_no_safe_cast_sql() {
5987 let safe_cast_expr = Expression::SafeCast(Box::new(Cast {
5989 this: Expression::Literal(Box::new(Literal::String("123".to_string()))),
5990 to: DataType::Int {
5991 length: None,
5992 integer_spelling: false,
5993 },
5994 trailing_comments: vec![],
5995 double_colon_syntax: false,
5996 format: None,
5997 default: None,
5998 inferred_type: None,
5999 }));
6000
6001 let result = no_safe_cast_sql(safe_cast_expr).unwrap();
6002 assert!(matches!(result, Expression::Cast(_)));
6003 }
6004
6005 #[test]
6006 fn test_explode_to_unnest_presto() {
6007 let spark = Dialect::get(DialectType::Spark);
6008 let result = spark
6009 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::Presto)
6010 .unwrap();
6011 assert_eq!(
6012 result[0],
6013 "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))"
6014 );
6015 }
6016
6017 #[test]
6018 fn test_explode_to_unnest_bigquery() {
6019 let spark = Dialect::get(DialectType::Spark);
6020 let result = spark
6021 .transpile("SELECT EXPLODE(x) FROM tbl", DialectType::BigQuery)
6022 .unwrap();
6023 assert_eq!(
6024 result[0],
6025 "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))"
6026 );
6027 }
6028}