1use std::collections::{HashMap, HashSet};
13
14use crate::dialects::DialectType;
15use crate::expressions::{
16 BinaryOp, DataType, DotAccess, Expression, Function, IfFunc, ListAggOverflow, Literal, Map,
17 Nvl2Func, 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 Expression::Coalesce(coalesce) => self.coerce_arg_types(&coalesce.expressions),
428
429 Expression::Count(_) => Some(DataType::BigInt { length: None }),
431 Expression::Sum(agg) => self.annotate_sum(&agg.this),
432 Expression::SumIf(f) => self.annotate_sum(&f.this),
433 Expression::Avg(_) => Some(DataType::Double {
434 precision: None,
435 scale: None,
436 }),
437 Expression::Min(agg) => self.annotate(&agg.this),
438 Expression::Max(agg) => self.annotate(&agg.this),
439 Expression::GroupConcat(_) | Expression::StringAgg(_) | Expression::ListAgg(_) => {
440 Some(DataType::VarChar {
441 length: None,
442 parenthesized_length: false,
443 })
444 }
445
446 Expression::AggregateFunction(agg) => {
448 if !self.annotate_aggregates {
449 return None;
450 }
451 let func_name = agg.name.to_uppercase();
452 self.get_aggregate_return_type(&func_name, &agg.args)
453 }
454
455 Expression::Column(col) => {
457 if let Some(schema) = &self._schema {
458 let table_name = col.table.as_ref().map(|t| t.name.as_str()).unwrap_or("");
459 schema.get_column_type(table_name, &col.name.name).ok()
460 } else {
461 None
462 }
463 }
464
465 Expression::Cast(cast) => Some(cast.to.clone()),
467 Expression::SafeCast(cast) => Some(cast.to.clone()),
468 Expression::TryCast(cast) => Some(cast.to.clone()),
469
470 Expression::Subquery(subq) => {
472 if let Expression::Select(select) = &subq.this {
473 if let Some(first) = select.expressions.first() {
474 self.annotate(first)
475 } else {
476 None
477 }
478 } else {
479 None
480 }
481 }
482
483 Expression::Case(case) => {
485 if let Some(else_expr) = &case.else_ {
486 self.annotate(else_expr)
487 } else if let Some((_, then_expr)) = case.whens.first() {
488 self.annotate(then_expr)
489 } else {
490 None
491 }
492 }
493
494 Expression::Array(arr) => {
496 if let Some(first) = arr.expressions.first() {
497 if let Some(elem_type) = self.annotate(first) {
498 Some(DataType::Array {
499 element_type: Box::new(elem_type),
500 dimension: None,
501 })
502 } else {
503 Some(DataType::Array {
504 element_type: Box::new(DataType::Unknown),
505 dimension: None,
506 })
507 }
508 } else {
509 Some(DataType::Array {
510 element_type: Box::new(DataType::Unknown),
511 dimension: None,
512 })
513 }
514 }
515
516 Expression::Interval(_) => Some(DataType::Interval {
518 unit: None,
519 to: None,
520 }),
521
522 Expression::WindowFunction(window) => self.annotate(&window.this),
524
525 Expression::CurrentDate(_) => Some(DataType::Date),
527 Expression::CurrentTime(_) => Some(DataType::Time {
528 precision: None,
529 timezone: false,
530 }),
531 Expression::CurrentTimestamp(_) | Expression::CurrentTimestampLTZ(_) => {
532 Some(DataType::Timestamp {
533 precision: None,
534 timezone: false,
535 })
536 }
537
538 Expression::DateAdd(_)
540 | Expression::DateSub(_)
541 | Expression::ToDate(_)
542 | Expression::Date(_) => Some(DataType::Date),
543 Expression::DateDiff(_) | Expression::Extract(_) => Some(DataType::Int {
544 length: None,
545 integer_spelling: false,
546 }),
547 Expression::ToTimestamp(_) => Some(DataType::Timestamp {
548 precision: None,
549 timezone: false,
550 }),
551
552 Expression::Upper(_)
554 | Expression::Lower(_)
555 | Expression::Trim(_)
556 | Expression::LTrim(_)
557 | Expression::RTrim(_)
558 | Expression::Replace(_)
559 | Expression::Substring(_)
560 | Expression::Reverse(_)
561 | Expression::Left(_)
562 | Expression::Right(_)
563 | Expression::Repeat(_)
564 | Expression::Lpad(_)
565 | Expression::Rpad(_)
566 | Expression::ConcatWs(_)
567 | Expression::Overlay(_) => Some(DataType::VarChar {
568 length: None,
569 parenthesized_length: false,
570 }),
571 Expression::Length(_) => Some(DataType::Int {
572 length: None,
573 integer_spelling: false,
574 }),
575
576 Expression::Abs(_)
578 | Expression::Sqrt(_)
579 | Expression::Cbrt(_)
580 | Expression::Ln(_)
581 | Expression::Exp(_)
582 | Expression::Power(_)
583 | Expression::Log(_) => Some(DataType::Double {
584 precision: None,
585 scale: None,
586 }),
587 Expression::Round(_) => Some(DataType::Double {
588 precision: None,
589 scale: None,
590 }),
591 Expression::Floor(f) => self.annotate_math_function(&f.this),
592 Expression::Ceil(f) => self.annotate_math_function(&f.this),
593 Expression::Sign(s) => self.annotate(&s.this),
594 Expression::DateFormat(_) | Expression::FormatDate(_) | Expression::TimeToStr(_) => {
595 Some(DataType::VarChar {
596 length: None,
597 parenthesized_length: false,
598 })
599 }
600
601 Expression::Greatest(v) | Expression::Least(v) => self.coerce_arg_types(&v.expressions),
603
604 Expression::Alias(alias) => self.annotate(&alias.this),
606
607 Expression::Select(_) => None,
609
610 Expression::Subscript(sub) => self.annotate_subscript(sub),
614
615 Expression::Dot(dot) => self.annotate_dot(dot),
617
618 Expression::Struct(s) => self.annotate_struct(s),
622
623 Expression::Map(map) => self.annotate_map(map),
627 Expression::MapFromEntries(mfe) => {
628 if let Some(DataType::Array { element_type, .. }) = self.annotate(&mfe.this) {
630 if let DataType::Struct { fields, .. } = *element_type {
631 if fields.len() >= 2 {
632 return Some(DataType::Map {
633 key_type: Box::new(fields[0].data_type.clone()),
634 value_type: Box::new(fields[1].data_type.clone()),
635 });
636 }
637 }
638 }
639 Some(DataType::Map {
640 key_type: Box::new(DataType::Unknown),
641 value_type: Box::new(DataType::Unknown),
642 })
643 }
644
645 Expression::Union(union) => self.annotate_set_operation(&union.left, &union.right),
649 Expression::Intersect(intersect) => {
650 self.annotate_set_operation(&intersect.left, &intersect.right)
651 }
652 Expression::Except(except) => self.annotate_set_operation(&except.left, &except.right),
653
654 Expression::Lateral(lateral) => {
658 self.annotate(&lateral.this)
660 }
661 Expression::LateralView(lv) => {
662 self.annotate_lateral_view(lv)
664 }
665 Expression::Unnest(unnest) => {
666 if let Some(DataType::Array { element_type, .. }) = self.annotate(&unnest.this) {
668 Some(*element_type)
669 } else {
670 None
671 }
672 }
673 Expression::Explode(explode) => {
674 if let Some(DataType::Array { element_type, .. }) = self.annotate(&explode.this) {
676 Some(*element_type)
677 } else if let Some(DataType::Map {
678 key_type,
679 value_type,
680 }) = self.annotate(&explode.this)
681 {
682 Some(DataType::Struct {
684 fields: vec![
685 StructField::new("key".to_string(), *key_type),
686 StructField::new("value".to_string(), *value_type),
687 ],
688 nested: false,
689 })
690 } else {
691 None
692 }
693 }
694 Expression::ExplodeOuter(explode) => {
695 if let Some(DataType::Array { element_type, .. }) = self.annotate(&explode.this) {
697 Some(*element_type)
698 } else {
699 None
700 }
701 }
702 Expression::GenerateSeries(gs) => {
703 if let Some(ref start) = gs.start {
705 self.annotate(start)
706 } else if let Some(ref end) = gs.end {
707 self.annotate(end)
708 } else {
709 Some(DataType::Int {
710 length: None,
711 integer_spelling: false,
712 })
713 }
714 }
715
716 _ => None,
718 }
719 }
720
721 pub fn annotate_in_place(&mut self, expr: &mut Expression) {
727 self.annotate_children_in_place(expr);
729
730 let dt = self.annotate(expr);
734
735 if let Some(data_type) = dt {
737 expr.set_inferred_type(data_type);
738 }
739 }
740
741 fn annotate_children_in_place(&mut self, expr: &mut Expression) {
743 match expr {
744 Expression::And(op)
746 | Expression::Or(op)
747 | Expression::Add(op)
748 | Expression::Sub(op)
749 | Expression::Mul(op)
750 | Expression::Div(op)
751 | Expression::Mod(op)
752 | Expression::Eq(op)
753 | Expression::Neq(op)
754 | Expression::Lt(op)
755 | Expression::Lte(op)
756 | Expression::Gt(op)
757 | Expression::Gte(op)
758 | Expression::Concat(op)
759 | Expression::BitwiseAnd(op)
760 | Expression::BitwiseOr(op)
761 | Expression::BitwiseXor(op)
762 | Expression::Adjacent(op)
763 | Expression::TsMatch(op)
764 | Expression::PropertyEQ(op)
765 | Expression::ArrayContainsAll(op)
766 | Expression::ArrayContainedBy(op)
767 | Expression::ArrayOverlaps(op)
768 | Expression::JSONBContainsAllTopKeys(op)
769 | Expression::JSONBContainsAnyTopKeys(op)
770 | Expression::JSONBDeleteAtPath(op)
771 | Expression::ExtendsLeft(op)
772 | Expression::ExtendsRight(op)
773 | Expression::Is(op)
774 | Expression::MemberOf(op)
775 | Expression::Match(op)
776 | Expression::NullSafeEq(op)
777 | Expression::NullSafeNeq(op)
778 | Expression::Glob(op)
779 | Expression::BitwiseLeftShift(op)
780 | Expression::BitwiseRightShift(op) => {
781 self.annotate_in_place(&mut op.left);
782 self.annotate_in_place(&mut op.right);
783 }
784
785 Expression::Like(op) | Expression::ILike(op) => {
787 self.annotate_in_place(&mut op.left);
788 self.annotate_in_place(&mut op.right);
789 }
790
791 Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
793 self.annotate_in_place(&mut op.this);
794 }
795
796 Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
798 self.annotate_in_place(&mut c.this);
799 }
800
801 Expression::Case(c) => {
803 if let Some(ref mut operand) = c.operand {
804 self.annotate_in_place(operand);
805 }
806 for (cond, then_expr) in &mut c.whens {
807 self.annotate_in_place(cond);
808 self.annotate_in_place(then_expr);
809 }
810 if let Some(ref mut else_expr) = c.else_ {
811 self.annotate_in_place(else_expr);
812 }
813 }
814
815 Expression::Alias(a) => {
817 self.annotate_in_place(&mut a.this);
818 }
819
820 Expression::Column(_) => {}
822
823 Expression::Dot(dot) => {
825 self.annotate_in_place(&mut dot.this);
826 }
827
828 Expression::Function(f) => {
830 for arg in &mut f.args {
831 self.annotate_in_place(arg);
832 }
833 }
834 Expression::Unnest(unnest) => {
835 self.annotate_in_place(&mut unnest.this);
836 for expression in &mut unnest.expressions {
837 self.annotate_in_place(expression);
838 }
839 }
840
841 Expression::IfFunc(f) => {
843 self.annotate_in_place(&mut f.condition);
844 self.annotate_in_place(&mut f.true_value);
845 if let Some(false_value) = &mut f.false_value {
846 self.annotate_in_place(false_value);
847 }
848 }
849 Expression::Nvl2(f) => {
850 self.annotate_in_place(&mut f.this);
851 self.annotate_in_place(&mut f.true_value);
852 self.annotate_in_place(&mut f.false_value);
853 }
854
855 Expression::AggregateFunction(f) => {
857 for arg in &mut f.args {
858 self.annotate_in_place(arg);
859 }
860 }
861
862 Expression::Count(f) => {
864 if let Some(this) = &mut f.this {
865 self.annotate_in_place(this);
866 }
867 if let Some(filter) = &mut f.filter {
868 self.annotate_in_place(filter);
869 }
870 }
871 Expression::GroupConcat(f) => {
872 self.annotate_in_place(&mut f.this);
873 if let Some(separator) = &mut f.separator {
874 self.annotate_in_place(separator);
875 }
876 if let Some(order_by) = &mut f.order_by {
877 for ordered in order_by {
878 self.annotate_in_place(&mut ordered.this);
879 }
880 }
881 if let Some(filter) = &mut f.filter {
882 self.annotate_in_place(filter);
883 }
884 }
885 Expression::StringAgg(f) => {
886 self.annotate_in_place(&mut f.this);
887 if let Some(separator) = &mut f.separator {
888 self.annotate_in_place(separator);
889 }
890 if let Some(order_by) = &mut f.order_by {
891 for ordered in order_by {
892 self.annotate_in_place(&mut ordered.this);
893 }
894 }
895 if let Some(filter) = &mut f.filter {
896 self.annotate_in_place(filter);
897 }
898 if let Some(limit) = &mut f.limit {
899 self.annotate_in_place(limit);
900 }
901 }
902 Expression::ListAgg(f) => {
903 self.annotate_in_place(&mut f.this);
904 if let Some(separator) = &mut f.separator {
905 self.annotate_in_place(separator);
906 }
907 if let Some(order_by) = &mut f.order_by {
908 for ordered in order_by {
909 self.annotate_in_place(&mut ordered.this);
910 }
911 }
912 if let Some(filter) = &mut f.filter {
913 self.annotate_in_place(filter);
914 }
915 if let Some(ListAggOverflow::Truncate {
916 filler: Some(filler),
917 ..
918 }) = &mut f.on_overflow
919 {
920 self.annotate_in_place(filler);
921 }
922 }
923 Expression::SumIf(f) => {
924 self.annotate_in_place(&mut f.this);
925 self.annotate_in_place(&mut f.condition);
926 if let Some(filter) = &mut f.filter {
927 self.annotate_in_place(filter);
928 }
929 }
930
931 Expression::WindowFunction(w) => {
933 self.annotate_in_place(&mut w.this);
934 }
935
936 Expression::Subquery(s) => {
938 self.annotate_in_place(&mut s.this);
939 }
940
941 Expression::Upper(f)
943 | Expression::Lower(f)
944 | Expression::Length(f)
945 | Expression::LTrim(f)
946 | Expression::RTrim(f)
947 | Expression::Reverse(f)
948 | Expression::Abs(f)
949 | Expression::Sqrt(f)
950 | Expression::Cbrt(f)
951 | Expression::Ln(f)
952 | Expression::Exp(f)
953 | Expression::Sign(f)
954 | Expression::Date(f)
955 | Expression::Time(f)
956 | Expression::Explode(f)
957 | Expression::ExplodeOuter(f)
958 | Expression::MapFromEntries(f)
959 | Expression::MapKeys(f)
960 | Expression::MapValues(f)
961 | Expression::ArrayLength(f)
962 | Expression::ArraySize(f)
963 | Expression::Cardinality(f)
964 | Expression::ArrayReverse(f)
965 | Expression::ArrayDistinct(f)
966 | Expression::ArrayFlatten(f)
967 | Expression::ArrayCompact(f)
968 | Expression::ToArray(f)
969 | Expression::JsonArrayLength(f)
970 | Expression::JsonKeys(f)
971 | Expression::JsonType(f)
972 | Expression::ParseJson(f)
973 | Expression::ToJson(f)
974 | Expression::Year(f)
975 | Expression::Month(f)
976 | Expression::Day(f)
977 | Expression::Hour(f)
978 | Expression::Minute(f)
979 | Expression::Second(f)
980 | Expression::Initcap(f)
981 | Expression::Ascii(f)
982 | Expression::Chr(f)
983 | Expression::Soundex(f)
984 | Expression::ByteLength(f)
985 | Expression::Hex(f)
986 | Expression::LowerHex(f)
987 | Expression::Unicode(f)
988 | Expression::Typeof(f)
989 | Expression::BitwiseCount(f)
990 | Expression::Epoch(f)
991 | Expression::EpochMs(f)
992 | Expression::Radians(f)
993 | Expression::Degrees(f)
994 | Expression::Sin(f)
995 | Expression::Cos(f)
996 | Expression::Tan(f)
997 | Expression::Asin(f)
998 | Expression::Acos(f)
999 | Expression::Atan(f)
1000 | Expression::IsNan(f)
1001 | Expression::IsInf(f) => {
1002 self.annotate_in_place(&mut f.this);
1003 }
1004
1005 Expression::Power(f)
1007 | Expression::NullIf(f)
1008 | Expression::IfNull(f)
1009 | Expression::Nvl(f)
1010 | Expression::Contains(f)
1011 | Expression::StartsWith(f)
1012 | Expression::EndsWith(f)
1013 | Expression::Levenshtein(f)
1014 | Expression::ModFunc(f)
1015 | Expression::IntDiv(f)
1016 | Expression::Atan2(f)
1017 | Expression::AddMonths(f)
1018 | Expression::MonthsBetween(f)
1019 | Expression::NextDay(f)
1020 | Expression::UnixToTimeStr(f)
1021 | Expression::ArrayContains(f)
1022 | Expression::ArrayPosition(f)
1023 | Expression::ArrayAppend(f)
1024 | Expression::ArrayPrepend(f)
1025 | Expression::ArrayUnion(f)
1026 | Expression::ArrayExcept(f)
1027 | Expression::ArrayRemove(f)
1028 | Expression::StarMap(f)
1029 | Expression::MapFromArrays(f)
1030 | Expression::MapContainsKey(f)
1031 | Expression::ElementAt(f)
1032 | Expression::JsonMergePatch(f) => {
1033 self.annotate_in_place(&mut f.this);
1034 self.annotate_in_place(&mut f.expression);
1035 }
1036
1037 Expression::Coalesce(f)
1039 | Expression::Greatest(f)
1040 | Expression::Least(f)
1041 | Expression::ArrayConcat(f)
1042 | Expression::ArrayIntersect(f)
1043 | Expression::ArrayZip(f)
1044 | Expression::MapConcat(f)
1045 | Expression::JsonArray(f) => {
1046 for e in &mut f.expressions {
1047 self.annotate_in_place(e);
1048 }
1049 }
1050
1051 Expression::Sum(f)
1053 | Expression::Avg(f)
1054 | Expression::Min(f)
1055 | Expression::Max(f)
1056 | Expression::ArrayAgg(f)
1057 | Expression::CountIf(f)
1058 | Expression::Stddev(f)
1059 | Expression::StddevPop(f)
1060 | Expression::StddevSamp(f)
1061 | Expression::Variance(f)
1062 | Expression::VarPop(f)
1063 | Expression::VarSamp(f)
1064 | Expression::Median(f)
1065 | Expression::Mode(f)
1066 | Expression::First(f)
1067 | Expression::Last(f)
1068 | Expression::AnyValue(f)
1069 | Expression::ApproxDistinct(f)
1070 | Expression::ApproxCountDistinct(f)
1071 | Expression::LogicalAnd(f)
1072 | Expression::LogicalOr(f)
1073 | Expression::Skewness(f)
1074 | Expression::ArrayConcatAgg(f)
1075 | Expression::ArrayUniqueAgg(f)
1076 | Expression::BoolXorAgg(f)
1077 | Expression::BitwiseAndAgg(f)
1078 | Expression::BitwiseOrAgg(f)
1079 | Expression::BitwiseXorAgg(f) => {
1080 self.annotate_in_place(&mut f.this);
1081 }
1082
1083 Expression::Select(s) => {
1085 for e in &mut s.expressions {
1086 self.annotate_in_place(e);
1087 }
1088 }
1089
1090 _ => {}
1092 }
1093 }
1094
1095 fn annotate_math_function(&mut self, arg: &Expression) -> Option<DataType> {
1098 let input_type = self.annotate(arg)?;
1099 match input_type {
1100 DataType::TinyInt { .. }
1101 | DataType::SmallInt { .. }
1102 | DataType::Int { .. }
1103 | DataType::BigInt { .. } => Some(DataType::Double {
1104 precision: None,
1105 scale: None,
1106 }),
1107 other => Some(other),
1108 }
1109 }
1110
1111 fn annotate_subscript(&mut self, sub: &Subscript) -> Option<DataType> {
1113 let base_type = self.annotate(&sub.this)?;
1114
1115 match base_type {
1116 DataType::Array { element_type, .. } => Some(*element_type),
1117 DataType::Map { value_type, .. } => Some(*value_type),
1118 DataType::Json | DataType::JsonB => Some(DataType::Json), DataType::VarChar { .. } | DataType::Text => {
1120 Some(DataType::VarChar {
1122 length: Some(1),
1123 parenthesized_length: false,
1124 })
1125 }
1126 _ => None,
1127 }
1128 }
1129
1130 fn annotate_dot(&mut self, dot: &DotAccess) -> Option<DataType> {
1132 let base_type = self.annotate(&dot.this)?;
1133 let DataType::Struct { fields, .. } = base_type else {
1134 return None;
1135 };
1136 let field_name = normalize_name(&dot.field.name, self._dialect, false, true);
1137
1138 fields
1139 .into_iter()
1140 .find(|field| normalize_name(&field.name, self._dialect, false, true) == field_name)
1141 .map(|field| field.data_type)
1142 }
1143
1144 fn annotate_struct(&mut self, s: &Struct) -> Option<DataType> {
1146 let fields: Vec<StructField> = s
1147 .fields
1148 .iter()
1149 .map(|(name, expr)| {
1150 let field_type = self.annotate(expr).unwrap_or(DataType::Unknown);
1151 StructField::new(name.clone().unwrap_or_default(), field_type)
1152 })
1153 .collect();
1154 Some(DataType::Struct {
1155 fields,
1156 nested: false,
1157 })
1158 }
1159
1160 fn annotate_map(&mut self, map: &Map) -> Option<DataType> {
1162 let key_type = if let Some(first_key) = map.keys.first() {
1163 self.annotate(first_key).unwrap_or(DataType::Unknown)
1164 } else {
1165 DataType::Unknown
1166 };
1167
1168 let value_type = if let Some(first_value) = map.values.first() {
1169 self.annotate(first_value).unwrap_or(DataType::Unknown)
1170 } else {
1171 DataType::Unknown
1172 };
1173
1174 Some(DataType::Map {
1175 key_type: Box::new(key_type),
1176 value_type: Box::new(value_type),
1177 })
1178 }
1179
1180 fn annotate_set_operation(
1183 &mut self,
1184 _left: &Expression,
1185 _right: &Expression,
1186 ) -> Option<DataType> {
1187 None
1191 }
1192
1193 fn annotate_lateral_view(&mut self, lv: &crate::expressions::LateralView) -> Option<DataType> {
1195 self.annotate(&lv.this)
1197 }
1198
1199 fn annotate_literal(&self, lit: &Literal) -> Option<DataType> {
1201 match lit {
1202 Literal::String(_)
1203 | Literal::NationalString(_)
1204 | Literal::TripleQuotedString(_, _)
1205 | Literal::EscapeString(_)
1206 | Literal::DollarString(_)
1207 | Literal::RawString(_) => Some(DataType::VarChar {
1208 length: None,
1209 parenthesized_length: false,
1210 }),
1211 Literal::Number(n) => {
1212 if n.contains('.') || n.contains('e') || n.contains('E') {
1214 Some(DataType::Double {
1215 precision: None,
1216 scale: None,
1217 })
1218 } else {
1219 if let Ok(_) = n.parse::<i32>() {
1221 Some(DataType::Int {
1222 length: None,
1223 integer_spelling: false,
1224 })
1225 } else {
1226 Some(DataType::BigInt { length: None })
1227 }
1228 }
1229 }
1230 Literal::HexString(_) | Literal::BitString(_) | Literal::ByteString(_) => {
1231 Some(DataType::VarBinary { length: None })
1232 }
1233 Literal::HexNumber(_) => Some(DataType::BigInt { length: None }),
1234 Literal::Date(_) => Some(DataType::Date),
1235 Literal::Time(_) => Some(DataType::Time {
1236 precision: None,
1237 timezone: false,
1238 }),
1239 Literal::Timestamp(_) => Some(DataType::Timestamp {
1240 precision: None,
1241 timezone: false,
1242 }),
1243 Literal::Datetime(_) => Some(DataType::Custom {
1244 name: "DATETIME".to_string(),
1245 }),
1246 }
1247 }
1248
1249 fn annotate_arithmetic(&mut self, op: &BinaryOp) -> Option<DataType> {
1251 let left_type = self.annotate(&op.left);
1252 let right_type = self.annotate(&op.right);
1253
1254 match (left_type, right_type) {
1255 (Some(l), Some(r)) => self.coerce_types(&l, &r),
1256 (Some(t), None) | (None, Some(t)) => Some(t),
1257 (None, None) => None,
1258 }
1259 }
1260
1261 fn annotate_function(&mut self, func: &Function) -> Option<DataType> {
1263 let func_name = func.name.to_uppercase();
1264
1265 if self._dialect == Some(DialectType::DuckDB) && !func.quoted && func_name == "DATE_TRUNC" {
1266 return self.annotate_duckdb_date_trunc(func);
1267 }
1268
1269 if let Some(return_type) = self.function_return_types.get(&func_name) {
1271 if *return_type != DataType::Unknown {
1272 return Some(return_type.clone());
1273 }
1274 }
1275
1276 match func_name.as_str() {
1278 "UNNEST" => func.args.first().and_then(|arg| match self.annotate(arg) {
1279 Some(DataType::Array { element_type, .. }) => Some(*element_type),
1280 _ => None,
1281 }),
1282 "COALESCE" | "IFNULL" | "NVL" | "ISNULL" => {
1283 for arg in &func.args {
1285 if let Some(arg_type) = self.annotate(arg) {
1286 return Some(arg_type);
1287 }
1288 }
1289 None
1290 }
1291 "NULLIF" => {
1292 func.args.first().and_then(|arg| self.annotate(arg))
1294 }
1295 "GREATEST" | "LEAST" => {
1296 self.coerce_arg_types(&func.args)
1298 }
1299 "IF" | "IIF" => {
1300 if func.args.len() >= 2 {
1302 self.annotate(&func.args[1])
1303 } else {
1304 None
1305 }
1306 }
1307 _ => {
1308 func.args.first().and_then(|arg| self.annotate(arg))
1310 }
1311 }
1312 }
1313
1314 fn annotate_duckdb_date_trunc(&mut self, func: &Function) -> Option<DataType> {
1316 if func.args.len() != 2 {
1317 return None;
1318 }
1319
1320 match self.annotate(&func.args[1])? {
1321 DataType::Date => Some(DataType::Timestamp {
1322 precision: None,
1323 timezone: false,
1324 }),
1325 DataType::Timestamp { timezone, .. } => Some(DataType::Timestamp {
1326 precision: None,
1327 timezone,
1328 }),
1329 DataType::Interval { .. } => Some(DataType::Interval {
1330 unit: None,
1331 to: None,
1332 }),
1333 _ => None,
1334 }
1335 }
1336
1337 fn annotate_if_func(&mut self, func: &IfFunc) -> Option<DataType> {
1339 let true_type = self.annotate(&func.true_value);
1340 let false_type = func
1341 .false_value
1342 .as_ref()
1343 .and_then(|expr| self.annotate(expr));
1344
1345 match (true_type, false_type) {
1346 (Some(left), Some(right)) => self.coerce_types(&left, &right),
1347 (Some(dt), None) | (None, Some(dt)) => Some(dt),
1348 (None, None) => None,
1349 }
1350 }
1351
1352 fn annotate_nvl2(&mut self, func: &Nvl2Func) -> Option<DataType> {
1354 let true_type = self.annotate(&func.true_value);
1355 let false_type = self.annotate(&func.false_value);
1356
1357 match (true_type, false_type) {
1358 (Some(left), Some(right)) => self.coerce_types(&left, &right),
1359 (Some(dt), None) | (None, Some(dt)) => Some(dt),
1360 (None, None) => None,
1361 }
1362 }
1363
1364 fn get_aggregate_return_type(
1366 &mut self,
1367 func_name: &str,
1368 args: &[Expression],
1369 ) -> Option<DataType> {
1370 match func_name {
1371 "COUNT" | "COUNT_IF" => Some(DataType::BigInt { length: None }),
1372 "SUM_IF" => {
1373 if let Some(arg) = args.first() {
1374 self.annotate_sum(arg)
1375 } else {
1376 Some(DataType::Decimal {
1377 precision: None,
1378 scale: None,
1379 })
1380 }
1381 }
1382 "SUM" => {
1383 if let Some(arg) = args.first() {
1384 self.annotate_sum(arg)
1385 } else {
1386 Some(DataType::Decimal {
1387 precision: None,
1388 scale: None,
1389 })
1390 }
1391 }
1392 "AVG" => Some(DataType::Double {
1393 precision: None,
1394 scale: None,
1395 }),
1396 "MIN" | "MAX" => {
1397 let input_type = args.first().and_then(|arg| self.annotate(arg));
1401 if args.len() == 2 {
1402 input_type.map(|element_type| DataType::Array {
1403 element_type: Box::new(element_type),
1404 dimension: None,
1405 })
1406 } else {
1407 input_type
1408 }
1409 }
1410 "STRING_AGG" | "GROUP_CONCAT" | "LISTAGG" | "ARRAY_AGG" => Some(DataType::VarChar {
1411 length: None,
1412 parenthesized_length: false,
1413 }),
1414 "BOOL_AND" | "BOOL_OR" | "EVERY" | "ANY" | "SOME" => Some(DataType::Boolean),
1415 "BIT_AND" | "BIT_OR" | "BIT_XOR" => Some(DataType::BigInt { length: None }),
1416 "STDDEV" | "STDDEV_POP" | "STDDEV_SAMP" | "VARIANCE" | "VAR_POP" | "VAR_SAMP" => {
1417 Some(DataType::Double {
1418 precision: None,
1419 scale: None,
1420 })
1421 }
1422 "PERCENTILE_CONT" | "PERCENTILE_DISC" | "MEDIAN" => {
1423 args.first().and_then(|arg| self.annotate(arg))
1424 }
1425 _ => None,
1426 }
1427 }
1428
1429 fn annotate_sum(&mut self, arg: &Expression) -> Option<DataType> {
1431 match self.annotate(arg) {
1432 Some(DataType::TinyInt { .. })
1433 | Some(DataType::SmallInt { .. })
1434 | Some(DataType::Int { .. }) => Some(DataType::BigInt { length: None }),
1435 Some(DataType::BigInt { .. }) => Some(DataType::BigInt { length: None }),
1436 Some(DataType::Float { .. }) | Some(DataType::Double { .. }) => {
1437 Some(DataType::Double {
1438 precision: None,
1439 scale: None,
1440 })
1441 }
1442 Some(DataType::Decimal { precision, scale }) => {
1443 Some(DataType::Decimal { precision, scale })
1444 }
1445 _ => Some(DataType::Decimal {
1446 precision: None,
1447 scale: None,
1448 }),
1449 }
1450 }
1451
1452 fn coerce_arg_types(&mut self, args: &[Expression]) -> Option<DataType> {
1454 let mut result_type: Option<DataType> = None;
1455 for arg in args {
1456 if let Some(arg_type) = self.annotate(arg) {
1457 result_type = match result_type {
1458 Some(t) => self.coerce_types(&t, &arg_type),
1459 None => Some(arg_type),
1460 };
1461 }
1462 }
1463 result_type
1464 }
1465
1466 fn coerce_types(&self, left: &DataType, right: &DataType) -> Option<DataType> {
1468 if left == right {
1470 return Some(left.clone());
1471 }
1472
1473 match (left, right) {
1475 (DataType::Date, DataType::Interval { .. })
1476 | (DataType::Interval { .. }, DataType::Date) => return Some(DataType::Date),
1477 (
1478 DataType::Timestamp {
1479 precision,
1480 timezone,
1481 },
1482 DataType::Interval { .. },
1483 )
1484 | (
1485 DataType::Interval { .. },
1486 DataType::Timestamp {
1487 precision,
1488 timezone,
1489 },
1490 ) => {
1491 return Some(DataType::Timestamp {
1492 precision: *precision,
1493 timezone: *timezone,
1494 });
1495 }
1496 _ => {}
1497 }
1498
1499 let left_class = TypeCoercionClass::from_data_type(left);
1501 let right_class = TypeCoercionClass::from_data_type(right);
1502
1503 match (left_class, right_class) {
1504 (Some(lc), Some(rc)) if lc == rc => {
1506 if lc == TypeCoercionClass::Numeric {
1508 Some(self.wider_numeric_type(left, right))
1509 } else {
1510 Some(left.clone())
1512 }
1513 }
1514 (Some(lc), Some(rc)) => {
1516 if lc > rc {
1517 Some(left.clone())
1518 } else {
1519 Some(right.clone())
1520 }
1521 }
1522 (Some(_), None) => Some(left.clone()),
1524 (None, Some(_)) => Some(right.clone()),
1525 (None, None) => Some(DataType::Unknown),
1527 }
1528 }
1529
1530 fn wider_numeric_type(&self, left: &DataType, right: &DataType) -> DataType {
1532 let order = |dt: &DataType| -> u8 {
1533 match dt {
1534 DataType::Boolean => 0,
1535 DataType::TinyInt { .. } => 1,
1536 DataType::SmallInt { .. } => 2,
1537 DataType::Int { .. } => 3,
1538 DataType::BigInt { .. } => 4,
1539 DataType::Float { .. } => 5,
1540 DataType::Double { .. } => 6,
1541 DataType::Decimal { .. } => 7,
1542 _ => 0,
1543 }
1544 };
1545
1546 if order(left) >= order(right) {
1547 left.clone()
1548 } else {
1549 right.clone()
1550 }
1551 }
1552}
1553
1554struct ScopedSchema<'a> {
1559 parent: Option<&'a dyn Schema>,
1560 tables: HashMap<String, HashMap<String, DataType>>,
1561 dialect: Option<DialectType>,
1562}
1563
1564impl<'a> ScopedSchema<'a> {
1565 fn new(parent: Option<&'a dyn Schema>, dialect: Option<DialectType>) -> Self {
1566 Self {
1567 parent,
1568 tables: HashMap::new(),
1569 dialect,
1570 }
1571 }
1572
1573 fn normalized(&self, name: &str, is_table: bool) -> String {
1574 normalize_name(name, self.dialect, is_table, true)
1575 }
1576
1577 fn local_column_type(&self, table: &str, column: &str) -> Option<DataType> {
1578 let table = self.normalized(table, true);
1579 let column = self.normalized(column, false);
1580 self.tables
1581 .get(&table)
1582 .and_then(|columns| columns.get(&column))
1583 .cloned()
1584 }
1585
1586 fn local_tables_for_column(&self, column: &str) -> Vec<String> {
1587 let column = self.normalized(column, false);
1588 self.tables
1589 .iter()
1590 .filter_map(|(table, columns)| columns.contains_key(&column).then(|| table.clone()))
1591 .collect()
1592 }
1593}
1594
1595impl Schema for ScopedSchema<'_> {
1596 fn dialect(&self) -> Option<DialectType> {
1597 self.dialect
1598 .or_else(|| self.parent.and_then(Schema::dialect))
1599 }
1600
1601 fn add_table(
1602 &mut self,
1603 table: &str,
1604 columns: &[(String, DataType)],
1605 _dialect: Option<DialectType>,
1606 ) -> SchemaResult<()> {
1607 let table = self.normalized(table, true);
1608 let columns = columns
1609 .iter()
1610 .map(|(name, data_type)| (self.normalized(name, false), data_type.clone()))
1611 .collect();
1612 self.tables.insert(table, columns);
1613 Ok(())
1614 }
1615
1616 fn column_names(&self, table: &str) -> SchemaResult<Vec<String>> {
1617 let table = self.normalized(table, true);
1618 if let Some(columns) = self.tables.get(&table) {
1619 return Ok(columns.keys().cloned().collect());
1620 }
1621 self.parent
1622 .ok_or_else(|| SchemaError::TableNotFound(table.clone()))?
1623 .column_names(&table)
1624 }
1625
1626 fn get_column_type(&self, table: &str, column: &str) -> SchemaResult<DataType> {
1627 if table.is_empty() {
1628 let local_tables = self.local_tables_for_column(column);
1629 return match local_tables.as_slice() {
1630 [local_table] => self.get_column_type(local_table, column),
1631 [] => self
1632 .parent
1633 .ok_or_else(|| SchemaError::ColumnNotFound {
1634 table: String::new(),
1635 column: column.to_string(),
1636 })?
1637 .get_column_type(table, column),
1638 _ => Err(SchemaError::AmbiguousTable {
1639 table: String::new(),
1640 matches: local_tables.join(", "),
1641 }),
1642 };
1643 }
1644
1645 let normalized_table = self.normalized(table, true);
1646 if self.tables.contains_key(&normalized_table) {
1647 return self.local_column_type(table, column).ok_or_else(|| {
1648 SchemaError::ColumnNotFound {
1649 table: table.to_string(),
1650 column: column.to_string(),
1651 }
1652 });
1653 }
1654
1655 self.parent
1656 .ok_or_else(|| SchemaError::ColumnNotFound {
1657 table: table.to_string(),
1658 column: column.to_string(),
1659 })?
1660 .get_column_type(table, column)
1661 }
1662
1663 fn has_column(&self, table: &str, column: &str) -> bool {
1664 self.get_column_type(table, column).is_ok()
1665 }
1666
1667 fn supported_table_args(&self) -> &[&str] {
1668 TABLE_PARTS
1669 }
1670
1671 fn is_empty(&self) -> bool {
1672 self.tables.is_empty() && self.parent.is_none_or(Schema::is_empty)
1673 }
1674
1675 fn depth(&self) -> usize {
1676 self.parent.map_or(1, |schema| schema.depth().max(1))
1677 }
1678
1679 fn find_tables_for_column(&self, column: &str) -> Vec<String> {
1680 let mut tables = self.local_tables_for_column(column);
1681 if let Some(parent) = self.parent {
1682 tables.extend(parent.find_tables_for_column(column));
1683 }
1684 let mut seen = HashSet::new();
1685 tables.retain(|table| seen.insert(table.clone()));
1686 tables
1687 }
1688}
1689
1690type OutputColumns = Vec<(String, DataType)>;
1691
1692fn table_name(table: &crate::expressions::TableRef) -> String {
1693 let mut parts = Vec::new();
1694 if let Some(catalog) = &table.catalog {
1695 parts.push(catalog.name.as_str());
1696 }
1697 if let Some(schema) = &table.schema {
1698 parts.push(schema.name.as_str());
1699 }
1700 parts.push(table.name.name.as_str());
1701 parts.join(".")
1702}
1703
1704fn table_columns(schema: &dyn Schema, table: &str) -> OutputColumns {
1705 schema
1706 .column_names(table)
1707 .unwrap_or_default()
1708 .into_iter()
1709 .map(|column| {
1710 let data_type = schema
1711 .get_column_type(table, &column)
1712 .unwrap_or(DataType::Unknown);
1713 (column, data_type)
1714 })
1715 .collect()
1716}
1717
1718fn apply_column_aliases(
1719 mut columns: OutputColumns,
1720 aliases: &[crate::expressions::Identifier],
1721) -> OutputColumns {
1722 for ((name, _), alias) in columns.iter_mut().zip(aliases) {
1723 *name = alias.name.clone();
1724 }
1725 columns
1726}
1727
1728fn projection_name(expression: &Expression) -> Option<String> {
1729 match expression {
1730 Expression::Alias(alias) => Some(alias.alias.name.clone()),
1731 Expression::Column(column) => Some(column.name.name.clone()),
1732 Expression::Identifier(identifier) => Some(identifier.name.clone()),
1733 _ => None,
1734 }
1735}
1736
1737fn projection_type(expression: &Expression) -> DataType {
1738 expression
1739 .inferred_type()
1740 .or_else(|| match expression {
1741 Expression::Alias(alias) => alias.this.inferred_type(),
1742 _ => None,
1743 })
1744 .cloned()
1745 .unwrap_or(DataType::Unknown)
1746}
1747
1748fn query_outputs(expressions: &[Expression]) -> OutputColumns {
1749 expressions
1750 .iter()
1751 .filter_map(|expression| {
1752 projection_name(expression).map(|name| (name, projection_type(expression)))
1753 })
1754 .collect()
1755}
1756
1757fn array_element_type(data_type: Option<&DataType>) -> DataType {
1758 match data_type {
1759 Some(DataType::Array { element_type, .. }) => (**element_type).clone(),
1760 _ => DataType::Unknown,
1761 }
1762}
1763
1764fn unnest_output_types(unnest: &crate::expressions::UnnestFunc) -> Vec<DataType> {
1765 let mut types = vec![array_element_type(unnest.this.inferred_type())];
1766 types.extend(
1767 unnest
1768 .expressions
1769 .iter()
1770 .map(|expression| array_element_type(expression.inferred_type())),
1771 );
1772 if unnest.with_ordinality || unnest.offset_alias.is_some() {
1773 types.push(DataType::BigInt { length: None });
1774 }
1775 types
1776}
1777
1778fn virtual_output_columns(
1779 expression: &Expression,
1780 source_alias: &str,
1781 column_aliases: &[crate::expressions::Identifier],
1782) -> OutputColumns {
1783 let (types, offset_alias) = match expression {
1784 Expression::Unnest(unnest) => (unnest_output_types(unnest), unnest.offset_alias.as_ref()),
1785 Expression::Explode(explode) | Expression::ExplodeOuter(explode) => {
1786 (vec![array_element_type(explode.this.inferred_type())], None)
1787 }
1788 Expression::Function(function) if function.name.eq_ignore_ascii_case("UNNEST") => (
1789 function
1790 .args
1791 .iter()
1792 .map(|argument| array_element_type(argument.inferred_type()))
1793 .collect(),
1794 None,
1795 ),
1796 _ => return Vec::new(),
1797 };
1798
1799 if column_aliases.is_empty() {
1800 let mut columns = Vec::new();
1801 if let Some(data_type) = types.first() {
1802 columns.push((source_alias.to_string(), data_type.clone()));
1803 }
1804 if let Some(offset_alias) = offset_alias {
1805 columns.push((offset_alias.name.clone(), DataType::BigInt { length: None }));
1806 }
1807 columns
1808 } else {
1809 column_aliases
1810 .iter()
1811 .zip(types)
1812 .map(|(alias, data_type)| (alias.name.clone(), data_type))
1813 .collect()
1814 }
1815}
1816
1817fn annotate_relation_source(
1818 expression: &mut Expression,
1819 schema: &mut ScopedSchema<'_>,
1820 dialect: Option<DialectType>,
1821) {
1822 match expression {
1823 Expression::Table(table) => {
1824 let source_table = table_name(table);
1825 let mut columns = table_columns(schema, &source_table);
1826 columns = apply_column_aliases(columns, &table.column_aliases);
1827 let visible_name = table
1828 .alias
1829 .as_ref()
1830 .map(|alias| alias.name.as_str())
1831 .unwrap_or(table.name.name.as_str());
1832 let _ = schema.add_table(visible_name, &columns, dialect);
1833 }
1834 Expression::Subquery(subquery) => {
1835 let mut columns = annotate_scoped_expression(&mut subquery.this, Some(schema), dialect);
1836 columns = apply_column_aliases(columns, &subquery.column_aliases);
1837 if let Some((_, first_type)) = columns.first() {
1838 subquery.inferred_type = Some(first_type.clone());
1839 }
1840 if let Some(alias) = &subquery.alias {
1841 let _ = schema.add_table(&alias.name, &columns, dialect);
1842 }
1843 }
1844 Expression::Alias(alias) => {
1845 match &mut alias.this {
1846 Expression::Subquery(subquery) => {
1847 let columns =
1848 annotate_scoped_expression(&mut subquery.this, Some(schema), dialect);
1849 let columns = apply_column_aliases(columns, &alias.column_aliases);
1850 let _ = schema.add_table(&alias.alias.name, &columns, dialect);
1851 return;
1852 }
1853 _ => {
1854 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1855 annotator.annotate_in_place(&mut alias.this);
1856 }
1857 }
1858 let columns =
1859 virtual_output_columns(&alias.this, &alias.alias.name, &alias.column_aliases);
1860 if !columns.is_empty() {
1861 let _ = schema.add_table(&alias.alias.name, &columns, dialect);
1862 }
1863 }
1864 Expression::Unnest(_) => {
1865 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1866 annotator.annotate_in_place(expression);
1867 if let Expression::Unnest(unnest) = expression {
1868 if let Some(alias) = &unnest.alias {
1869 let alias_name = alias.name.clone();
1870 let columns = unnest_output_types(unnest)
1871 .into_iter()
1872 .next()
1873 .map(|data_type| vec![(alias_name.clone(), data_type)])
1874 .unwrap_or_default();
1875 let _ = schema.add_table(&alias_name, &columns, dialect);
1876 }
1877 }
1878 }
1879 Expression::Lateral(lateral) => {
1880 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1881 annotator.annotate_in_place(&mut lateral.this);
1882 if let Some(alias) = &lateral.alias {
1883 let aliases: Vec<_> = lateral
1884 .column_aliases
1885 .iter()
1886 .map(crate::expressions::Identifier::new)
1887 .collect();
1888 let columns = virtual_output_columns(&lateral.this, alias, &aliases);
1889 if !columns.is_empty() {
1890 let _ = schema.add_table(alias, &columns, dialect);
1891 }
1892 }
1893 }
1894 Expression::Paren(paren) => annotate_relation_source(&mut paren.this, schema, dialect),
1895 _ => {
1896 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1897 annotator.annotate_in_place(expression);
1898 }
1899 }
1900}
1901
1902fn annotate_with(
1903 with: &mut Option<crate::expressions::With>,
1904 schema: &mut ScopedSchema<'_>,
1905 dialect: Option<DialectType>,
1906) {
1907 if let Some(with) = with {
1908 for cte in &mut with.ctes {
1909 let columns = annotate_scoped_expression(&mut cte.this, Some(schema), dialect);
1910 let columns = apply_column_aliases(columns, &cte.columns);
1911 let _ = schema.add_table(&cte.alias.name, &columns, dialect);
1912 }
1913 }
1914}
1915
1916fn annotate_select(
1917 select: &mut crate::expressions::Select,
1918 parent: Option<&dyn Schema>,
1919 dialect: Option<DialectType>,
1920) -> OutputColumns {
1921 let mut schema = ScopedSchema::new(parent, dialect);
1922 annotate_with(&mut select.with, &mut schema, dialect);
1923
1924 if let Some(from) = &mut select.from {
1925 for source in &mut from.expressions {
1926 annotate_relation_source(source, &mut schema, dialect);
1927 }
1928 }
1929 for join in &mut select.joins {
1930 annotate_relation_source(&mut join.this, &mut schema, dialect);
1931 }
1932
1933 let mut annotator = TypeAnnotator::new(Some(&schema), dialect);
1934 for expression in &mut select.expressions {
1935 annotator.annotate_in_place(expression);
1936 }
1937 query_outputs(&select.expressions)
1938}
1939
1940fn annotate_scoped_expression(
1941 expression: &mut Expression,
1942 parent: Option<&dyn Schema>,
1943 dialect: Option<DialectType>,
1944) -> OutputColumns {
1945 match expression {
1946 Expression::Select(select) => annotate_select(select, parent, dialect),
1947 Expression::Subquery(subquery) => {
1948 let columns = annotate_scoped_expression(&mut subquery.this, parent, dialect);
1949 if let Some((_, first_type)) = columns.first() {
1950 subquery.inferred_type = Some(first_type.clone());
1951 }
1952 columns
1953 }
1954 Expression::Cte(cte) => annotate_scoped_expression(&mut cte.this, parent, dialect),
1955 Expression::Paren(paren) => annotate_scoped_expression(&mut paren.this, parent, dialect),
1956 Expression::Union(union) => {
1957 let mut schema = ScopedSchema::new(parent, dialect);
1958 annotate_with(&mut union.with, &mut schema, dialect);
1959 let columns = annotate_scoped_expression(&mut union.left, Some(&schema), dialect);
1960 annotate_scoped_expression(&mut union.right, Some(&schema), dialect);
1961 columns
1962 }
1963 Expression::Intersect(intersect) => {
1964 let mut schema = ScopedSchema::new(parent, dialect);
1965 annotate_with(&mut intersect.with, &mut schema, dialect);
1966 let columns = annotate_scoped_expression(&mut intersect.left, Some(&schema), dialect);
1967 annotate_scoped_expression(&mut intersect.right, Some(&schema), dialect);
1968 columns
1969 }
1970 Expression::Except(except) => {
1971 let mut schema = ScopedSchema::new(parent, dialect);
1972 annotate_with(&mut except.with, &mut schema, dialect);
1973 let columns = annotate_scoped_expression(&mut except.left, Some(&schema), dialect);
1974 annotate_scoped_expression(&mut except.right, Some(&schema), dialect);
1975 columns
1976 }
1977 _ => {
1978 let mut annotator = TypeAnnotator::new(parent, dialect);
1979 annotator.annotate_in_place(expression);
1980 Vec::new()
1981 }
1982 }
1983}
1984
1985pub fn annotate_types(
1991 expr: &mut Expression,
1992 schema: Option<&dyn Schema>,
1993 dialect: Option<DialectType>,
1994) {
1995 annotate_scoped_expression(expr, schema, dialect);
1996}
1997
1998#[cfg(test)]
1999mod tests {
2000 use super::*;
2001 use crate::expressions::{BooleanLiteral, Cast, Null};
2002 use crate::{parse_one, DialectType, MappingSchema, Schema};
2003
2004 fn make_int_literal(val: i64) -> Expression {
2005 Expression::Literal(Box::new(Literal::Number(val.to_string())))
2006 }
2007
2008 fn make_float_literal(val: f64) -> Expression {
2009 Expression::Literal(Box::new(Literal::Number(val.to_string())))
2010 }
2011
2012 fn make_string_literal(val: &str) -> Expression {
2013 Expression::Literal(Box::new(Literal::String(val.to_string())))
2014 }
2015
2016 fn make_bool_literal(val: bool) -> Expression {
2017 Expression::Boolean(BooleanLiteral { value: val })
2018 }
2019
2020 #[test]
2021 fn test_literal_types() {
2022 let mut annotator = TypeAnnotator::new(None, None);
2023
2024 let int_expr = make_int_literal(42);
2026 assert_eq!(
2027 annotator.annotate(&int_expr),
2028 Some(DataType::Int {
2029 length: None,
2030 integer_spelling: false
2031 })
2032 );
2033
2034 let float_expr = make_float_literal(3.14);
2036 assert_eq!(
2037 annotator.annotate(&float_expr),
2038 Some(DataType::Double {
2039 precision: None,
2040 scale: None
2041 })
2042 );
2043
2044 let string_expr = make_string_literal("hello");
2046 assert_eq!(
2047 annotator.annotate(&string_expr),
2048 Some(DataType::VarChar {
2049 length: None,
2050 parenthesized_length: false
2051 })
2052 );
2053
2054 let bool_expr = make_bool_literal(true);
2056 assert_eq!(annotator.annotate(&bool_expr), Some(DataType::Boolean));
2057
2058 let null_expr = Expression::Null(Null);
2060 assert_eq!(annotator.annotate(&null_expr), None);
2061 }
2062
2063 #[test]
2064 fn test_comparison_types() {
2065 let mut annotator = TypeAnnotator::new(None, None);
2066
2067 let cmp = Expression::Gt(Box::new(BinaryOp::new(
2069 make_int_literal(1),
2070 make_int_literal(2),
2071 )));
2072 assert_eq!(annotator.annotate(&cmp), Some(DataType::Boolean));
2073
2074 let eq = Expression::Eq(Box::new(BinaryOp::new(
2076 make_string_literal("a"),
2077 make_string_literal("b"),
2078 )));
2079 assert_eq!(annotator.annotate(&eq), Some(DataType::Boolean));
2080 }
2081
2082 #[test]
2083 fn test_arithmetic_types() {
2084 let mut annotator = TypeAnnotator::new(None, None);
2085
2086 let add_int = Expression::Add(Box::new(BinaryOp::new(
2088 make_int_literal(1),
2089 make_int_literal(2),
2090 )));
2091 assert_eq!(
2092 annotator.annotate(&add_int),
2093 Some(DataType::Int {
2094 length: None,
2095 integer_spelling: false
2096 })
2097 );
2098
2099 let add_mixed = Expression::Add(Box::new(BinaryOp::new(
2101 make_int_literal(1),
2102 make_float_literal(2.5), )));
2104 assert_eq!(
2105 annotator.annotate(&add_mixed),
2106 Some(DataType::Double {
2107 precision: None,
2108 scale: None
2109 })
2110 );
2111 }
2112
2113 #[test]
2114 fn test_string_concat_type() {
2115 let mut annotator = TypeAnnotator::new(None, None);
2116
2117 let concat = Expression::Concat(Box::new(BinaryOp::new(
2119 make_string_literal("hello"),
2120 make_string_literal(" world"),
2121 )));
2122 assert_eq!(
2123 annotator.annotate(&concat),
2124 Some(DataType::VarChar {
2125 length: None,
2126 parenthesized_length: false
2127 })
2128 );
2129 }
2130
2131 #[test]
2132 fn test_cast_type() {
2133 let mut annotator = TypeAnnotator::new(None, None);
2134
2135 let cast = Expression::Cast(Box::new(Cast {
2137 this: make_int_literal(1),
2138 to: DataType::VarChar {
2139 length: Some(10),
2140 parenthesized_length: false,
2141 },
2142 trailing_comments: vec![],
2143 double_colon_syntax: false,
2144 format: None,
2145 default: None,
2146 inferred_type: None,
2147 }));
2148 assert_eq!(
2149 annotator.annotate(&cast),
2150 Some(DataType::VarChar {
2151 length: Some(10),
2152 parenthesized_length: false
2153 })
2154 );
2155 }
2156
2157 #[test]
2158 fn test_function_types() {
2159 let mut annotator = TypeAnnotator::new(None, None);
2160
2161 let count =
2163 Expression::Function(Box::new(Function::new("COUNT", vec![make_int_literal(1)])));
2164 assert_eq!(
2165 annotator.annotate(&count),
2166 Some(DataType::BigInt { length: None })
2167 );
2168
2169 let upper = Expression::Function(Box::new(Function::new(
2171 "UPPER",
2172 vec![make_string_literal("hello")],
2173 )));
2174 assert_eq!(
2175 annotator.annotate(&upper),
2176 Some(DataType::VarChar {
2177 length: None,
2178 parenthesized_length: false
2179 })
2180 );
2181
2182 let now = Expression::Function(Box::new(Function::new("NOW", vec![])));
2184 assert_eq!(
2185 annotator.annotate(&now),
2186 Some(DataType::Timestamp {
2187 precision: None,
2188 timezone: false
2189 })
2190 );
2191 }
2192
2193 #[test]
2194 fn test_duckdb_date_trunc_overload_types() {
2195 fn cast_to(data_type: DataType) -> Expression {
2196 Expression::Cast(Box::new(Cast {
2197 this: make_string_literal("value"),
2198 to: data_type,
2199 format: None,
2200 trailing_comments: Vec::new(),
2201 double_colon_syntax: false,
2202 default: None,
2203 inferred_type: None,
2204 }))
2205 }
2206
2207 fn date_trunc(value: Expression) -> Expression {
2208 Expression::Function(Box::new(Function::new(
2209 "DATE_TRUNC",
2210 vec![make_string_literal("month"), value],
2211 )))
2212 }
2213
2214 let mut annotator = TypeAnnotator::new(None, Some(DialectType::DuckDB));
2215
2216 for input_type in [
2217 DataType::Date,
2218 DataType::Timestamp {
2219 precision: Some(9),
2220 timezone: false,
2221 },
2222 ] {
2223 assert_eq!(
2224 annotator.annotate(&date_trunc(cast_to(input_type))),
2225 Some(DataType::Timestamp {
2226 precision: None,
2227 timezone: false,
2228 })
2229 );
2230 }
2231
2232 assert_eq!(
2233 annotator.annotate(&date_trunc(cast_to(DataType::Timestamp {
2234 precision: Some(6),
2235 timezone: true,
2236 }))),
2237 Some(DataType::Timestamp {
2238 precision: None,
2239 timezone: true,
2240 })
2241 );
2242 assert_eq!(
2243 annotator.annotate(&date_trunc(cast_to(DataType::Interval {
2244 unit: Some("DAY".to_string()),
2245 to: Some("SECOND".to_string()),
2246 }))),
2247 Some(DataType::Interval {
2248 unit: None,
2249 to: None,
2250 })
2251 );
2252 assert_eq!(
2253 annotator.annotate(&date_trunc(Expression::Null(Null))),
2254 None
2255 );
2256 }
2257
2258 #[test]
2259 fn test_coalesce_type_inference() {
2260 let mut annotator = TypeAnnotator::new(None, None);
2261
2262 let coalesce = Expression::Function(Box::new(Function::new(
2264 "COALESCE",
2265 vec![Expression::Null(Null), make_int_literal(1)],
2266 )));
2267 assert_eq!(
2268 annotator.annotate(&coalesce),
2269 Some(DataType::Int {
2270 length: None,
2271 integer_spelling: false
2272 })
2273 );
2274
2275 let specialized_coalesce = Expression::Coalesce(Box::new(crate::expressions::VarArgFunc {
2276 expressions: vec![Expression::Null(Null), make_int_literal(1)],
2277 original_name: None,
2278 inferred_type: None,
2279 }));
2280 assert_eq!(
2281 annotator.annotate(&specialized_coalesce),
2282 Some(DataType::Int {
2283 length: None,
2284 integer_spelling: false
2285 })
2286 );
2287 }
2288
2289 #[test]
2290 fn test_type_coercion_class() {
2291 assert_eq!(
2293 TypeCoercionClass::from_data_type(&DataType::VarChar {
2294 length: None,
2295 parenthesized_length: false
2296 }),
2297 Some(TypeCoercionClass::Text)
2298 );
2299 assert_eq!(
2300 TypeCoercionClass::from_data_type(&DataType::Text),
2301 Some(TypeCoercionClass::Text)
2302 );
2303
2304 assert_eq!(
2306 TypeCoercionClass::from_data_type(&DataType::Int {
2307 length: None,
2308 integer_spelling: false
2309 }),
2310 Some(TypeCoercionClass::Numeric)
2311 );
2312 assert_eq!(
2313 TypeCoercionClass::from_data_type(&DataType::Double {
2314 precision: None,
2315 scale: None
2316 }),
2317 Some(TypeCoercionClass::Numeric)
2318 );
2319
2320 assert_eq!(
2322 TypeCoercionClass::from_data_type(&DataType::Date),
2323 Some(TypeCoercionClass::Timelike)
2324 );
2325 assert_eq!(
2326 TypeCoercionClass::from_data_type(&DataType::Timestamp {
2327 precision: None,
2328 timezone: false
2329 }),
2330 Some(TypeCoercionClass::Timelike)
2331 );
2332
2333 assert_eq!(TypeCoercionClass::from_data_type(&DataType::Json), None);
2335 }
2336
2337 #[test]
2338 fn test_wider_numeric_type() {
2339 let annotator = TypeAnnotator::new(None, None);
2340
2341 let result = annotator.wider_numeric_type(
2343 &DataType::Int {
2344 length: None,
2345 integer_spelling: false,
2346 },
2347 &DataType::BigInt { length: None },
2348 );
2349 assert_eq!(result, DataType::BigInt { length: None });
2350
2351 let result = annotator.wider_numeric_type(
2353 &DataType::Float {
2354 precision: None,
2355 scale: None,
2356 real_spelling: false,
2357 },
2358 &DataType::Double {
2359 precision: None,
2360 scale: None,
2361 },
2362 );
2363 assert_eq!(
2364 result,
2365 DataType::Double {
2366 precision: None,
2367 scale: None
2368 }
2369 );
2370
2371 let result = annotator.wider_numeric_type(
2373 &DataType::Int {
2374 length: None,
2375 integer_spelling: false,
2376 },
2377 &DataType::Double {
2378 precision: None,
2379 scale: None,
2380 },
2381 );
2382 assert_eq!(
2383 result,
2384 DataType::Double {
2385 precision: None,
2386 scale: None
2387 }
2388 );
2389 }
2390
2391 #[test]
2392 fn test_aggregate_return_types() {
2393 let mut annotator = TypeAnnotator::new(None, None);
2394
2395 let sum_type = annotator.get_aggregate_return_type("SUM", &[make_int_literal(1)]);
2397 assert_eq!(sum_type, Some(DataType::BigInt { length: None }));
2398
2399 let avg_type = annotator.get_aggregate_return_type("AVG", &[make_int_literal(1)]);
2401 assert_eq!(
2402 avg_type,
2403 Some(DataType::Double {
2404 precision: None,
2405 scale: None
2406 })
2407 );
2408
2409 let min_type = annotator.get_aggregate_return_type("MIN", &[make_string_literal("a")]);
2411 assert_eq!(
2412 min_type,
2413 Some(DataType::VarChar {
2414 length: None,
2415 parenthesized_length: false
2416 })
2417 );
2418
2419 let top_n_type = annotator
2421 .get_aggregate_return_type("MAX", &[make_string_literal("a"), make_int_literal(2)]);
2422 assert_eq!(
2423 top_n_type,
2424 Some(DataType::Array {
2425 element_type: Box::new(DataType::VarChar {
2426 length: None,
2427 parenthesized_length: false,
2428 }),
2429 dimension: None,
2430 })
2431 );
2432 }
2433
2434 #[test]
2435 fn test_date_literal_types() {
2436 let mut annotator = TypeAnnotator::new(None, None);
2437
2438 let date_expr = Expression::Literal(Box::new(Literal::Date("2024-01-15".to_string())));
2440 assert_eq!(annotator.annotate(&date_expr), Some(DataType::Date));
2441
2442 let time_expr = Expression::Literal(Box::new(Literal::Time("10:30:00".to_string())));
2444 assert_eq!(
2445 annotator.annotate(&time_expr),
2446 Some(DataType::Time {
2447 precision: None,
2448 timezone: false
2449 })
2450 );
2451
2452 let ts_expr = Expression::Literal(Box::new(Literal::Timestamp(
2454 "2024-01-15 10:30:00".to_string(),
2455 )));
2456 assert_eq!(
2457 annotator.annotate(&ts_expr),
2458 Some(DataType::Timestamp {
2459 precision: None,
2460 timezone: false
2461 })
2462 );
2463 }
2464
2465 #[test]
2466 fn test_logical_operations() {
2467 let mut annotator = TypeAnnotator::new(None, None);
2468
2469 let and_expr = Expression::And(Box::new(BinaryOp::new(
2471 make_bool_literal(true),
2472 make_bool_literal(false),
2473 )));
2474 assert_eq!(annotator.annotate(&and_expr), Some(DataType::Boolean));
2475
2476 let or_expr = Expression::Or(Box::new(BinaryOp::new(
2478 make_bool_literal(true),
2479 make_bool_literal(false),
2480 )));
2481 assert_eq!(annotator.annotate(&or_expr), Some(DataType::Boolean));
2482
2483 let not_expr = Expression::Not(Box::new(crate::expressions::UnaryOp::new(
2485 make_bool_literal(true),
2486 )));
2487 assert_eq!(annotator.annotate(¬_expr), Some(DataType::Boolean));
2488 }
2489
2490 #[test]
2495 fn test_subscript_array_type() {
2496 let mut annotator = TypeAnnotator::new(None, None);
2497
2498 let arr = Expression::Array(Box::new(crate::expressions::Array {
2500 expressions: vec![make_int_literal(1), make_int_literal(2)],
2501 }));
2502 let subscript = Expression::Subscript(Box::new(crate::expressions::Subscript {
2503 this: arr,
2504 index: make_int_literal(0),
2505 }));
2506 assert_eq!(
2507 annotator.annotate(&subscript),
2508 Some(DataType::Int {
2509 length: None,
2510 integer_spelling: false
2511 })
2512 );
2513 }
2514
2515 #[test]
2516 fn test_subscript_map_type() {
2517 let mut annotator = TypeAnnotator::new(None, None);
2518
2519 let map = Expression::Map(Box::new(crate::expressions::Map {
2521 keys: vec![make_string_literal("a")],
2522 values: vec![make_int_literal(1)],
2523 }));
2524 let subscript = Expression::Subscript(Box::new(crate::expressions::Subscript {
2525 this: map,
2526 index: make_string_literal("a"),
2527 }));
2528 assert_eq!(
2529 annotator.annotate(&subscript),
2530 Some(DataType::Int {
2531 length: None,
2532 integer_spelling: false
2533 })
2534 );
2535 }
2536
2537 #[test]
2538 fn test_struct_type() {
2539 let mut annotator = TypeAnnotator::new(None, None);
2540
2541 let struct_expr = Expression::Struct(Box::new(crate::expressions::Struct {
2543 fields: vec![
2544 (Some("name".to_string()), make_string_literal("Alice")),
2545 (Some("age".to_string()), make_int_literal(30)),
2546 ],
2547 }));
2548 let result = annotator.annotate(&struct_expr);
2549 assert!(matches!(result, Some(DataType::Struct { fields, .. }) if fields.len() == 2));
2550 }
2551
2552 #[test]
2553 fn test_map_type() {
2554 let mut annotator = TypeAnnotator::new(None, None);
2555
2556 let map_expr = Expression::Map(Box::new(crate::expressions::Map {
2558 keys: vec![make_string_literal("a"), make_string_literal("b")],
2559 values: vec![make_int_literal(1), make_int_literal(2)],
2560 }));
2561 let result = annotator.annotate(&map_expr);
2562 assert!(matches!(
2563 result,
2564 Some(DataType::Map { key_type, value_type })
2565 if matches!(*key_type, DataType::VarChar { .. })
2566 && matches!(*value_type, DataType::Int { .. })
2567 ));
2568 }
2569
2570 #[test]
2571 fn test_explode_array_type() {
2572 let mut annotator = TypeAnnotator::new(None, None);
2573
2574 let arr = Expression::Array(Box::new(crate::expressions::Array {
2576 expressions: vec![make_int_literal(1), make_int_literal(2)],
2577 }));
2578 let explode = Expression::Explode(Box::new(crate::expressions::UnaryFunc {
2579 this: arr,
2580 original_name: None,
2581 inferred_type: None,
2582 }));
2583 assert_eq!(
2584 annotator.annotate(&explode),
2585 Some(DataType::Int {
2586 length: None,
2587 integer_spelling: false
2588 })
2589 );
2590 }
2591
2592 #[test]
2593 fn test_unnest_array_type() {
2594 let mut annotator = TypeAnnotator::new(None, None);
2595
2596 let arr = Expression::Array(Box::new(crate::expressions::Array {
2598 expressions: vec![make_string_literal("a"), make_string_literal("b")],
2599 }));
2600 let unnest = Expression::Unnest(Box::new(crate::expressions::UnnestFunc {
2601 this: arr,
2602 expressions: Vec::new(),
2603 with_ordinality: false,
2604 alias: None,
2605 offset_alias: None,
2606 inferred_type: None,
2607 }));
2608 assert_eq!(
2609 annotator.annotate(&unnest),
2610 Some(DataType::VarChar {
2611 length: None,
2612 parenthesized_length: false
2613 })
2614 );
2615 }
2616
2617 #[test]
2618 fn test_set_operation_type() {
2619 let mut annotator = TypeAnnotator::new(None, None);
2620
2621 let select = Expression::Select(Box::new(crate::expressions::Select::default()));
2623 let union = Expression::Union(Box::new(crate::expressions::Union {
2624 left: select.clone(),
2625 right: select.clone(),
2626 all: false,
2627 distinct: false,
2628 with: None,
2629 order_by: None,
2630 limit: None,
2631 offset: None,
2632 by_name: false,
2633 side: None,
2634 kind: None,
2635 corresponding: false,
2636 strict: false,
2637 on_columns: Vec::new(),
2638 distribute_by: None,
2639 sort_by: None,
2640 cluster_by: None,
2641 }));
2642 assert_eq!(annotator.annotate(&union), None);
2643 }
2644
2645 #[test]
2646 fn test_floor_ceil_input_dependent_types() {
2647 use crate::expressions::{CeilFunc, FloorFunc};
2648
2649 let mut annotator = TypeAnnotator::new(None, None);
2650
2651 let floor_int = Expression::Floor(Box::new(FloorFunc {
2653 this: make_int_literal(42),
2654 scale: None,
2655 to: None,
2656 }));
2657 assert_eq!(
2658 annotator.annotate(&floor_int),
2659 Some(DataType::Double {
2660 precision: None,
2661 scale: None,
2662 })
2663 );
2664
2665 let ceil_int = Expression::Ceil(Box::new(CeilFunc {
2666 this: make_int_literal(42),
2667 decimals: None,
2668 to: None,
2669 }));
2670 assert_eq!(
2671 annotator.annotate(&ceil_int),
2672 Some(DataType::Double {
2673 precision: None,
2674 scale: None,
2675 })
2676 );
2677
2678 let floor_float = Expression::Floor(Box::new(FloorFunc {
2680 this: make_float_literal(3.14),
2681 scale: None,
2682 to: None,
2683 }));
2684 assert_eq!(
2685 annotator.annotate(&floor_float),
2686 Some(DataType::Double {
2687 precision: None,
2688 scale: None,
2689 })
2690 );
2691
2692 let floor_fn =
2694 Expression::Function(Box::new(Function::new("FLOOR", vec![make_int_literal(1)])));
2695 assert_eq!(
2696 annotator.annotate(&floor_fn),
2697 Some(DataType::Int {
2698 length: None,
2699 integer_spelling: false,
2700 })
2701 );
2702 }
2703
2704 #[test]
2705 fn test_sign_preserves_input_type() {
2706 use crate::expressions::UnaryFunc;
2707
2708 let mut annotator = TypeAnnotator::new(None, None);
2709
2710 let sign_int = Expression::Sign(Box::new(UnaryFunc {
2712 this: make_int_literal(42),
2713 original_name: None,
2714 inferred_type: None,
2715 }));
2716 assert_eq!(
2717 annotator.annotate(&sign_int),
2718 Some(DataType::Int {
2719 length: None,
2720 integer_spelling: false,
2721 })
2722 );
2723
2724 let sign_float = Expression::Sign(Box::new(UnaryFunc {
2726 this: make_float_literal(3.14),
2727 original_name: None,
2728 inferred_type: None,
2729 }));
2730 assert_eq!(
2731 annotator.annotate(&sign_float),
2732 Some(DataType::Double {
2733 precision: None,
2734 scale: None,
2735 })
2736 );
2737
2738 let sign_cast = Expression::Sign(Box::new(UnaryFunc {
2740 this: Expression::Cast(Box::new(Cast {
2741 this: make_int_literal(42),
2742 to: DataType::Int {
2743 length: None,
2744 integer_spelling: false,
2745 },
2746 format: None,
2747 trailing_comments: Vec::new(),
2748 double_colon_syntax: false,
2749 default: None,
2750 inferred_type: None,
2751 })),
2752 original_name: None,
2753 inferred_type: None,
2754 }));
2755 assert_eq!(
2756 annotator.annotate(&sign_cast),
2757 Some(DataType::Int {
2758 length: None,
2759 integer_spelling: false,
2760 })
2761 );
2762 }
2763
2764 #[test]
2765 fn test_date_format_types() {
2766 use crate::expressions::{DateFormatFunc, TimeToStr};
2767
2768 let mut annotator = TypeAnnotator::new(None, None);
2769
2770 let date_fmt = Expression::DateFormat(Box::new(DateFormatFunc {
2772 this: make_string_literal("2024-01-01"),
2773 format: make_string_literal("%Y-%m-%d"),
2774 }));
2775 assert_eq!(
2776 annotator.annotate(&date_fmt),
2777 Some(DataType::VarChar {
2778 length: None,
2779 parenthesized_length: false,
2780 })
2781 );
2782
2783 let format_date = Expression::FormatDate(Box::new(DateFormatFunc {
2785 this: make_string_literal("2024-01-01"),
2786 format: make_string_literal("%Y-%m-%d"),
2787 }));
2788 assert_eq!(
2789 annotator.annotate(&format_date),
2790 Some(DataType::VarChar {
2791 length: None,
2792 parenthesized_length: false,
2793 })
2794 );
2795
2796 let time_to_str = Expression::TimeToStr(Box::new(TimeToStr {
2798 this: Box::new(make_string_literal("2024-01-01")),
2799 format: "%Y-%m-%d".to_string(),
2800 culture: None,
2801 zone: None,
2802 }));
2803 assert_eq!(
2804 annotator.annotate(&time_to_str),
2805 Some(DataType::VarChar {
2806 length: None,
2807 parenthesized_length: false,
2808 })
2809 );
2810
2811 let date_fmt_fn = Expression::Function(Box::new(Function::new(
2813 "DATE_FORMAT",
2814 vec![
2815 make_string_literal("2024-01-01"),
2816 make_string_literal("%Y-%m-%d"),
2817 ],
2818 )));
2819 assert_eq!(
2820 annotator.annotate(&date_fmt_fn),
2821 Some(DataType::VarChar {
2822 length: None,
2823 parenthesized_length: false,
2824 })
2825 );
2826 }
2827
2828 #[test]
2831 fn test_annotate_in_place_sets_type_on_root() {
2832 let mut expr = Expression::Add(Box::new(BinaryOp::new(
2834 make_int_literal(1),
2835 make_int_literal(2),
2836 )));
2837 annotate_types(&mut expr, None, None);
2838 assert_eq!(
2839 expr.inferred_type(),
2840 Some(&DataType::Int {
2841 length: None,
2842 integer_spelling: false,
2843 })
2844 );
2845 }
2846
2847 #[test]
2848 fn test_annotate_in_place_sets_types_on_children() {
2849 let inner_add = Expression::Add(Box::new(BinaryOp::new(
2852 make_int_literal(1),
2853 make_float_literal(2.5),
2854 )));
2855 let inner_sub = Expression::Sub(Box::new(BinaryOp::new(
2856 make_int_literal(3),
2857 make_int_literal(4),
2858 )));
2859 let mut expr = Expression::Add(Box::new(BinaryOp::new(inner_add, inner_sub)));
2860 annotate_types(&mut expr, None, None);
2861
2862 assert_eq!(
2864 expr.inferred_type(),
2865 Some(&DataType::Double {
2866 precision: None,
2867 scale: None,
2868 })
2869 );
2870
2871 if let Expression::Add(op) = &expr {
2873 assert_eq!(
2875 op.left.inferred_type(),
2876 Some(&DataType::Double {
2877 precision: None,
2878 scale: None,
2879 })
2880 );
2881 assert_eq!(
2883 op.right.inferred_type(),
2884 Some(&DataType::Int {
2885 length: None,
2886 integer_spelling: false,
2887 })
2888 );
2889 } else {
2890 panic!("Expected Add expression");
2891 }
2892 }
2893
2894 #[test]
2895 fn test_annotate_in_place_comparison() {
2896 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
2897 make_int_literal(1),
2898 make_int_literal(2),
2899 )));
2900 annotate_types(&mut expr, None, None);
2901 assert_eq!(expr.inferred_type(), Some(&DataType::Boolean));
2902 }
2903
2904 #[test]
2905 fn test_annotate_in_place_cast() {
2906 let mut expr = Expression::Cast(Box::new(Cast {
2907 this: make_int_literal(42),
2908 to: DataType::VarChar {
2909 length: None,
2910 parenthesized_length: false,
2911 },
2912 trailing_comments: vec![],
2913 double_colon_syntax: false,
2914 format: None,
2915 default: None,
2916 inferred_type: None,
2917 }));
2918 annotate_types(&mut expr, None, None);
2919 assert_eq!(
2920 expr.inferred_type(),
2921 Some(&DataType::VarChar {
2922 length: None,
2923 parenthesized_length: false,
2924 })
2925 );
2926 }
2927
2928 #[test]
2929 fn test_annotate_in_place_nested_expression() {
2930 let add = Expression::Add(Box::new(BinaryOp::new(
2932 make_int_literal(1),
2933 make_int_literal(2),
2934 )));
2935 let mut expr = Expression::Gt(Box::new(BinaryOp::new(add, make_int_literal(0))));
2936 annotate_types(&mut expr, None, None);
2937
2938 assert_eq!(expr.inferred_type(), Some(&DataType::Boolean));
2939
2940 if let Expression::Gt(op) = &expr {
2942 assert_eq!(
2943 op.left.inferred_type(),
2944 Some(&DataType::Int {
2945 length: None,
2946 integer_spelling: false,
2947 })
2948 );
2949 }
2950 }
2951
2952 #[test]
2953 fn test_annotate_in_place_parsed_sql() {
2954 use crate::parser::Parser;
2955 let mut expr =
2956 Parser::parse_sql("SELECT 1 + 2.0, 'hello', TRUE").expect("parse failed")[0].clone();
2957 annotate_types(&mut expr, None, None);
2958
2959 assert!(expr.inferred_type().is_none());
2963 }
2964
2965 #[test]
2966 fn test_inferred_type_json_roundtrip() {
2967 let mut expr = Expression::Add(Box::new(BinaryOp::new(
2968 make_int_literal(1),
2969 make_int_literal(2),
2970 )));
2971 annotate_types(&mut expr, None, None);
2972
2973 let json = serde_json::to_string(&expr).expect("serialize failed");
2975 assert!(json.contains("inferred_type"));
2977
2978 let deserialized: Expression = serde_json::from_str(&json).expect("deserialize failed");
2980 assert_eq!(
2981 deserialized.inferred_type(),
2982 Some(&DataType::Int {
2983 length: None,
2984 integer_spelling: false,
2985 })
2986 );
2987 }
2988
2989 #[test]
2990 fn test_inferred_type_none_not_serialized() {
2991 let expr = Expression::Add(Box::new(BinaryOp::new(
2993 make_int_literal(1),
2994 make_int_literal(2),
2995 )));
2996 let json = serde_json::to_string(&expr).expect("serialize failed");
2997 assert!(!json.contains("inferred_type"));
2998 }
2999
3000 #[test]
3001 fn test_annotate_if_func_bigquery_node_and_alias_type() {
3002 let mut schema = MappingSchema::with_dialect(DialectType::BigQuery);
3003 schema
3004 .add_table(
3005 "t",
3006 &[("col1".to_string(), DataType::String { length: None })],
3007 None,
3008 )
3009 .unwrap();
3010
3011 let mut expr = parse_one(
3012 "SELECT IF(col1 IS NOT NULL, 1, 0) AS x FROM t",
3013 DialectType::BigQuery,
3014 )
3015 .unwrap();
3016 annotate_types(&mut expr, Some(&schema), Some(DialectType::BigQuery));
3017
3018 let Expression::Select(select) = &expr else {
3019 panic!("expected select");
3020 };
3021 let Expression::Alias(alias) = &select.expressions[0] else {
3022 panic!("expected alias");
3023 };
3024
3025 assert_eq!(
3026 alias.this.inferred_type(),
3027 Some(&DataType::Int {
3028 length: None,
3029 integer_spelling: false,
3030 })
3031 );
3032 assert_eq!(
3033 select.expressions[0].inferred_type(),
3034 Some(&DataType::Int {
3035 length: None,
3036 integer_spelling: false,
3037 })
3038 );
3039 }
3040
3041 #[test]
3042 fn test_annotate_nvl2_node_type() {
3043 let mut expr = parse_one("SELECT NVL2(a, 1, 0) AS x", DialectType::Generic).unwrap();
3044 annotate_types(&mut expr, None, None);
3045
3046 let Expression::Select(select) = &expr else {
3047 panic!("expected select");
3048 };
3049 let Expression::Alias(alias) = &select.expressions[0] else {
3050 panic!("expected alias");
3051 };
3052
3053 assert_eq!(
3054 alias.this.inferred_type(),
3055 Some(&DataType::Int {
3056 length: None,
3057 integer_spelling: false,
3058 })
3059 );
3060 }
3061
3062 #[test]
3063 fn test_annotate_count_node_type() {
3064 let mut expr = parse_one("SELECT COUNT(1) AS x", DialectType::Generic).unwrap();
3065 annotate_types(&mut expr, None, None);
3066
3067 let Expression::Select(select) = &expr else {
3068 panic!("expected select");
3069 };
3070 let Expression::Alias(alias) = &select.expressions[0] else {
3071 panic!("expected alias");
3072 };
3073
3074 assert_eq!(
3075 alias.this.inferred_type(),
3076 Some(&DataType::BigInt { length: None })
3077 );
3078 }
3079
3080 #[test]
3081 fn test_annotate_group_concat_node_type() {
3082 let mut expr = parse_one("SELECT GROUP_CONCAT(a) AS x", DialectType::Generic).unwrap();
3083 annotate_types(&mut expr, None, None);
3084
3085 let Expression::Select(select) = &expr else {
3086 panic!("expected select");
3087 };
3088 let Expression::Alias(alias) = &select.expressions[0] else {
3089 panic!("expected alias");
3090 };
3091
3092 assert_eq!(
3093 alias.this.inferred_type(),
3094 Some(&DataType::VarChar {
3095 length: None,
3096 parenthesized_length: false,
3097 })
3098 );
3099 }
3100
3101 #[test]
3102 fn test_annotate_sum_if_generic_aggregate_type() {
3103 let mut expr =
3104 parse_one("SELECT SUM_IF(1, a > 0) AS x FROM t", DialectType::Generic).unwrap();
3105 annotate_types(&mut expr, None, None);
3106
3107 let Expression::Select(select) = &expr else {
3108 panic!("expected select");
3109 };
3110 let Expression::Alias(alias) = &select.expressions[0] else {
3111 panic!("expected alias");
3112 };
3113
3114 assert_eq!(
3115 select.expressions[0].inferred_type(),
3116 Some(&DataType::BigInt { length: None })
3117 );
3118 assert_eq!(
3119 alias.this.inferred_type(),
3120 Some(&DataType::BigInt { length: None })
3121 );
3122 }
3123}