1use super::{DialectImpl, DialectType};
14use crate::error::Result;
15use crate::expressions::{
16 Alias, BinaryOp, Cast, Column, Cte, DataType, Exists, Expression, From, Function, Identifier,
17 In, Join, JoinKind, LikeOp, Literal, Null, Over, Paren, QuantifiedExpr, QuantifiedOp, Select,
18 Star, StringAggFunc, Subquery, TrimFunc, TrimPosition, Tuple, UnaryFunc, Values, Where,
19 WindowFunction,
20};
21#[cfg(feature = "generate")]
22use crate::generator::GeneratorConfig;
23use crate::tokens::TokenizerConfig;
24use std::collections::HashMap;
25
26pub struct TSQLDialect;
28
29impl DialectImpl for TSQLDialect {
30 fn dialect_type(&self) -> DialectType {
31 DialectType::TSQL
32 }
33
34 fn tokenizer_config(&self) -> TokenizerConfig {
35 let mut config = TokenizerConfig::default();
36 config.identifiers.insert('[', ']');
38 config.identifiers.insert('"', '"');
40 config.hex_number_strings = true;
42 config
43 }
44
45 #[cfg(feature = "generate")]
46
47 fn generator_config(&self) -> GeneratorConfig {
48 use crate::generator::IdentifierQuoteStyle;
49 GeneratorConfig {
50 identifier_quote: '[',
52 identifier_quote_style: IdentifierQuoteStyle::BRACKET,
53 dialect: Some(DialectType::TSQL),
54 limit_fetch_style: crate::generator::LimitFetchStyle::FetchFirst,
57 null_ordering_supported: false,
59 aggregate_filter_supported: false,
61 supports_select_into: true,
63 alter_table_include_column_keyword: false,
65 computed_column_with_type: false,
67 cte_recursive_keyword_required: false,
69 ensure_bools: true,
71 supports_single_arg_concat: false,
73 tablesample_seed_keyword: "REPEATABLE",
75 json_path_bracketed_key_supported: false,
77 supports_to_number: false,
79 set_op_modifiers: false,
81 copy_params_eq_required: true,
83 except_intersect_support_all_clause: false,
85 alter_set_wrapped: true,
87 try_supported: true,
89 nvl2_supported: false,
91 parameter_default_equals: true,
93 supports_window_exclude: false,
95 multi_arg_distinct: false,
97 locking_reads_supported: false,
99 ..Default::default()
100 }
101 }
102
103 #[cfg(feature = "transpile")]
104
105 fn transform_expr(&self, expr: Expression) -> Result<Expression> {
106 if let Expression::CreateTable(mut ct) = expr {
108 for col in &mut ct.columns {
109 if let Ok(Expression::DataType(new_dt)) =
110 self.transform_data_type(col.data_type.clone())
111 {
112 col.data_type = new_dt;
113 }
114 }
115 return Ok(Expression::CreateTable(ct));
116 }
117
118 match expr {
119 Expression::Select(mut select) => {
124 select.expressions = select
125 .expressions
126 .into_iter()
127 .map(|e| {
128 match e {
129 Expression::Eq(op) => {
130 match &op.left {
133 Expression::Column(col)
134 if col.table.is_none()
135 && !col.name.name.starts_with('@') =>
136 {
137 Expression::Alias(Box::new(Alias {
138 this: op.right,
139 alias: col.name.clone(),
140 column_aliases: Vec::new(),
141 alias_explicit_as: false,
142 alias_keyword: None,
143 pre_alias_comments: Vec::new(),
144 trailing_comments: Vec::new(),
145 inferred_type: None,
146 }))
147 }
148 Expression::Identifier(ident)
149 if !ident.name.starts_with('@') =>
150 {
151 Expression::Alias(Box::new(Alias {
152 this: op.right,
153 alias: ident.clone(),
154 column_aliases: Vec::new(),
155 alias_explicit_as: false,
156 alias_keyword: None,
157 pre_alias_comments: Vec::new(),
158 trailing_comments: Vec::new(),
159 inferred_type: None,
160 }))
161 }
162 _ => Expression::Eq(op),
163 }
164 }
165 other => other,
166 }
167 })
168 .collect();
169
170 Self::normalize_frame_incompatible_window_functions(&mut select);
171
172 let outer_qualifier = Self::single_select_source_qualifier(&select);
173
174 select.expressions = select
175 .expressions
176 .into_iter()
177 .map(|expression| {
178 Self::rewrite_tuple_in_subquery_predicates(
179 expression,
180 outer_qualifier.as_ref(),
181 false,
182 )
183 })
184 .collect();
185
186 for join in &mut select.joins {
187 if let Some(on) = join.on.take() {
188 join.on = Some(Self::rewrite_tuple_in_subquery_predicates(
189 on,
190 outer_qualifier.as_ref(),
191 false,
192 ));
193 }
194 if let Some(match_condition) = join.match_condition.take() {
195 join.match_condition = Some(Self::rewrite_tuple_in_subquery_predicates(
196 match_condition,
197 outer_qualifier.as_ref(),
198 false,
199 ));
200 }
201 }
202
203 if let Some(ref mut prewhere) = select.prewhere {
204 *prewhere = Self::rewrite_tuple_in_subquery_predicates(
205 std::mem::replace(prewhere, Expression::Null(Null)),
206 outer_qualifier.as_ref(),
207 false,
208 );
209 }
210
211 if let Some(ref mut where_clause) = select.where_clause {
212 where_clause.this = Self::rewrite_tuple_in_subquery_predicates(
213 std::mem::replace(&mut where_clause.this, Expression::Null(Null)),
214 outer_qualifier.as_ref(),
215 false,
216 );
217 }
218
219 if let Some(ref mut having) = select.having {
220 having.this = Self::rewrite_tuple_in_subquery_predicates(
221 std::mem::replace(&mut having.this, Expression::Null(Null)),
222 outer_qualifier.as_ref(),
223 false,
224 );
225 }
226
227 if let Some(ref mut qualify) = select.qualify {
228 qualify.this = Self::rewrite_tuple_in_subquery_predicates(
229 std::mem::replace(&mut qualify.this, Expression::Null(Null)),
230 outer_qualifier.as_ref(),
231 false,
232 );
233 }
234
235 if let Some(ref mut with) = select.with {
237 with.ctes = with
238 .ctes
239 .drain(..)
240 .map(|cte| self.transform_cte_inner(cte))
241 .collect();
242 }
243
244 Self::rewrite_comma_lateral_sources_to_joins(&mut select);
245
246 Ok(Expression::Select(select))
247 }
248
249 Expression::DataType(dt) => self.transform_data_type(dt),
251
252 Expression::IsTrue(it) => Ok(Self::boolean_test_predicate(it.this, true, it.not)),
256 Expression::IsFalse(it) => Ok(Self::boolean_test_predicate(it.this, false, it.not)),
257
258 Expression::In(mut in_expr) if in_expr.not => {
262 in_expr.not = false;
263 Ok(Expression::Not(Box::new(crate::expressions::UnaryOp {
264 this: Expression::In(in_expr),
265 inferred_type: None,
266 })))
267 }
268
269 Expression::Coalesce(f) if f.expressions.len() == 2 => Ok(Expression::Function(
272 Box::new(Function::new("ISNULL".to_string(), f.expressions)),
273 )),
274
275 Expression::Nvl(f) => Ok(Expression::Function(Box::new(Function::new(
277 "ISNULL".to_string(),
278 vec![f.this, f.expression],
279 )))),
280
281 Expression::GroupConcat(f) => Ok(Expression::StringAgg(Box::new(StringAggFunc {
283 this: f.this,
284 separator: f.separator,
285 order_by: f.order_by,
286 distinct: f.distinct,
287 filter: f.filter,
288 limit: None,
289 inferred_type: None,
290 }))),
291
292 Expression::ListAgg(f) => Ok(Expression::StringAgg(Box::new(StringAggFunc {
294 this: f.this,
295 separator: f.separator,
296 order_by: f.order_by,
297 distinct: f.distinct,
298 filter: f.filter,
299 limit: None,
300 inferred_type: None,
301 }))),
302
303 Expression::Sum(f) => Ok(Expression::Sum(Self::without_inert_ordering(f))),
307 Expression::Avg(f) => Ok(Expression::Avg(Self::without_inert_ordering(f))),
308 Expression::Min(f) => Ok(Expression::Min(Self::without_inert_ordering(f))),
309 Expression::Max(f) => Ok(Expression::Max(Self::without_inert_ordering(f))),
310 Expression::AnyValue(f) => Ok(Expression::Max(Self::without_inert_ordering(f))),
311 Expression::ApproxCountDistinct(f) => Ok(Expression::ApproxCountDistinct(
312 Self::without_inert_ordering(f),
313 )),
314
315 Expression::LogicalAnd(f) => Self::transform_logical_aggregate(f.this, f.filter, "MIN"),
318 Expression::LogicalOr(f) => Self::transform_logical_aggregate(f.this, f.filter, "MAX"),
319
320 Expression::WindowFunction(f) => Ok(Self::reassociate_logical_aggregate_window(*f)),
324
325 Expression::TryCast(c) => Ok(Expression::TryCast(c)),
327
328 Expression::SafeCast(c) => Ok(Expression::TryCast(c)),
330
331 Expression::ILike(op) => {
333 let lower_left = Expression::Lower(Box::new(UnaryFunc::new(op.left)));
336 let lower_right = Expression::Lower(Box::new(UnaryFunc::new(op.right)));
337 Ok(Expression::Like(Box::new(LikeOp {
338 left: lower_left,
339 right: lower_right,
340 escape: op.escape,
341 quantifier: op.quantifier,
342 inferred_type: None,
343 })))
344 }
345
346 Expression::Concat(op) => {
349 Ok(Expression::Add(op))
351 }
352
353 Expression::Random(_) => Ok(Expression::Rand(Box::new(crate::expressions::Rand {
355 seed: None,
356 lower: None,
357 upper: None,
358 }))),
359
360 Expression::Unnest(f) => {
362 Ok(Expression::Function(Box::new(Function::new(
365 "OPENJSON".to_string(),
366 vec![f.this],
367 ))))
368 }
369
370 Expression::Explode(f) => Ok(Expression::Function(Box::new(Function::new(
372 "OPENJSON".to_string(),
373 vec![f.this],
374 )))),
375
376 Expression::Join(join) => Ok(Expression::Join(Box::new(
378 Self::transform_lateral_join_to_apply(*join)?,
379 ))),
380
381 Expression::Length(f) => Ok(Expression::Function(Box::new(Function::new(
383 "LEN".to_string(),
384 vec![f.this],
385 )))),
386
387 Expression::Stddev(f) => Ok(Expression::Function(Box::new(Function::new(
389 "STDEV".to_string(),
390 vec![f.this],
391 )))),
392 Expression::StddevSamp(f) => Ok(Expression::Function(Box::new(Function::new(
393 "STDEV".to_string(),
394 vec![f.this],
395 )))),
396 Expression::StddevPop(f) => Ok(Expression::Function(Box::new(Function::new(
397 "STDEVP".to_string(),
398 vec![f.this],
399 )))),
400
401 Expression::Boolean(b) => {
403 let value = if b.value { 1 } else { 0 };
404 Ok(Expression::Literal(Box::new(
405 crate::expressions::Literal::Number(value.to_string()),
406 )))
407 }
408
409 Expression::Ln(f) => Ok(Expression::Function(Box::new(Function::new(
411 "LOG".to_string(),
412 vec![f.this],
413 )))),
414
415 Expression::CurrentDate(_) => Ok(Self::cast_getdate_to(DataType::Date)),
418
419 Expression::CurrentTime(_) => Ok(Self::cast_getdate_to(DataType::Time {
421 precision: None,
422 timezone: false,
423 })),
424
425 Expression::CurrentTimestamp(_) => Ok(Self::getdate()),
427
428 Expression::Localtimestamp(_) => Ok(Self::getdate()),
430
431 Expression::MakeDate(f) => Ok(Self::function(
433 "DATEFROMPARTS",
434 vec![f.year, f.month, f.day],
435 )),
436
437 Expression::DateDiff(f) => {
439 let unit_str = match f.unit {
441 Some(crate::expressions::IntervalUnit::Year) => "YEAR",
442 Some(crate::expressions::IntervalUnit::Quarter) => "QUARTER",
443 Some(crate::expressions::IntervalUnit::Month) => "MONTH",
444 Some(crate::expressions::IntervalUnit::Week) => "WEEK",
445 Some(crate::expressions::IntervalUnit::Day) => "DAY",
446 Some(crate::expressions::IntervalUnit::Hour) => "HOUR",
447 Some(crate::expressions::IntervalUnit::Minute) => "MINUTE",
448 Some(crate::expressions::IntervalUnit::Second) => "SECOND",
449 Some(crate::expressions::IntervalUnit::Millisecond) => "MILLISECOND",
450 Some(crate::expressions::IntervalUnit::Microsecond) => "MICROSECOND",
451 Some(crate::expressions::IntervalUnit::Nanosecond) => "NANOSECOND",
452 None => "DAY",
453 };
454 let unit = Expression::Identifier(crate::expressions::Identifier {
455 name: unit_str.to_string(),
456 quoted: false,
457 trailing_comments: Vec::new(),
458 span: None,
459 });
460 Ok(Expression::Function(Box::new(Function::new(
461 "DATEDIFF".to_string(),
462 vec![unit, f.expression, f.this], ))))
464 }
465
466 Expression::DateAdd(f) => {
468 let unit_str = match f.unit {
469 crate::expressions::IntervalUnit::Year => "YEAR",
470 crate::expressions::IntervalUnit::Quarter => "QUARTER",
471 crate::expressions::IntervalUnit::Month => "MONTH",
472 crate::expressions::IntervalUnit::Week => "WEEK",
473 crate::expressions::IntervalUnit::Day => "DAY",
474 crate::expressions::IntervalUnit::Hour => "HOUR",
475 crate::expressions::IntervalUnit::Minute => "MINUTE",
476 crate::expressions::IntervalUnit::Second => "SECOND",
477 crate::expressions::IntervalUnit::Millisecond => "MILLISECOND",
478 crate::expressions::IntervalUnit::Microsecond => "MICROSECOND",
479 crate::expressions::IntervalUnit::Nanosecond => "NANOSECOND",
480 };
481 let unit = Expression::Identifier(crate::expressions::Identifier {
482 name: unit_str.to_string(),
483 quoted: false,
484 trailing_comments: Vec::new(),
485 span: None,
486 });
487 Ok(Expression::Function(Box::new(Function::new(
488 "DATEADD".to_string(),
489 vec![unit, f.interval, f.this],
490 ))))
491 }
492
493 Expression::Uuid(_) => Ok(Expression::Function(Box::new(Function::new(
496 "NEWID".to_string(),
497 vec![],
498 )))),
499
500 Expression::IfFunc(f) => {
503 let false_val = f
504 .false_value
505 .unwrap_or(Expression::Null(crate::expressions::Null));
506 Ok(Expression::Function(Box::new(Function::new(
507 "IIF".to_string(),
508 vec![f.condition, f.true_value, false_val],
509 ))))
510 }
511
512 Expression::StringAgg(f) => Ok(Expression::StringAgg(f)),
515
516 Expression::LastDay(f) => Ok(Expression::Function(Box::new(Function::new(
518 "EOMONTH".to_string(),
519 vec![f.this.clone()],
520 )))),
521
522 Expression::Ceil(f) => Ok(Expression::Function(Box::new(Function::new(
524 "CEILING".to_string(),
525 vec![f.this],
526 )))),
527
528 Expression::Repeat(f) => Ok(Expression::Function(Box::new(Function::new(
530 "REPLICATE".to_string(),
531 vec![f.this, f.times],
532 )))),
533
534 Expression::Chr(f) => Ok(Expression::Function(Box::new(Function::new(
536 "CHAR".to_string(),
537 vec![f.this],
538 )))),
539
540 Expression::Overlay(f) => Ok(Self::overlay_to_stuff(*f)),
542
543 Expression::StartsWith(f) => Ok(Self::starts_with_predicate(f.this, f.expression)),
546
547 Expression::DecodeCase(mut f)
549 if f.expressions.len() == 2
550 && Self::literal_string(&f.expressions[1])
551 .is_some_and(|format| format.eq_ignore_ascii_case("hex")) =>
552 {
553 Ok(Self::tsql_convert(
554 DataType::Custom {
555 name: "VARBINARY(MAX)".to_string(),
556 },
557 f.expressions.remove(0),
558 Some(2),
559 ))
560 }
561
562 Expression::ToNumber(f) => Ok(Self::to_number_or_fallback(*f)),
565
566 Expression::VarPop(f) => Ok(Expression::Function(Box::new(Function::new(
569 "VARP".to_string(),
570 vec![f.this],
571 )))),
572
573 Expression::Variance(f) => Ok(Expression::Function(Box::new(Function::new(
575 "VAR".to_string(),
576 vec![f.this],
577 )))),
578 Expression::VarSamp(f) => Ok(Expression::Function(Box::new(Function::new(
579 "VAR".to_string(),
580 vec![f.this],
581 )))),
582
583 Expression::MD5Digest(f) => Ok(Expression::Function(Box::new(Function::new(
586 "HASHBYTES".to_string(),
587 vec![Expression::string("MD5"), *f.this],
588 )))),
589
590 Expression::SHA(f) => Ok(Expression::Function(Box::new(Function::new(
592 "HASHBYTES".to_string(),
593 vec![Expression::string("SHA1"), f.this],
594 )))),
595
596 Expression::SHA1Digest(f) => Ok(Expression::Function(Box::new(Function::new(
598 "HASHBYTES".to_string(),
599 vec![Expression::string("SHA1"), f.this],
600 )))),
601
602 Expression::ArrayToString(f) => Ok(Expression::Function(Box::new(Function::new(
605 "STRING_AGG".to_string(),
606 vec![f.this],
607 )))),
608
609 Expression::AutoIncrementColumnConstraint(_) => Ok(Expression::Function(Box::new(
612 Function::new("IDENTITY".to_string(), vec![]),
613 ))),
614
615 Expression::CreateView(mut view) => {
619 view.name.catalog = None;
621 Ok(Expression::CreateView(view))
622 }
623
624 Expression::DropView(mut view) => {
625 view.name.catalog = None;
627 Ok(Expression::DropView(view))
628 }
629
630 Expression::JSONExtract(e) if e.variant_extract.is_some() => {
634 let path = match *e.expression {
635 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
636 let Literal::String(s) = lit.as_ref() else {
637 unreachable!()
638 };
639 let normalized = if s.starts_with('$') {
640 s.clone()
641 } else if s.starts_with('[') {
642 format!("${}", s)
643 } else {
644 format!("$.{}", s)
645 };
646 Expression::Literal(Box::new(Literal::String(normalized)))
647 }
648 other => other,
649 };
650 let json_query = Expression::Function(Box::new(Function::new(
651 "JSON_QUERY".to_string(),
652 vec![(*e.this).clone(), path.clone()],
653 )));
654 let json_value = Expression::Function(Box::new(Function::new(
655 "JSON_VALUE".to_string(),
656 vec![*e.this, path],
657 )));
658 Ok(Expression::Function(Box::new(Function::new(
659 "ISNULL".to_string(),
660 vec![json_query, json_value],
661 ))))
662 }
663
664 Expression::Function(f) => self.transform_function(*f),
666
667 Expression::AggregateFunction(f) => self.transform_aggregate_function(f),
669
670 Expression::Cte(cte) => self.transform_cte(*cte),
673
674 Expression::Subquery(subquery) => self.transform_subquery(*subquery),
677
678 Expression::JsonQuery(f) => {
680 let json_query = Expression::Function(Box::new(Function::new(
681 "JSON_QUERY".to_string(),
682 vec![f.this.clone(), f.path.clone()],
683 )));
684 let json_value = Expression::Function(Box::new(Function::new(
685 "JSON_VALUE".to_string(),
686 vec![f.this, f.path],
687 )));
688 Ok(Expression::Function(Box::new(Function::new(
689 "ISNULL".to_string(),
690 vec![json_query, json_value],
691 ))))
692 }
693 Expression::JsonValue(f) => Ok(Expression::Function(Box::new(Function::new(
695 "JSON_VALUE".to_string(),
696 vec![f.this, f.path],
697 )))),
698
699 Expression::Any(q) => {
703 Ok(Self::lower_scalar_array_quantifier(&q, true).unwrap_or(Expression::Any(q)))
704 }
705 Expression::All(q) => {
706 Ok(Self::lower_scalar_array_quantifier(&q, false).unwrap_or(Expression::All(q)))
707 }
708
709 _ => Ok(expr),
711 }
712 }
713}
714
715#[cfg(feature = "transpile")]
716impl TSQLDialect {
717 fn getdate() -> Expression {
718 Expression::Function(Box::new(Function::new("GETDATE".to_string(), vec![])))
719 }
720
721 fn cast_getdate_to(to: DataType) -> Expression {
722 Expression::Cast(Box::new(Cast {
723 this: Self::getdate(),
724 to,
725 trailing_comments: Vec::new(),
726 double_colon_syntax: false,
727 format: None,
728 default: None,
729 inferred_type: None,
730 }))
731 }
732
733 fn cast(this: Expression, to: DataType) -> Expression {
734 Expression::Cast(Box::new(Cast {
735 this,
736 to,
737 trailing_comments: Vec::new(),
738 double_colon_syntax: false,
739 format: None,
740 default: None,
741 inferred_type: None,
742 }))
743 }
744
745 fn function(name: impl Into<String>, args: Vec<Expression>) -> Expression {
746 Expression::Function(Box::new(Function::new(name, args)))
747 }
748
749 fn make_time(mut args: Vec<Expression>) -> Expression {
750 let seconds = args.pop().expect("MAKE_TIME has three arguments");
751 let minute = args.pop().expect("MAKE_TIME has three arguments");
752 let hour = args.pop().expect("MAKE_TIME has three arguments");
753
754 if let Some((whole_seconds, microseconds)) = Self::literal_time_parts(&seconds) {
755 let (fractions, precision) = if microseconds == 0 {
756 (Expression::number(0), Expression::number(0))
757 } else {
758 (Expression::number(microseconds), Expression::number(6))
759 };
760
761 return Self::function(
762 "TIMEFROMPARTS",
763 vec![
764 hour,
765 minute,
766 Expression::number(whole_seconds),
767 fractions,
768 precision,
769 ],
770 );
771 }
772
773 let rounded_microseconds = Self::cast(
777 Self::function(
778 "ROUND",
779 vec![
780 Expression::Mul(Box::new(BinaryOp::new(
781 seconds,
782 Expression::number(1_000_000),
783 ))),
784 Expression::number(0),
785 ],
786 ),
787 DataType::BigInt { length: None },
788 );
789
790 Self::function(
791 "TIMEFROMPARTS",
792 vec![
793 hour,
794 minute,
795 Expression::Div(Box::new(BinaryOp::new(
796 rounded_microseconds.clone(),
797 Expression::number(1_000_000),
798 ))),
799 Expression::Mod(Box::new(BinaryOp::new(
800 rounded_microseconds,
801 Expression::number(1_000_000),
802 ))),
803 Expression::number(6),
804 ],
805 )
806 }
807
808 fn literal_time_parts(expr: &Expression) -> Option<(i64, i64)> {
809 let value = match expr {
810 Expression::Literal(lit) => match lit.as_ref() {
811 Literal::Number(value) => value.parse::<f64>().ok()?,
812 _ => return None,
813 },
814 Expression::Paren(paren) => return Self::literal_time_parts(&paren.this),
815 Expression::Cast(cast) | Expression::TryCast(cast) | Expression::SafeCast(cast)
816 if Self::is_numeric_data_type(&cast.to) =>
817 {
818 let parts = Self::literal_time_parts(&cast.this);
819 return match (&cast.to, parts) {
820 (_, Some((0, 0))) => Some((0, 0)),
824 (DataType::Float { .. } | DataType::Double { .. }, parts) => parts,
825 _ => None,
826 };
827 }
828 _ => return None,
829 };
830
831 if !value.is_finite() || value < 0.0 || value > i64::MAX as f64 / 1_000_000.0 {
832 return None;
833 }
834
835 let total_microseconds = (value * 1_000_000.0).round() as i64;
836 Some((
837 total_microseconds / 1_000_000,
838 total_microseconds % 1_000_000,
839 ))
840 }
841
842 fn lower(this: Expression) -> Expression {
843 Expression::Lower(Box::new(UnaryFunc::new(this)))
844 }
845
846 fn tsql_convert(to: DataType, expression: Expression, style: Option<i64>) -> Expression {
847 let mut args = vec![Expression::DataType(to), expression];
848 if let Some(style) = style {
849 args.push(Expression::number(style));
850 }
851 Self::function("CONVERT", args)
852 }
853
854 fn tsql_hex_text(expression: Expression, varchar_type: DataType) -> Expression {
855 Self::lower(Self::tsql_convert(varchar_type, expression, Some(2)))
856 }
857
858 fn tsql_hex_from_varbinary(expression: Expression) -> Expression {
859 Self::tsql_hex_text(
860 Self::cast(
861 expression,
862 DataType::Custom {
863 name: "VARBINARY(MAX)".to_string(),
864 },
865 ),
866 DataType::Text,
867 )
868 }
869
870 fn tsql_postgres_to_hex(expression: Expression) -> Expression {
871 let hex = Self::tsql_hex_from_varbinary(expression);
872 let without_leading_zeroes = Self::function("LTRIM", vec![hex, Expression::string("0")]);
873 let non_empty = Self::function(
874 "NULLIF",
875 vec![without_leading_zeroes, Expression::string("")],
876 );
877 Self::function("ISNULL", vec![non_empty, Expression::string("0")])
878 }
879
880 fn tsql_md5_hex(expression: Expression) -> Expression {
881 let hashbytes = Self::function("HASHBYTES", vec![Expression::string("MD5"), expression]);
882 Self::tsql_hex_text(
883 hashbytes,
884 DataType::VarChar {
885 length: Some(32),
886 parenthesized_length: false,
887 },
888 )
889 }
890
891 fn overlay_to_stuff(f: crate::expressions::OverlayFunc) -> Expression {
892 let length = f
893 .length
894 .unwrap_or_else(|| Self::function("LEN", vec![f.replacement.clone()]));
895 Self::function("STUFF", vec![f.this, f.from, length, f.replacement])
896 }
897
898 fn starts_with_predicate(this: Expression, prefix: Expression) -> Expression {
899 let prefix_len = Self::function("LEN", vec![prefix.clone()]);
900 let left_prefix = Self::function("LEFT", vec![this, prefix_len]);
901 Self::eq(left_prefix, prefix)
902 }
903
904 fn to_number_or_fallback(f: crate::expressions::ToNumber) -> Expression {
905 let crate::expressions::ToNumber {
906 this,
907 format,
908 nlsparam,
909 precision,
910 scale,
911 safe,
912 safe_name,
913 } = f;
914
915 if nlsparam.is_none()
916 && precision.is_none()
917 && scale.is_none()
918 && safe.is_none()
919 && safe_name.is_none()
920 {
921 if let Some(format) = format.as_deref() {
922 if let Some(scale) = Self::simple_to_number_scale(format) {
923 return Self::function(
924 "TRY_CONVERT",
925 vec![
926 Expression::DataType(DataType::Decimal {
927 precision: Some(18),
928 scale: Some(scale),
929 }),
930 *this,
931 ],
932 );
933 }
934 }
935 }
936
937 Expression::ToNumber(Box::new(crate::expressions::ToNumber {
938 this,
939 format,
940 nlsparam,
941 precision,
942 scale,
943 safe,
944 safe_name,
945 }))
946 }
947
948 fn simple_to_number_scale(format: &Expression) -> Option<u32> {
949 let format = Self::literal_string(format)?;
950 let format = format.strip_prefix("FM").unwrap_or(format);
951 let mut saw_digit = false;
952 let mut saw_decimal = false;
953 let mut scale = 0u32;
954
955 for ch in format.chars() {
956 match ch {
957 '9' | '0' => {
958 saw_digit = true;
959 if saw_decimal {
960 scale = scale.checked_add(1)?;
961 }
962 }
963 '.' if !saw_decimal => saw_decimal = true,
964 ',' | ' ' => return None,
967 _ => return None,
968 }
969 }
970
971 saw_digit.then_some(scale)
972 }
973
974 fn binary(
975 left: Expression,
976 right: Expression,
977 op: fn(Box<BinaryOp>) -> Expression,
978 ) -> Expression {
979 op(Box::new(BinaryOp {
980 left,
981 right,
982 left_comments: Vec::new(),
983 operator_comments: Vec::new(),
984 trailing_comments: Vec::new(),
985 inferred_type: None,
986 }))
987 }
988
989 fn eq(left: Expression, right: Expression) -> Expression {
990 Self::binary(left, right, Expression::Eq)
991 }
992
993 fn or(left: Expression, right: Expression) -> Expression {
994 Self::binary(left, right, Expression::Or)
995 }
996
997 fn not(this: Expression) -> Expression {
998 Expression::Not(Box::new(crate::expressions::UnaryOp {
999 this,
1000 inferred_type: None,
1001 }))
1002 }
1003
1004 fn is_null(this: Expression) -> Expression {
1005 Expression::IsNull(Box::new(crate::expressions::IsNull {
1006 this,
1007 not: false,
1008 postfix_form: false,
1009 }))
1010 }
1011
1012 fn paren(this: Expression) -> Expression {
1013 Expression::Paren(Box::new(Paren {
1014 this,
1015 trailing_comments: Vec::new(),
1016 }))
1017 }
1018
1019 fn boolean_test_case_for_predicate(
1020 predicate: Expression,
1021 test_true: bool,
1022 negated: bool,
1023 ) -> Expression {
1024 let condition = match (test_true, negated) {
1025 (true, false) => predicate,
1026 (false, false) => Self::not(predicate),
1027 (true, true) => {
1028 return Expression::Case(Box::new(crate::expressions::Case {
1029 operand: None,
1030 whens: vec![(predicate, Expression::number(0))],
1031 else_: Some(Expression::number(1)),
1032 comments: Vec::new(),
1033 inferred_type: None,
1034 }))
1035 }
1036 (false, true) => {
1037 return Expression::Case(Box::new(crate::expressions::Case {
1038 operand: None,
1039 whens: vec![(Self::not(predicate), Expression::number(0))],
1040 else_: Some(Expression::number(1)),
1041 comments: Vec::new(),
1042 inferred_type: None,
1043 }))
1044 }
1045 };
1046
1047 Expression::Case(Box::new(crate::expressions::Case {
1048 operand: None,
1049 whens: vec![(condition, Expression::number(1))],
1050 else_: Some(Expression::number(0)),
1051 comments: Vec::new(),
1052 inferred_type: None,
1053 }))
1054 }
1055
1056 fn boolean_test_predicate(operand: Expression, test_true: bool, negated: bool) -> Expression {
1057 if Self::is_boolean_predicate_operand(&operand) {
1058 return match (test_true, negated) {
1059 (true, false) => operand,
1060 (false, false) => Self::not(operand),
1061 _ => Self::eq(
1062 Self::boolean_test_case_for_predicate(operand, test_true, negated),
1063 Expression::number(1),
1064 ),
1065 };
1066 }
1067
1068 match (test_true, negated) {
1069 (true, false) => Self::eq(operand, Expression::number(1)),
1070 (false, false) => Self::eq(operand, Expression::number(0)),
1071 (true, true) => Self::or(
1072 Self::eq(operand.clone(), Expression::number(0)),
1073 Self::is_null(operand),
1074 ),
1075 (false, true) => Self::or(
1076 Self::eq(operand.clone(), Expression::number(1)),
1077 Self::is_null(operand),
1078 ),
1079 }
1080 }
1081
1082 fn is_boolean_predicate_operand(expr: &Expression) -> bool {
1083 match expr {
1084 Expression::Paren(paren) => Self::is_boolean_predicate_operand(&paren.this),
1085 Expression::Eq(_)
1086 | Expression::Neq(_)
1087 | Expression::Lt(_)
1088 | Expression::Lte(_)
1089 | Expression::Gt(_)
1090 | Expression::Gte(_)
1091 | Expression::Is(_)
1092 | Expression::IsNull(_)
1093 | Expression::IsTrue(_)
1094 | Expression::IsFalse(_)
1095 | Expression::Like(_)
1096 | Expression::ILike(_)
1097 | Expression::SimilarTo(_)
1098 | Expression::Glob(_)
1099 | Expression::RegexpLike(_)
1100 | Expression::In(_)
1101 | Expression::Between(_)
1102 | Expression::Exists(_)
1103 | Expression::And(_)
1104 | Expression::Or(_)
1105 | Expression::Not(_)
1106 | Expression::Any(_)
1107 | Expression::All(_)
1108 | Expression::EqualNull(_) => true,
1109 _ => false,
1110 }
1111 }
1112
1113 fn scalar_array_comparison_values(expr: &Expression) -> Option<Vec<Expression>> {
1114 let (mut values, element_type) = Self::scalar_array_comparison_values_inner(expr)?;
1115 if let Some(to) = element_type {
1116 values = values
1117 .into_iter()
1118 .map(|value| Self::cast_scalar_array_comparison_value(value, to.clone()))
1119 .collect();
1120 }
1121 Some(values)
1122 }
1123
1124 fn lower_scalar_array_quantifier(
1125 quantified: &QuantifiedExpr,
1126 is_any: bool,
1127 ) -> Option<Expression> {
1128 let op = quantified.op.as_ref()?;
1129 let expressions = Self::scalar_array_comparison_values(&quantified.subquery)?;
1130
1131 if expressions.is_empty() {
1132 return Some(Self::eq(
1133 Expression::number(1),
1134 Expression::number(if is_any { 0 } else { 1 }),
1135 ));
1136 }
1137
1138 if is_any && matches!(op, QuantifiedOp::Eq) {
1139 return Some(Self::in_list(quantified.this.clone(), expressions, false));
1140 }
1141
1142 if !is_any && matches!(op, QuantifiedOp::Neq) {
1143 return Some(Self::in_list(quantified.this.clone(), expressions, true));
1144 }
1145
1146 let mut comparisons = expressions
1147 .into_iter()
1148 .map(|expression| Self::quantified_comparison(quantified.this.clone(), expression, op));
1149 let first = comparisons.next()?;
1150 let combined = comparisons.fold(first, |left, right| {
1151 if is_any {
1152 Expression::Or(Box::new(BinaryOp::new(left, right)))
1153 } else {
1154 Expression::And(Box::new(BinaryOp::new(left, right)))
1155 }
1156 });
1157
1158 Some(Self::paren(combined))
1159 }
1160
1161 fn in_list(this: Expression, expressions: Vec<Expression>, not: bool) -> Expression {
1162 Expression::In(Box::new(In {
1163 this,
1164 expressions,
1165 query: None,
1166 not,
1167 global: false,
1168 unnest: None,
1169 is_field: false,
1170 }))
1171 }
1172
1173 fn quantified_comparison(left: Expression, right: Expression, op: &QuantifiedOp) -> Expression {
1174 let binary = Box::new(BinaryOp::new(left, right));
1175 match op {
1176 QuantifiedOp::Eq => Expression::Eq(binary),
1177 QuantifiedOp::Neq => Expression::Neq(binary),
1178 QuantifiedOp::Lt => Expression::Lt(binary),
1179 QuantifiedOp::Lte => Expression::Lte(binary),
1180 QuantifiedOp::Gt => Expression::Gt(binary),
1181 QuantifiedOp::Gte => Expression::Gte(binary),
1182 }
1183 }
1184
1185 fn scalar_array_comparison_values_inner(
1186 expr: &Expression,
1187 ) -> Option<(Vec<Expression>, Option<DataType>)> {
1188 match expr {
1189 Expression::ArrayFunc(a) => Some((a.expressions.clone(), None)),
1190 Expression::Array(a) => Some((a.expressions.clone(), None)),
1191 Expression::Tuple(t) => Some((t.expressions.clone(), None)),
1192 Expression::Paren(p) => Self::scalar_array_comparison_values_inner(&p.this),
1193 Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1194 let DataType::Array { element_type, .. } = &c.to else {
1195 return None;
1196 };
1197 let (values, _) = Self::scalar_array_comparison_values_inner(&c.this)?;
1198 Some((values, Some((**element_type).clone())))
1199 }
1200 _ => None,
1201 }
1202 }
1203
1204 fn cast_scalar_array_comparison_value(value: Expression, to: DataType) -> Expression {
1205 if matches!(&value, Expression::Cast(c) if c.to == to) {
1206 return value;
1207 }
1208
1209 Expression::Cast(Box::new(Cast {
1210 this: value,
1211 to,
1212 trailing_comments: Vec::new(),
1213 double_colon_syntax: false,
1214 format: None,
1215 default: None,
1216 inferred_type: None,
1217 }))
1218 }
1219
1220 fn normalize_frame_incompatible_window_functions(select: &mut Select) {
1221 let window_map: HashMap<String, Over> = select
1222 .windows
1223 .as_ref()
1224 .map(|windows| {
1225 windows
1226 .iter()
1227 .map(|window| (window.name.name.to_lowercase(), window.spec.clone()))
1228 .collect()
1229 })
1230 .unwrap_or_default();
1231
1232 for expr in &mut select.expressions {
1233 Self::normalize_frame_incompatible_window_expr(expr, &window_map);
1234 }
1235
1236 if let Some(order_by) = &mut select.order_by {
1237 for ordered in &mut order_by.expressions {
1238 Self::normalize_frame_incompatible_window_expr(&mut ordered.this, &window_map);
1239 }
1240 }
1241
1242 if let Some(qualify) = &mut select.qualify {
1243 Self::normalize_frame_incompatible_window_expr(&mut qualify.this, &window_map);
1244 }
1245 }
1246
1247 fn normalize_frame_incompatible_window_expr(
1248 expr: &mut Expression,
1249 window_map: &HashMap<String, Over>,
1250 ) {
1251 match expr {
1252 Expression::WindowFunction(wf) => {
1253 Self::normalize_frame_incompatible_window_expr(&mut wf.this, window_map);
1254
1255 if !Self::is_tsql_frame_incompatible_window_function(&wf.this) {
1256 return;
1257 }
1258
1259 wf.over.frame = None;
1260
1261 let Some(window_name) = wf.over.window_name.clone() else {
1262 return;
1263 };
1264 let Some(named_spec) =
1265 Self::resolve_named_window_spec(&window_name.name, window_map, &mut Vec::new())
1266 else {
1267 return;
1268 };
1269
1270 if named_spec.frame.is_none() {
1271 return;
1272 }
1273
1274 if wf.over.partition_by.is_empty() {
1275 wf.over.partition_by = named_spec.partition_by;
1276 }
1277 if wf.over.order_by.is_empty() {
1278 wf.over.order_by = named_spec.order_by;
1279 }
1280 wf.over.window_name = None;
1281 wf.over.frame = None;
1282 }
1283 Expression::Alias(alias) => {
1284 Self::normalize_frame_incompatible_window_expr(&mut alias.this, window_map);
1285 }
1286 Expression::Paren(paren) => {
1287 Self::normalize_frame_incompatible_window_expr(&mut paren.this, window_map);
1288 }
1289 Expression::Cast(cast) | Expression::TryCast(cast) | Expression::SafeCast(cast) => {
1290 Self::normalize_frame_incompatible_window_expr(&mut cast.this, window_map);
1291 }
1292 Expression::Function(function) => {
1293 for arg in &mut function.args {
1294 Self::normalize_frame_incompatible_window_expr(arg, window_map);
1295 }
1296 }
1297 Expression::Case(case) => {
1298 if let Some(operand) = &mut case.operand {
1299 Self::normalize_frame_incompatible_window_expr(operand, window_map);
1300 }
1301 for (condition, result) in &mut case.whens {
1302 Self::normalize_frame_incompatible_window_expr(condition, window_map);
1303 Self::normalize_frame_incompatible_window_expr(result, window_map);
1304 }
1305 if let Some(else_expr) = &mut case.else_ {
1306 Self::normalize_frame_incompatible_window_expr(else_expr, window_map);
1307 }
1308 }
1309 Expression::And(op)
1310 | Expression::Or(op)
1311 | Expression::Add(op)
1312 | Expression::Sub(op)
1313 | Expression::Mul(op)
1314 | Expression::Div(op)
1315 | Expression::Mod(op)
1316 | Expression::Eq(op)
1317 | Expression::Neq(op)
1318 | Expression::Lt(op)
1319 | Expression::Lte(op)
1320 | Expression::Gt(op)
1321 | Expression::Gte(op)
1322 | Expression::Match(op)
1323 | Expression::BitwiseAnd(op)
1324 | Expression::BitwiseOr(op)
1325 | Expression::BitwiseXor(op)
1326 | Expression::Concat(op)
1327 | Expression::Adjacent(op)
1328 | Expression::TsMatch(op)
1329 | Expression::PropertyEQ(op)
1330 | Expression::ArrayContainsAll(op)
1331 | Expression::ArrayContainedBy(op)
1332 | Expression::ArrayOverlaps(op)
1333 | Expression::JSONBContainsAllTopKeys(op)
1334 | Expression::JSONBContainsAnyTopKeys(op)
1335 | Expression::JSONBDeleteAtPath(op)
1336 | Expression::ExtendsLeft(op)
1337 | Expression::ExtendsRight(op)
1338 | Expression::Is(op)
1339 | Expression::MemberOf(op) => {
1340 Self::normalize_frame_incompatible_window_expr(&mut op.left, window_map);
1341 Self::normalize_frame_incompatible_window_expr(&mut op.right, window_map);
1342 }
1343 Expression::Like(op) | Expression::ILike(op) => {
1344 Self::normalize_frame_incompatible_window_expr(&mut op.left, window_map);
1345 Self::normalize_frame_incompatible_window_expr(&mut op.right, window_map);
1346 if let Some(escape) = &mut op.escape {
1347 Self::normalize_frame_incompatible_window_expr(escape, window_map);
1348 }
1349 }
1350 Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1351 Self::normalize_frame_incompatible_window_expr(&mut op.this, window_map);
1352 }
1353 Expression::In(in_expr) => {
1354 Self::normalize_frame_incompatible_window_expr(&mut in_expr.this, window_map);
1355 for value in &mut in_expr.expressions {
1356 Self::normalize_frame_incompatible_window_expr(value, window_map);
1357 }
1358 }
1359 Expression::Between(between) => {
1360 Self::normalize_frame_incompatible_window_expr(&mut between.this, window_map);
1361 Self::normalize_frame_incompatible_window_expr(&mut between.low, window_map);
1362 Self::normalize_frame_incompatible_window_expr(&mut between.high, window_map);
1363 }
1364 Expression::IsNull(is_null) => {
1365 Self::normalize_frame_incompatible_window_expr(&mut is_null.this, window_map);
1366 }
1367 Expression::IsTrue(is_true) | Expression::IsFalse(is_true) => {
1368 Self::normalize_frame_incompatible_window_expr(&mut is_true.this, window_map);
1369 }
1370 _ => {}
1371 }
1372 }
1373
1374 fn is_tsql_frame_incompatible_window_function(expr: &Expression) -> bool {
1375 matches!(
1376 expr,
1377 Expression::RowNumber(_)
1378 | Expression::Rank(_)
1379 | Expression::DenseRank(_)
1380 | Expression::NTile(_)
1381 | Expression::Ntile(_)
1382 | Expression::Lead(_)
1383 | Expression::Lag(_)
1384 | Expression::PercentRank(_)
1385 | Expression::CumeDist(_)
1386 )
1387 }
1388
1389 fn resolve_named_window_spec(
1390 name: &str,
1391 window_map: &HashMap<String, Over>,
1392 seen: &mut Vec<String>,
1393 ) -> Option<Over> {
1394 let key = name.to_lowercase();
1395 if seen.iter().any(|seen_name| seen_name == &key) {
1396 return None;
1397 }
1398
1399 let named_spec = window_map.get(&key)?.clone();
1400 seen.push(key);
1401
1402 let mut resolved = if let Some(base_window) = &named_spec.window_name {
1403 Self::resolve_named_window_spec(&base_window.name, window_map, seen)
1404 .unwrap_or_else(Self::empty_over)
1405 } else {
1406 Self::empty_over()
1407 };
1408
1409 if !named_spec.partition_by.is_empty() {
1410 resolved.partition_by = named_spec.partition_by;
1411 }
1412 if !named_spec.order_by.is_empty() {
1413 resolved.order_by = named_spec.order_by;
1414 }
1415 if named_spec.frame.is_some() {
1416 resolved.frame = named_spec.frame;
1417 }
1418
1419 Some(resolved)
1420 }
1421
1422 fn empty_over() -> Over {
1423 Over {
1424 window_name: None,
1425 partition_by: Vec::new(),
1426 order_by: Vec::new(),
1427 frame: None,
1428 alias: None,
1429 }
1430 }
1431
1432 const LATERAL_WRAPPER_SOURCE_ALIAS: &'static str = "_polyglot_lateral_source";
1433 const LATERAL_WRAPPER_OUTPUT_ALIAS: &'static str = "_polyglot_lateral";
1434
1435 fn transform_lateral_join_to_apply(mut join: Join) -> Result<Join> {
1436 let Some(apply_kind) = Self::lateral_apply_kind(&join) else {
1437 return Ok(join);
1438 };
1439
1440 let original_alias = Self::table_expression_alias(&join.this);
1441 let on = join.on.take();
1442 let rhs = Self::remove_lateral_marker(join.this);
1443 join.this = if on
1444 .as_ref()
1445 .is_some_and(|expr| !Self::is_true_condition(expr))
1446 {
1447 Self::wrap_lateral_apply_rhs(rhs, on.expect("checked as Some"), original_alias)?
1448 } else {
1449 rhs
1450 };
1451 join.using.clear();
1452 join.kind = apply_kind;
1453 join.use_inner_keyword = false;
1454 join.use_outer_keyword = false;
1455 join.deferred_condition = false;
1456 join.join_hint = None;
1457 join.match_condition = None;
1458 join.directed = false;
1459 Ok(join)
1460 }
1461
1462 fn rewrite_comma_lateral_sources_to_joins(select: &mut Select) {
1463 let Some(from) = select.from.as_mut() else {
1464 return;
1465 };
1466 let has_comma_lateral = from
1467 .expressions
1468 .iter()
1469 .skip(1)
1470 .any(Self::is_lateral_table_expression);
1471 let has_apply_join = select
1472 .joins
1473 .iter()
1474 .any(|join| matches!(join.kind, JoinKind::CrossApply | JoinKind::OuterApply));
1475
1476 if from.expressions.len() < 2 || (!has_comma_lateral && !has_apply_join) {
1477 return;
1478 }
1479
1480 let mut expressions = std::mem::take(&mut from.expressions).into_iter();
1481 let Some(first) = expressions.next() else {
1482 return;
1483 };
1484 from.expressions = vec![first];
1485
1486 let mut joins = expressions
1487 .map(|source| {
1488 if Self::is_lateral_table_expression(&source) {
1489 Self::new_join(Self::remove_lateral_marker(source), JoinKind::CrossApply)
1490 } else {
1491 Self::new_join(source, JoinKind::Cross)
1492 }
1493 })
1494 .collect::<Vec<_>>();
1495 joins.append(&mut select.joins);
1496 select.joins = joins;
1497 }
1498
1499 fn new_join(this: Expression, kind: JoinKind) -> Join {
1500 Join {
1501 this,
1502 on: None,
1503 using: Vec::new(),
1504 kind,
1505 use_inner_keyword: false,
1506 use_outer_keyword: false,
1507 deferred_condition: false,
1508 join_hint: None,
1509 match_condition: None,
1510 pivots: Vec::new(),
1511 comments: Vec::new(),
1512 nesting_group: 0,
1513 directed: false,
1514 }
1515 }
1516
1517 fn lateral_apply_kind(join: &Join) -> Option<JoinKind> {
1518 if !join.using.is_empty() {
1519 return None;
1520 }
1521
1522 match join.kind {
1523 JoinKind::Lateral => Some(JoinKind::CrossApply),
1524 JoinKind::LeftLateral => Some(JoinKind::OuterApply),
1525 JoinKind::Cross | JoinKind::Inner | JoinKind::Implicit
1526 if Self::is_lateral_table_expression(&join.this) =>
1527 {
1528 Some(JoinKind::CrossApply)
1529 }
1530 JoinKind::Left if Self::is_lateral_table_expression(&join.this) => {
1531 Some(JoinKind::OuterApply)
1532 }
1533 _ => None,
1534 }
1535 }
1536
1537 fn is_true_condition(expr: &Expression) -> bool {
1538 match expr {
1539 Expression::Boolean(boolean) => boolean.value,
1540 Expression::Literal(lit) => {
1541 matches!(lit.as_ref(), Literal::Number(value) if value.trim() == "1")
1542 }
1543 Expression::Eq(op) => {
1544 Self::is_true_condition(&op.left) && Self::is_true_condition(&op.right)
1545 }
1546 Expression::Paren(paren) => Self::is_true_condition(&paren.this),
1547 _ => false,
1548 }
1549 }
1550
1551 fn table_expression_alias(expr: &Expression) -> Option<(Identifier, Vec<Identifier>)> {
1552 match expr {
1553 Expression::Subquery(subquery) => subquery
1554 .alias
1555 .clone()
1556 .map(|alias| (alias, subquery.column_aliases.clone())),
1557 Expression::Alias(alias) if !alias.alias.is_empty() => {
1558 Some((alias.alias.clone(), alias.column_aliases.clone()))
1559 }
1560 Expression::Lateral(lateral) => lateral.alias.as_ref().map(|alias| {
1561 (
1562 if lateral.alias_quoted {
1563 Identifier::quoted(alias)
1564 } else {
1565 Identifier::new(alias)
1566 },
1567 lateral
1568 .column_aliases
1569 .iter()
1570 .map(|column| Identifier::new(column.clone()))
1571 .collect(),
1572 )
1573 }),
1574 _ => None,
1575 }
1576 }
1577
1578 fn wrap_lateral_apply_rhs(
1579 rhs: Expression,
1580 predicate: Expression,
1581 original_alias: Option<(Identifier, Vec<Identifier>)>,
1582 ) -> Result<Expression> {
1583 let (outer_alias, column_aliases) = original_alias.unwrap_or_else(|| {
1584 (
1585 Identifier::new(Self::LATERAL_WRAPPER_OUTPUT_ALIAS),
1586 Vec::new(),
1587 )
1588 });
1589 let inner_alias = Identifier::new(Self::LATERAL_WRAPPER_SOURCE_ALIAS);
1590 let source =
1591 Self::with_table_expression_alias(rhs, inner_alias.clone(), column_aliases.clone());
1592 let predicate = Self::rewrite_column_qualifier(predicate, &outer_alias, &inner_alias)?;
1593
1594 let mut select = Select::new();
1595 select.expressions = vec![Expression::Star(Star {
1596 table: None,
1597 except: None,
1598 replace: None,
1599 rename: None,
1600 trailing_comments: Vec::new(),
1601 span: None,
1602 })];
1603 select.from = Some(crate::expressions::From {
1604 expressions: vec![source],
1605 });
1606 select.where_clause = Some(Where { this: predicate });
1607
1608 Ok(Expression::Subquery(Box::new(Subquery {
1609 this: Expression::Select(Box::new(select)),
1610 alias: Some(outer_alias),
1611 column_aliases,
1612 alias_explicit_as: true,
1613 alias_keyword: None,
1614 order_by: None,
1615 limit: None,
1616 offset: None,
1617 distribute_by: None,
1618 sort_by: None,
1619 cluster_by: None,
1620 lateral: false,
1621 modifiers_inside: false,
1622 trailing_comments: Vec::new(),
1623 inferred_type: None,
1624 })))
1625 }
1626
1627 fn with_table_expression_alias(
1628 expr: Expression,
1629 alias: Identifier,
1630 column_aliases: Vec<Identifier>,
1631 ) -> Expression {
1632 match expr {
1633 Expression::Subquery(mut subquery) => {
1634 subquery.alias = Some(alias);
1635 subquery.column_aliases = column_aliases;
1636 subquery.alias_explicit_as = true;
1637 subquery.alias_keyword = None;
1638 Expression::Subquery(subquery)
1639 }
1640 Expression::Alias(mut aliased) => {
1641 aliased.alias = alias;
1642 aliased.column_aliases = column_aliases;
1643 aliased.alias_explicit_as = true;
1644 aliased.alias_keyword = None;
1645 Expression::Alias(aliased)
1646 }
1647 Expression::Table(mut table) => {
1648 table.alias = Some(alias);
1649 table.alias_explicit_as = true;
1650 table.column_aliases = column_aliases;
1651 Expression::Table(table)
1652 }
1653 other => Expression::Alias(Box::new(Alias {
1654 this: other,
1655 alias,
1656 column_aliases,
1657 alias_explicit_as: true,
1658 alias_keyword: None,
1659 pre_alias_comments: Vec::new(),
1660 trailing_comments: Vec::new(),
1661 inferred_type: None,
1662 })),
1663 }
1664 }
1665
1666 fn rewrite_column_qualifier(
1667 expr: Expression,
1668 from: &Identifier,
1669 to: &Identifier,
1670 ) -> Result<Expression> {
1671 super::transform_recursive(expr, &|expr| {
1672 Ok(match expr {
1673 Expression::Column(mut column)
1674 if column
1675 .table
1676 .as_ref()
1677 .is_some_and(|table| Self::same_identifier(table, from)) =>
1678 {
1679 column.table = Some(to.clone());
1680 Expression::Column(column)
1681 }
1682 other => other,
1683 })
1684 })
1685 }
1686
1687 fn same_identifier(left: &Identifier, right: &Identifier) -> bool {
1688 if left.quoted || right.quoted {
1689 left.quoted == right.quoted && left.name == right.name
1690 } else {
1691 left.name.eq_ignore_ascii_case(&right.name)
1692 }
1693 }
1694
1695 fn is_lateral_table_expression(expr: &Expression) -> bool {
1696 match expr {
1697 Expression::Subquery(subquery) => subquery.lateral,
1698 Expression::Lateral(_) => true,
1699 Expression::Alias(alias) => Self::is_lateral_table_expression(&alias.this),
1700 _ => false,
1701 }
1702 }
1703
1704 fn remove_lateral_marker(expr: Expression) -> Expression {
1705 match expr {
1706 Expression::Subquery(mut subquery) => {
1707 subquery.lateral = false;
1708 Expression::Subquery(subquery)
1709 }
1710 Expression::Lateral(lateral) => Self::lateral_to_table_expression(*lateral),
1711 Expression::Alias(mut alias) => {
1712 alias.this = Self::remove_lateral_marker(alias.this);
1713 Expression::Alias(alias)
1714 }
1715 other => other,
1716 }
1717 }
1718
1719 fn lateral_to_table_expression(lateral: crate::expressions::Lateral) -> Expression {
1720 let expr = *lateral.this;
1721 let Some(alias) = lateral.alias else {
1722 return expr;
1723 };
1724
1725 Expression::Alias(Box::new(Alias {
1726 this: expr,
1727 alias: if lateral.alias_quoted {
1728 Identifier::quoted(alias)
1729 } else {
1730 Identifier::new(alias)
1731 },
1732 column_aliases: lateral
1733 .column_aliases
1734 .into_iter()
1735 .map(Identifier::new)
1736 .collect(),
1737 alias_explicit_as: true,
1738 alias_keyword: None,
1739 pre_alias_comments: Vec::new(),
1740 trailing_comments: Vec::new(),
1741 inferred_type: None,
1742 }))
1743 }
1744
1745 fn rewrite_tuple_in_subquery_predicates(
1746 expr: Expression,
1747 outer_qualifier: Option<&Identifier>,
1748 under_not: bool,
1749 ) -> Expression {
1750 match expr {
1751 Expression::In(in_expr) if !under_not => {
1752 let in_expr = *in_expr;
1753 Self::tuple_in_subquery_to_exists(&in_expr, outer_qualifier, in_expr.not)
1754 .unwrap_or_else(|| Expression::In(Box::new(in_expr)))
1755 }
1756 Expression::Eq(op) if !under_not => {
1757 let op = *op;
1758 Self::tuple_subquery_eq_to_exists(&op, outer_qualifier)
1759 .unwrap_or_else(|| Expression::Eq(Box::new(op)))
1760 }
1761 Expression::And(mut op) => {
1762 op.left =
1763 Self::rewrite_tuple_in_subquery_predicates(op.left, outer_qualifier, under_not);
1764 op.right = Self::rewrite_tuple_in_subquery_predicates(
1765 op.right,
1766 outer_qualifier,
1767 under_not,
1768 );
1769 Expression::And(op)
1770 }
1771 Expression::Or(mut op) => {
1772 op.left =
1773 Self::rewrite_tuple_in_subquery_predicates(op.left, outer_qualifier, under_not);
1774 op.right = Self::rewrite_tuple_in_subquery_predicates(
1775 op.right,
1776 outer_qualifier,
1777 under_not,
1778 );
1779 Expression::Or(op)
1780 }
1781 Expression::Paren(mut paren) => {
1782 paren.this = Self::rewrite_tuple_in_subquery_predicates(
1783 paren.this,
1784 outer_qualifier,
1785 under_not,
1786 );
1787 Expression::Paren(paren)
1788 }
1789 Expression::Not(mut not) => {
1790 if let Some(rewritten) = Self::direct_tuple_subquery_predicate_to_exists(
1791 ¬.this,
1792 outer_qualifier,
1793 true,
1794 ) {
1795 rewritten
1796 } else {
1797 not.this =
1798 Self::rewrite_tuple_in_subquery_predicates(not.this, outer_qualifier, true);
1799 Expression::Not(not)
1800 }
1801 }
1802 Expression::Alias(mut alias) => {
1803 alias.this = Self::rewrite_tuple_in_subquery_predicates(
1804 alias.this,
1805 outer_qualifier,
1806 under_not,
1807 );
1808 Expression::Alias(alias)
1809 }
1810 Expression::Cast(mut cast) => {
1811 cast.this = Self::rewrite_tuple_in_subquery_predicates(
1812 cast.this,
1813 outer_qualifier,
1814 under_not,
1815 );
1816 if let Some(format) = cast.format.take() {
1817 cast.format = Some(Box::new(Self::rewrite_tuple_in_subquery_predicates(
1818 *format,
1819 outer_qualifier,
1820 under_not,
1821 )));
1822 }
1823 if let Some(default) = cast.default.take() {
1824 cast.default = Some(Box::new(Self::rewrite_tuple_in_subquery_predicates(
1825 *default,
1826 outer_qualifier,
1827 under_not,
1828 )));
1829 }
1830 Expression::Cast(cast)
1831 }
1832 Expression::TryCast(mut cast) => {
1833 cast.this = Self::rewrite_tuple_in_subquery_predicates(
1834 cast.this,
1835 outer_qualifier,
1836 under_not,
1837 );
1838 Expression::TryCast(cast)
1839 }
1840 Expression::SafeCast(mut cast) => {
1841 cast.this = Self::rewrite_tuple_in_subquery_predicates(
1842 cast.this,
1843 outer_qualifier,
1844 under_not,
1845 );
1846 Expression::SafeCast(cast)
1847 }
1848 Expression::Case(mut case) => {
1849 if let Some(operand) = case.operand.take() {
1850 case.operand = Some(Self::rewrite_tuple_in_subquery_predicates(
1851 operand,
1852 outer_qualifier,
1853 under_not,
1854 ));
1855 }
1856 case.whens = case
1857 .whens
1858 .into_iter()
1859 .map(|(condition, result)| {
1860 (
1861 Self::rewrite_tuple_in_subquery_predicates(
1862 condition,
1863 outer_qualifier,
1864 false,
1865 ),
1866 Self::rewrite_tuple_in_subquery_predicates(
1867 result,
1868 outer_qualifier,
1869 under_not,
1870 ),
1871 )
1872 })
1873 .collect();
1874 if let Some(else_) = case.else_.take() {
1875 case.else_ = Some(Self::rewrite_tuple_in_subquery_predicates(
1876 else_,
1877 outer_qualifier,
1878 under_not,
1879 ));
1880 }
1881 Expression::Case(case)
1882 }
1883 Expression::IfFunc(mut if_func) => {
1884 if_func.condition = Self::rewrite_tuple_in_subquery_predicates(
1885 if_func.condition,
1886 outer_qualifier,
1887 false,
1888 );
1889 if_func.true_value = Self::rewrite_tuple_in_subquery_predicates(
1890 if_func.true_value,
1891 outer_qualifier,
1892 under_not,
1893 );
1894 if let Some(false_value) = if_func.false_value.take() {
1895 if_func.false_value = Some(Self::rewrite_tuple_in_subquery_predicates(
1896 false_value,
1897 outer_qualifier,
1898 under_not,
1899 ));
1900 }
1901 Expression::IfFunc(if_func)
1902 }
1903 other => other,
1904 }
1905 }
1906
1907 fn direct_tuple_subquery_predicate_to_exists(
1908 expr: &Expression,
1909 outer_qualifier: Option<&Identifier>,
1910 negated: bool,
1911 ) -> Option<Expression> {
1912 match expr {
1913 Expression::In(in_expr) => {
1914 Self::tuple_in_subquery_to_exists(in_expr, outer_qualifier, negated ^ in_expr.not)
1915 }
1916 Expression::Paren(paren) => Self::direct_tuple_subquery_predicate_to_exists(
1917 &paren.this,
1918 outer_qualifier,
1919 negated,
1920 ),
1921 _ => None,
1922 }
1923 }
1924
1925 fn tuple_in_subquery_to_exists(
1926 in_expr: &In,
1927 outer_qualifier: Option<&Identifier>,
1928 negated: bool,
1929 ) -> Option<Expression> {
1930 if in_expr.unnest.is_some() {
1931 return None;
1932 }
1933
1934 let left_expressions = Self::tuple_expressions(&in_expr.this)?;
1935 let mut select = Self::select_from_in_rhs(in_expr)?;
1936
1937 if left_expressions.len() != select.expressions.len() || left_expressions.is_empty() {
1938 return None;
1939 }
1940
1941 let inner_qualifier = Self::single_select_source_qualifier(&select);
1942 let mut predicates = Vec::with_capacity(left_expressions.len() + 1);
1943 for (projection, left) in select
1944 .expressions
1945 .iter()
1946 .cloned()
1947 .zip(left_expressions.iter().cloned())
1948 {
1949 let inner = Self::tuple_in_projection_expr(projection, inner_qualifier.as_ref())?;
1950 let outer = Self::qualify_tuple_operand(left, outer_qualifier);
1951 predicates.push(if negated {
1952 Self::tuple_component_may_match(inner, outer)
1953 } else {
1954 Expression::Eq(Box::new(BinaryOp::new(inner, outer)))
1955 });
1956 }
1957
1958 if let Some(where_clause) = select.where_clause.take() {
1959 predicates.push(where_clause.this);
1960 }
1961
1962 select.expressions = vec![Expression::number(1)];
1963 select.where_clause = Some(Where {
1964 this: Self::and_all(predicates)?,
1965 });
1966
1967 Some(Expression::Exists(Box::new(Exists {
1968 this: Expression::Select(Box::new(select)),
1969 not: negated,
1970 })))
1971 }
1972
1973 fn tuple_subquery_eq_to_exists(
1974 op: &BinaryOp,
1975 outer_qualifier: Option<&Identifier>,
1976 ) -> Option<Expression> {
1977 if let Some((tuple_expr, query_expr)) = Self::tuple_and_query_operands(&op.left, &op.right)
1978 {
1979 return Self::tuple_subquery_eq_to_exists_inner(
1980 tuple_expr,
1981 query_expr,
1982 outer_qualifier,
1983 );
1984 }
1985
1986 if let Some((tuple_expr, query_expr)) = Self::tuple_and_query_operands(&op.right, &op.left)
1987 {
1988 return Self::tuple_subquery_eq_to_exists_inner(
1989 tuple_expr,
1990 query_expr,
1991 outer_qualifier,
1992 );
1993 }
1994
1995 None
1996 }
1997
1998 fn tuple_subquery_eq_to_exists_inner(
1999 tuple_expr: &Expression,
2000 query_expr: &Expression,
2001 outer_qualifier: Option<&Identifier>,
2002 ) -> Option<Expression> {
2003 let tuple_expressions = Self::tuple_expressions(tuple_expr)?;
2004 let mut select = Self::select_from_query_expression(query_expr)?;
2005
2006 if tuple_expressions.len() != select.expressions.len() || tuple_expressions.is_empty() {
2007 return None;
2008 }
2009
2010 let inner_qualifier = Self::single_select_source_qualifier(&select);
2011 let mut predicates = Vec::with_capacity(tuple_expressions.len() + 1);
2012 for (projection, tuple_operand) in select
2013 .expressions
2014 .iter()
2015 .cloned()
2016 .zip(tuple_expressions.iter().cloned())
2017 {
2018 let inner = Self::tuple_in_projection_expr(projection, inner_qualifier.as_ref())?;
2019 let outer = Self::qualify_tuple_operand(tuple_operand, outer_qualifier);
2020 predicates.push(Expression::Eq(Box::new(BinaryOp::new(inner, outer))));
2021 }
2022
2023 if let Some(where_clause) = select.where_clause.take() {
2024 predicates.push(where_clause.this);
2025 }
2026
2027 select.expressions = vec![Expression::number(1)];
2028 select.where_clause = Some(Where {
2029 this: Self::and_all(predicates)?,
2030 });
2031
2032 Some(Expression::Exists(Box::new(Exists {
2033 this: Expression::Select(Box::new(select)),
2034 not: false,
2035 })))
2036 }
2037
2038 fn tuple_and_query_operands<'a>(
2039 tuple_candidate: &'a Expression,
2040 query_candidate: &'a Expression,
2041 ) -> Option<(&'a Expression, &'a Expression)> {
2042 if Self::tuple_expressions(tuple_candidate).is_some()
2043 && Self::select_from_query_expression(query_candidate).is_some()
2044 {
2045 Some((tuple_candidate, query_candidate))
2046 } else {
2047 None
2048 }
2049 }
2050
2051 fn select_from_query_expression(expr: &Expression) -> Option<Select> {
2052 match expr {
2053 Expression::Select(select) => Some((**select).clone()),
2054 Expression::Subquery(subquery) => Self::select_from_query_expression(&subquery.this),
2055 Expression::Paren(paren) => Self::select_from_query_expression(&paren.this),
2056 _ => None,
2057 }
2058 }
2059
2060 fn select_from_in_rhs(in_expr: &In) -> Option<Select> {
2061 if let Some(values) = Self::values_from_in_rhs(in_expr) {
2062 return Self::select_from_values(&values);
2063 }
2064
2065 if let Some(query) = &in_expr.query {
2066 return if in_expr.expressions.is_empty() {
2067 Self::select_from_query_expression(query)
2068 } else {
2069 None
2070 };
2071 }
2072
2073 if in_expr.expressions.len() == 1 {
2074 Self::select_from_query_expression(&in_expr.expressions[0])
2075 } else {
2076 None
2077 }
2078 }
2079
2080 fn values_from_in_rhs(in_expr: &In) -> Option<Values> {
2081 if let Some(query) = &in_expr.query {
2082 return if in_expr.expressions.is_empty() {
2083 Self::values_from_expression(query)
2084 } else {
2085 None
2086 };
2087 }
2088
2089 if in_expr.expressions.len() == 1 {
2090 if let Some(values) = Self::values_from_expression(&in_expr.expressions[0]) {
2091 return Some(values);
2092 }
2093 }
2094
2095 let Expression::Function(first_row) = in_expr.expressions.first()? else {
2097 return None;
2098 };
2099 if !first_row.name.eq_ignore_ascii_case("VALUES") {
2100 return None;
2101 }
2102
2103 let mut rows = Vec::with_capacity(in_expr.expressions.len());
2104 rows.push(Tuple {
2105 expressions: first_row.args.clone(),
2106 });
2107 for row in &in_expr.expressions[1..] {
2108 rows.push(Self::tuple_from_values_row(row)?);
2109 }
2110
2111 Some(Values {
2112 expressions: rows,
2113 alias: None,
2114 column_aliases: Vec::new(),
2115 })
2116 }
2117
2118 fn values_from_expression(expr: &Expression) -> Option<Values> {
2119 match expr {
2120 Expression::Values(values) => Some((**values).clone()),
2121 Expression::Paren(paren) => Self::values_from_expression(&paren.this),
2122 Expression::Subquery(subquery) => Self::values_from_expression(&subquery.this),
2123 _ => None,
2124 }
2125 }
2126
2127 fn tuple_from_values_row(expr: &Expression) -> Option<Tuple> {
2128 match expr {
2129 Expression::Tuple(tuple) => Some((**tuple).clone()),
2130 Expression::Paren(paren) => match &paren.this {
2131 Expression::Tuple(tuple) => Some((**tuple).clone()),
2132 other => Some(Tuple {
2133 expressions: vec![other.clone()],
2134 }),
2135 },
2136 _ => None,
2137 }
2138 }
2139
2140 fn select_from_values(values: &Values) -> Option<Select> {
2141 let column_count = values.expressions.first()?.expressions.len();
2142 if column_count == 0
2143 || values
2144 .expressions
2145 .iter()
2146 .any(|row| row.expressions.len() != column_count)
2147 {
2148 return None;
2149 }
2150
2151 let source_alias = Identifier::new("_polyglot_values");
2152 let column_aliases = (1..=column_count)
2153 .map(|index| Identifier::new(format!("_polyglot_value_{index}")))
2154 .collect::<Vec<_>>();
2155 let projections = column_aliases
2156 .iter()
2157 .cloned()
2158 .map(|column| Self::column_from_identifier(column, Some(source_alias.clone())))
2159 .collect();
2160
2161 let mut source_values = values.clone();
2162 source_values.alias = None;
2163 source_values.column_aliases.clear();
2164
2165 let source = Expression::Subquery(Box::new(Subquery {
2166 this: Expression::Values(Box::new(source_values)),
2167 alias: Some(source_alias),
2168 column_aliases,
2169 alias_explicit_as: true,
2170 alias_keyword: None,
2171 order_by: None,
2172 limit: None,
2173 offset: None,
2174 distribute_by: None,
2175 sort_by: None,
2176 cluster_by: None,
2177 lateral: false,
2178 modifiers_inside: false,
2179 trailing_comments: Vec::new(),
2180 inferred_type: None,
2181 }));
2182
2183 let mut select = Select::new();
2184 select.expressions = projections;
2185 select.from = Some(From {
2186 expressions: vec![source],
2187 });
2188 Some(select)
2189 }
2190
2191 fn tuple_expressions(expr: &Expression) -> Option<&[Expression]> {
2192 match expr {
2193 Expression::Tuple(tuple) => Some(&tuple.expressions),
2194 Expression::Function(function) if function.name.eq_ignore_ascii_case("ROW") => {
2195 Some(&function.args)
2196 }
2197 Expression::Paren(paren) => Self::tuple_expressions(&paren.this),
2198 _ => None,
2199 }
2200 }
2201
2202 fn tuple_in_projection_expr(
2203 expr: Expression,
2204 qualifier: Option<&Identifier>,
2205 ) -> Option<Expression> {
2206 match expr {
2207 Expression::Alias(alias) => Self::tuple_in_projection_expr(alias.this, qualifier),
2208 Expression::Column(mut column) => {
2209 if column.table.is_none() {
2210 column.table = qualifier.cloned();
2211 }
2212 Some(Expression::Column(column))
2213 }
2214 Expression::Identifier(identifier) => {
2215 Some(Self::column_from_identifier(identifier, qualifier.cloned()))
2216 }
2217 Expression::Dot(_) => Some(expr),
2218 other => Some(Self::qualify_tuple_expression(other, qualifier)),
2219 }
2220 }
2221
2222 fn qualify_tuple_operand(expr: Expression, qualifier: Option<&Identifier>) -> Expression {
2223 Self::qualify_tuple_expression(expr, qualifier)
2224 }
2225
2226 fn qualify_tuple_expression(expr: Expression, qualifier: Option<&Identifier>) -> Expression {
2227 match expr {
2228 Expression::Column(mut column) => {
2229 if column.table.is_none() {
2230 column.table = qualifier.cloned();
2231 }
2232 Expression::Column(column)
2233 }
2234 Expression::Identifier(identifier) => {
2235 Self::column_from_identifier(identifier, qualifier.cloned())
2236 }
2237 Expression::Alias(mut alias) => {
2238 alias.this = Self::qualify_tuple_expression(alias.this, qualifier);
2239 Expression::Alias(alias)
2240 }
2241 Expression::Paren(mut paren) => {
2242 paren.this = Self::qualify_tuple_expression(paren.this, qualifier);
2243 Expression::Paren(paren)
2244 }
2245 Expression::Cast(mut cast) => {
2246 cast.this = Self::qualify_tuple_expression(cast.this, qualifier);
2247 if let Some(format) = cast.format.take() {
2248 cast.format =
2249 Some(Box::new(Self::qualify_tuple_expression(*format, qualifier)));
2250 }
2251 if let Some(default) = cast.default.take() {
2252 cast.default = Some(Box::new(Self::qualify_tuple_expression(
2253 *default, qualifier,
2254 )));
2255 }
2256 Expression::Cast(cast)
2257 }
2258 Expression::TryCast(mut cast) => {
2259 cast.this = Self::qualify_tuple_expression(cast.this, qualifier);
2260 Expression::TryCast(cast)
2261 }
2262 Expression::SafeCast(mut cast) => {
2263 cast.this = Self::qualify_tuple_expression(cast.this, qualifier);
2264 Expression::SafeCast(cast)
2265 }
2266 Expression::Function(mut function) => {
2267 function.args = function
2268 .args
2269 .into_iter()
2270 .map(|arg| Self::qualify_tuple_expression(arg, qualifier))
2271 .collect();
2272 Expression::Function(function)
2273 }
2274 Expression::Add(mut op) => {
2275 op.left = Self::qualify_tuple_expression(op.left, qualifier);
2276 op.right = Self::qualify_tuple_expression(op.right, qualifier);
2277 Expression::Add(op)
2278 }
2279 Expression::Sub(mut op) => {
2280 op.left = Self::qualify_tuple_expression(op.left, qualifier);
2281 op.right = Self::qualify_tuple_expression(op.right, qualifier);
2282 Expression::Sub(op)
2283 }
2284 Expression::Mul(mut op) => {
2285 op.left = Self::qualify_tuple_expression(op.left, qualifier);
2286 op.right = Self::qualify_tuple_expression(op.right, qualifier);
2287 Expression::Mul(op)
2288 }
2289 Expression::Div(mut op) => {
2290 op.left = Self::qualify_tuple_expression(op.left, qualifier);
2291 op.right = Self::qualify_tuple_expression(op.right, qualifier);
2292 Expression::Div(op)
2293 }
2294 Expression::Mod(mut op) => {
2295 op.left = Self::qualify_tuple_expression(op.left, qualifier);
2296 op.right = Self::qualify_tuple_expression(op.right, qualifier);
2297 Expression::Mod(op)
2298 }
2299 other => other,
2300 }
2301 }
2302
2303 fn tuple_component_may_match(inner: Expression, outer: Expression) -> Expression {
2304 Self::paren(
2305 Self::or_all(vec![
2306 Expression::Eq(Box::new(BinaryOp::new(inner.clone(), outer.clone()))),
2307 Self::is_null(inner),
2308 Self::is_null(outer),
2309 ])
2310 .expect("tuple component match condition is non-empty"),
2311 )
2312 }
2313
2314 fn column_from_identifier(identifier: Identifier, table: Option<Identifier>) -> Expression {
2315 Expression::Column(Box::new(Column {
2316 name: identifier,
2317 table,
2318 join_mark: false,
2319 trailing_comments: Vec::new(),
2320 span: None,
2321 inferred_type: None,
2322 }))
2323 }
2324
2325 fn single_select_source_qualifier(select: &Select) -> Option<Identifier> {
2326 if !select.joins.is_empty() {
2327 return None;
2328 }
2329
2330 let from = select.from.as_ref()?;
2331 if from.expressions.len() != 1 {
2332 return None;
2333 }
2334
2335 Self::source_qualifier(&from.expressions[0])
2336 }
2337
2338 fn source_qualifier(source: &Expression) -> Option<Identifier> {
2339 match source {
2340 Expression::Table(table) => table.alias.clone().or_else(|| Some(table.name.clone())),
2341 Expression::Subquery(subquery) => subquery.alias.clone(),
2342 _ => None,
2343 }
2344 }
2345
2346 fn and_all(mut predicates: Vec<Expression>) -> Option<Expression> {
2347 if predicates.is_empty() {
2348 return None;
2349 }
2350
2351 let first = predicates.remove(0);
2352 Some(predicates.into_iter().fold(first, |left, right| {
2353 Expression::And(Box::new(BinaryOp::new(left, right)))
2354 }))
2355 }
2356
2357 fn or_all(mut predicates: Vec<Expression>) -> Option<Expression> {
2358 if predicates.is_empty() {
2359 return None;
2360 }
2361
2362 let first = predicates.remove(0);
2363 Some(predicates.into_iter().fold(first, |left, right| {
2364 Expression::Or(Box::new(BinaryOp::new(left, right)))
2365 }))
2366 }
2367
2368 pub(super) fn transform_data_type(
2370 &self,
2371 dt: crate::expressions::DataType,
2372 ) -> Result<Expression> {
2373 use crate::expressions::DataType;
2374 let transformed = match dt {
2375 DataType::Boolean => DataType::Custom {
2377 name: "BIT".to_string(),
2378 },
2379 DataType::Int { .. } => dt,
2381 DataType::Decimal { precision, scale } => DataType::Custom {
2384 name: if let (Some(p), Some(s)) = (&precision, &scale) {
2385 format!("NUMERIC({}, {})", p, s)
2386 } else if let Some(p) = &precision {
2387 format!("NUMERIC({})", p)
2388 } else {
2389 "NUMERIC".to_string()
2390 },
2391 },
2392 DataType::Text => DataType::Custom {
2394 name: "VARCHAR(MAX)".to_string(),
2395 },
2396 DataType::Timestamp { .. } => DataType::Custom {
2398 name: "DATETIME2".to_string(),
2399 },
2400 DataType::Uuid => DataType::Custom {
2402 name: "UNIQUEIDENTIFIER".to_string(),
2403 },
2404 DataType::Custom { ref name } => {
2406 let upper = name.trim().to_uppercase();
2407 let (base_name, precision, _scale) = Self::parse_type_precision_and_scale(&upper);
2408 match base_name.as_str() {
2409 "DOUBLE PRECISION" => DataType::Custom {
2411 name: "FLOAT".to_string(),
2412 },
2413 "BPCHAR" => {
2415 if let Some(len) = precision {
2416 DataType::Char { length: Some(len) }
2417 } else {
2418 DataType::Char { length: None }
2419 }
2420 }
2421 _ => dt,
2422 }
2423 }
2424 other => other,
2426 };
2427 Ok(Expression::DataType(transformed))
2428 }
2429
2430 pub(super) fn parse_type_precision_and_scale(name: &str) -> (String, Option<u32>, Option<u32>) {
2432 if let Some(paren_pos) = name.find('(') {
2433 let base = name[..paren_pos].to_string();
2434 let rest = &name[paren_pos + 1..];
2435 if let Some(close_pos) = rest.find(')') {
2436 let args = &rest[..close_pos];
2437 let parts: Vec<&str> = args.split(',').map(|s| s.trim()).collect();
2438 let precision = parts.first().and_then(|s| s.parse::<u32>().ok());
2439 let scale = parts.get(1).and_then(|s| s.parse::<u32>().ok());
2440 return (base, precision, scale);
2441 }
2442 (base, None, None)
2443 } else {
2444 (name.to_string(), None, None)
2445 }
2446 }
2447
2448 fn transform_logical_aggregate(
2449 condition: Expression,
2450 filter: Option<Expression>,
2451 aggregate_name: &str,
2452 ) -> Result<Expression> {
2453 let false_condition = Expression::Not(Box::new(crate::expressions::UnaryOp {
2454 this: condition.clone(),
2455 inferred_type: None,
2456 }));
2457 let true_condition = Self::apply_aggregate_filter(condition, filter.clone());
2458 let false_condition = Self::apply_aggregate_filter(false_condition, filter);
2459
2460 let case_expr = Expression::Case(Box::new(crate::expressions::Case {
2461 operand: None,
2462 whens: vec![
2463 (true_condition, Expression::number(1)),
2464 (false_condition, Expression::number(0)),
2465 ],
2466 else_: Some(Expression::null()),
2467 comments: Vec::new(),
2468 inferred_type: None,
2469 }));
2470
2471 let case_expr = crate::transforms::ensure_bools(case_expr)?;
2472 let aggregate = Expression::Function(Box::new(Function::new(
2473 aggregate_name.to_string(),
2474 vec![case_expr],
2475 )));
2476
2477 Ok(Expression::Cast(Box::new(Cast {
2478 this: aggregate,
2479 to: DataType::Custom {
2480 name: "BIT".to_string(),
2481 },
2482 trailing_comments: Vec::new(),
2483 double_colon_syntax: false,
2484 format: None,
2485 default: None,
2486 inferred_type: None,
2487 })))
2488 }
2489
2490 fn reassociate_logical_aggregate_window(mut window: WindowFunction) -> Expression {
2491 let Expression::Cast(mut cast) = window.this else {
2492 return Expression::WindowFunction(Box::new(window));
2493 };
2494
2495 if !Self::is_transformed_logical_aggregate_cast(&cast) {
2496 window.this = Expression::Cast(cast);
2497 return Expression::WindowFunction(Box::new(window));
2498 }
2499
2500 window.this = cast.this;
2501 cast.this = Expression::WindowFunction(Box::new(window));
2502 Expression::Cast(cast)
2503 }
2504
2505 fn is_transformed_logical_aggregate_cast(cast: &Cast) -> bool {
2506 if !matches!(
2507 &cast.to,
2508 DataType::Custom { name } if name.eq_ignore_ascii_case("BIT")
2509 ) {
2510 return false;
2511 }
2512
2513 let Expression::Function(function) = &cast.this else {
2514 return false;
2515 };
2516 if !matches!(function.name.to_ascii_uppercase().as_str(), "MIN" | "MAX")
2517 || function.args.len() != 1
2518 {
2519 return false;
2520 }
2521
2522 matches!(
2523 function.args.first(),
2524 Some(Expression::Case(case))
2525 if case.operand.is_none()
2526 && case.whens.len() == 2
2527 && matches!(case.else_.as_ref(), Some(Expression::Null(_)))
2528 )
2529 }
2530
2531 fn apply_aggregate_filter(condition: Expression, filter: Option<Expression>) -> Expression {
2532 match filter {
2533 Some(filter) => Expression::And(Box::new(crate::expressions::BinaryOp::new(
2534 filter, condition,
2535 ))),
2536 None => condition,
2537 }
2538 }
2539
2540 fn transform_function(&self, f: Function) -> Result<Expression> {
2541 let name_upper = f.name.to_uppercase();
2542 match name_upper.as_str() {
2543 "COALESCE" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
2545 "ISNULL".to_string(),
2546 f.args,
2547 )))),
2548
2549 "NVL" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
2551 "ISNULL".to_string(),
2552 f.args,
2553 )))),
2554
2555 "GROUP_CONCAT" if !f.args.is_empty() => Ok(Expression::Function(Box::new(
2557 Function::new("STRING_AGG".to_string(), f.args),
2558 ))),
2559
2560 "STRING_AGG" => Ok(Expression::Function(Box::new(f))),
2562
2563 "LISTAGG" if !f.args.is_empty() => Ok(Expression::Function(Box::new(Function::new(
2565 "STRING_AGG".to_string(),
2566 f.args,
2567 )))),
2568
2569 "SUBSTR" => Ok(Expression::Function(Box::new(Function::new(
2571 "SUBSTRING".to_string(),
2572 f.args,
2573 )))),
2574
2575 "LENGTH" if f.args.len() == 1 => Ok(Expression::Function(Box::new(Function::new(
2577 "LEN".to_string(),
2578 f.args,
2579 )))),
2580
2581 "BTRIM" if f.args.len() == 1 || f.args.len() == 2 => {
2583 let mut args = f.args;
2584 let this = args.remove(0);
2585 let characters = if args.is_empty() {
2586 None
2587 } else {
2588 Some(args.remove(0))
2589 };
2590 Ok(Expression::Trim(Box::new(TrimFunc {
2591 this,
2592 sql_standard_syntax: characters.is_some(),
2593 characters,
2594 position: TrimPosition::Both,
2595 position_explicit: false,
2596 })))
2597 }
2598
2599 "MD5" if f.args.len() == 1 => {
2601 let mut args = f.args;
2602 Ok(Self::tsql_md5_hex(args.remove(0)))
2603 }
2604
2605 "SHA256" if f.args.len() == 1 => {
2606 let mut args = f.args;
2607 Ok(Self::function(
2608 "HASHBYTES",
2609 vec![Expression::string("SHA2_256"), args.remove(0)],
2610 ))
2611 }
2612
2613 "SHA512" if f.args.len() == 1 => {
2614 let mut args = f.args;
2615 Ok(Self::function(
2616 "HASHBYTES",
2617 vec![Expression::string("SHA2_512"), args.remove(0)],
2618 ))
2619 }
2620
2621 "OCTET_LENGTH" if f.args.len() == 1 => Ok(Self::function("DATALENGTH", f.args)),
2623
2624 "BIT_LENGTH" if f.args.len() == 1 => {
2626 let mut args = f.args;
2627 Ok(Expression::Mul(Box::new(BinaryOp::new(
2628 Self::function("DATALENGTH", vec![args.remove(0)]),
2629 Expression::number(8),
2630 ))))
2631 }
2632
2633 "TO_HEX" if f.args.len() == 1 => {
2637 let mut args = f.args;
2638 Ok(Self::tsql_postgres_to_hex(args.remove(0)))
2639 }
2640
2641 "ENCODE" if f.args.len() == 2 => {
2643 let mut args = f.args;
2644 let this = args.remove(0);
2645 let encoding = args.remove(0);
2646 if Self::literal_string(&encoding)
2647 .is_some_and(|encoding| encoding.eq_ignore_ascii_case("hex"))
2648 {
2649 Ok(Self::tsql_hex_from_varbinary(this))
2650 } else {
2651 Ok(Expression::Function(Box::new(Function::new(
2652 "ENCODE".to_string(),
2653 vec![this, encoding],
2654 ))))
2655 }
2656 }
2657
2658 "DECODE"
2661 if f.args.len() == 2
2662 && Self::literal_string(&f.args[1])
2663 .is_some_and(|format| format.eq_ignore_ascii_case("hex")) =>
2664 {
2665 let mut args = f.args;
2666 Ok(Self::tsql_convert(
2667 DataType::Custom {
2668 name: "VARBINARY(MAX)".to_string(),
2669 },
2670 args.remove(0),
2671 Some(2),
2672 ))
2673 }
2674
2675 "REPEAT" if f.args.len() == 2 => Ok(Expression::Function(Box::new(Function::new(
2677 "REPLICATE".to_string(),
2678 f.args,
2679 )))),
2680
2681 "CHR" if f.args.len() == 1 => Ok(Expression::Function(Box::new(Function::new(
2683 "CHAR".to_string(),
2684 f.args,
2685 )))),
2686
2687 "RANDOM" => Ok(Expression::Rand(Box::new(crate::expressions::Rand {
2689 seed: None,
2690 lower: None,
2691 upper: None,
2692 }))),
2693
2694 "NOW" => Ok(Self::getdate()),
2696
2697 "CURRENT_TIMESTAMP" => Ok(Self::getdate()),
2699
2700 "CURRENT_DATE" => Ok(Self::cast_getdate_to(DataType::Date)),
2702
2703 "CURRENT_TIME" => Ok(Self::cast_getdate_to(DataType::Time {
2705 precision: None,
2706 timezone: false,
2707 })),
2708
2709 "LOCALTIMESTAMP" => Ok(Self::getdate()),
2711
2712 "CLOCK_TIMESTAMP" if f.args.is_empty() => Ok(Self::function("SYSDATETIME", vec![])),
2714
2715 "MAKE_DATE" if f.args.len() == 3 => Ok(Self::function("DATEFROMPARTS", f.args)),
2717
2718 "MAKE_TIME" if f.args.len() == 3 => Ok(Self::make_time(f.args)),
2721
2722 "TO_DATE" if f.args.len() == 2 => {
2726 Self::formatted_str_to_date_or_fallback(f.args, "TO_DATE")
2727 }
2728
2729 "TO_DATE" if f.args.len() == 1 => {
2731 let mut args = f.args;
2732 Ok(Expression::Cast(Box::new(Cast {
2733 this: args.remove(0),
2734 to: DataType::Date,
2735 trailing_comments: Vec::new(),
2736 double_colon_syntax: false,
2737 format: None,
2738 default: None,
2739 inferred_type: None,
2740 })))
2741 }
2742
2743 "TO_TIMESTAMP" if f.args.len() == 2 => {
2746 Self::formatted_str_to_time_or_fallback(f.args, "TO_TIMESTAMP")
2747 }
2748
2749 "TO_TIMESTAMP" if f.args.len() == 1 => {
2751 let mut args = f.args;
2752 Ok(Expression::UnixToTime(Box::new(
2753 crate::expressions::UnixToTime {
2754 this: Box::new(args.remove(0)),
2755 scale: Some(0),
2756 zone: None,
2757 hours: None,
2758 minutes: None,
2759 format: None,
2760 target_type: None,
2761 },
2762 )))
2763 }
2764
2765 "TO_CHAR" if f.args.len() == 2 => {
2768 Self::formatted_time_to_str_or_fallback(f.args, "TO_CHAR")
2769 }
2770
2771 "TO_CHAR" => Ok(Expression::Function(Box::new(Function::new(
2773 "FORMAT".to_string(),
2774 f.args,
2775 )))),
2776
2777 "DATE_FORMAT" => Ok(Expression::Function(Box::new(Function::new(
2779 "FORMAT".to_string(),
2780 f.args,
2781 )))),
2782
2783 "DATE_TRUNC" | "DATETRUNC" => {
2786 let mut args = Self::uppercase_first_arg_if_identifier(f.args);
2787 if args.len() >= 2 {
2789 if let Expression::Literal(lit) = &args[1] {
2790 if let Literal::String(_) = lit.as_ref() {
2791 args[1] = Expression::Cast(Box::new(Cast {
2792 this: args[1].clone(),
2793 to: DataType::Custom {
2794 name: "DATETIME2".to_string(),
2795 },
2796 trailing_comments: Vec::new(),
2797 double_colon_syntax: false,
2798 format: None,
2799 default: None,
2800 inferred_type: None,
2801 }));
2802 }
2803 }
2804 }
2805 Ok(Expression::Function(Box::new(Function::new(
2806 "DATETRUNC".to_string(),
2807 args,
2808 ))))
2809 }
2810
2811 "DATEADD" => {
2813 let args = Self::uppercase_first_arg_if_identifier(f.args);
2814 Ok(Expression::Function(Box::new(Function::new(
2815 "DATEADD".to_string(),
2816 args,
2817 ))))
2818 }
2819
2820 "DATEDIFF" => {
2822 let args = Self::uppercase_first_arg_if_identifier(f.args);
2823 Ok(Expression::Function(Box::new(Function::new(
2824 "DATEDIFF".to_string(),
2825 args,
2826 ))))
2827 }
2828
2829 "EXTRACT" => Ok(Expression::Function(Box::new(Function::new(
2831 "DATEPART".to_string(),
2832 f.args,
2833 )))),
2834
2835 "STRPOS" | "POSITION" if f.args.len() >= 2 => {
2837 Ok(Expression::Function(Box::new(Function::new(
2839 "CHARINDEX".to_string(),
2840 f.args,
2841 ))))
2842 }
2843
2844 "CHARINDEX" => Ok(Expression::Function(Box::new(f))),
2846
2847 "CEILING" | "CEIL" if f.args.len() == 1 => Ok(Expression::Function(Box::new(
2849 Function::new("CEILING".to_string(), f.args),
2850 ))),
2851
2852 "JSON_EXTRACT" => Ok(Expression::Function(Box::new(Function::new(
2857 "JSON_VALUE".to_string(),
2858 f.args,
2859 )))),
2860
2861 "JSON_EXTRACT_SCALAR" => Ok(Expression::Function(Box::new(Function::new(
2863 "JSON_VALUE".to_string(),
2864 f.args,
2865 )))),
2866
2867 "PARSE_JSON" if f.args.len() == 1 => Ok(f.args.into_iter().next().unwrap()),
2869
2870 "GET_PATH" if f.args.len() == 2 => {
2872 let mut args = f.args;
2873 let this = args.remove(0);
2874 let path = args.remove(0);
2875 let json_path = match &path {
2876 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
2877 let Literal::String(s) = lit.as_ref() else {
2878 unreachable!()
2879 };
2880 let normalized = if s.starts_with('$') {
2881 s.clone()
2882 } else if s.starts_with('[') {
2883 format!("${}", s)
2884 } else {
2885 format!("$.{}", s)
2886 };
2887 Expression::Literal(Box::new(Literal::String(normalized)))
2888 }
2889 _ => path,
2890 };
2891 let json_query = Expression::Function(Box::new(Function::new(
2893 "JSON_QUERY".to_string(),
2894 vec![this.clone(), json_path.clone()],
2895 )));
2896 let json_value = Expression::Function(Box::new(Function::new(
2897 "JSON_VALUE".to_string(),
2898 vec![this, json_path],
2899 )));
2900 Ok(Expression::Function(Box::new(Function::new(
2901 "ISNULL".to_string(),
2902 vec![json_query, json_value],
2903 ))))
2904 }
2905
2906 "JSON_QUERY" if f.args.len() == 1 => {
2909 let this = f.args.into_iter().next().unwrap();
2910 let path = Expression::Literal(Box::new(Literal::String("$".to_string())));
2911 let json_query = Expression::Function(Box::new(Function::new(
2912 "JSON_QUERY".to_string(),
2913 vec![this.clone(), path.clone()],
2914 )));
2915 let json_value = Expression::Function(Box::new(Function::new(
2916 "JSON_VALUE".to_string(),
2917 vec![this, path],
2918 )));
2919 Ok(Expression::Function(Box::new(Function::new(
2920 "ISNULL".to_string(),
2921 vec![json_query, json_value],
2922 ))))
2923 }
2924
2925 "SPLIT" => Ok(Expression::Function(Box::new(Function::new(
2927 "STRING_SPLIT".to_string(),
2928 f.args,
2929 )))),
2930
2931 "REGEXP_LIKE" => {
2934 Ok(Expression::Function(Box::new(Function::new(
2936 "PATINDEX".to_string(),
2937 f.args,
2938 ))))
2939 }
2940
2941 "LN" if f.args.len() == 1 => Ok(Expression::Function(Box::new(Function::new(
2943 "LOG".to_string(),
2944 f.args,
2945 )))),
2946
2947 "STDDEV" | "STDDEV_SAMP" => Ok(Expression::Function(Box::new(Function::new(
2952 "STDEV".to_string(),
2953 f.args,
2954 )))),
2955
2956 "STDDEV_POP" => Ok(Expression::Function(Box::new(Function::new(
2958 "STDEVP".to_string(),
2959 f.args,
2960 )))),
2961
2962 "VARIANCE" | "VAR_SAMP" => Ok(Expression::Function(Box::new(Function::new(
2964 "VAR".to_string(),
2965 f.args,
2966 )))),
2967
2968 "VAR_POP" => Ok(Expression::Function(Box::new(Function::new(
2970 "VARP".to_string(),
2971 f.args,
2972 )))),
2973
2974 "BOOL_AND" | "LOGICAL_AND" | "BOOLAND_AGG" | "EVERY" if f.args.len() == 1 => {
2976 let mut args = f.args;
2977 Self::transform_logical_aggregate(args.remove(0), None, "MIN")
2978 }
2979 "BOOL_OR" | "LOGICAL_OR" | "BOOLOR_AGG" if f.args.len() == 1 => {
2980 let mut args = f.args;
2981 Self::transform_logical_aggregate(args.remove(0), None, "MAX")
2982 }
2983
2984 "DATE_ADD" => {
2986 if f.args.len() == 2 {
2987 let mut args = f.args;
2988 let date = args.remove(0);
2989 let interval = args.remove(0);
2990 let unit = Expression::Identifier(crate::expressions::Identifier {
2991 name: "DAY".to_string(),
2992 quoted: false,
2993 trailing_comments: Vec::new(),
2994 span: None,
2995 });
2996 Ok(Expression::Function(Box::new(Function::new(
2997 "DATEADD".to_string(),
2998 vec![unit, interval, date],
2999 ))))
3000 } else {
3001 let args = Self::uppercase_first_arg_if_identifier(f.args);
3002 Ok(Expression::Function(Box::new(Function::new(
3003 "DATEADD".to_string(),
3004 args,
3005 ))))
3006 }
3007 }
3008
3009 "INSERT" => Ok(Expression::Function(Box::new(Function::new(
3011 "STUFF".to_string(),
3012 f.args,
3013 )))),
3014
3015 "SUSER_NAME" | "SUSER_SNAME" | "SYSTEM_USER" => Ok(Expression::CurrentUser(Box::new(
3017 crate::expressions::CurrentUser { this: None },
3018 ))),
3019
3020 _ => Ok(Expression::Function(Box::new(f))),
3022 }
3023 }
3024
3025 fn literal_string(expr: &Expression) -> Option<&str> {
3026 match expr {
3027 Expression::Literal(lit) => match lit.as_ref() {
3028 Literal::String(s) => Some(s),
3029 _ => None,
3030 },
3031 Expression::Cast(cast) | Expression::TryCast(cast) | Expression::SafeCast(cast)
3032 if Self::is_text_data_type(&cast.to) =>
3033 {
3034 Self::literal_string(&cast.this)
3035 }
3036 _ => None,
3037 }
3038 }
3039
3040 fn is_text_data_type(data_type: &DataType) -> bool {
3041 match data_type {
3042 DataType::Char { .. }
3043 | DataType::VarChar { .. }
3044 | DataType::String { .. }
3045 | DataType::Text
3046 | DataType::TextWithLength { .. } => true,
3047 DataType::Custom { name } => {
3048 let base = name
3049 .split_once('(')
3050 .map_or(name.as_str(), |(base, _)| base)
3051 .trim();
3052 matches!(
3053 base.to_ascii_uppercase().as_str(),
3054 "CHAR"
3055 | "NCHAR"
3056 | "VARCHAR"
3057 | "NVARCHAR"
3058 | "TEXT"
3059 | "NTEXT"
3060 | "STRING"
3061 | "CHARACTER VARYING"
3062 )
3063 }
3064 _ => false,
3065 }
3066 }
3067
3068 fn is_numeric_data_type(data_type: &DataType) -> bool {
3069 match data_type {
3070 DataType::TinyInt { .. }
3071 | DataType::SmallInt { .. }
3072 | DataType::Int { .. }
3073 | DataType::BigInt { .. }
3074 | DataType::Float { .. }
3075 | DataType::Double { .. }
3076 | DataType::Decimal { .. } => true,
3077 DataType::Custom { name } => {
3078 let base = name
3079 .split_once('(')
3080 .map_or(name.as_str(), |(base, _)| base)
3081 .trim();
3082 matches!(
3083 base.to_ascii_uppercase().as_str(),
3084 "TINYINT"
3085 | "SMALLINT"
3086 | "INT"
3087 | "INTEGER"
3088 | "BIGINT"
3089 | "DECIMAL"
3090 | "NUMERIC"
3091 | "REAL"
3092 | "FLOAT"
3093 | "MONEY"
3094 | "SMALLMONEY"
3095 )
3096 }
3097 _ => false,
3098 }
3099 }
3100
3101 fn is_explicitly_numeric_expression(expr: &Expression) -> bool {
3102 if expr.inferred_type().is_some_and(Self::is_numeric_data_type) {
3103 return true;
3104 }
3105
3106 match expr {
3107 Expression::Literal(literal) => matches!(literal.as_ref(), Literal::Number(_)),
3108 Expression::Cast(cast) | Expression::TryCast(cast) | Expression::SafeCast(cast) => {
3109 Self::is_numeric_data_type(&cast.to)
3110 }
3111 Expression::Alias(alias) => Self::is_explicitly_numeric_expression(&alias.this),
3112 Expression::Paren(paren) => Self::is_explicitly_numeric_expression(&paren.this),
3113 Expression::Neg(unary) => Self::is_explicitly_numeric_expression(&unary.this),
3114 _ => false,
3115 }
3116 }
3117
3118 fn is_postgres_numeric_to_char_format(format: &str) -> bool {
3119 let mut unquoted = String::with_capacity(format.len());
3120 let mut quoted = false;
3121 let mut chars = format.chars().peekable();
3122
3123 while let Some(ch) = chars.next() {
3124 if ch == '"' {
3125 if quoted && chars.peek() == Some(&'"') {
3126 chars.next();
3127 } else {
3128 quoted = !quoted;
3129 }
3130 } else if !quoted {
3131 unquoted.extend(ch.to_uppercase());
3132 }
3133 }
3134
3135 unquoted.contains(['9', '0'])
3136 || ["PR", "SG", "PL", "RN", "EEEE"]
3137 .iter()
3138 .any(|token| unquoted.contains(token))
3139 }
3140
3141 fn postgres_format_to_strftime(format: &str) -> String {
3142 const POSTGRES_FORMAT_TO_STRFTIME: &[(&str, &str)] = &[
3143 ("FMHH24", "%-H"),
3144 ("FMHH12", "%-I"),
3145 ("FMDDD", "%-j"),
3146 ("TMMonth", "%B"),
3147 ("TMMon", "%b"),
3148 ("TMDay", "%A"),
3149 ("TMDy", "%a"),
3150 ("YYYY", "%Y"),
3151 ("yyyy", "%Y"),
3152 ("HH24", "%H"),
3153 ("HH12", "%I"),
3154 ("FMDD", "%-d"),
3155 ("FMMM", "%-m"),
3156 ("FMMI", "%-M"),
3157 ("FMSS", "%-S"),
3158 ("DDD", "%j"),
3159 ("ddd", "%j"),
3160 ("YY", "%y"),
3161 ("yy", "%y"),
3162 ("MM", "%m"),
3163 ("mm", "%m"),
3164 ("DD", "%d"),
3165 ("dd", "%d"),
3166 ("MI", "%M"),
3167 ("mi", "%M"),
3168 ("SS", "%S"),
3169 ("ss", "%S"),
3170 ("US", "%f"),
3171 ("OF", "%z"),
3172 ("TZ", "%Z"),
3173 ("WW", "%U"),
3174 ("ww", "%U"),
3175 ("D", "%u"),
3176 ("d", "%u"),
3177 ];
3178 crate::format_tokens::convert_format_tokens(format, POSTGRES_FORMAT_TO_STRFTIME)
3179 .unwrap_or_else(|| format.to_string())
3180 }
3181
3182 fn formatted_str_to_time_or_fallback(
3183 mut args: Vec<Expression>,
3184 original_name: &str,
3185 ) -> Result<Expression> {
3186 let this = args.remove(0);
3187 let format = args.remove(0);
3188 if let Some(format) = Self::literal_string(&format) {
3189 Ok(Expression::StrToTime(Box::new(
3190 crate::expressions::StrToTime {
3191 this: Box::new(this),
3192 format: Self::postgres_format_to_strftime(format),
3193 zone: None,
3194 safe: None,
3195 target_type: Some(Box::new(Expression::DataType(DataType::Custom {
3196 name: "DATETIME2".to_string(),
3197 }))),
3198 },
3199 )))
3200 } else {
3201 Ok(Expression::Function(Box::new(Function::new(
3202 original_name.to_string(),
3203 vec![this, format],
3204 ))))
3205 }
3206 }
3207
3208 fn formatted_str_to_date_or_fallback(
3209 mut args: Vec<Expression>,
3210 original_name: &str,
3211 ) -> Result<Expression> {
3212 let this = args.remove(0);
3213 let format = args.remove(0);
3214 if let Some(format) = Self::literal_string(&format) {
3215 Ok(Expression::StrToDate(Box::new(
3216 crate::expressions::StrToDate {
3217 this: Box::new(this),
3218 format: Some(Self::postgres_format_to_strftime(format)),
3219 safe: None,
3220 },
3221 )))
3222 } else {
3223 Ok(Expression::Function(Box::new(Function::new(
3224 original_name.to_string(),
3225 vec![this, format],
3226 ))))
3227 }
3228 }
3229
3230 fn formatted_time_to_str_or_fallback(
3231 mut args: Vec<Expression>,
3232 original_name: &str,
3233 ) -> Result<Expression> {
3234 let this = args.remove(0);
3235 let format = args.remove(0);
3236 if let Some(format_string) = Self::literal_string(&format).map(str::to_owned) {
3237 if Self::is_explicitly_numeric_expression(&this)
3238 || Self::is_postgres_numeric_to_char_format(&format_string)
3239 {
3240 return Ok(Expression::Function(Box::new(Function::new(
3241 original_name.to_string(),
3242 vec![this, format],
3243 ))));
3244 }
3245
3246 Ok(Expression::TimeToStr(Box::new(
3247 crate::expressions::TimeToStr {
3248 this: Box::new(this),
3249 format: Self::postgres_format_to_strftime(&format_string),
3250 culture: None,
3251 zone: None,
3252 },
3253 )))
3254 } else {
3255 Ok(Expression::Function(Box::new(Function::new(
3256 original_name.to_string(),
3257 vec![this, format],
3258 ))))
3259 }
3260 }
3261
3262 fn transform_aggregate_function(
3263 &self,
3264 mut f: Box<crate::expressions::AggregateFunction>,
3265 ) -> Result<Expression> {
3266 let name_upper = f.name.to_uppercase();
3267 if matches!(
3268 name_upper.as_str(),
3269 "SUM"
3270 | "AVG"
3271 | "MIN"
3272 | "MAX"
3273 | "COUNT"
3274 | "COUNT_BIG"
3275 | "ANY_VALUE"
3276 | "APPROX_COUNT_DISTINCT"
3277 | "STDEV"
3278 | "STDEVP"
3279 | "VAR"
3280 | "VARP"
3281 | "BOOL_AND"
3282 | "BOOL_OR"
3283 | "LOGICAL_AND"
3284 | "LOGICAL_OR"
3285 | "BIT_AND"
3286 | "BIT_OR"
3287 | "BIT_XOR"
3288 ) {
3289 f.order_by.clear();
3290 }
3291
3292 match name_upper.as_str() {
3293 "GROUP_CONCAT" if !f.args.is_empty() => Ok(Expression::Function(Box::new(
3295 Function::new("STRING_AGG".to_string(), f.args),
3296 ))),
3297
3298 "LISTAGG" if !f.args.is_empty() => Ok(Expression::Function(Box::new(Function::new(
3300 "STRING_AGG".to_string(),
3301 f.args,
3302 )))),
3303
3304 "ARRAY_AGG" if !f.args.is_empty() => {
3307 Ok(Expression::Function(Box::new(Function::new(
3309 "STRING_AGG".to_string(),
3310 f.args,
3311 ))))
3312 }
3313
3314 "BOOL_AND" | "LOGICAL_AND" | "BOOLAND_AGG" | "EVERY" if f.args.len() == 1 => {
3316 let mut args = f.args;
3317 Self::transform_logical_aggregate(args.remove(0), f.filter, "MIN")
3318 }
3319 "BOOL_OR" | "LOGICAL_OR" | "BOOLOR_AGG" if f.args.len() == 1 => {
3320 let mut args = f.args;
3321 Self::transform_logical_aggregate(args.remove(0), f.filter, "MAX")
3322 }
3323
3324 _ => Ok(Expression::AggregateFunction(f)),
3326 }
3327 }
3328
3329 fn without_inert_ordering(
3330 mut aggregate: Box<crate::expressions::AggFunc>,
3331 ) -> Box<crate::expressions::AggFunc> {
3332 aggregate.order_by.clear();
3333 aggregate
3334 }
3335
3336 fn transform_cte(&self, cte: Cte) -> Result<Expression> {
3340 Ok(Expression::Cte(Box::new(self.transform_cte_inner(cte))))
3341 }
3342
3343 fn transform_cte_inner(&self, mut cte: Cte) -> Cte {
3345 if cte.columns.is_empty() {
3348 cte.this = self.qualify_derived_table_outputs(cte.this);
3349 }
3350 cte
3351 }
3352
3353 fn transform_subquery(&self, mut subquery: Subquery) -> Result<Expression> {
3357 if subquery.alias.is_some() && subquery.column_aliases.is_empty() {
3360 subquery.this = self.qualify_derived_table_outputs(subquery.this);
3361 }
3362 Ok(Expression::Subquery(Box::new(subquery)))
3363 }
3364
3365 fn qualify_derived_table_outputs(&self, expr: Expression) -> Expression {
3369 match expr {
3370 Expression::Select(mut select) => {
3371 let has_from = select.from.is_some();
3374 if !has_from {
3375 select.expressions = select
3376 .expressions
3377 .into_iter()
3378 .map(|e| self.maybe_alias_expression(e))
3379 .collect();
3380 }
3381 Expression::Select(select)
3382 }
3383 Expression::Union(mut u) => {
3385 let left = std::mem::replace(&mut u.left, Expression::Null(Null));
3386 u.left = self.qualify_derived_table_outputs(left);
3387 Expression::Union(u)
3388 }
3389 Expression::Intersect(mut i) => {
3390 let left = std::mem::replace(&mut i.left, Expression::Null(Null));
3391 i.left = self.qualify_derived_table_outputs(left);
3392 Expression::Intersect(i)
3393 }
3394 Expression::Except(mut e) => {
3395 let left = std::mem::replace(&mut e.left, Expression::Null(Null));
3396 e.left = self.qualify_derived_table_outputs(left);
3397 Expression::Except(e)
3398 }
3399 Expression::Subquery(mut s) => {
3401 s.this = self.qualify_derived_table_outputs(s.this);
3402 Expression::Subquery(s)
3403 }
3404 other => other,
3406 }
3407 }
3408
3409 fn maybe_alias_expression(&self, expr: Expression) -> Expression {
3414 match &expr {
3415 Expression::Alias(_) => expr,
3417 Expression::Aliases(_) => expr,
3419 Expression::Star(_) => expr,
3421 _ => {
3426 if let Some(output_name) = self.get_output_name(&expr) {
3427 Expression::Alias(Box::new(Alias {
3428 this: expr,
3429 alias: Identifier {
3430 name: output_name,
3431 quoted: true, trailing_comments: Vec::new(),
3433 span: None,
3434 },
3435 column_aliases: Vec::new(),
3436 alias_explicit_as: false,
3437 alias_keyword: None,
3438 pre_alias_comments: Vec::new(),
3439 trailing_comments: Vec::new(),
3440 inferred_type: None,
3441 }))
3442 } else {
3443 expr
3445 }
3446 }
3447 }
3448 }
3449
3450 fn get_output_name(&self, expr: &Expression) -> Option<String> {
3454 match expr {
3455 Expression::Literal(lit) => match lit.as_ref() {
3457 Literal::Number(n) => Some(n.clone()),
3458 Literal::String(s) => Some(s.clone()),
3459 Literal::HexString(h) => Some(format!("0x{}", h)),
3460 Literal::HexNumber(h) => Some(format!("0x{}", h)),
3461 Literal::BitString(b) => Some(format!("b{}", b)),
3462 Literal::ByteString(b) => Some(format!("b'{}'", b)),
3463 Literal::NationalString(s) => Some(format!("N'{}'", s)),
3464 Literal::Date(d) => Some(d.clone()),
3465 Literal::Time(t) => Some(t.clone()),
3466 Literal::Timestamp(ts) => Some(ts.clone()),
3467 Literal::Datetime(dt) => Some(dt.clone()),
3468 Literal::TripleQuotedString(s, _) => Some(s.clone()),
3469 Literal::EscapeString(s) => Some(s.clone()),
3470 Literal::DollarString(s) => Some(s.clone()),
3471 Literal::RawString(s) => Some(s.clone()),
3472 },
3473 Expression::Column(col) => Some(col.name.name.clone()),
3475 Expression::Identifier(ident) => Some(ident.name.clone()),
3477 Expression::Boolean(b) => Some(if b.value { "1" } else { "0" }.to_string()),
3479 Expression::Null(_) => Some("NULL".to_string()),
3481 Expression::Function(f) => Some(f.name.clone()),
3483 Expression::AggregateFunction(f) => Some(f.name.clone()),
3485 _ => Some(format!("_col_{}", 0)),
3487 }
3488 }
3489
3490 fn uppercase_first_arg_if_identifier(mut args: Vec<Expression>) -> Vec<Expression> {
3492 use crate::expressions::Identifier;
3493 if !args.is_empty() {
3494 match &args[0] {
3495 Expression::Identifier(id) => {
3496 args[0] = Expression::Identifier(Identifier {
3497 name: id.name.to_uppercase(),
3498 quoted: id.quoted,
3499 trailing_comments: id.trailing_comments.clone(),
3500 span: None,
3501 });
3502 }
3503 Expression::Var(v) => {
3504 args[0] = Expression::Identifier(Identifier {
3505 name: v.this.to_uppercase(),
3506 quoted: false,
3507 trailing_comments: Vec::new(),
3508 span: None,
3509 });
3510 }
3511 Expression::Column(col) if col.table.is_none() => {
3512 args[0] = Expression::Identifier(Identifier {
3513 name: col.name.name.to_uppercase(),
3514 quoted: col.name.quoted,
3515 trailing_comments: col.name.trailing_comments.clone(),
3516 span: None,
3517 });
3518 }
3519 _ => {}
3520 }
3521 }
3522 args
3523 }
3524}
3525
3526#[cfg(test)]
3527mod tests {
3528 use super::*;
3529 use crate::dialects::Dialect;
3530
3531 fn transpile_to_tsql(sql: &str) -> String {
3532 let dialect = Dialect::get(DialectType::Generic);
3533 let result = dialect
3534 .transpile(sql, DialectType::TSQL)
3535 .expect("Transpile failed");
3536 result[0].clone()
3537 }
3538
3539 #[test]
3540 fn test_nvl_to_isnull() {
3541 let result = transpile_to_tsql("SELECT NVL(a, b)");
3542 assert!(
3543 result.contains("ISNULL"),
3544 "Expected ISNULL, got: {}",
3545 result
3546 );
3547 }
3548
3549 #[test]
3550 fn test_coalesce_to_isnull() {
3551 let result = transpile_to_tsql("SELECT COALESCE(a, b)");
3552 assert!(
3553 result.contains("ISNULL"),
3554 "Expected ISNULL, got: {}",
3555 result
3556 );
3557 }
3558
3559 #[test]
3560 fn test_basic_select() {
3561 let result = transpile_to_tsql("SELECT a, b FROM users WHERE id = 1");
3562 assert!(result.contains("SELECT"));
3563 assert!(result.contains("FROM users"));
3564 }
3565
3566 #[test]
3567 fn test_length_to_len() {
3568 let result = transpile_to_tsql("SELECT LENGTH(name)");
3569 assert!(result.contains("LEN"), "Expected LEN, got: {}", result);
3570 }
3571
3572 #[test]
3573 fn test_issue_374_tsql_parse_then_generate_uses_len() {
3574 let sql = "SELECT LEN(table.col1) - LEN(table.col2) FROM table";
3575 let ast = Dialect::get(DialectType::TSQL)
3576 .parse(sql)
3577 .expect("T-SQL should parse");
3578 let expression = &ast[0];
3579
3580 for target in [DialectType::TSQL, DialectType::Fabric] {
3581 let generated = Dialect::get(target)
3582 .generate(expression)
3583 .expect("AST should generate");
3584 assert_eq!(generated, sql, "failed for target {target:?}");
3585 }
3586
3587 let standard_sql = "SELECT LENGTH(table.col1) - LENGTH(table.col2) FROM table";
3588 for target in [DialectType::Generic, DialectType::PostgreSQL] {
3589 let generated = Dialect::get(target)
3590 .generate(expression)
3591 .expect("AST should generate");
3592 assert_eq!(generated, standard_sql, "failed for target {target:?}");
3593 }
3594 }
3595
3596 #[test]
3597 fn test_now_to_getdate() {
3598 let result = transpile_to_tsql("SELECT NOW()");
3599 assert!(
3600 result.contains("GETDATE"),
3601 "Expected GETDATE, got: {}",
3602 result
3603 );
3604 }
3605
3606 #[test]
3607 fn test_group_concat_to_string_agg() {
3608 let result = transpile_to_tsql("SELECT GROUP_CONCAT(name)");
3609 assert!(
3610 result.contains("STRING_AGG"),
3611 "Expected STRING_AGG, got: {}",
3612 result
3613 );
3614 }
3615
3616 #[test]
3617 fn test_listagg_to_string_agg() {
3618 let result = transpile_to_tsql("SELECT LISTAGG(name)");
3619 assert!(
3620 result.contains("STRING_AGG"),
3621 "Expected STRING_AGG, got: {}",
3622 result
3623 );
3624 }
3625
3626 #[test]
3627 fn test_ln_to_log() {
3628 let result = transpile_to_tsql("SELECT LN(x)");
3629 assert!(result.contains("LOG"), "Expected LOG, got: {}", result);
3630 }
3631
3632 #[test]
3633 fn test_stddev_to_stdev() {
3634 let result = transpile_to_tsql("SELECT STDDEV(x)");
3635 assert!(result.contains("STDEV"), "Expected STDEV, got: {}", result);
3636 }
3637
3638 #[test]
3639 fn test_bracket_identifiers() {
3640 let dialect = Dialect::get(DialectType::TSQL);
3642 let config = dialect.generator_config();
3643 assert_eq!(config.identifier_quote, '[');
3644 }
3645
3646 #[test]
3647 fn test_json_query_isnull_wrapper_simple() {
3648 let dialect = Dialect::get(DialectType::TSQL);
3650 let result = dialect
3651 .transpile(r#"JSON_QUERY(x, '$')"#, DialectType::TSQL)
3652 .expect("transpile failed");
3653 assert!(
3654 result[0].contains("ISNULL"),
3655 "JSON_QUERY should be wrapped with ISNULL: {}",
3656 result[0]
3657 );
3658 }
3659
3660 #[test]
3661 fn test_json_query_isnull_wrapper_nested() {
3662 let dialect = Dialect::get(DialectType::TSQL);
3663 let result = dialect
3664 .transpile(
3665 r#"JSON_QUERY(REPLACE(REPLACE(x, '''', '"'), '""', '"'))"#,
3666 DialectType::TSQL,
3667 )
3668 .expect("transpile failed");
3669 let expected = r#"ISNULL(JSON_QUERY(REPLACE(REPLACE(x, '''', '"'), '""', '"'), '$'), JSON_VALUE(REPLACE(REPLACE(x, '''', '"'), '""', '"'), '$'))"#;
3670 assert_eq!(
3671 result[0], expected,
3672 "JSON_QUERY should be wrapped with ISNULL"
3673 );
3674 }
3675}