1use std::collections::{HashMap, HashSet};
13
14use crate::dialects::DialectType;
15use crate::expressions::{
16 BinaryOp, DataType, Expression, Function, IfFunc, ListAggOverflow, Literal, Map, Nvl2Func,
17 Struct, StructField, Subscript,
18};
19use crate::schema::{normalize_name, Schema, SchemaError, SchemaResult, TABLE_PARTS};
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
24pub enum TypeCoercionClass {
25 Text = 0,
27 Numeric = 1,
29 Timelike = 2,
31}
32
33impl TypeCoercionClass {
34 pub fn from_data_type(dt: &DataType) -> Option<Self> {
36 match dt {
37 DataType::Char { .. }
39 | DataType::VarChar { .. }
40 | DataType::Text
41 | DataType::Binary { .. }
42 | DataType::VarBinary { .. }
43 | DataType::Blob => Some(TypeCoercionClass::Text),
44
45 DataType::Boolean
47 | DataType::TinyInt { .. }
48 | DataType::SmallInt { .. }
49 | DataType::Int { .. }
50 | DataType::BigInt { .. }
51 | DataType::Float { .. }
52 | DataType::Double { .. }
53 | DataType::Decimal { .. } => Some(TypeCoercionClass::Numeric),
54
55 DataType::Date
57 | DataType::Time { .. }
58 | DataType::Timestamp { .. }
59 | DataType::Interval { .. } => Some(TypeCoercionClass::Timelike),
60
61 _ => None,
63 }
64 }
65}
66
67pub struct TypeAnnotator<'a> {
69 _schema: Option<&'a dyn Schema>,
71 _dialect: Option<DialectType>,
73 annotate_aggregates: bool,
75 function_return_types: HashMap<String, DataType>,
77}
78
79impl<'a> TypeAnnotator<'a> {
80 pub fn new(schema: Option<&'a dyn Schema>, dialect: Option<DialectType>) -> Self {
82 let mut annotator = Self {
83 _schema: schema,
84 _dialect: dialect,
85 annotate_aggregates: true,
86 function_return_types: HashMap::new(),
87 };
88 annotator.init_function_return_types();
89 annotator
90 }
91
92 fn init_function_return_types(&mut self) {
94 self.function_return_types
96 .insert("COUNT".to_string(), DataType::BigInt { length: None });
97 self.function_return_types.insert(
98 "SUM".to_string(),
99 DataType::Decimal {
100 precision: None,
101 scale: None,
102 },
103 );
104 self.function_return_types.insert(
105 "AVG".to_string(),
106 DataType::Double {
107 precision: None,
108 scale: None,
109 },
110 );
111
112 self.function_return_types.insert(
114 "CONCAT".to_string(),
115 DataType::VarChar {
116 length: None,
117 parenthesized_length: false,
118 },
119 );
120 self.function_return_types.insert(
121 "UPPER".to_string(),
122 DataType::VarChar {
123 length: None,
124 parenthesized_length: false,
125 },
126 );
127 self.function_return_types.insert(
128 "LOWER".to_string(),
129 DataType::VarChar {
130 length: None,
131 parenthesized_length: false,
132 },
133 );
134 self.function_return_types.insert(
135 "TRIM".to_string(),
136 DataType::VarChar {
137 length: None,
138 parenthesized_length: false,
139 },
140 );
141 self.function_return_types.insert(
142 "LTRIM".to_string(),
143 DataType::VarChar {
144 length: None,
145 parenthesized_length: false,
146 },
147 );
148 self.function_return_types.insert(
149 "RTRIM".to_string(),
150 DataType::VarChar {
151 length: None,
152 parenthesized_length: false,
153 },
154 );
155 self.function_return_types.insert(
156 "SUBSTRING".to_string(),
157 DataType::VarChar {
158 length: None,
159 parenthesized_length: false,
160 },
161 );
162 self.function_return_types.insert(
163 "SUBSTR".to_string(),
164 DataType::VarChar {
165 length: None,
166 parenthesized_length: false,
167 },
168 );
169 self.function_return_types.insert(
170 "REPLACE".to_string(),
171 DataType::VarChar {
172 length: None,
173 parenthesized_length: false,
174 },
175 );
176 self.function_return_types.insert(
177 "LENGTH".to_string(),
178 DataType::Int {
179 length: None,
180 integer_spelling: false,
181 },
182 );
183 self.function_return_types.insert(
184 "CHAR_LENGTH".to_string(),
185 DataType::Int {
186 length: None,
187 integer_spelling: false,
188 },
189 );
190
191 self.function_return_types.insert(
193 "NOW".to_string(),
194 DataType::Timestamp {
195 precision: None,
196 timezone: false,
197 },
198 );
199 self.function_return_types.insert(
200 "CURRENT_TIMESTAMP".to_string(),
201 DataType::Timestamp {
202 precision: None,
203 timezone: false,
204 },
205 );
206 self.function_return_types
207 .insert("CURRENT_DATE".to_string(), DataType::Date);
208 self.function_return_types.insert(
209 "CURRENT_TIME".to_string(),
210 DataType::Time {
211 precision: None,
212 timezone: false,
213 },
214 );
215 self.function_return_types
216 .insert("DATE".to_string(), DataType::Date);
217 self.function_return_types.insert(
218 "YEAR".to_string(),
219 DataType::Int {
220 length: None,
221 integer_spelling: false,
222 },
223 );
224 self.function_return_types.insert(
225 "MONTH".to_string(),
226 DataType::Int {
227 length: None,
228 integer_spelling: false,
229 },
230 );
231 self.function_return_types.insert(
232 "DAY".to_string(),
233 DataType::Int {
234 length: None,
235 integer_spelling: false,
236 },
237 );
238 self.function_return_types.insert(
239 "HOUR".to_string(),
240 DataType::Int {
241 length: None,
242 integer_spelling: false,
243 },
244 );
245 self.function_return_types.insert(
246 "MINUTE".to_string(),
247 DataType::Int {
248 length: None,
249 integer_spelling: false,
250 },
251 );
252 self.function_return_types.insert(
253 "SECOND".to_string(),
254 DataType::Int {
255 length: None,
256 integer_spelling: false,
257 },
258 );
259 self.function_return_types.insert(
260 "EXTRACT".to_string(),
261 DataType::Int {
262 length: None,
263 integer_spelling: false,
264 },
265 );
266 self.function_return_types.insert(
267 "DATE_DIFF".to_string(),
268 DataType::Int {
269 length: None,
270 integer_spelling: false,
271 },
272 );
273 self.function_return_types.insert(
274 "DATEDIFF".to_string(),
275 DataType::Int {
276 length: None,
277 integer_spelling: false,
278 },
279 );
280
281 self.function_return_types.insert(
283 "ABS".to_string(),
284 DataType::Double {
285 precision: None,
286 scale: None,
287 },
288 );
289 self.function_return_types.insert(
290 "ROUND".to_string(),
291 DataType::Double {
292 precision: None,
293 scale: None,
294 },
295 );
296 self.function_return_types.insert(
297 "DATE_FORMAT".to_string(),
298 DataType::VarChar {
299 length: None,
300 parenthesized_length: false,
301 },
302 );
303 self.function_return_types.insert(
304 "FORMAT_DATE".to_string(),
305 DataType::VarChar {
306 length: None,
307 parenthesized_length: false,
308 },
309 );
310 self.function_return_types.insert(
311 "TIME_TO_STR".to_string(),
312 DataType::VarChar {
313 length: None,
314 parenthesized_length: false,
315 },
316 );
317 self.function_return_types.insert(
318 "SQRT".to_string(),
319 DataType::Double {
320 precision: None,
321 scale: None,
322 },
323 );
324 self.function_return_types.insert(
325 "POWER".to_string(),
326 DataType::Double {
327 precision: None,
328 scale: None,
329 },
330 );
331 self.function_return_types.insert(
332 "MOD".to_string(),
333 DataType::Int {
334 length: None,
335 integer_spelling: false,
336 },
337 );
338 self.function_return_types.insert(
339 "LOG".to_string(),
340 DataType::Double {
341 precision: None,
342 scale: None,
343 },
344 );
345 self.function_return_types.insert(
346 "LN".to_string(),
347 DataType::Double {
348 precision: None,
349 scale: None,
350 },
351 );
352 self.function_return_types.insert(
353 "EXP".to_string(),
354 DataType::Double {
355 precision: None,
356 scale: None,
357 },
358 );
359
360 self.function_return_types
362 .insert("COALESCE".to_string(), DataType::Unknown);
363 self.function_return_types
364 .insert("NULLIF".to_string(), DataType::Unknown);
365 self.function_return_types
366 .insert("GREATEST".to_string(), DataType::Unknown);
367 self.function_return_types
368 .insert("LEAST".to_string(), DataType::Unknown);
369 }
370
371 pub fn annotate(&mut self, expr: &Expression) -> Option<DataType> {
373 match expr {
374 Expression::Literal(lit) => self.annotate_literal(lit),
376 Expression::Boolean(_) => Some(DataType::Boolean),
377 Expression::Null(_) => None, Expression::Add(op)
381 | Expression::Sub(op)
382 | Expression::Mul(op)
383 | Expression::Div(op)
384 | Expression::Mod(op) => self.annotate_arithmetic(op),
385
386 Expression::Eq(_)
388 | Expression::Neq(_)
389 | Expression::Lt(_)
390 | Expression::Lte(_)
391 | Expression::Gt(_)
392 | Expression::Gte(_)
393 | Expression::Like(_)
394 | Expression::ILike(_) => Some(DataType::Boolean),
395
396 Expression::And(_) | Expression::Or(_) | Expression::Not(_) => Some(DataType::Boolean),
398
399 Expression::Between(_)
401 | Expression::In(_)
402 | Expression::IsNull(_)
403 | Expression::IsTrue(_)
404 | Expression::IsFalse(_)
405 | Expression::Is(_)
406 | Expression::Exists(_) => Some(DataType::Boolean),
407
408 Expression::Concat(_) => Some(DataType::VarChar {
410 length: None,
411 parenthesized_length: false,
412 }),
413
414 Expression::BitwiseAnd(_)
416 | Expression::BitwiseOr(_)
417 | Expression::BitwiseXor(_)
418 | Expression::BitwiseNot(_) => Some(DataType::BigInt { length: None }),
419
420 Expression::Neg(op) => self.annotate(&op.this),
422
423 Expression::Function(func) => self.annotate_function(func),
425 Expression::IfFunc(if_func) => self.annotate_if_func(if_func),
426 Expression::Nvl2(nvl2) => self.annotate_nvl2(nvl2),
427
428 Expression::Count(_) => Some(DataType::BigInt { length: None }),
430 Expression::Sum(agg) => self.annotate_sum(&agg.this),
431 Expression::SumIf(f) => self.annotate_sum(&f.this),
432 Expression::Avg(_) => Some(DataType::Double {
433 precision: None,
434 scale: None,
435 }),
436 Expression::Min(agg) => self.annotate(&agg.this),
437 Expression::Max(agg) => self.annotate(&agg.this),
438 Expression::GroupConcat(_) | Expression::StringAgg(_) | Expression::ListAgg(_) => {
439 Some(DataType::VarChar {
440 length: None,
441 parenthesized_length: false,
442 })
443 }
444
445 Expression::AggregateFunction(agg) => {
447 if !self.annotate_aggregates {
448 return None;
449 }
450 let func_name = agg.name.to_uppercase();
451 self.get_aggregate_return_type(&func_name, &agg.args)
452 }
453
454 Expression::Column(col) => {
456 if let Some(schema) = &self._schema {
457 let table_name = col.table.as_ref().map(|t| t.name.as_str()).unwrap_or("");
458 schema.get_column_type(table_name, &col.name.name).ok()
459 } else {
460 None
461 }
462 }
463
464 Expression::Cast(cast) => Some(cast.to.clone()),
466 Expression::SafeCast(cast) => Some(cast.to.clone()),
467 Expression::TryCast(cast) => Some(cast.to.clone()),
468
469 Expression::Subquery(subq) => {
471 if let Expression::Select(select) = &subq.this {
472 if let Some(first) = select.expressions.first() {
473 self.annotate(first)
474 } else {
475 None
476 }
477 } else {
478 None
479 }
480 }
481
482 Expression::Case(case) => {
484 if let Some(else_expr) = &case.else_ {
485 self.annotate(else_expr)
486 } else if let Some((_, then_expr)) = case.whens.first() {
487 self.annotate(then_expr)
488 } else {
489 None
490 }
491 }
492
493 Expression::Array(arr) => {
495 if let Some(first) = arr.expressions.first() {
496 if let Some(elem_type) = self.annotate(first) {
497 Some(DataType::Array {
498 element_type: Box::new(elem_type),
499 dimension: None,
500 })
501 } else {
502 Some(DataType::Array {
503 element_type: Box::new(DataType::Unknown),
504 dimension: None,
505 })
506 }
507 } else {
508 Some(DataType::Array {
509 element_type: Box::new(DataType::Unknown),
510 dimension: None,
511 })
512 }
513 }
514
515 Expression::Interval(_) => Some(DataType::Interval {
517 unit: None,
518 to: None,
519 }),
520
521 Expression::WindowFunction(window) => self.annotate(&window.this),
523
524 Expression::CurrentDate(_) => Some(DataType::Date),
526 Expression::CurrentTime(_) => Some(DataType::Time {
527 precision: None,
528 timezone: false,
529 }),
530 Expression::CurrentTimestamp(_) | Expression::CurrentTimestampLTZ(_) => {
531 Some(DataType::Timestamp {
532 precision: None,
533 timezone: false,
534 })
535 }
536
537 Expression::DateAdd(_)
539 | Expression::DateSub(_)
540 | Expression::ToDate(_)
541 | Expression::Date(_) => Some(DataType::Date),
542 Expression::DateDiff(_) | Expression::Extract(_) => Some(DataType::Int {
543 length: None,
544 integer_spelling: false,
545 }),
546 Expression::ToTimestamp(_) => Some(DataType::Timestamp {
547 precision: None,
548 timezone: false,
549 }),
550
551 Expression::Upper(_)
553 | Expression::Lower(_)
554 | Expression::Trim(_)
555 | Expression::LTrim(_)
556 | Expression::RTrim(_)
557 | Expression::Replace(_)
558 | Expression::Substring(_)
559 | Expression::Reverse(_)
560 | Expression::Left(_)
561 | Expression::Right(_)
562 | Expression::Repeat(_)
563 | Expression::Lpad(_)
564 | Expression::Rpad(_)
565 | Expression::ConcatWs(_)
566 | Expression::Overlay(_) => Some(DataType::VarChar {
567 length: None,
568 parenthesized_length: false,
569 }),
570 Expression::Length(_) => Some(DataType::Int {
571 length: None,
572 integer_spelling: false,
573 }),
574
575 Expression::Abs(_)
577 | Expression::Sqrt(_)
578 | Expression::Cbrt(_)
579 | Expression::Ln(_)
580 | Expression::Exp(_)
581 | Expression::Power(_)
582 | Expression::Log(_) => Some(DataType::Double {
583 precision: None,
584 scale: None,
585 }),
586 Expression::Round(_) => Some(DataType::Double {
587 precision: None,
588 scale: None,
589 }),
590 Expression::Floor(f) => self.annotate_math_function(&f.this),
591 Expression::Ceil(f) => self.annotate_math_function(&f.this),
592 Expression::Sign(s) => self.annotate(&s.this),
593 Expression::DateFormat(_) | Expression::FormatDate(_) | Expression::TimeToStr(_) => {
594 Some(DataType::VarChar {
595 length: None,
596 parenthesized_length: false,
597 })
598 }
599
600 Expression::Greatest(v) | Expression::Least(v) => self.coerce_arg_types(&v.expressions),
602
603 Expression::Alias(alias) => self.annotate(&alias.this),
605
606 Expression::Select(_) => None,
608
609 Expression::Subscript(sub) => self.annotate_subscript(sub),
613
614 Expression::Dot(_) => None,
616
617 Expression::Struct(s) => self.annotate_struct(s),
621
622 Expression::Map(map) => self.annotate_map(map),
626 Expression::MapFromEntries(mfe) => {
627 if let Some(DataType::Array { element_type, .. }) = self.annotate(&mfe.this) {
629 if let DataType::Struct { fields, .. } = *element_type {
630 if fields.len() >= 2 {
631 return Some(DataType::Map {
632 key_type: Box::new(fields[0].data_type.clone()),
633 value_type: Box::new(fields[1].data_type.clone()),
634 });
635 }
636 }
637 }
638 Some(DataType::Map {
639 key_type: Box::new(DataType::Unknown),
640 value_type: Box::new(DataType::Unknown),
641 })
642 }
643
644 Expression::Union(union) => self.annotate_set_operation(&union.left, &union.right),
648 Expression::Intersect(intersect) => {
649 self.annotate_set_operation(&intersect.left, &intersect.right)
650 }
651 Expression::Except(except) => self.annotate_set_operation(&except.left, &except.right),
652
653 Expression::Lateral(lateral) => {
657 self.annotate(&lateral.this)
659 }
660 Expression::LateralView(lv) => {
661 self.annotate_lateral_view(lv)
663 }
664 Expression::Unnest(unnest) => {
665 if let Some(DataType::Array { element_type, .. }) = self.annotate(&unnest.this) {
667 Some(*element_type)
668 } else {
669 None
670 }
671 }
672 Expression::Explode(explode) => {
673 if let Some(DataType::Array { element_type, .. }) = self.annotate(&explode.this) {
675 Some(*element_type)
676 } else if let Some(DataType::Map {
677 key_type,
678 value_type,
679 }) = self.annotate(&explode.this)
680 {
681 Some(DataType::Struct {
683 fields: vec![
684 StructField::new("key".to_string(), *key_type),
685 StructField::new("value".to_string(), *value_type),
686 ],
687 nested: false,
688 })
689 } else {
690 None
691 }
692 }
693 Expression::ExplodeOuter(explode) => {
694 if let Some(DataType::Array { element_type, .. }) = self.annotate(&explode.this) {
696 Some(*element_type)
697 } else {
698 None
699 }
700 }
701 Expression::GenerateSeries(gs) => {
702 if let Some(ref start) = gs.start {
704 self.annotate(start)
705 } else if let Some(ref end) = gs.end {
706 self.annotate(end)
707 } else {
708 Some(DataType::Int {
709 length: None,
710 integer_spelling: false,
711 })
712 }
713 }
714
715 _ => None,
717 }
718 }
719
720 pub fn annotate_in_place(&mut self, expr: &mut Expression) {
726 self.annotate_children_in_place(expr);
728
729 let dt = self.annotate(expr);
733
734 if let Some(data_type) = dt {
736 expr.set_inferred_type(data_type);
737 }
738 }
739
740 fn annotate_children_in_place(&mut self, expr: &mut Expression) {
742 match expr {
743 Expression::And(op)
745 | Expression::Or(op)
746 | Expression::Add(op)
747 | Expression::Sub(op)
748 | Expression::Mul(op)
749 | Expression::Div(op)
750 | Expression::Mod(op)
751 | Expression::Eq(op)
752 | Expression::Neq(op)
753 | Expression::Lt(op)
754 | Expression::Lte(op)
755 | Expression::Gt(op)
756 | Expression::Gte(op)
757 | Expression::Concat(op)
758 | Expression::BitwiseAnd(op)
759 | Expression::BitwiseOr(op)
760 | Expression::BitwiseXor(op)
761 | Expression::Adjacent(op)
762 | Expression::TsMatch(op)
763 | Expression::PropertyEQ(op)
764 | Expression::ArrayContainsAll(op)
765 | Expression::ArrayContainedBy(op)
766 | Expression::ArrayOverlaps(op)
767 | Expression::JSONBContainsAllTopKeys(op)
768 | Expression::JSONBContainsAnyTopKeys(op)
769 | Expression::JSONBDeleteAtPath(op)
770 | Expression::ExtendsLeft(op)
771 | Expression::ExtendsRight(op)
772 | Expression::Is(op)
773 | Expression::MemberOf(op)
774 | Expression::Match(op)
775 | Expression::NullSafeEq(op)
776 | Expression::NullSafeNeq(op)
777 | Expression::Glob(op)
778 | Expression::BitwiseLeftShift(op)
779 | Expression::BitwiseRightShift(op) => {
780 self.annotate_in_place(&mut op.left);
781 self.annotate_in_place(&mut op.right);
782 }
783
784 Expression::Like(op) | Expression::ILike(op) => {
786 self.annotate_in_place(&mut op.left);
787 self.annotate_in_place(&mut op.right);
788 }
789
790 Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
792 self.annotate_in_place(&mut op.this);
793 }
794
795 Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
797 self.annotate_in_place(&mut c.this);
798 }
799
800 Expression::Case(c) => {
802 if let Some(ref mut operand) = c.operand {
803 self.annotate_in_place(operand);
804 }
805 for (cond, then_expr) in &mut c.whens {
806 self.annotate_in_place(cond);
807 self.annotate_in_place(then_expr);
808 }
809 if let Some(ref mut else_expr) = c.else_ {
810 self.annotate_in_place(else_expr);
811 }
812 }
813
814 Expression::Alias(a) => {
816 self.annotate_in_place(&mut a.this);
817 }
818
819 Expression::Column(_) => {}
821
822 Expression::Function(f) => {
824 for arg in &mut f.args {
825 self.annotate_in_place(arg);
826 }
827 }
828 Expression::Unnest(unnest) => {
829 self.annotate_in_place(&mut unnest.this);
830 for expression in &mut unnest.expressions {
831 self.annotate_in_place(expression);
832 }
833 }
834
835 Expression::IfFunc(f) => {
837 self.annotate_in_place(&mut f.condition);
838 self.annotate_in_place(&mut f.true_value);
839 if let Some(false_value) = &mut f.false_value {
840 self.annotate_in_place(false_value);
841 }
842 }
843 Expression::Nvl2(f) => {
844 self.annotate_in_place(&mut f.this);
845 self.annotate_in_place(&mut f.true_value);
846 self.annotate_in_place(&mut f.false_value);
847 }
848
849 Expression::AggregateFunction(f) => {
851 for arg in &mut f.args {
852 self.annotate_in_place(arg);
853 }
854 }
855
856 Expression::Count(f) => {
858 if let Some(this) = &mut f.this {
859 self.annotate_in_place(this);
860 }
861 if let Some(filter) = &mut f.filter {
862 self.annotate_in_place(filter);
863 }
864 }
865 Expression::GroupConcat(f) => {
866 self.annotate_in_place(&mut f.this);
867 if let Some(separator) = &mut f.separator {
868 self.annotate_in_place(separator);
869 }
870 if let Some(order_by) = &mut f.order_by {
871 for ordered in order_by {
872 self.annotate_in_place(&mut ordered.this);
873 }
874 }
875 if let Some(filter) = &mut f.filter {
876 self.annotate_in_place(filter);
877 }
878 }
879 Expression::StringAgg(f) => {
880 self.annotate_in_place(&mut f.this);
881 if let Some(separator) = &mut f.separator {
882 self.annotate_in_place(separator);
883 }
884 if let Some(order_by) = &mut f.order_by {
885 for ordered in order_by {
886 self.annotate_in_place(&mut ordered.this);
887 }
888 }
889 if let Some(filter) = &mut f.filter {
890 self.annotate_in_place(filter);
891 }
892 if let Some(limit) = &mut f.limit {
893 self.annotate_in_place(limit);
894 }
895 }
896 Expression::ListAgg(f) => {
897 self.annotate_in_place(&mut f.this);
898 if let Some(separator) = &mut f.separator {
899 self.annotate_in_place(separator);
900 }
901 if let Some(order_by) = &mut f.order_by {
902 for ordered in order_by {
903 self.annotate_in_place(&mut ordered.this);
904 }
905 }
906 if let Some(filter) = &mut f.filter {
907 self.annotate_in_place(filter);
908 }
909 if let Some(ListAggOverflow::Truncate {
910 filler: Some(filler),
911 ..
912 }) = &mut f.on_overflow
913 {
914 self.annotate_in_place(filler);
915 }
916 }
917 Expression::SumIf(f) => {
918 self.annotate_in_place(&mut f.this);
919 self.annotate_in_place(&mut f.condition);
920 if let Some(filter) = &mut f.filter {
921 self.annotate_in_place(filter);
922 }
923 }
924
925 Expression::WindowFunction(w) => {
927 self.annotate_in_place(&mut w.this);
928 }
929
930 Expression::Subquery(s) => {
932 self.annotate_in_place(&mut s.this);
933 }
934
935 Expression::Upper(f)
937 | Expression::Lower(f)
938 | Expression::Length(f)
939 | Expression::LTrim(f)
940 | Expression::RTrim(f)
941 | Expression::Reverse(f)
942 | Expression::Abs(f)
943 | Expression::Sqrt(f)
944 | Expression::Cbrt(f)
945 | Expression::Ln(f)
946 | Expression::Exp(f)
947 | Expression::Sign(f)
948 | Expression::Date(f)
949 | Expression::Time(f)
950 | Expression::Explode(f)
951 | Expression::ExplodeOuter(f)
952 | Expression::MapFromEntries(f)
953 | Expression::MapKeys(f)
954 | Expression::MapValues(f)
955 | Expression::ArrayLength(f)
956 | Expression::ArraySize(f)
957 | Expression::Cardinality(f)
958 | Expression::ArrayReverse(f)
959 | Expression::ArrayDistinct(f)
960 | Expression::ArrayFlatten(f)
961 | Expression::ArrayCompact(f)
962 | Expression::ToArray(f)
963 | Expression::JsonArrayLength(f)
964 | Expression::JsonKeys(f)
965 | Expression::JsonType(f)
966 | Expression::ParseJson(f)
967 | Expression::ToJson(f)
968 | Expression::Year(f)
969 | Expression::Month(f)
970 | Expression::Day(f)
971 | Expression::Hour(f)
972 | Expression::Minute(f)
973 | Expression::Second(f)
974 | Expression::Initcap(f)
975 | Expression::Ascii(f)
976 | Expression::Chr(f)
977 | Expression::Soundex(f)
978 | Expression::ByteLength(f)
979 | Expression::Hex(f)
980 | Expression::LowerHex(f)
981 | Expression::Unicode(f)
982 | Expression::Typeof(f)
983 | Expression::BitwiseCount(f)
984 | Expression::Epoch(f)
985 | Expression::EpochMs(f)
986 | Expression::Radians(f)
987 | Expression::Degrees(f)
988 | Expression::Sin(f)
989 | Expression::Cos(f)
990 | Expression::Tan(f)
991 | Expression::Asin(f)
992 | Expression::Acos(f)
993 | Expression::Atan(f)
994 | Expression::IsNan(f)
995 | Expression::IsInf(f) => {
996 self.annotate_in_place(&mut f.this);
997 }
998
999 Expression::Power(f)
1001 | Expression::NullIf(f)
1002 | Expression::IfNull(f)
1003 | Expression::Nvl(f)
1004 | Expression::Contains(f)
1005 | Expression::StartsWith(f)
1006 | Expression::EndsWith(f)
1007 | Expression::Levenshtein(f)
1008 | Expression::ModFunc(f)
1009 | Expression::IntDiv(f)
1010 | Expression::Atan2(f)
1011 | Expression::AddMonths(f)
1012 | Expression::MonthsBetween(f)
1013 | Expression::NextDay(f)
1014 | Expression::UnixToTimeStr(f)
1015 | Expression::ArrayContains(f)
1016 | Expression::ArrayPosition(f)
1017 | Expression::ArrayAppend(f)
1018 | Expression::ArrayPrepend(f)
1019 | Expression::ArrayUnion(f)
1020 | Expression::ArrayExcept(f)
1021 | Expression::ArrayRemove(f)
1022 | Expression::StarMap(f)
1023 | Expression::MapFromArrays(f)
1024 | Expression::MapContainsKey(f)
1025 | Expression::ElementAt(f)
1026 | Expression::JsonMergePatch(f) => {
1027 self.annotate_in_place(&mut f.this);
1028 self.annotate_in_place(&mut f.expression);
1029 }
1030
1031 Expression::Coalesce(f)
1033 | Expression::Greatest(f)
1034 | Expression::Least(f)
1035 | Expression::ArrayConcat(f)
1036 | Expression::ArrayIntersect(f)
1037 | Expression::ArrayZip(f)
1038 | Expression::MapConcat(f)
1039 | Expression::JsonArray(f) => {
1040 for e in &mut f.expressions {
1041 self.annotate_in_place(e);
1042 }
1043 }
1044
1045 Expression::Sum(f)
1047 | Expression::Avg(f)
1048 | Expression::Min(f)
1049 | Expression::Max(f)
1050 | Expression::ArrayAgg(f)
1051 | Expression::CountIf(f)
1052 | Expression::Stddev(f)
1053 | Expression::StddevPop(f)
1054 | Expression::StddevSamp(f)
1055 | Expression::Variance(f)
1056 | Expression::VarPop(f)
1057 | Expression::VarSamp(f)
1058 | Expression::Median(f)
1059 | Expression::Mode(f)
1060 | Expression::First(f)
1061 | Expression::Last(f)
1062 | Expression::AnyValue(f)
1063 | Expression::ApproxDistinct(f)
1064 | Expression::ApproxCountDistinct(f)
1065 | Expression::LogicalAnd(f)
1066 | Expression::LogicalOr(f)
1067 | Expression::Skewness(f)
1068 | Expression::ArrayConcatAgg(f)
1069 | Expression::ArrayUniqueAgg(f)
1070 | Expression::BoolXorAgg(f)
1071 | Expression::BitwiseAndAgg(f)
1072 | Expression::BitwiseOrAgg(f)
1073 | Expression::BitwiseXorAgg(f) => {
1074 self.annotate_in_place(&mut f.this);
1075 }
1076
1077 Expression::Select(s) => {
1079 for e in &mut s.expressions {
1080 self.annotate_in_place(e);
1081 }
1082 }
1083
1084 _ => {}
1086 }
1087 }
1088
1089 fn annotate_math_function(&mut self, arg: &Expression) -> Option<DataType> {
1092 let input_type = self.annotate(arg)?;
1093 match input_type {
1094 DataType::TinyInt { .. }
1095 | DataType::SmallInt { .. }
1096 | DataType::Int { .. }
1097 | DataType::BigInt { .. } => Some(DataType::Double {
1098 precision: None,
1099 scale: None,
1100 }),
1101 other => Some(other),
1102 }
1103 }
1104
1105 fn annotate_subscript(&mut self, sub: &Subscript) -> Option<DataType> {
1107 let base_type = self.annotate(&sub.this)?;
1108
1109 match base_type {
1110 DataType::Array { element_type, .. } => Some(*element_type),
1111 DataType::Map { value_type, .. } => Some(*value_type),
1112 DataType::Json | DataType::JsonB => Some(DataType::Json), DataType::VarChar { .. } | DataType::Text => {
1114 Some(DataType::VarChar {
1116 length: Some(1),
1117 parenthesized_length: false,
1118 })
1119 }
1120 _ => None,
1121 }
1122 }
1123
1124 fn annotate_struct(&mut self, s: &Struct) -> Option<DataType> {
1126 let fields: Vec<StructField> = s
1127 .fields
1128 .iter()
1129 .map(|(name, expr)| {
1130 let field_type = self.annotate(expr).unwrap_or(DataType::Unknown);
1131 StructField::new(name.clone().unwrap_or_default(), field_type)
1132 })
1133 .collect();
1134 Some(DataType::Struct {
1135 fields,
1136 nested: false,
1137 })
1138 }
1139
1140 fn annotate_map(&mut self, map: &Map) -> Option<DataType> {
1142 let key_type = if let Some(first_key) = map.keys.first() {
1143 self.annotate(first_key).unwrap_or(DataType::Unknown)
1144 } else {
1145 DataType::Unknown
1146 };
1147
1148 let value_type = if let Some(first_value) = map.values.first() {
1149 self.annotate(first_value).unwrap_or(DataType::Unknown)
1150 } else {
1151 DataType::Unknown
1152 };
1153
1154 Some(DataType::Map {
1155 key_type: Box::new(key_type),
1156 value_type: Box::new(value_type),
1157 })
1158 }
1159
1160 fn annotate_set_operation(
1163 &mut self,
1164 _left: &Expression,
1165 _right: &Expression,
1166 ) -> Option<DataType> {
1167 None
1171 }
1172
1173 fn annotate_lateral_view(&mut self, lv: &crate::expressions::LateralView) -> Option<DataType> {
1175 self.annotate(&lv.this)
1177 }
1178
1179 fn annotate_literal(&self, lit: &Literal) -> Option<DataType> {
1181 match lit {
1182 Literal::String(_)
1183 | Literal::NationalString(_)
1184 | Literal::TripleQuotedString(_, _)
1185 | Literal::EscapeString(_)
1186 | Literal::DollarString(_)
1187 | Literal::RawString(_) => Some(DataType::VarChar {
1188 length: None,
1189 parenthesized_length: false,
1190 }),
1191 Literal::Number(n) => {
1192 if n.contains('.') || n.contains('e') || n.contains('E') {
1194 Some(DataType::Double {
1195 precision: None,
1196 scale: None,
1197 })
1198 } else {
1199 if let Ok(_) = n.parse::<i32>() {
1201 Some(DataType::Int {
1202 length: None,
1203 integer_spelling: false,
1204 })
1205 } else {
1206 Some(DataType::BigInt { length: None })
1207 }
1208 }
1209 }
1210 Literal::HexString(_) | Literal::BitString(_) | Literal::ByteString(_) => {
1211 Some(DataType::VarBinary { length: None })
1212 }
1213 Literal::HexNumber(_) => Some(DataType::BigInt { length: None }),
1214 Literal::Date(_) => Some(DataType::Date),
1215 Literal::Time(_) => Some(DataType::Time {
1216 precision: None,
1217 timezone: false,
1218 }),
1219 Literal::Timestamp(_) => Some(DataType::Timestamp {
1220 precision: None,
1221 timezone: false,
1222 }),
1223 Literal::Datetime(_) => Some(DataType::Custom {
1224 name: "DATETIME".to_string(),
1225 }),
1226 }
1227 }
1228
1229 fn annotate_arithmetic(&mut self, op: &BinaryOp) -> Option<DataType> {
1231 let left_type = self.annotate(&op.left);
1232 let right_type = self.annotate(&op.right);
1233
1234 match (left_type, right_type) {
1235 (Some(l), Some(r)) => self.coerce_types(&l, &r),
1236 (Some(t), None) | (None, Some(t)) => Some(t),
1237 (None, None) => None,
1238 }
1239 }
1240
1241 fn annotate_function(&mut self, func: &Function) -> Option<DataType> {
1243 let func_name = func.name.to_uppercase();
1244
1245 if let Some(return_type) = self.function_return_types.get(&func_name) {
1247 if *return_type != DataType::Unknown {
1248 return Some(return_type.clone());
1249 }
1250 }
1251
1252 match func_name.as_str() {
1254 "UNNEST" => func.args.first().and_then(|arg| match self.annotate(arg) {
1255 Some(DataType::Array { element_type, .. }) => Some(*element_type),
1256 _ => None,
1257 }),
1258 "COALESCE" | "IFNULL" | "NVL" | "ISNULL" => {
1259 for arg in &func.args {
1261 if let Some(arg_type) = self.annotate(arg) {
1262 return Some(arg_type);
1263 }
1264 }
1265 None
1266 }
1267 "NULLIF" => {
1268 func.args.first().and_then(|arg| self.annotate(arg))
1270 }
1271 "GREATEST" | "LEAST" => {
1272 self.coerce_arg_types(&func.args)
1274 }
1275 "IF" | "IIF" => {
1276 if func.args.len() >= 2 {
1278 self.annotate(&func.args[1])
1279 } else {
1280 None
1281 }
1282 }
1283 _ => {
1284 func.args.first().and_then(|arg| self.annotate(arg))
1286 }
1287 }
1288 }
1289
1290 fn annotate_if_func(&mut self, func: &IfFunc) -> Option<DataType> {
1292 let true_type = self.annotate(&func.true_value);
1293 let false_type = func
1294 .false_value
1295 .as_ref()
1296 .and_then(|expr| self.annotate(expr));
1297
1298 match (true_type, false_type) {
1299 (Some(left), Some(right)) => self.coerce_types(&left, &right),
1300 (Some(dt), None) | (None, Some(dt)) => Some(dt),
1301 (None, None) => None,
1302 }
1303 }
1304
1305 fn annotate_nvl2(&mut self, func: &Nvl2Func) -> Option<DataType> {
1307 let true_type = self.annotate(&func.true_value);
1308 let false_type = self.annotate(&func.false_value);
1309
1310 match (true_type, false_type) {
1311 (Some(left), Some(right)) => self.coerce_types(&left, &right),
1312 (Some(dt), None) | (None, Some(dt)) => Some(dt),
1313 (None, None) => None,
1314 }
1315 }
1316
1317 fn get_aggregate_return_type(
1319 &mut self,
1320 func_name: &str,
1321 args: &[Expression],
1322 ) -> Option<DataType> {
1323 match func_name {
1324 "COUNT" | "COUNT_IF" => Some(DataType::BigInt { length: None }),
1325 "SUM_IF" => {
1326 if let Some(arg) = args.first() {
1327 self.annotate_sum(arg)
1328 } else {
1329 Some(DataType::Decimal {
1330 precision: None,
1331 scale: None,
1332 })
1333 }
1334 }
1335 "SUM" => {
1336 if let Some(arg) = args.first() {
1337 self.annotate_sum(arg)
1338 } else {
1339 Some(DataType::Decimal {
1340 precision: None,
1341 scale: None,
1342 })
1343 }
1344 }
1345 "AVG" => Some(DataType::Double {
1346 precision: None,
1347 scale: None,
1348 }),
1349 "MIN" | "MAX" => {
1350 args.first().and_then(|arg| self.annotate(arg))
1352 }
1353 "STRING_AGG" | "GROUP_CONCAT" | "LISTAGG" | "ARRAY_AGG" => Some(DataType::VarChar {
1354 length: None,
1355 parenthesized_length: false,
1356 }),
1357 "BOOL_AND" | "BOOL_OR" | "EVERY" | "ANY" | "SOME" => Some(DataType::Boolean),
1358 "BIT_AND" | "BIT_OR" | "BIT_XOR" => Some(DataType::BigInt { length: None }),
1359 "STDDEV" | "STDDEV_POP" | "STDDEV_SAMP" | "VARIANCE" | "VAR_POP" | "VAR_SAMP" => {
1360 Some(DataType::Double {
1361 precision: None,
1362 scale: None,
1363 })
1364 }
1365 "PERCENTILE_CONT" | "PERCENTILE_DISC" | "MEDIAN" => {
1366 args.first().and_then(|arg| self.annotate(arg))
1367 }
1368 _ => None,
1369 }
1370 }
1371
1372 fn annotate_sum(&mut self, arg: &Expression) -> Option<DataType> {
1374 match self.annotate(arg) {
1375 Some(DataType::TinyInt { .. })
1376 | Some(DataType::SmallInt { .. })
1377 | Some(DataType::Int { .. }) => Some(DataType::BigInt { length: None }),
1378 Some(DataType::BigInt { .. }) => Some(DataType::BigInt { length: None }),
1379 Some(DataType::Float { .. }) | Some(DataType::Double { .. }) => {
1380 Some(DataType::Double {
1381 precision: None,
1382 scale: None,
1383 })
1384 }
1385 Some(DataType::Decimal { precision, scale }) => {
1386 Some(DataType::Decimal { precision, scale })
1387 }
1388 _ => Some(DataType::Decimal {
1389 precision: None,
1390 scale: None,
1391 }),
1392 }
1393 }
1394
1395 fn coerce_arg_types(&mut self, args: &[Expression]) -> Option<DataType> {
1397 let mut result_type: Option<DataType> = None;
1398 for arg in args {
1399 if let Some(arg_type) = self.annotate(arg) {
1400 result_type = match result_type {
1401 Some(t) => self.coerce_types(&t, &arg_type),
1402 None => Some(arg_type),
1403 };
1404 }
1405 }
1406 result_type
1407 }
1408
1409 fn coerce_types(&self, left: &DataType, right: &DataType) -> Option<DataType> {
1411 if left == right {
1413 return Some(left.clone());
1414 }
1415
1416 match (left, right) {
1418 (DataType::Date, DataType::Interval { .. })
1419 | (DataType::Interval { .. }, DataType::Date) => return Some(DataType::Date),
1420 (
1421 DataType::Timestamp {
1422 precision,
1423 timezone,
1424 },
1425 DataType::Interval { .. },
1426 )
1427 | (
1428 DataType::Interval { .. },
1429 DataType::Timestamp {
1430 precision,
1431 timezone,
1432 },
1433 ) => {
1434 return Some(DataType::Timestamp {
1435 precision: *precision,
1436 timezone: *timezone,
1437 });
1438 }
1439 _ => {}
1440 }
1441
1442 let left_class = TypeCoercionClass::from_data_type(left);
1444 let right_class = TypeCoercionClass::from_data_type(right);
1445
1446 match (left_class, right_class) {
1447 (Some(lc), Some(rc)) if lc == rc => {
1449 if lc == TypeCoercionClass::Numeric {
1451 Some(self.wider_numeric_type(left, right))
1452 } else {
1453 Some(left.clone())
1455 }
1456 }
1457 (Some(lc), Some(rc)) => {
1459 if lc > rc {
1460 Some(left.clone())
1461 } else {
1462 Some(right.clone())
1463 }
1464 }
1465 (Some(_), None) => Some(left.clone()),
1467 (None, Some(_)) => Some(right.clone()),
1468 (None, None) => Some(DataType::Unknown),
1470 }
1471 }
1472
1473 fn wider_numeric_type(&self, left: &DataType, right: &DataType) -> DataType {
1475 let order = |dt: &DataType| -> u8 {
1476 match dt {
1477 DataType::Boolean => 0,
1478 DataType::TinyInt { .. } => 1,
1479 DataType::SmallInt { .. } => 2,
1480 DataType::Int { .. } => 3,
1481 DataType::BigInt { .. } => 4,
1482 DataType::Float { .. } => 5,
1483 DataType::Double { .. } => 6,
1484 DataType::Decimal { .. } => 7,
1485 _ => 0,
1486 }
1487 };
1488
1489 if order(left) >= order(right) {
1490 left.clone()
1491 } else {
1492 right.clone()
1493 }
1494 }
1495}
1496
1497struct ScopedSchema<'a> {
1502 parent: Option<&'a dyn Schema>,
1503 tables: HashMap<String, HashMap<String, DataType>>,
1504 dialect: Option<DialectType>,
1505}
1506
1507impl<'a> ScopedSchema<'a> {
1508 fn new(parent: Option<&'a dyn Schema>, dialect: Option<DialectType>) -> Self {
1509 Self {
1510 parent,
1511 tables: HashMap::new(),
1512 dialect,
1513 }
1514 }
1515
1516 fn normalized(&self, name: &str, is_table: bool) -> String {
1517 normalize_name(name, self.dialect, is_table, true)
1518 }
1519
1520 fn local_column_type(&self, table: &str, column: &str) -> Option<DataType> {
1521 let table = self.normalized(table, true);
1522 let column = self.normalized(column, false);
1523 self.tables
1524 .get(&table)
1525 .and_then(|columns| columns.get(&column))
1526 .cloned()
1527 }
1528
1529 fn local_tables_for_column(&self, column: &str) -> Vec<String> {
1530 let column = self.normalized(column, false);
1531 self.tables
1532 .iter()
1533 .filter_map(|(table, columns)| columns.contains_key(&column).then(|| table.clone()))
1534 .collect()
1535 }
1536}
1537
1538impl Schema for ScopedSchema<'_> {
1539 fn dialect(&self) -> Option<DialectType> {
1540 self.dialect
1541 .or_else(|| self.parent.and_then(Schema::dialect))
1542 }
1543
1544 fn add_table(
1545 &mut self,
1546 table: &str,
1547 columns: &[(String, DataType)],
1548 _dialect: Option<DialectType>,
1549 ) -> SchemaResult<()> {
1550 let table = self.normalized(table, true);
1551 let columns = columns
1552 .iter()
1553 .map(|(name, data_type)| (self.normalized(name, false), data_type.clone()))
1554 .collect();
1555 self.tables.insert(table, columns);
1556 Ok(())
1557 }
1558
1559 fn column_names(&self, table: &str) -> SchemaResult<Vec<String>> {
1560 let table = self.normalized(table, true);
1561 if let Some(columns) = self.tables.get(&table) {
1562 return Ok(columns.keys().cloned().collect());
1563 }
1564 self.parent
1565 .ok_or_else(|| SchemaError::TableNotFound(table.clone()))?
1566 .column_names(&table)
1567 }
1568
1569 fn get_column_type(&self, table: &str, column: &str) -> SchemaResult<DataType> {
1570 if table.is_empty() {
1571 let local_tables = self.local_tables_for_column(column);
1572 return match local_tables.as_slice() {
1573 [local_table] => self.get_column_type(local_table, column),
1574 [] => self
1575 .parent
1576 .ok_or_else(|| SchemaError::ColumnNotFound {
1577 table: String::new(),
1578 column: column.to_string(),
1579 })?
1580 .get_column_type(table, column),
1581 _ => Err(SchemaError::AmbiguousTable {
1582 table: String::new(),
1583 matches: local_tables.join(", "),
1584 }),
1585 };
1586 }
1587
1588 let normalized_table = self.normalized(table, true);
1589 if self.tables.contains_key(&normalized_table) {
1590 return self.local_column_type(table, column).ok_or_else(|| {
1591 SchemaError::ColumnNotFound {
1592 table: table.to_string(),
1593 column: column.to_string(),
1594 }
1595 });
1596 }
1597
1598 self.parent
1599 .ok_or_else(|| SchemaError::ColumnNotFound {
1600 table: table.to_string(),
1601 column: column.to_string(),
1602 })?
1603 .get_column_type(table, column)
1604 }
1605
1606 fn has_column(&self, table: &str, column: &str) -> bool {
1607 self.get_column_type(table, column).is_ok()
1608 }
1609
1610 fn supported_table_args(&self) -> &[&str] {
1611 TABLE_PARTS
1612 }
1613
1614 fn is_empty(&self) -> bool {
1615 self.tables.is_empty() && self.parent.is_none_or(Schema::is_empty)
1616 }
1617
1618 fn depth(&self) -> usize {
1619 self.parent.map_or(1, |schema| schema.depth().max(1))
1620 }
1621
1622 fn find_tables_for_column(&self, column: &str) -> Vec<String> {
1623 let mut tables = self.local_tables_for_column(column);
1624 if let Some(parent) = self.parent {
1625 tables.extend(parent.find_tables_for_column(column));
1626 }
1627 let mut seen = HashSet::new();
1628 tables.retain(|table| seen.insert(table.clone()));
1629 tables
1630 }
1631}
1632
1633type OutputColumns = Vec<(String, DataType)>;
1634
1635fn table_name(table: &crate::expressions::TableRef) -> String {
1636 let mut parts = Vec::new();
1637 if let Some(catalog) = &table.catalog {
1638 parts.push(catalog.name.as_str());
1639 }
1640 if let Some(schema) = &table.schema {
1641 parts.push(schema.name.as_str());
1642 }
1643 parts.push(table.name.name.as_str());
1644 parts.join(".")
1645}
1646
1647fn table_columns(schema: &dyn Schema, table: &str) -> OutputColumns {
1648 schema
1649 .column_names(table)
1650 .unwrap_or_default()
1651 .into_iter()
1652 .map(|column| {
1653 let data_type = schema
1654 .get_column_type(table, &column)
1655 .unwrap_or(DataType::Unknown);
1656 (column, data_type)
1657 })
1658 .collect()
1659}
1660
1661fn apply_column_aliases(
1662 mut columns: OutputColumns,
1663 aliases: &[crate::expressions::Identifier],
1664) -> OutputColumns {
1665 for ((name, _), alias) in columns.iter_mut().zip(aliases) {
1666 *name = alias.name.clone();
1667 }
1668 columns
1669}
1670
1671fn projection_name(expression: &Expression) -> Option<String> {
1672 match expression {
1673 Expression::Alias(alias) => Some(alias.alias.name.clone()),
1674 Expression::Column(column) => Some(column.name.name.clone()),
1675 Expression::Identifier(identifier) => Some(identifier.name.clone()),
1676 _ => None,
1677 }
1678}
1679
1680fn projection_type(expression: &Expression) -> DataType {
1681 expression
1682 .inferred_type()
1683 .or_else(|| match expression {
1684 Expression::Alias(alias) => alias.this.inferred_type(),
1685 _ => None,
1686 })
1687 .cloned()
1688 .unwrap_or(DataType::Unknown)
1689}
1690
1691fn query_outputs(expressions: &[Expression]) -> OutputColumns {
1692 expressions
1693 .iter()
1694 .filter_map(|expression| {
1695 projection_name(expression).map(|name| (name, projection_type(expression)))
1696 })
1697 .collect()
1698}
1699
1700fn array_element_type(data_type: Option<&DataType>) -> DataType {
1701 match data_type {
1702 Some(DataType::Array { element_type, .. }) => (**element_type).clone(),
1703 _ => DataType::Unknown,
1704 }
1705}
1706
1707fn unnest_output_types(unnest: &crate::expressions::UnnestFunc) -> Vec<DataType> {
1708 let mut types = vec![array_element_type(unnest.this.inferred_type())];
1709 types.extend(
1710 unnest
1711 .expressions
1712 .iter()
1713 .map(|expression| array_element_type(expression.inferred_type())),
1714 );
1715 if unnest.with_ordinality || unnest.offset_alias.is_some() {
1716 types.push(DataType::BigInt { length: None });
1717 }
1718 types
1719}
1720
1721fn virtual_output_columns(
1722 expression: &Expression,
1723 source_alias: &str,
1724 column_aliases: &[crate::expressions::Identifier],
1725) -> OutputColumns {
1726 let (types, offset_alias) = match expression {
1727 Expression::Unnest(unnest) => (unnest_output_types(unnest), unnest.offset_alias.as_ref()),
1728 Expression::Explode(explode) | Expression::ExplodeOuter(explode) => {
1729 (vec![array_element_type(explode.this.inferred_type())], None)
1730 }
1731 Expression::Function(function) if function.name.eq_ignore_ascii_case("UNNEST") => (
1732 function
1733 .args
1734 .iter()
1735 .map(|argument| array_element_type(argument.inferred_type()))
1736 .collect(),
1737 None,
1738 ),
1739 _ => return Vec::new(),
1740 };
1741
1742 if column_aliases.is_empty() {
1743 let mut columns = Vec::new();
1744 if let Some(data_type) = types.first() {
1745 columns.push((source_alias.to_string(), data_type.clone()));
1746 }
1747 if let Some(offset_alias) = offset_alias {
1748 columns.push((offset_alias.name.clone(), DataType::BigInt { length: None }));
1749 }
1750 columns
1751 } else {
1752 column_aliases
1753 .iter()
1754 .zip(types)
1755 .map(|(alias, data_type)| (alias.name.clone(), data_type))
1756 .collect()
1757 }
1758}
1759
1760fn annotate_relation_source(
1761 expression: &mut Expression,
1762 schema: &mut ScopedSchema<'_>,
1763 dialect: Option<DialectType>,
1764) {
1765 match expression {
1766 Expression::Table(table) => {
1767 let source_table = table_name(table);
1768 let mut columns = table_columns(schema, &source_table);
1769 columns = apply_column_aliases(columns, &table.column_aliases);
1770 let visible_name = table
1771 .alias
1772 .as_ref()
1773 .map(|alias| alias.name.as_str())
1774 .unwrap_or(table.name.name.as_str());
1775 let _ = schema.add_table(visible_name, &columns, dialect);
1776 }
1777 Expression::Subquery(subquery) => {
1778 let mut columns = annotate_scoped_expression(&mut subquery.this, Some(schema), dialect);
1779 columns = apply_column_aliases(columns, &subquery.column_aliases);
1780 if let Some((_, first_type)) = columns.first() {
1781 subquery.inferred_type = Some(first_type.clone());
1782 }
1783 if let Some(alias) = &subquery.alias {
1784 let _ = schema.add_table(&alias.name, &columns, dialect);
1785 }
1786 }
1787 Expression::Alias(alias) => {
1788 match &mut alias.this {
1789 Expression::Subquery(subquery) => {
1790 let columns =
1791 annotate_scoped_expression(&mut subquery.this, Some(schema), dialect);
1792 let columns = apply_column_aliases(columns, &alias.column_aliases);
1793 let _ = schema.add_table(&alias.alias.name, &columns, dialect);
1794 return;
1795 }
1796 _ => {
1797 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1798 annotator.annotate_in_place(&mut alias.this);
1799 }
1800 }
1801 let columns =
1802 virtual_output_columns(&alias.this, &alias.alias.name, &alias.column_aliases);
1803 if !columns.is_empty() {
1804 let _ = schema.add_table(&alias.alias.name, &columns, dialect);
1805 }
1806 }
1807 Expression::Unnest(_) => {
1808 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1809 annotator.annotate_in_place(expression);
1810 if let Expression::Unnest(unnest) = expression {
1811 if let Some(alias) = &unnest.alias {
1812 let alias_name = alias.name.clone();
1813 let columns = unnest_output_types(unnest)
1814 .into_iter()
1815 .next()
1816 .map(|data_type| vec![(alias_name.clone(), data_type)])
1817 .unwrap_or_default();
1818 let _ = schema.add_table(&alias_name, &columns, dialect);
1819 }
1820 }
1821 }
1822 Expression::Lateral(lateral) => {
1823 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1824 annotator.annotate_in_place(&mut lateral.this);
1825 if let Some(alias) = &lateral.alias {
1826 let aliases: Vec<_> = lateral
1827 .column_aliases
1828 .iter()
1829 .map(crate::expressions::Identifier::new)
1830 .collect();
1831 let columns = virtual_output_columns(&lateral.this, alias, &aliases);
1832 if !columns.is_empty() {
1833 let _ = schema.add_table(alias, &columns, dialect);
1834 }
1835 }
1836 }
1837 Expression::Paren(paren) => annotate_relation_source(&mut paren.this, schema, dialect),
1838 _ => {
1839 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1840 annotator.annotate_in_place(expression);
1841 }
1842 }
1843}
1844
1845fn annotate_with(
1846 with: &mut Option<crate::expressions::With>,
1847 schema: &mut ScopedSchema<'_>,
1848 dialect: Option<DialectType>,
1849) {
1850 if let Some(with) = with {
1851 for cte in &mut with.ctes {
1852 let columns = annotate_scoped_expression(&mut cte.this, Some(schema), dialect);
1853 let columns = apply_column_aliases(columns, &cte.columns);
1854 let _ = schema.add_table(&cte.alias.name, &columns, dialect);
1855 }
1856 }
1857}
1858
1859fn annotate_select(
1860 select: &mut crate::expressions::Select,
1861 parent: Option<&dyn Schema>,
1862 dialect: Option<DialectType>,
1863) -> OutputColumns {
1864 let mut schema = ScopedSchema::new(parent, dialect);
1865 annotate_with(&mut select.with, &mut schema, dialect);
1866
1867 if let Some(from) = &mut select.from {
1868 for source in &mut from.expressions {
1869 annotate_relation_source(source, &mut schema, dialect);
1870 }
1871 }
1872 for join in &mut select.joins {
1873 annotate_relation_source(&mut join.this, &mut schema, dialect);
1874 }
1875
1876 let mut annotator = TypeAnnotator::new(Some(&schema), dialect);
1877 for expression in &mut select.expressions {
1878 annotator.annotate_in_place(expression);
1879 }
1880 query_outputs(&select.expressions)
1881}
1882
1883fn annotate_scoped_expression(
1884 expression: &mut Expression,
1885 parent: Option<&dyn Schema>,
1886 dialect: Option<DialectType>,
1887) -> OutputColumns {
1888 match expression {
1889 Expression::Select(select) => annotate_select(select, parent, dialect),
1890 Expression::Subquery(subquery) => {
1891 let columns = annotate_scoped_expression(&mut subquery.this, parent, dialect);
1892 if let Some((_, first_type)) = columns.first() {
1893 subquery.inferred_type = Some(first_type.clone());
1894 }
1895 columns
1896 }
1897 Expression::Cte(cte) => annotate_scoped_expression(&mut cte.this, parent, dialect),
1898 Expression::Paren(paren) => annotate_scoped_expression(&mut paren.this, parent, dialect),
1899 Expression::Union(union) => {
1900 let mut schema = ScopedSchema::new(parent, dialect);
1901 annotate_with(&mut union.with, &mut schema, dialect);
1902 let columns = annotate_scoped_expression(&mut union.left, Some(&schema), dialect);
1903 annotate_scoped_expression(&mut union.right, Some(&schema), dialect);
1904 columns
1905 }
1906 Expression::Intersect(intersect) => {
1907 let mut schema = ScopedSchema::new(parent, dialect);
1908 annotate_with(&mut intersect.with, &mut schema, dialect);
1909 let columns = annotate_scoped_expression(&mut intersect.left, Some(&schema), dialect);
1910 annotate_scoped_expression(&mut intersect.right, Some(&schema), dialect);
1911 columns
1912 }
1913 Expression::Except(except) => {
1914 let mut schema = ScopedSchema::new(parent, dialect);
1915 annotate_with(&mut except.with, &mut schema, dialect);
1916 let columns = annotate_scoped_expression(&mut except.left, Some(&schema), dialect);
1917 annotate_scoped_expression(&mut except.right, Some(&schema), dialect);
1918 columns
1919 }
1920 _ => {
1921 let mut annotator = TypeAnnotator::new(parent, dialect);
1922 annotator.annotate_in_place(expression);
1923 Vec::new()
1924 }
1925 }
1926}
1927
1928pub fn annotate_types(
1934 expr: &mut Expression,
1935 schema: Option<&dyn Schema>,
1936 dialect: Option<DialectType>,
1937) {
1938 annotate_scoped_expression(expr, schema, dialect);
1939}
1940
1941#[cfg(test)]
1942mod tests {
1943 use super::*;
1944 use crate::expressions::{BooleanLiteral, Cast, Null};
1945 use crate::{parse_one, DialectType, MappingSchema, Schema};
1946
1947 fn make_int_literal(val: i64) -> Expression {
1948 Expression::Literal(Box::new(Literal::Number(val.to_string())))
1949 }
1950
1951 fn make_float_literal(val: f64) -> Expression {
1952 Expression::Literal(Box::new(Literal::Number(val.to_string())))
1953 }
1954
1955 fn make_string_literal(val: &str) -> Expression {
1956 Expression::Literal(Box::new(Literal::String(val.to_string())))
1957 }
1958
1959 fn make_bool_literal(val: bool) -> Expression {
1960 Expression::Boolean(BooleanLiteral { value: val })
1961 }
1962
1963 #[test]
1964 fn test_literal_types() {
1965 let mut annotator = TypeAnnotator::new(None, None);
1966
1967 let int_expr = make_int_literal(42);
1969 assert_eq!(
1970 annotator.annotate(&int_expr),
1971 Some(DataType::Int {
1972 length: None,
1973 integer_spelling: false
1974 })
1975 );
1976
1977 let float_expr = make_float_literal(3.14);
1979 assert_eq!(
1980 annotator.annotate(&float_expr),
1981 Some(DataType::Double {
1982 precision: None,
1983 scale: None
1984 })
1985 );
1986
1987 let string_expr = make_string_literal("hello");
1989 assert_eq!(
1990 annotator.annotate(&string_expr),
1991 Some(DataType::VarChar {
1992 length: None,
1993 parenthesized_length: false
1994 })
1995 );
1996
1997 let bool_expr = make_bool_literal(true);
1999 assert_eq!(annotator.annotate(&bool_expr), Some(DataType::Boolean));
2000
2001 let null_expr = Expression::Null(Null);
2003 assert_eq!(annotator.annotate(&null_expr), None);
2004 }
2005
2006 #[test]
2007 fn test_comparison_types() {
2008 let mut annotator = TypeAnnotator::new(None, None);
2009
2010 let cmp = Expression::Gt(Box::new(BinaryOp::new(
2012 make_int_literal(1),
2013 make_int_literal(2),
2014 )));
2015 assert_eq!(annotator.annotate(&cmp), Some(DataType::Boolean));
2016
2017 let eq = Expression::Eq(Box::new(BinaryOp::new(
2019 make_string_literal("a"),
2020 make_string_literal("b"),
2021 )));
2022 assert_eq!(annotator.annotate(&eq), Some(DataType::Boolean));
2023 }
2024
2025 #[test]
2026 fn test_arithmetic_types() {
2027 let mut annotator = TypeAnnotator::new(None, None);
2028
2029 let add_int = Expression::Add(Box::new(BinaryOp::new(
2031 make_int_literal(1),
2032 make_int_literal(2),
2033 )));
2034 assert_eq!(
2035 annotator.annotate(&add_int),
2036 Some(DataType::Int {
2037 length: None,
2038 integer_spelling: false
2039 })
2040 );
2041
2042 let add_mixed = Expression::Add(Box::new(BinaryOp::new(
2044 make_int_literal(1),
2045 make_float_literal(2.5), )));
2047 assert_eq!(
2048 annotator.annotate(&add_mixed),
2049 Some(DataType::Double {
2050 precision: None,
2051 scale: None
2052 })
2053 );
2054 }
2055
2056 #[test]
2057 fn test_string_concat_type() {
2058 let mut annotator = TypeAnnotator::new(None, None);
2059
2060 let concat = Expression::Concat(Box::new(BinaryOp::new(
2062 make_string_literal("hello"),
2063 make_string_literal(" world"),
2064 )));
2065 assert_eq!(
2066 annotator.annotate(&concat),
2067 Some(DataType::VarChar {
2068 length: None,
2069 parenthesized_length: false
2070 })
2071 );
2072 }
2073
2074 #[test]
2075 fn test_cast_type() {
2076 let mut annotator = TypeAnnotator::new(None, None);
2077
2078 let cast = Expression::Cast(Box::new(Cast {
2080 this: make_int_literal(1),
2081 to: DataType::VarChar {
2082 length: Some(10),
2083 parenthesized_length: false,
2084 },
2085 trailing_comments: vec![],
2086 double_colon_syntax: false,
2087 format: None,
2088 default: None,
2089 inferred_type: None,
2090 }));
2091 assert_eq!(
2092 annotator.annotate(&cast),
2093 Some(DataType::VarChar {
2094 length: Some(10),
2095 parenthesized_length: false
2096 })
2097 );
2098 }
2099
2100 #[test]
2101 fn test_function_types() {
2102 let mut annotator = TypeAnnotator::new(None, None);
2103
2104 let count =
2106 Expression::Function(Box::new(Function::new("COUNT", vec![make_int_literal(1)])));
2107 assert_eq!(
2108 annotator.annotate(&count),
2109 Some(DataType::BigInt { length: None })
2110 );
2111
2112 let upper = Expression::Function(Box::new(Function::new(
2114 "UPPER",
2115 vec![make_string_literal("hello")],
2116 )));
2117 assert_eq!(
2118 annotator.annotate(&upper),
2119 Some(DataType::VarChar {
2120 length: None,
2121 parenthesized_length: false
2122 })
2123 );
2124
2125 let now = Expression::Function(Box::new(Function::new("NOW", vec![])));
2127 assert_eq!(
2128 annotator.annotate(&now),
2129 Some(DataType::Timestamp {
2130 precision: None,
2131 timezone: false
2132 })
2133 );
2134 }
2135
2136 #[test]
2137 fn test_coalesce_type_inference() {
2138 let mut annotator = TypeAnnotator::new(None, None);
2139
2140 let coalesce = Expression::Function(Box::new(Function::new(
2142 "COALESCE",
2143 vec![Expression::Null(Null), make_int_literal(1)],
2144 )));
2145 assert_eq!(
2146 annotator.annotate(&coalesce),
2147 Some(DataType::Int {
2148 length: None,
2149 integer_spelling: false
2150 })
2151 );
2152 }
2153
2154 #[test]
2155 fn test_type_coercion_class() {
2156 assert_eq!(
2158 TypeCoercionClass::from_data_type(&DataType::VarChar {
2159 length: None,
2160 parenthesized_length: false
2161 }),
2162 Some(TypeCoercionClass::Text)
2163 );
2164 assert_eq!(
2165 TypeCoercionClass::from_data_type(&DataType::Text),
2166 Some(TypeCoercionClass::Text)
2167 );
2168
2169 assert_eq!(
2171 TypeCoercionClass::from_data_type(&DataType::Int {
2172 length: None,
2173 integer_spelling: false
2174 }),
2175 Some(TypeCoercionClass::Numeric)
2176 );
2177 assert_eq!(
2178 TypeCoercionClass::from_data_type(&DataType::Double {
2179 precision: None,
2180 scale: None
2181 }),
2182 Some(TypeCoercionClass::Numeric)
2183 );
2184
2185 assert_eq!(
2187 TypeCoercionClass::from_data_type(&DataType::Date),
2188 Some(TypeCoercionClass::Timelike)
2189 );
2190 assert_eq!(
2191 TypeCoercionClass::from_data_type(&DataType::Timestamp {
2192 precision: None,
2193 timezone: false
2194 }),
2195 Some(TypeCoercionClass::Timelike)
2196 );
2197
2198 assert_eq!(TypeCoercionClass::from_data_type(&DataType::Json), None);
2200 }
2201
2202 #[test]
2203 fn test_wider_numeric_type() {
2204 let annotator = TypeAnnotator::new(None, None);
2205
2206 let result = annotator.wider_numeric_type(
2208 &DataType::Int {
2209 length: None,
2210 integer_spelling: false,
2211 },
2212 &DataType::BigInt { length: None },
2213 );
2214 assert_eq!(result, DataType::BigInt { length: None });
2215
2216 let result = annotator.wider_numeric_type(
2218 &DataType::Float {
2219 precision: None,
2220 scale: None,
2221 real_spelling: false,
2222 },
2223 &DataType::Double {
2224 precision: None,
2225 scale: None,
2226 },
2227 );
2228 assert_eq!(
2229 result,
2230 DataType::Double {
2231 precision: None,
2232 scale: None
2233 }
2234 );
2235
2236 let result = annotator.wider_numeric_type(
2238 &DataType::Int {
2239 length: None,
2240 integer_spelling: false,
2241 },
2242 &DataType::Double {
2243 precision: None,
2244 scale: None,
2245 },
2246 );
2247 assert_eq!(
2248 result,
2249 DataType::Double {
2250 precision: None,
2251 scale: None
2252 }
2253 );
2254 }
2255
2256 #[test]
2257 fn test_aggregate_return_types() {
2258 let mut annotator = TypeAnnotator::new(None, None);
2259
2260 let sum_type = annotator.get_aggregate_return_type("SUM", &[make_int_literal(1)]);
2262 assert_eq!(sum_type, Some(DataType::BigInt { length: None }));
2263
2264 let avg_type = annotator.get_aggregate_return_type("AVG", &[make_int_literal(1)]);
2266 assert_eq!(
2267 avg_type,
2268 Some(DataType::Double {
2269 precision: None,
2270 scale: None
2271 })
2272 );
2273
2274 let min_type = annotator.get_aggregate_return_type("MIN", &[make_string_literal("a")]);
2276 assert_eq!(
2277 min_type,
2278 Some(DataType::VarChar {
2279 length: None,
2280 parenthesized_length: false
2281 })
2282 );
2283 }
2284
2285 #[test]
2286 fn test_date_literal_types() {
2287 let mut annotator = TypeAnnotator::new(None, None);
2288
2289 let date_expr = Expression::Literal(Box::new(Literal::Date("2024-01-15".to_string())));
2291 assert_eq!(annotator.annotate(&date_expr), Some(DataType::Date));
2292
2293 let time_expr = Expression::Literal(Box::new(Literal::Time("10:30:00".to_string())));
2295 assert_eq!(
2296 annotator.annotate(&time_expr),
2297 Some(DataType::Time {
2298 precision: None,
2299 timezone: false
2300 })
2301 );
2302
2303 let ts_expr = Expression::Literal(Box::new(Literal::Timestamp(
2305 "2024-01-15 10:30:00".to_string(),
2306 )));
2307 assert_eq!(
2308 annotator.annotate(&ts_expr),
2309 Some(DataType::Timestamp {
2310 precision: None,
2311 timezone: false
2312 })
2313 );
2314 }
2315
2316 #[test]
2317 fn test_logical_operations() {
2318 let mut annotator = TypeAnnotator::new(None, None);
2319
2320 let and_expr = Expression::And(Box::new(BinaryOp::new(
2322 make_bool_literal(true),
2323 make_bool_literal(false),
2324 )));
2325 assert_eq!(annotator.annotate(&and_expr), Some(DataType::Boolean));
2326
2327 let or_expr = Expression::Or(Box::new(BinaryOp::new(
2329 make_bool_literal(true),
2330 make_bool_literal(false),
2331 )));
2332 assert_eq!(annotator.annotate(&or_expr), Some(DataType::Boolean));
2333
2334 let not_expr = Expression::Not(Box::new(crate::expressions::UnaryOp::new(
2336 make_bool_literal(true),
2337 )));
2338 assert_eq!(annotator.annotate(¬_expr), Some(DataType::Boolean));
2339 }
2340
2341 #[test]
2346 fn test_subscript_array_type() {
2347 let mut annotator = TypeAnnotator::new(None, None);
2348
2349 let arr = Expression::Array(Box::new(crate::expressions::Array {
2351 expressions: vec![make_int_literal(1), make_int_literal(2)],
2352 }));
2353 let subscript = Expression::Subscript(Box::new(crate::expressions::Subscript {
2354 this: arr,
2355 index: make_int_literal(0),
2356 }));
2357 assert_eq!(
2358 annotator.annotate(&subscript),
2359 Some(DataType::Int {
2360 length: None,
2361 integer_spelling: false
2362 })
2363 );
2364 }
2365
2366 #[test]
2367 fn test_subscript_map_type() {
2368 let mut annotator = TypeAnnotator::new(None, None);
2369
2370 let map = Expression::Map(Box::new(crate::expressions::Map {
2372 keys: vec![make_string_literal("a")],
2373 values: vec![make_int_literal(1)],
2374 }));
2375 let subscript = Expression::Subscript(Box::new(crate::expressions::Subscript {
2376 this: map,
2377 index: make_string_literal("a"),
2378 }));
2379 assert_eq!(
2380 annotator.annotate(&subscript),
2381 Some(DataType::Int {
2382 length: None,
2383 integer_spelling: false
2384 })
2385 );
2386 }
2387
2388 #[test]
2389 fn test_struct_type() {
2390 let mut annotator = TypeAnnotator::new(None, None);
2391
2392 let struct_expr = Expression::Struct(Box::new(crate::expressions::Struct {
2394 fields: vec![
2395 (Some("name".to_string()), make_string_literal("Alice")),
2396 (Some("age".to_string()), make_int_literal(30)),
2397 ],
2398 }));
2399 let result = annotator.annotate(&struct_expr);
2400 assert!(matches!(result, Some(DataType::Struct { fields, .. }) if fields.len() == 2));
2401 }
2402
2403 #[test]
2404 fn test_map_type() {
2405 let mut annotator = TypeAnnotator::new(None, None);
2406
2407 let map_expr = Expression::Map(Box::new(crate::expressions::Map {
2409 keys: vec![make_string_literal("a"), make_string_literal("b")],
2410 values: vec![make_int_literal(1), make_int_literal(2)],
2411 }));
2412 let result = annotator.annotate(&map_expr);
2413 assert!(matches!(
2414 result,
2415 Some(DataType::Map { key_type, value_type })
2416 if matches!(*key_type, DataType::VarChar { .. })
2417 && matches!(*value_type, DataType::Int { .. })
2418 ));
2419 }
2420
2421 #[test]
2422 fn test_explode_array_type() {
2423 let mut annotator = TypeAnnotator::new(None, None);
2424
2425 let arr = Expression::Array(Box::new(crate::expressions::Array {
2427 expressions: vec![make_int_literal(1), make_int_literal(2)],
2428 }));
2429 let explode = Expression::Explode(Box::new(crate::expressions::UnaryFunc {
2430 this: arr,
2431 original_name: None,
2432 inferred_type: None,
2433 }));
2434 assert_eq!(
2435 annotator.annotate(&explode),
2436 Some(DataType::Int {
2437 length: None,
2438 integer_spelling: false
2439 })
2440 );
2441 }
2442
2443 #[test]
2444 fn test_unnest_array_type() {
2445 let mut annotator = TypeAnnotator::new(None, None);
2446
2447 let arr = Expression::Array(Box::new(crate::expressions::Array {
2449 expressions: vec![make_string_literal("a"), make_string_literal("b")],
2450 }));
2451 let unnest = Expression::Unnest(Box::new(crate::expressions::UnnestFunc {
2452 this: arr,
2453 expressions: Vec::new(),
2454 with_ordinality: false,
2455 alias: None,
2456 offset_alias: None,
2457 inferred_type: None,
2458 }));
2459 assert_eq!(
2460 annotator.annotate(&unnest),
2461 Some(DataType::VarChar {
2462 length: None,
2463 parenthesized_length: false
2464 })
2465 );
2466 }
2467
2468 #[test]
2469 fn test_set_operation_type() {
2470 let mut annotator = TypeAnnotator::new(None, None);
2471
2472 let select = Expression::Select(Box::new(crate::expressions::Select::default()));
2474 let union = Expression::Union(Box::new(crate::expressions::Union {
2475 left: select.clone(),
2476 right: select.clone(),
2477 all: false,
2478 distinct: false,
2479 with: None,
2480 order_by: None,
2481 limit: None,
2482 offset: None,
2483 by_name: false,
2484 side: None,
2485 kind: None,
2486 corresponding: false,
2487 strict: false,
2488 on_columns: Vec::new(),
2489 distribute_by: None,
2490 sort_by: None,
2491 cluster_by: None,
2492 }));
2493 assert_eq!(annotator.annotate(&union), None);
2494 }
2495
2496 #[test]
2497 fn test_floor_ceil_input_dependent_types() {
2498 use crate::expressions::{CeilFunc, FloorFunc};
2499
2500 let mut annotator = TypeAnnotator::new(None, None);
2501
2502 let floor_int = Expression::Floor(Box::new(FloorFunc {
2504 this: make_int_literal(42),
2505 scale: None,
2506 to: None,
2507 }));
2508 assert_eq!(
2509 annotator.annotate(&floor_int),
2510 Some(DataType::Double {
2511 precision: None,
2512 scale: None,
2513 })
2514 );
2515
2516 let ceil_int = Expression::Ceil(Box::new(CeilFunc {
2517 this: make_int_literal(42),
2518 decimals: None,
2519 to: None,
2520 }));
2521 assert_eq!(
2522 annotator.annotate(&ceil_int),
2523 Some(DataType::Double {
2524 precision: None,
2525 scale: None,
2526 })
2527 );
2528
2529 let floor_float = Expression::Floor(Box::new(FloorFunc {
2531 this: make_float_literal(3.14),
2532 scale: None,
2533 to: None,
2534 }));
2535 assert_eq!(
2536 annotator.annotate(&floor_float),
2537 Some(DataType::Double {
2538 precision: None,
2539 scale: None,
2540 })
2541 );
2542
2543 let floor_fn =
2545 Expression::Function(Box::new(Function::new("FLOOR", vec![make_int_literal(1)])));
2546 assert_eq!(
2547 annotator.annotate(&floor_fn),
2548 Some(DataType::Int {
2549 length: None,
2550 integer_spelling: false,
2551 })
2552 );
2553 }
2554
2555 #[test]
2556 fn test_sign_preserves_input_type() {
2557 use crate::expressions::UnaryFunc;
2558
2559 let mut annotator = TypeAnnotator::new(None, None);
2560
2561 let sign_int = Expression::Sign(Box::new(UnaryFunc {
2563 this: make_int_literal(42),
2564 original_name: None,
2565 inferred_type: None,
2566 }));
2567 assert_eq!(
2568 annotator.annotate(&sign_int),
2569 Some(DataType::Int {
2570 length: None,
2571 integer_spelling: false,
2572 })
2573 );
2574
2575 let sign_float = Expression::Sign(Box::new(UnaryFunc {
2577 this: make_float_literal(3.14),
2578 original_name: None,
2579 inferred_type: None,
2580 }));
2581 assert_eq!(
2582 annotator.annotate(&sign_float),
2583 Some(DataType::Double {
2584 precision: None,
2585 scale: None,
2586 })
2587 );
2588
2589 let sign_cast = Expression::Sign(Box::new(UnaryFunc {
2591 this: Expression::Cast(Box::new(Cast {
2592 this: make_int_literal(42),
2593 to: DataType::Int {
2594 length: None,
2595 integer_spelling: false,
2596 },
2597 format: None,
2598 trailing_comments: Vec::new(),
2599 double_colon_syntax: false,
2600 default: None,
2601 inferred_type: None,
2602 })),
2603 original_name: None,
2604 inferred_type: None,
2605 }));
2606 assert_eq!(
2607 annotator.annotate(&sign_cast),
2608 Some(DataType::Int {
2609 length: None,
2610 integer_spelling: false,
2611 })
2612 );
2613 }
2614
2615 #[test]
2616 fn test_date_format_types() {
2617 use crate::expressions::{DateFormatFunc, TimeToStr};
2618
2619 let mut annotator = TypeAnnotator::new(None, None);
2620
2621 let date_fmt = Expression::DateFormat(Box::new(DateFormatFunc {
2623 this: make_string_literal("2024-01-01"),
2624 format: make_string_literal("%Y-%m-%d"),
2625 }));
2626 assert_eq!(
2627 annotator.annotate(&date_fmt),
2628 Some(DataType::VarChar {
2629 length: None,
2630 parenthesized_length: false,
2631 })
2632 );
2633
2634 let format_date = Expression::FormatDate(Box::new(DateFormatFunc {
2636 this: make_string_literal("2024-01-01"),
2637 format: make_string_literal("%Y-%m-%d"),
2638 }));
2639 assert_eq!(
2640 annotator.annotate(&format_date),
2641 Some(DataType::VarChar {
2642 length: None,
2643 parenthesized_length: false,
2644 })
2645 );
2646
2647 let time_to_str = Expression::TimeToStr(Box::new(TimeToStr {
2649 this: Box::new(make_string_literal("2024-01-01")),
2650 format: "%Y-%m-%d".to_string(),
2651 culture: None,
2652 zone: None,
2653 }));
2654 assert_eq!(
2655 annotator.annotate(&time_to_str),
2656 Some(DataType::VarChar {
2657 length: None,
2658 parenthesized_length: false,
2659 })
2660 );
2661
2662 let date_fmt_fn = Expression::Function(Box::new(Function::new(
2664 "DATE_FORMAT",
2665 vec![
2666 make_string_literal("2024-01-01"),
2667 make_string_literal("%Y-%m-%d"),
2668 ],
2669 )));
2670 assert_eq!(
2671 annotator.annotate(&date_fmt_fn),
2672 Some(DataType::VarChar {
2673 length: None,
2674 parenthesized_length: false,
2675 })
2676 );
2677 }
2678
2679 #[test]
2682 fn test_annotate_in_place_sets_type_on_root() {
2683 let mut expr = Expression::Add(Box::new(BinaryOp::new(
2685 make_int_literal(1),
2686 make_int_literal(2),
2687 )));
2688 annotate_types(&mut expr, None, None);
2689 assert_eq!(
2690 expr.inferred_type(),
2691 Some(&DataType::Int {
2692 length: None,
2693 integer_spelling: false,
2694 })
2695 );
2696 }
2697
2698 #[test]
2699 fn test_annotate_in_place_sets_types_on_children() {
2700 let inner_add = Expression::Add(Box::new(BinaryOp::new(
2703 make_int_literal(1),
2704 make_float_literal(2.5),
2705 )));
2706 let inner_sub = Expression::Sub(Box::new(BinaryOp::new(
2707 make_int_literal(3),
2708 make_int_literal(4),
2709 )));
2710 let mut expr = Expression::Add(Box::new(BinaryOp::new(inner_add, inner_sub)));
2711 annotate_types(&mut expr, None, None);
2712
2713 assert_eq!(
2715 expr.inferred_type(),
2716 Some(&DataType::Double {
2717 precision: None,
2718 scale: None,
2719 })
2720 );
2721
2722 if let Expression::Add(op) = &expr {
2724 assert_eq!(
2726 op.left.inferred_type(),
2727 Some(&DataType::Double {
2728 precision: None,
2729 scale: None,
2730 })
2731 );
2732 assert_eq!(
2734 op.right.inferred_type(),
2735 Some(&DataType::Int {
2736 length: None,
2737 integer_spelling: false,
2738 })
2739 );
2740 } else {
2741 panic!("Expected Add expression");
2742 }
2743 }
2744
2745 #[test]
2746 fn test_annotate_in_place_comparison() {
2747 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
2748 make_int_literal(1),
2749 make_int_literal(2),
2750 )));
2751 annotate_types(&mut expr, None, None);
2752 assert_eq!(expr.inferred_type(), Some(&DataType::Boolean));
2753 }
2754
2755 #[test]
2756 fn test_annotate_in_place_cast() {
2757 let mut expr = Expression::Cast(Box::new(Cast {
2758 this: make_int_literal(42),
2759 to: DataType::VarChar {
2760 length: None,
2761 parenthesized_length: false,
2762 },
2763 trailing_comments: vec![],
2764 double_colon_syntax: false,
2765 format: None,
2766 default: None,
2767 inferred_type: None,
2768 }));
2769 annotate_types(&mut expr, None, None);
2770 assert_eq!(
2771 expr.inferred_type(),
2772 Some(&DataType::VarChar {
2773 length: None,
2774 parenthesized_length: false,
2775 })
2776 );
2777 }
2778
2779 #[test]
2780 fn test_annotate_in_place_nested_expression() {
2781 let add = Expression::Add(Box::new(BinaryOp::new(
2783 make_int_literal(1),
2784 make_int_literal(2),
2785 )));
2786 let mut expr = Expression::Gt(Box::new(BinaryOp::new(add, make_int_literal(0))));
2787 annotate_types(&mut expr, None, None);
2788
2789 assert_eq!(expr.inferred_type(), Some(&DataType::Boolean));
2790
2791 if let Expression::Gt(op) = &expr {
2793 assert_eq!(
2794 op.left.inferred_type(),
2795 Some(&DataType::Int {
2796 length: None,
2797 integer_spelling: false,
2798 })
2799 );
2800 }
2801 }
2802
2803 #[test]
2804 fn test_annotate_in_place_parsed_sql() {
2805 use crate::parser::Parser;
2806 let mut expr =
2807 Parser::parse_sql("SELECT 1 + 2.0, 'hello', TRUE").expect("parse failed")[0].clone();
2808 annotate_types(&mut expr, None, None);
2809
2810 assert!(expr.inferred_type().is_none());
2814 }
2815
2816 #[test]
2817 fn test_inferred_type_json_roundtrip() {
2818 let mut expr = Expression::Add(Box::new(BinaryOp::new(
2819 make_int_literal(1),
2820 make_int_literal(2),
2821 )));
2822 annotate_types(&mut expr, None, None);
2823
2824 let json = serde_json::to_string(&expr).expect("serialize failed");
2826 assert!(json.contains("inferred_type"));
2828
2829 let deserialized: Expression = serde_json::from_str(&json).expect("deserialize failed");
2831 assert_eq!(
2832 deserialized.inferred_type(),
2833 Some(&DataType::Int {
2834 length: None,
2835 integer_spelling: false,
2836 })
2837 );
2838 }
2839
2840 #[test]
2841 fn test_inferred_type_none_not_serialized() {
2842 let expr = Expression::Add(Box::new(BinaryOp::new(
2844 make_int_literal(1),
2845 make_int_literal(2),
2846 )));
2847 let json = serde_json::to_string(&expr).expect("serialize failed");
2848 assert!(!json.contains("inferred_type"));
2849 }
2850
2851 #[test]
2852 fn test_annotate_if_func_bigquery_node_and_alias_type() {
2853 let mut schema = MappingSchema::with_dialect(DialectType::BigQuery);
2854 schema
2855 .add_table(
2856 "t",
2857 &[("col1".to_string(), DataType::String { length: None })],
2858 None,
2859 )
2860 .unwrap();
2861
2862 let mut expr = parse_one(
2863 "SELECT IF(col1 IS NOT NULL, 1, 0) AS x FROM t",
2864 DialectType::BigQuery,
2865 )
2866 .unwrap();
2867 annotate_types(&mut expr, Some(&schema), Some(DialectType::BigQuery));
2868
2869 let Expression::Select(select) = &expr else {
2870 panic!("expected select");
2871 };
2872 let Expression::Alias(alias) = &select.expressions[0] else {
2873 panic!("expected alias");
2874 };
2875
2876 assert_eq!(
2877 alias.this.inferred_type(),
2878 Some(&DataType::Int {
2879 length: None,
2880 integer_spelling: false,
2881 })
2882 );
2883 assert_eq!(
2884 select.expressions[0].inferred_type(),
2885 Some(&DataType::Int {
2886 length: None,
2887 integer_spelling: false,
2888 })
2889 );
2890 }
2891
2892 #[test]
2893 fn test_annotate_nvl2_node_type() {
2894 let mut expr = parse_one("SELECT NVL2(a, 1, 0) AS x", DialectType::Generic).unwrap();
2895 annotate_types(&mut expr, None, None);
2896
2897 let Expression::Select(select) = &expr else {
2898 panic!("expected select");
2899 };
2900 let Expression::Alias(alias) = &select.expressions[0] else {
2901 panic!("expected alias");
2902 };
2903
2904 assert_eq!(
2905 alias.this.inferred_type(),
2906 Some(&DataType::Int {
2907 length: None,
2908 integer_spelling: false,
2909 })
2910 );
2911 }
2912
2913 #[test]
2914 fn test_annotate_count_node_type() {
2915 let mut expr = parse_one("SELECT COUNT(1) AS x", DialectType::Generic).unwrap();
2916 annotate_types(&mut expr, None, None);
2917
2918 let Expression::Select(select) = &expr else {
2919 panic!("expected select");
2920 };
2921 let Expression::Alias(alias) = &select.expressions[0] else {
2922 panic!("expected alias");
2923 };
2924
2925 assert_eq!(
2926 alias.this.inferred_type(),
2927 Some(&DataType::BigInt { length: None })
2928 );
2929 }
2930
2931 #[test]
2932 fn test_annotate_group_concat_node_type() {
2933 let mut expr = parse_one("SELECT GROUP_CONCAT(a) AS x", DialectType::Generic).unwrap();
2934 annotate_types(&mut expr, None, None);
2935
2936 let Expression::Select(select) = &expr else {
2937 panic!("expected select");
2938 };
2939 let Expression::Alias(alias) = &select.expressions[0] else {
2940 panic!("expected alias");
2941 };
2942
2943 assert_eq!(
2944 alias.this.inferred_type(),
2945 Some(&DataType::VarChar {
2946 length: None,
2947 parenthesized_length: false,
2948 })
2949 );
2950 }
2951
2952 #[test]
2953 fn test_annotate_sum_if_generic_aggregate_type() {
2954 let mut expr =
2955 parse_one("SELECT SUM_IF(1, a > 0) AS x FROM t", DialectType::Generic).unwrap();
2956 annotate_types(&mut expr, None, None);
2957
2958 let Expression::Select(select) = &expr else {
2959 panic!("expected select");
2960 };
2961 let Expression::Alias(alias) = &select.expressions[0] else {
2962 panic!("expected alias");
2963 };
2964
2965 assert_eq!(
2966 select.expressions[0].inferred_type(),
2967 Some(&DataType::BigInt { length: None })
2968 );
2969 assert_eq!(
2970 alias.this.inferred_type(),
2971 Some(&DataType::BigInt { length: None })
2972 );
2973 }
2974}