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 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(_) => None,
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::Function(f) => {
825 for arg in &mut f.args {
826 self.annotate_in_place(arg);
827 }
828 }
829 Expression::Unnest(unnest) => {
830 self.annotate_in_place(&mut unnest.this);
831 for expression in &mut unnest.expressions {
832 self.annotate_in_place(expression);
833 }
834 }
835
836 Expression::IfFunc(f) => {
838 self.annotate_in_place(&mut f.condition);
839 self.annotate_in_place(&mut f.true_value);
840 if let Some(false_value) = &mut f.false_value {
841 self.annotate_in_place(false_value);
842 }
843 }
844 Expression::Nvl2(f) => {
845 self.annotate_in_place(&mut f.this);
846 self.annotate_in_place(&mut f.true_value);
847 self.annotate_in_place(&mut f.false_value);
848 }
849
850 Expression::AggregateFunction(f) => {
852 for arg in &mut f.args {
853 self.annotate_in_place(arg);
854 }
855 }
856
857 Expression::Count(f) => {
859 if let Some(this) = &mut f.this {
860 self.annotate_in_place(this);
861 }
862 if let Some(filter) = &mut f.filter {
863 self.annotate_in_place(filter);
864 }
865 }
866 Expression::GroupConcat(f) => {
867 self.annotate_in_place(&mut f.this);
868 if let Some(separator) = &mut f.separator {
869 self.annotate_in_place(separator);
870 }
871 if let Some(order_by) = &mut f.order_by {
872 for ordered in order_by {
873 self.annotate_in_place(&mut ordered.this);
874 }
875 }
876 if let Some(filter) = &mut f.filter {
877 self.annotate_in_place(filter);
878 }
879 }
880 Expression::StringAgg(f) => {
881 self.annotate_in_place(&mut f.this);
882 if let Some(separator) = &mut f.separator {
883 self.annotate_in_place(separator);
884 }
885 if let Some(order_by) = &mut f.order_by {
886 for ordered in order_by {
887 self.annotate_in_place(&mut ordered.this);
888 }
889 }
890 if let Some(filter) = &mut f.filter {
891 self.annotate_in_place(filter);
892 }
893 if let Some(limit) = &mut f.limit {
894 self.annotate_in_place(limit);
895 }
896 }
897 Expression::ListAgg(f) => {
898 self.annotate_in_place(&mut f.this);
899 if let Some(separator) = &mut f.separator {
900 self.annotate_in_place(separator);
901 }
902 if let Some(order_by) = &mut f.order_by {
903 for ordered in order_by {
904 self.annotate_in_place(&mut ordered.this);
905 }
906 }
907 if let Some(filter) = &mut f.filter {
908 self.annotate_in_place(filter);
909 }
910 if let Some(ListAggOverflow::Truncate {
911 filler: Some(filler),
912 ..
913 }) = &mut f.on_overflow
914 {
915 self.annotate_in_place(filler);
916 }
917 }
918 Expression::SumIf(f) => {
919 self.annotate_in_place(&mut f.this);
920 self.annotate_in_place(&mut f.condition);
921 if let Some(filter) = &mut f.filter {
922 self.annotate_in_place(filter);
923 }
924 }
925
926 Expression::WindowFunction(w) => {
928 self.annotate_in_place(&mut w.this);
929 }
930
931 Expression::Subquery(s) => {
933 self.annotate_in_place(&mut s.this);
934 }
935
936 Expression::Upper(f)
938 | Expression::Lower(f)
939 | Expression::Length(f)
940 | Expression::LTrim(f)
941 | Expression::RTrim(f)
942 | Expression::Reverse(f)
943 | Expression::Abs(f)
944 | Expression::Sqrt(f)
945 | Expression::Cbrt(f)
946 | Expression::Ln(f)
947 | Expression::Exp(f)
948 | Expression::Sign(f)
949 | Expression::Date(f)
950 | Expression::Time(f)
951 | Expression::Explode(f)
952 | Expression::ExplodeOuter(f)
953 | Expression::MapFromEntries(f)
954 | Expression::MapKeys(f)
955 | Expression::MapValues(f)
956 | Expression::ArrayLength(f)
957 | Expression::ArraySize(f)
958 | Expression::Cardinality(f)
959 | Expression::ArrayReverse(f)
960 | Expression::ArrayDistinct(f)
961 | Expression::ArrayFlatten(f)
962 | Expression::ArrayCompact(f)
963 | Expression::ToArray(f)
964 | Expression::JsonArrayLength(f)
965 | Expression::JsonKeys(f)
966 | Expression::JsonType(f)
967 | Expression::ParseJson(f)
968 | Expression::ToJson(f)
969 | Expression::Year(f)
970 | Expression::Month(f)
971 | Expression::Day(f)
972 | Expression::Hour(f)
973 | Expression::Minute(f)
974 | Expression::Second(f)
975 | Expression::Initcap(f)
976 | Expression::Ascii(f)
977 | Expression::Chr(f)
978 | Expression::Soundex(f)
979 | Expression::ByteLength(f)
980 | Expression::Hex(f)
981 | Expression::LowerHex(f)
982 | Expression::Unicode(f)
983 | Expression::Typeof(f)
984 | Expression::BitwiseCount(f)
985 | Expression::Epoch(f)
986 | Expression::EpochMs(f)
987 | Expression::Radians(f)
988 | Expression::Degrees(f)
989 | Expression::Sin(f)
990 | Expression::Cos(f)
991 | Expression::Tan(f)
992 | Expression::Asin(f)
993 | Expression::Acos(f)
994 | Expression::Atan(f)
995 | Expression::IsNan(f)
996 | Expression::IsInf(f) => {
997 self.annotate_in_place(&mut f.this);
998 }
999
1000 Expression::Power(f)
1002 | Expression::NullIf(f)
1003 | Expression::IfNull(f)
1004 | Expression::Nvl(f)
1005 | Expression::Contains(f)
1006 | Expression::StartsWith(f)
1007 | Expression::EndsWith(f)
1008 | Expression::Levenshtein(f)
1009 | Expression::ModFunc(f)
1010 | Expression::IntDiv(f)
1011 | Expression::Atan2(f)
1012 | Expression::AddMonths(f)
1013 | Expression::MonthsBetween(f)
1014 | Expression::NextDay(f)
1015 | Expression::UnixToTimeStr(f)
1016 | Expression::ArrayContains(f)
1017 | Expression::ArrayPosition(f)
1018 | Expression::ArrayAppend(f)
1019 | Expression::ArrayPrepend(f)
1020 | Expression::ArrayUnion(f)
1021 | Expression::ArrayExcept(f)
1022 | Expression::ArrayRemove(f)
1023 | Expression::StarMap(f)
1024 | Expression::MapFromArrays(f)
1025 | Expression::MapContainsKey(f)
1026 | Expression::ElementAt(f)
1027 | Expression::JsonMergePatch(f) => {
1028 self.annotate_in_place(&mut f.this);
1029 self.annotate_in_place(&mut f.expression);
1030 }
1031
1032 Expression::Coalesce(f)
1034 | Expression::Greatest(f)
1035 | Expression::Least(f)
1036 | Expression::ArrayConcat(f)
1037 | Expression::ArrayIntersect(f)
1038 | Expression::ArrayZip(f)
1039 | Expression::MapConcat(f)
1040 | Expression::JsonArray(f) => {
1041 for e in &mut f.expressions {
1042 self.annotate_in_place(e);
1043 }
1044 }
1045
1046 Expression::Sum(f)
1048 | Expression::Avg(f)
1049 | Expression::Min(f)
1050 | Expression::Max(f)
1051 | Expression::ArrayAgg(f)
1052 | Expression::CountIf(f)
1053 | Expression::Stddev(f)
1054 | Expression::StddevPop(f)
1055 | Expression::StddevSamp(f)
1056 | Expression::Variance(f)
1057 | Expression::VarPop(f)
1058 | Expression::VarSamp(f)
1059 | Expression::Median(f)
1060 | Expression::Mode(f)
1061 | Expression::First(f)
1062 | Expression::Last(f)
1063 | Expression::AnyValue(f)
1064 | Expression::ApproxDistinct(f)
1065 | Expression::ApproxCountDistinct(f)
1066 | Expression::LogicalAnd(f)
1067 | Expression::LogicalOr(f)
1068 | Expression::Skewness(f)
1069 | Expression::ArrayConcatAgg(f)
1070 | Expression::ArrayUniqueAgg(f)
1071 | Expression::BoolXorAgg(f)
1072 | Expression::BitwiseAndAgg(f)
1073 | Expression::BitwiseOrAgg(f)
1074 | Expression::BitwiseXorAgg(f) => {
1075 self.annotate_in_place(&mut f.this);
1076 }
1077
1078 Expression::Select(s) => {
1080 for e in &mut s.expressions {
1081 self.annotate_in_place(e);
1082 }
1083 }
1084
1085 _ => {}
1087 }
1088 }
1089
1090 fn annotate_math_function(&mut self, arg: &Expression) -> Option<DataType> {
1093 let input_type = self.annotate(arg)?;
1094 match input_type {
1095 DataType::TinyInt { .. }
1096 | DataType::SmallInt { .. }
1097 | DataType::Int { .. }
1098 | DataType::BigInt { .. } => Some(DataType::Double {
1099 precision: None,
1100 scale: None,
1101 }),
1102 other => Some(other),
1103 }
1104 }
1105
1106 fn annotate_subscript(&mut self, sub: &Subscript) -> Option<DataType> {
1108 let base_type = self.annotate(&sub.this)?;
1109
1110 match base_type {
1111 DataType::Array { element_type, .. } => Some(*element_type),
1112 DataType::Map { value_type, .. } => Some(*value_type),
1113 DataType::Json | DataType::JsonB => Some(DataType::Json), DataType::VarChar { .. } | DataType::Text => {
1115 Some(DataType::VarChar {
1117 length: Some(1),
1118 parenthesized_length: false,
1119 })
1120 }
1121 _ => None,
1122 }
1123 }
1124
1125 fn annotate_struct(&mut self, s: &Struct) -> Option<DataType> {
1127 let fields: Vec<StructField> = s
1128 .fields
1129 .iter()
1130 .map(|(name, expr)| {
1131 let field_type = self.annotate(expr).unwrap_or(DataType::Unknown);
1132 StructField::new(name.clone().unwrap_or_default(), field_type)
1133 })
1134 .collect();
1135 Some(DataType::Struct {
1136 fields,
1137 nested: false,
1138 })
1139 }
1140
1141 fn annotate_map(&mut self, map: &Map) -> Option<DataType> {
1143 let key_type = if let Some(first_key) = map.keys.first() {
1144 self.annotate(first_key).unwrap_or(DataType::Unknown)
1145 } else {
1146 DataType::Unknown
1147 };
1148
1149 let value_type = if let Some(first_value) = map.values.first() {
1150 self.annotate(first_value).unwrap_or(DataType::Unknown)
1151 } else {
1152 DataType::Unknown
1153 };
1154
1155 Some(DataType::Map {
1156 key_type: Box::new(key_type),
1157 value_type: Box::new(value_type),
1158 })
1159 }
1160
1161 fn annotate_set_operation(
1164 &mut self,
1165 _left: &Expression,
1166 _right: &Expression,
1167 ) -> Option<DataType> {
1168 None
1172 }
1173
1174 fn annotate_lateral_view(&mut self, lv: &crate::expressions::LateralView) -> Option<DataType> {
1176 self.annotate(&lv.this)
1178 }
1179
1180 fn annotate_literal(&self, lit: &Literal) -> Option<DataType> {
1182 match lit {
1183 Literal::String(_)
1184 | Literal::NationalString(_)
1185 | Literal::TripleQuotedString(_, _)
1186 | Literal::EscapeString(_)
1187 | Literal::DollarString(_)
1188 | Literal::RawString(_) => Some(DataType::VarChar {
1189 length: None,
1190 parenthesized_length: false,
1191 }),
1192 Literal::Number(n) => {
1193 if n.contains('.') || n.contains('e') || n.contains('E') {
1195 Some(DataType::Double {
1196 precision: None,
1197 scale: None,
1198 })
1199 } else {
1200 if let Ok(_) = n.parse::<i32>() {
1202 Some(DataType::Int {
1203 length: None,
1204 integer_spelling: false,
1205 })
1206 } else {
1207 Some(DataType::BigInt { length: None })
1208 }
1209 }
1210 }
1211 Literal::HexString(_) | Literal::BitString(_) | Literal::ByteString(_) => {
1212 Some(DataType::VarBinary { length: None })
1213 }
1214 Literal::HexNumber(_) => Some(DataType::BigInt { length: None }),
1215 Literal::Date(_) => Some(DataType::Date),
1216 Literal::Time(_) => Some(DataType::Time {
1217 precision: None,
1218 timezone: false,
1219 }),
1220 Literal::Timestamp(_) => Some(DataType::Timestamp {
1221 precision: None,
1222 timezone: false,
1223 }),
1224 Literal::Datetime(_) => Some(DataType::Custom {
1225 name: "DATETIME".to_string(),
1226 }),
1227 }
1228 }
1229
1230 fn annotate_arithmetic(&mut self, op: &BinaryOp) -> Option<DataType> {
1232 let left_type = self.annotate(&op.left);
1233 let right_type = self.annotate(&op.right);
1234
1235 match (left_type, right_type) {
1236 (Some(l), Some(r)) => self.coerce_types(&l, &r),
1237 (Some(t), None) | (None, Some(t)) => Some(t),
1238 (None, None) => None,
1239 }
1240 }
1241
1242 fn annotate_function(&mut self, func: &Function) -> Option<DataType> {
1244 let func_name = func.name.to_uppercase();
1245
1246 if self._dialect == Some(DialectType::DuckDB) && !func.quoted && func_name == "DATE_TRUNC" {
1247 return self.annotate_duckdb_date_trunc(func);
1248 }
1249
1250 if let Some(return_type) = self.function_return_types.get(&func_name) {
1252 if *return_type != DataType::Unknown {
1253 return Some(return_type.clone());
1254 }
1255 }
1256
1257 match func_name.as_str() {
1259 "UNNEST" => func.args.first().and_then(|arg| match self.annotate(arg) {
1260 Some(DataType::Array { element_type, .. }) => Some(*element_type),
1261 _ => None,
1262 }),
1263 "COALESCE" | "IFNULL" | "NVL" | "ISNULL" => {
1264 for arg in &func.args {
1266 if let Some(arg_type) = self.annotate(arg) {
1267 return Some(arg_type);
1268 }
1269 }
1270 None
1271 }
1272 "NULLIF" => {
1273 func.args.first().and_then(|arg| self.annotate(arg))
1275 }
1276 "GREATEST" | "LEAST" => {
1277 self.coerce_arg_types(&func.args)
1279 }
1280 "IF" | "IIF" => {
1281 if func.args.len() >= 2 {
1283 self.annotate(&func.args[1])
1284 } else {
1285 None
1286 }
1287 }
1288 _ => {
1289 func.args.first().and_then(|arg| self.annotate(arg))
1291 }
1292 }
1293 }
1294
1295 fn annotate_duckdb_date_trunc(&mut self, func: &Function) -> Option<DataType> {
1297 if func.args.len() != 2 {
1298 return None;
1299 }
1300
1301 match self.annotate(&func.args[1])? {
1302 DataType::Date => Some(DataType::Timestamp {
1303 precision: None,
1304 timezone: false,
1305 }),
1306 DataType::Timestamp { timezone, .. } => Some(DataType::Timestamp {
1307 precision: None,
1308 timezone,
1309 }),
1310 DataType::Interval { .. } => Some(DataType::Interval {
1311 unit: None,
1312 to: None,
1313 }),
1314 _ => None,
1315 }
1316 }
1317
1318 fn annotate_if_func(&mut self, func: &IfFunc) -> Option<DataType> {
1320 let true_type = self.annotate(&func.true_value);
1321 let false_type = func
1322 .false_value
1323 .as_ref()
1324 .and_then(|expr| self.annotate(expr));
1325
1326 match (true_type, false_type) {
1327 (Some(left), Some(right)) => self.coerce_types(&left, &right),
1328 (Some(dt), None) | (None, Some(dt)) => Some(dt),
1329 (None, None) => None,
1330 }
1331 }
1332
1333 fn annotate_nvl2(&mut self, func: &Nvl2Func) -> Option<DataType> {
1335 let true_type = self.annotate(&func.true_value);
1336 let false_type = self.annotate(&func.false_value);
1337
1338 match (true_type, false_type) {
1339 (Some(left), Some(right)) => self.coerce_types(&left, &right),
1340 (Some(dt), None) | (None, Some(dt)) => Some(dt),
1341 (None, None) => None,
1342 }
1343 }
1344
1345 fn get_aggregate_return_type(
1347 &mut self,
1348 func_name: &str,
1349 args: &[Expression],
1350 ) -> Option<DataType> {
1351 match func_name {
1352 "COUNT" | "COUNT_IF" => Some(DataType::BigInt { length: None }),
1353 "SUM_IF" => {
1354 if let Some(arg) = args.first() {
1355 self.annotate_sum(arg)
1356 } else {
1357 Some(DataType::Decimal {
1358 precision: None,
1359 scale: None,
1360 })
1361 }
1362 }
1363 "SUM" => {
1364 if let Some(arg) = args.first() {
1365 self.annotate_sum(arg)
1366 } else {
1367 Some(DataType::Decimal {
1368 precision: None,
1369 scale: None,
1370 })
1371 }
1372 }
1373 "AVG" => Some(DataType::Double {
1374 precision: None,
1375 scale: None,
1376 }),
1377 "MIN" | "MAX" => {
1378 args.first().and_then(|arg| self.annotate(arg))
1380 }
1381 "STRING_AGG" | "GROUP_CONCAT" | "LISTAGG" | "ARRAY_AGG" => Some(DataType::VarChar {
1382 length: None,
1383 parenthesized_length: false,
1384 }),
1385 "BOOL_AND" | "BOOL_OR" | "EVERY" | "ANY" | "SOME" => Some(DataType::Boolean),
1386 "BIT_AND" | "BIT_OR" | "BIT_XOR" => Some(DataType::BigInt { length: None }),
1387 "STDDEV" | "STDDEV_POP" | "STDDEV_SAMP" | "VARIANCE" | "VAR_POP" | "VAR_SAMP" => {
1388 Some(DataType::Double {
1389 precision: None,
1390 scale: None,
1391 })
1392 }
1393 "PERCENTILE_CONT" | "PERCENTILE_DISC" | "MEDIAN" => {
1394 args.first().and_then(|arg| self.annotate(arg))
1395 }
1396 _ => None,
1397 }
1398 }
1399
1400 fn annotate_sum(&mut self, arg: &Expression) -> Option<DataType> {
1402 match self.annotate(arg) {
1403 Some(DataType::TinyInt { .. })
1404 | Some(DataType::SmallInt { .. })
1405 | Some(DataType::Int { .. }) => Some(DataType::BigInt { length: None }),
1406 Some(DataType::BigInt { .. }) => Some(DataType::BigInt { length: None }),
1407 Some(DataType::Float { .. }) | Some(DataType::Double { .. }) => {
1408 Some(DataType::Double {
1409 precision: None,
1410 scale: None,
1411 })
1412 }
1413 Some(DataType::Decimal { precision, scale }) => {
1414 Some(DataType::Decimal { precision, scale })
1415 }
1416 _ => Some(DataType::Decimal {
1417 precision: None,
1418 scale: None,
1419 }),
1420 }
1421 }
1422
1423 fn coerce_arg_types(&mut self, args: &[Expression]) -> Option<DataType> {
1425 let mut result_type: Option<DataType> = None;
1426 for arg in args {
1427 if let Some(arg_type) = self.annotate(arg) {
1428 result_type = match result_type {
1429 Some(t) => self.coerce_types(&t, &arg_type),
1430 None => Some(arg_type),
1431 };
1432 }
1433 }
1434 result_type
1435 }
1436
1437 fn coerce_types(&self, left: &DataType, right: &DataType) -> Option<DataType> {
1439 if left == right {
1441 return Some(left.clone());
1442 }
1443
1444 match (left, right) {
1446 (DataType::Date, DataType::Interval { .. })
1447 | (DataType::Interval { .. }, DataType::Date) => return Some(DataType::Date),
1448 (
1449 DataType::Timestamp {
1450 precision,
1451 timezone,
1452 },
1453 DataType::Interval { .. },
1454 )
1455 | (
1456 DataType::Interval { .. },
1457 DataType::Timestamp {
1458 precision,
1459 timezone,
1460 },
1461 ) => {
1462 return Some(DataType::Timestamp {
1463 precision: *precision,
1464 timezone: *timezone,
1465 });
1466 }
1467 _ => {}
1468 }
1469
1470 let left_class = TypeCoercionClass::from_data_type(left);
1472 let right_class = TypeCoercionClass::from_data_type(right);
1473
1474 match (left_class, right_class) {
1475 (Some(lc), Some(rc)) if lc == rc => {
1477 if lc == TypeCoercionClass::Numeric {
1479 Some(self.wider_numeric_type(left, right))
1480 } else {
1481 Some(left.clone())
1483 }
1484 }
1485 (Some(lc), Some(rc)) => {
1487 if lc > rc {
1488 Some(left.clone())
1489 } else {
1490 Some(right.clone())
1491 }
1492 }
1493 (Some(_), None) => Some(left.clone()),
1495 (None, Some(_)) => Some(right.clone()),
1496 (None, None) => Some(DataType::Unknown),
1498 }
1499 }
1500
1501 fn wider_numeric_type(&self, left: &DataType, right: &DataType) -> DataType {
1503 let order = |dt: &DataType| -> u8 {
1504 match dt {
1505 DataType::Boolean => 0,
1506 DataType::TinyInt { .. } => 1,
1507 DataType::SmallInt { .. } => 2,
1508 DataType::Int { .. } => 3,
1509 DataType::BigInt { .. } => 4,
1510 DataType::Float { .. } => 5,
1511 DataType::Double { .. } => 6,
1512 DataType::Decimal { .. } => 7,
1513 _ => 0,
1514 }
1515 };
1516
1517 if order(left) >= order(right) {
1518 left.clone()
1519 } else {
1520 right.clone()
1521 }
1522 }
1523}
1524
1525struct ScopedSchema<'a> {
1530 parent: Option<&'a dyn Schema>,
1531 tables: HashMap<String, HashMap<String, DataType>>,
1532 dialect: Option<DialectType>,
1533}
1534
1535impl<'a> ScopedSchema<'a> {
1536 fn new(parent: Option<&'a dyn Schema>, dialect: Option<DialectType>) -> Self {
1537 Self {
1538 parent,
1539 tables: HashMap::new(),
1540 dialect,
1541 }
1542 }
1543
1544 fn normalized(&self, name: &str, is_table: bool) -> String {
1545 normalize_name(name, self.dialect, is_table, true)
1546 }
1547
1548 fn local_column_type(&self, table: &str, column: &str) -> Option<DataType> {
1549 let table = self.normalized(table, true);
1550 let column = self.normalized(column, false);
1551 self.tables
1552 .get(&table)
1553 .and_then(|columns| columns.get(&column))
1554 .cloned()
1555 }
1556
1557 fn local_tables_for_column(&self, column: &str) -> Vec<String> {
1558 let column = self.normalized(column, false);
1559 self.tables
1560 .iter()
1561 .filter_map(|(table, columns)| columns.contains_key(&column).then(|| table.clone()))
1562 .collect()
1563 }
1564}
1565
1566impl Schema for ScopedSchema<'_> {
1567 fn dialect(&self) -> Option<DialectType> {
1568 self.dialect
1569 .or_else(|| self.parent.and_then(Schema::dialect))
1570 }
1571
1572 fn add_table(
1573 &mut self,
1574 table: &str,
1575 columns: &[(String, DataType)],
1576 _dialect: Option<DialectType>,
1577 ) -> SchemaResult<()> {
1578 let table = self.normalized(table, true);
1579 let columns = columns
1580 .iter()
1581 .map(|(name, data_type)| (self.normalized(name, false), data_type.clone()))
1582 .collect();
1583 self.tables.insert(table, columns);
1584 Ok(())
1585 }
1586
1587 fn column_names(&self, table: &str) -> SchemaResult<Vec<String>> {
1588 let table = self.normalized(table, true);
1589 if let Some(columns) = self.tables.get(&table) {
1590 return Ok(columns.keys().cloned().collect());
1591 }
1592 self.parent
1593 .ok_or_else(|| SchemaError::TableNotFound(table.clone()))?
1594 .column_names(&table)
1595 }
1596
1597 fn get_column_type(&self, table: &str, column: &str) -> SchemaResult<DataType> {
1598 if table.is_empty() {
1599 let local_tables = self.local_tables_for_column(column);
1600 return match local_tables.as_slice() {
1601 [local_table] => self.get_column_type(local_table, column),
1602 [] => self
1603 .parent
1604 .ok_or_else(|| SchemaError::ColumnNotFound {
1605 table: String::new(),
1606 column: column.to_string(),
1607 })?
1608 .get_column_type(table, column),
1609 _ => Err(SchemaError::AmbiguousTable {
1610 table: String::new(),
1611 matches: local_tables.join(", "),
1612 }),
1613 };
1614 }
1615
1616 let normalized_table = self.normalized(table, true);
1617 if self.tables.contains_key(&normalized_table) {
1618 return self.local_column_type(table, column).ok_or_else(|| {
1619 SchemaError::ColumnNotFound {
1620 table: table.to_string(),
1621 column: column.to_string(),
1622 }
1623 });
1624 }
1625
1626 self.parent
1627 .ok_or_else(|| SchemaError::ColumnNotFound {
1628 table: table.to_string(),
1629 column: column.to_string(),
1630 })?
1631 .get_column_type(table, column)
1632 }
1633
1634 fn has_column(&self, table: &str, column: &str) -> bool {
1635 self.get_column_type(table, column).is_ok()
1636 }
1637
1638 fn supported_table_args(&self) -> &[&str] {
1639 TABLE_PARTS
1640 }
1641
1642 fn is_empty(&self) -> bool {
1643 self.tables.is_empty() && self.parent.is_none_or(Schema::is_empty)
1644 }
1645
1646 fn depth(&self) -> usize {
1647 self.parent.map_or(1, |schema| schema.depth().max(1))
1648 }
1649
1650 fn find_tables_for_column(&self, column: &str) -> Vec<String> {
1651 let mut tables = self.local_tables_for_column(column);
1652 if let Some(parent) = self.parent {
1653 tables.extend(parent.find_tables_for_column(column));
1654 }
1655 let mut seen = HashSet::new();
1656 tables.retain(|table| seen.insert(table.clone()));
1657 tables
1658 }
1659}
1660
1661type OutputColumns = Vec<(String, DataType)>;
1662
1663fn table_name(table: &crate::expressions::TableRef) -> String {
1664 let mut parts = Vec::new();
1665 if let Some(catalog) = &table.catalog {
1666 parts.push(catalog.name.as_str());
1667 }
1668 if let Some(schema) = &table.schema {
1669 parts.push(schema.name.as_str());
1670 }
1671 parts.push(table.name.name.as_str());
1672 parts.join(".")
1673}
1674
1675fn table_columns(schema: &dyn Schema, table: &str) -> OutputColumns {
1676 schema
1677 .column_names(table)
1678 .unwrap_or_default()
1679 .into_iter()
1680 .map(|column| {
1681 let data_type = schema
1682 .get_column_type(table, &column)
1683 .unwrap_or(DataType::Unknown);
1684 (column, data_type)
1685 })
1686 .collect()
1687}
1688
1689fn apply_column_aliases(
1690 mut columns: OutputColumns,
1691 aliases: &[crate::expressions::Identifier],
1692) -> OutputColumns {
1693 for ((name, _), alias) in columns.iter_mut().zip(aliases) {
1694 *name = alias.name.clone();
1695 }
1696 columns
1697}
1698
1699fn projection_name(expression: &Expression) -> Option<String> {
1700 match expression {
1701 Expression::Alias(alias) => Some(alias.alias.name.clone()),
1702 Expression::Column(column) => Some(column.name.name.clone()),
1703 Expression::Identifier(identifier) => Some(identifier.name.clone()),
1704 _ => None,
1705 }
1706}
1707
1708fn projection_type(expression: &Expression) -> DataType {
1709 expression
1710 .inferred_type()
1711 .or_else(|| match expression {
1712 Expression::Alias(alias) => alias.this.inferred_type(),
1713 _ => None,
1714 })
1715 .cloned()
1716 .unwrap_or(DataType::Unknown)
1717}
1718
1719fn query_outputs(expressions: &[Expression]) -> OutputColumns {
1720 expressions
1721 .iter()
1722 .filter_map(|expression| {
1723 projection_name(expression).map(|name| (name, projection_type(expression)))
1724 })
1725 .collect()
1726}
1727
1728fn array_element_type(data_type: Option<&DataType>) -> DataType {
1729 match data_type {
1730 Some(DataType::Array { element_type, .. }) => (**element_type).clone(),
1731 _ => DataType::Unknown,
1732 }
1733}
1734
1735fn unnest_output_types(unnest: &crate::expressions::UnnestFunc) -> Vec<DataType> {
1736 let mut types = vec![array_element_type(unnest.this.inferred_type())];
1737 types.extend(
1738 unnest
1739 .expressions
1740 .iter()
1741 .map(|expression| array_element_type(expression.inferred_type())),
1742 );
1743 if unnest.with_ordinality || unnest.offset_alias.is_some() {
1744 types.push(DataType::BigInt { length: None });
1745 }
1746 types
1747}
1748
1749fn virtual_output_columns(
1750 expression: &Expression,
1751 source_alias: &str,
1752 column_aliases: &[crate::expressions::Identifier],
1753) -> OutputColumns {
1754 let (types, offset_alias) = match expression {
1755 Expression::Unnest(unnest) => (unnest_output_types(unnest), unnest.offset_alias.as_ref()),
1756 Expression::Explode(explode) | Expression::ExplodeOuter(explode) => {
1757 (vec![array_element_type(explode.this.inferred_type())], None)
1758 }
1759 Expression::Function(function) if function.name.eq_ignore_ascii_case("UNNEST") => (
1760 function
1761 .args
1762 .iter()
1763 .map(|argument| array_element_type(argument.inferred_type()))
1764 .collect(),
1765 None,
1766 ),
1767 _ => return Vec::new(),
1768 };
1769
1770 if column_aliases.is_empty() {
1771 let mut columns = Vec::new();
1772 if let Some(data_type) = types.first() {
1773 columns.push((source_alias.to_string(), data_type.clone()));
1774 }
1775 if let Some(offset_alias) = offset_alias {
1776 columns.push((offset_alias.name.clone(), DataType::BigInt { length: None }));
1777 }
1778 columns
1779 } else {
1780 column_aliases
1781 .iter()
1782 .zip(types)
1783 .map(|(alias, data_type)| (alias.name.clone(), data_type))
1784 .collect()
1785 }
1786}
1787
1788fn annotate_relation_source(
1789 expression: &mut Expression,
1790 schema: &mut ScopedSchema<'_>,
1791 dialect: Option<DialectType>,
1792) {
1793 match expression {
1794 Expression::Table(table) => {
1795 let source_table = table_name(table);
1796 let mut columns = table_columns(schema, &source_table);
1797 columns = apply_column_aliases(columns, &table.column_aliases);
1798 let visible_name = table
1799 .alias
1800 .as_ref()
1801 .map(|alias| alias.name.as_str())
1802 .unwrap_or(table.name.name.as_str());
1803 let _ = schema.add_table(visible_name, &columns, dialect);
1804 }
1805 Expression::Subquery(subquery) => {
1806 let mut columns = annotate_scoped_expression(&mut subquery.this, Some(schema), dialect);
1807 columns = apply_column_aliases(columns, &subquery.column_aliases);
1808 if let Some((_, first_type)) = columns.first() {
1809 subquery.inferred_type = Some(first_type.clone());
1810 }
1811 if let Some(alias) = &subquery.alias {
1812 let _ = schema.add_table(&alias.name, &columns, dialect);
1813 }
1814 }
1815 Expression::Alias(alias) => {
1816 match &mut alias.this {
1817 Expression::Subquery(subquery) => {
1818 let columns =
1819 annotate_scoped_expression(&mut subquery.this, Some(schema), dialect);
1820 let columns = apply_column_aliases(columns, &alias.column_aliases);
1821 let _ = schema.add_table(&alias.alias.name, &columns, dialect);
1822 return;
1823 }
1824 _ => {
1825 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1826 annotator.annotate_in_place(&mut alias.this);
1827 }
1828 }
1829 let columns =
1830 virtual_output_columns(&alias.this, &alias.alias.name, &alias.column_aliases);
1831 if !columns.is_empty() {
1832 let _ = schema.add_table(&alias.alias.name, &columns, dialect);
1833 }
1834 }
1835 Expression::Unnest(_) => {
1836 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1837 annotator.annotate_in_place(expression);
1838 if let Expression::Unnest(unnest) = expression {
1839 if let Some(alias) = &unnest.alias {
1840 let alias_name = alias.name.clone();
1841 let columns = unnest_output_types(unnest)
1842 .into_iter()
1843 .next()
1844 .map(|data_type| vec![(alias_name.clone(), data_type)])
1845 .unwrap_or_default();
1846 let _ = schema.add_table(&alias_name, &columns, dialect);
1847 }
1848 }
1849 }
1850 Expression::Lateral(lateral) => {
1851 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1852 annotator.annotate_in_place(&mut lateral.this);
1853 if let Some(alias) = &lateral.alias {
1854 let aliases: Vec<_> = lateral
1855 .column_aliases
1856 .iter()
1857 .map(crate::expressions::Identifier::new)
1858 .collect();
1859 let columns = virtual_output_columns(&lateral.this, alias, &aliases);
1860 if !columns.is_empty() {
1861 let _ = schema.add_table(alias, &columns, dialect);
1862 }
1863 }
1864 }
1865 Expression::Paren(paren) => annotate_relation_source(&mut paren.this, schema, dialect),
1866 _ => {
1867 let mut annotator = TypeAnnotator::new(Some(schema), dialect);
1868 annotator.annotate_in_place(expression);
1869 }
1870 }
1871}
1872
1873fn annotate_with(
1874 with: &mut Option<crate::expressions::With>,
1875 schema: &mut ScopedSchema<'_>,
1876 dialect: Option<DialectType>,
1877) {
1878 if let Some(with) = with {
1879 for cte in &mut with.ctes {
1880 let columns = annotate_scoped_expression(&mut cte.this, Some(schema), dialect);
1881 let columns = apply_column_aliases(columns, &cte.columns);
1882 let _ = schema.add_table(&cte.alias.name, &columns, dialect);
1883 }
1884 }
1885}
1886
1887fn annotate_select(
1888 select: &mut crate::expressions::Select,
1889 parent: Option<&dyn Schema>,
1890 dialect: Option<DialectType>,
1891) -> OutputColumns {
1892 let mut schema = ScopedSchema::new(parent, dialect);
1893 annotate_with(&mut select.with, &mut schema, dialect);
1894
1895 if let Some(from) = &mut select.from {
1896 for source in &mut from.expressions {
1897 annotate_relation_source(source, &mut schema, dialect);
1898 }
1899 }
1900 for join in &mut select.joins {
1901 annotate_relation_source(&mut join.this, &mut schema, dialect);
1902 }
1903
1904 let mut annotator = TypeAnnotator::new(Some(&schema), dialect);
1905 for expression in &mut select.expressions {
1906 annotator.annotate_in_place(expression);
1907 }
1908 query_outputs(&select.expressions)
1909}
1910
1911fn annotate_scoped_expression(
1912 expression: &mut Expression,
1913 parent: Option<&dyn Schema>,
1914 dialect: Option<DialectType>,
1915) -> OutputColumns {
1916 match expression {
1917 Expression::Select(select) => annotate_select(select, parent, dialect),
1918 Expression::Subquery(subquery) => {
1919 let columns = annotate_scoped_expression(&mut subquery.this, parent, dialect);
1920 if let Some((_, first_type)) = columns.first() {
1921 subquery.inferred_type = Some(first_type.clone());
1922 }
1923 columns
1924 }
1925 Expression::Cte(cte) => annotate_scoped_expression(&mut cte.this, parent, dialect),
1926 Expression::Paren(paren) => annotate_scoped_expression(&mut paren.this, parent, dialect),
1927 Expression::Union(union) => {
1928 let mut schema = ScopedSchema::new(parent, dialect);
1929 annotate_with(&mut union.with, &mut schema, dialect);
1930 let columns = annotate_scoped_expression(&mut union.left, Some(&schema), dialect);
1931 annotate_scoped_expression(&mut union.right, Some(&schema), dialect);
1932 columns
1933 }
1934 Expression::Intersect(intersect) => {
1935 let mut schema = ScopedSchema::new(parent, dialect);
1936 annotate_with(&mut intersect.with, &mut schema, dialect);
1937 let columns = annotate_scoped_expression(&mut intersect.left, Some(&schema), dialect);
1938 annotate_scoped_expression(&mut intersect.right, Some(&schema), dialect);
1939 columns
1940 }
1941 Expression::Except(except) => {
1942 let mut schema = ScopedSchema::new(parent, dialect);
1943 annotate_with(&mut except.with, &mut schema, dialect);
1944 let columns = annotate_scoped_expression(&mut except.left, Some(&schema), dialect);
1945 annotate_scoped_expression(&mut except.right, Some(&schema), dialect);
1946 columns
1947 }
1948 _ => {
1949 let mut annotator = TypeAnnotator::new(parent, dialect);
1950 annotator.annotate_in_place(expression);
1951 Vec::new()
1952 }
1953 }
1954}
1955
1956pub fn annotate_types(
1962 expr: &mut Expression,
1963 schema: Option<&dyn Schema>,
1964 dialect: Option<DialectType>,
1965) {
1966 annotate_scoped_expression(expr, schema, dialect);
1967}
1968
1969#[cfg(test)]
1970mod tests {
1971 use super::*;
1972 use crate::expressions::{BooleanLiteral, Cast, Null};
1973 use crate::{parse_one, DialectType, MappingSchema, Schema};
1974
1975 fn make_int_literal(val: i64) -> Expression {
1976 Expression::Literal(Box::new(Literal::Number(val.to_string())))
1977 }
1978
1979 fn make_float_literal(val: f64) -> Expression {
1980 Expression::Literal(Box::new(Literal::Number(val.to_string())))
1981 }
1982
1983 fn make_string_literal(val: &str) -> Expression {
1984 Expression::Literal(Box::new(Literal::String(val.to_string())))
1985 }
1986
1987 fn make_bool_literal(val: bool) -> Expression {
1988 Expression::Boolean(BooleanLiteral { value: val })
1989 }
1990
1991 #[test]
1992 fn test_literal_types() {
1993 let mut annotator = TypeAnnotator::new(None, None);
1994
1995 let int_expr = make_int_literal(42);
1997 assert_eq!(
1998 annotator.annotate(&int_expr),
1999 Some(DataType::Int {
2000 length: None,
2001 integer_spelling: false
2002 })
2003 );
2004
2005 let float_expr = make_float_literal(3.14);
2007 assert_eq!(
2008 annotator.annotate(&float_expr),
2009 Some(DataType::Double {
2010 precision: None,
2011 scale: None
2012 })
2013 );
2014
2015 let string_expr = make_string_literal("hello");
2017 assert_eq!(
2018 annotator.annotate(&string_expr),
2019 Some(DataType::VarChar {
2020 length: None,
2021 parenthesized_length: false
2022 })
2023 );
2024
2025 let bool_expr = make_bool_literal(true);
2027 assert_eq!(annotator.annotate(&bool_expr), Some(DataType::Boolean));
2028
2029 let null_expr = Expression::Null(Null);
2031 assert_eq!(annotator.annotate(&null_expr), None);
2032 }
2033
2034 #[test]
2035 fn test_comparison_types() {
2036 let mut annotator = TypeAnnotator::new(None, None);
2037
2038 let cmp = Expression::Gt(Box::new(BinaryOp::new(
2040 make_int_literal(1),
2041 make_int_literal(2),
2042 )));
2043 assert_eq!(annotator.annotate(&cmp), Some(DataType::Boolean));
2044
2045 let eq = Expression::Eq(Box::new(BinaryOp::new(
2047 make_string_literal("a"),
2048 make_string_literal("b"),
2049 )));
2050 assert_eq!(annotator.annotate(&eq), Some(DataType::Boolean));
2051 }
2052
2053 #[test]
2054 fn test_arithmetic_types() {
2055 let mut annotator = TypeAnnotator::new(None, None);
2056
2057 let add_int = Expression::Add(Box::new(BinaryOp::new(
2059 make_int_literal(1),
2060 make_int_literal(2),
2061 )));
2062 assert_eq!(
2063 annotator.annotate(&add_int),
2064 Some(DataType::Int {
2065 length: None,
2066 integer_spelling: false
2067 })
2068 );
2069
2070 let add_mixed = Expression::Add(Box::new(BinaryOp::new(
2072 make_int_literal(1),
2073 make_float_literal(2.5), )));
2075 assert_eq!(
2076 annotator.annotate(&add_mixed),
2077 Some(DataType::Double {
2078 precision: None,
2079 scale: None
2080 })
2081 );
2082 }
2083
2084 #[test]
2085 fn test_string_concat_type() {
2086 let mut annotator = TypeAnnotator::new(None, None);
2087
2088 let concat = Expression::Concat(Box::new(BinaryOp::new(
2090 make_string_literal("hello"),
2091 make_string_literal(" world"),
2092 )));
2093 assert_eq!(
2094 annotator.annotate(&concat),
2095 Some(DataType::VarChar {
2096 length: None,
2097 parenthesized_length: false
2098 })
2099 );
2100 }
2101
2102 #[test]
2103 fn test_cast_type() {
2104 let mut annotator = TypeAnnotator::new(None, None);
2105
2106 let cast = Expression::Cast(Box::new(Cast {
2108 this: make_int_literal(1),
2109 to: DataType::VarChar {
2110 length: Some(10),
2111 parenthesized_length: false,
2112 },
2113 trailing_comments: vec![],
2114 double_colon_syntax: false,
2115 format: None,
2116 default: None,
2117 inferred_type: None,
2118 }));
2119 assert_eq!(
2120 annotator.annotate(&cast),
2121 Some(DataType::VarChar {
2122 length: Some(10),
2123 parenthesized_length: false
2124 })
2125 );
2126 }
2127
2128 #[test]
2129 fn test_function_types() {
2130 let mut annotator = TypeAnnotator::new(None, None);
2131
2132 let count =
2134 Expression::Function(Box::new(Function::new("COUNT", vec![make_int_literal(1)])));
2135 assert_eq!(
2136 annotator.annotate(&count),
2137 Some(DataType::BigInt { length: None })
2138 );
2139
2140 let upper = Expression::Function(Box::new(Function::new(
2142 "UPPER",
2143 vec![make_string_literal("hello")],
2144 )));
2145 assert_eq!(
2146 annotator.annotate(&upper),
2147 Some(DataType::VarChar {
2148 length: None,
2149 parenthesized_length: false
2150 })
2151 );
2152
2153 let now = Expression::Function(Box::new(Function::new("NOW", vec![])));
2155 assert_eq!(
2156 annotator.annotate(&now),
2157 Some(DataType::Timestamp {
2158 precision: None,
2159 timezone: false
2160 })
2161 );
2162 }
2163
2164 #[test]
2165 fn test_duckdb_date_trunc_overload_types() {
2166 fn cast_to(data_type: DataType) -> Expression {
2167 Expression::Cast(Box::new(Cast {
2168 this: make_string_literal("value"),
2169 to: data_type,
2170 format: None,
2171 trailing_comments: Vec::new(),
2172 double_colon_syntax: false,
2173 default: None,
2174 inferred_type: None,
2175 }))
2176 }
2177
2178 fn date_trunc(value: Expression) -> Expression {
2179 Expression::Function(Box::new(Function::new(
2180 "DATE_TRUNC",
2181 vec![make_string_literal("month"), value],
2182 )))
2183 }
2184
2185 let mut annotator = TypeAnnotator::new(None, Some(DialectType::DuckDB));
2186
2187 for input_type in [
2188 DataType::Date,
2189 DataType::Timestamp {
2190 precision: Some(9),
2191 timezone: false,
2192 },
2193 ] {
2194 assert_eq!(
2195 annotator.annotate(&date_trunc(cast_to(input_type))),
2196 Some(DataType::Timestamp {
2197 precision: None,
2198 timezone: false,
2199 })
2200 );
2201 }
2202
2203 assert_eq!(
2204 annotator.annotate(&date_trunc(cast_to(DataType::Timestamp {
2205 precision: Some(6),
2206 timezone: true,
2207 }))),
2208 Some(DataType::Timestamp {
2209 precision: None,
2210 timezone: true,
2211 })
2212 );
2213 assert_eq!(
2214 annotator.annotate(&date_trunc(cast_to(DataType::Interval {
2215 unit: Some("DAY".to_string()),
2216 to: Some("SECOND".to_string()),
2217 }))),
2218 Some(DataType::Interval {
2219 unit: None,
2220 to: None,
2221 })
2222 );
2223 assert_eq!(
2224 annotator.annotate(&date_trunc(Expression::Null(Null))),
2225 None
2226 );
2227 }
2228
2229 #[test]
2230 fn test_coalesce_type_inference() {
2231 let mut annotator = TypeAnnotator::new(None, None);
2232
2233 let coalesce = Expression::Function(Box::new(Function::new(
2235 "COALESCE",
2236 vec![Expression::Null(Null), make_int_literal(1)],
2237 )));
2238 assert_eq!(
2239 annotator.annotate(&coalesce),
2240 Some(DataType::Int {
2241 length: None,
2242 integer_spelling: false
2243 })
2244 );
2245
2246 let specialized_coalesce = Expression::Coalesce(Box::new(crate::expressions::VarArgFunc {
2247 expressions: vec![Expression::Null(Null), make_int_literal(1)],
2248 original_name: None,
2249 inferred_type: None,
2250 }));
2251 assert_eq!(
2252 annotator.annotate(&specialized_coalesce),
2253 Some(DataType::Int {
2254 length: None,
2255 integer_spelling: false
2256 })
2257 );
2258 }
2259
2260 #[test]
2261 fn test_type_coercion_class() {
2262 assert_eq!(
2264 TypeCoercionClass::from_data_type(&DataType::VarChar {
2265 length: None,
2266 parenthesized_length: false
2267 }),
2268 Some(TypeCoercionClass::Text)
2269 );
2270 assert_eq!(
2271 TypeCoercionClass::from_data_type(&DataType::Text),
2272 Some(TypeCoercionClass::Text)
2273 );
2274
2275 assert_eq!(
2277 TypeCoercionClass::from_data_type(&DataType::Int {
2278 length: None,
2279 integer_spelling: false
2280 }),
2281 Some(TypeCoercionClass::Numeric)
2282 );
2283 assert_eq!(
2284 TypeCoercionClass::from_data_type(&DataType::Double {
2285 precision: None,
2286 scale: None
2287 }),
2288 Some(TypeCoercionClass::Numeric)
2289 );
2290
2291 assert_eq!(
2293 TypeCoercionClass::from_data_type(&DataType::Date),
2294 Some(TypeCoercionClass::Timelike)
2295 );
2296 assert_eq!(
2297 TypeCoercionClass::from_data_type(&DataType::Timestamp {
2298 precision: None,
2299 timezone: false
2300 }),
2301 Some(TypeCoercionClass::Timelike)
2302 );
2303
2304 assert_eq!(TypeCoercionClass::from_data_type(&DataType::Json), None);
2306 }
2307
2308 #[test]
2309 fn test_wider_numeric_type() {
2310 let annotator = TypeAnnotator::new(None, None);
2311
2312 let result = annotator.wider_numeric_type(
2314 &DataType::Int {
2315 length: None,
2316 integer_spelling: false,
2317 },
2318 &DataType::BigInt { length: None },
2319 );
2320 assert_eq!(result, DataType::BigInt { length: None });
2321
2322 let result = annotator.wider_numeric_type(
2324 &DataType::Float {
2325 precision: None,
2326 scale: None,
2327 real_spelling: false,
2328 },
2329 &DataType::Double {
2330 precision: None,
2331 scale: None,
2332 },
2333 );
2334 assert_eq!(
2335 result,
2336 DataType::Double {
2337 precision: None,
2338 scale: None
2339 }
2340 );
2341
2342 let result = annotator.wider_numeric_type(
2344 &DataType::Int {
2345 length: None,
2346 integer_spelling: false,
2347 },
2348 &DataType::Double {
2349 precision: None,
2350 scale: None,
2351 },
2352 );
2353 assert_eq!(
2354 result,
2355 DataType::Double {
2356 precision: None,
2357 scale: None
2358 }
2359 );
2360 }
2361
2362 #[test]
2363 fn test_aggregate_return_types() {
2364 let mut annotator = TypeAnnotator::new(None, None);
2365
2366 let sum_type = annotator.get_aggregate_return_type("SUM", &[make_int_literal(1)]);
2368 assert_eq!(sum_type, Some(DataType::BigInt { length: None }));
2369
2370 let avg_type = annotator.get_aggregate_return_type("AVG", &[make_int_literal(1)]);
2372 assert_eq!(
2373 avg_type,
2374 Some(DataType::Double {
2375 precision: None,
2376 scale: None
2377 })
2378 );
2379
2380 let min_type = annotator.get_aggregate_return_type("MIN", &[make_string_literal("a")]);
2382 assert_eq!(
2383 min_type,
2384 Some(DataType::VarChar {
2385 length: None,
2386 parenthesized_length: false
2387 })
2388 );
2389 }
2390
2391 #[test]
2392 fn test_date_literal_types() {
2393 let mut annotator = TypeAnnotator::new(None, None);
2394
2395 let date_expr = Expression::Literal(Box::new(Literal::Date("2024-01-15".to_string())));
2397 assert_eq!(annotator.annotate(&date_expr), Some(DataType::Date));
2398
2399 let time_expr = Expression::Literal(Box::new(Literal::Time("10:30:00".to_string())));
2401 assert_eq!(
2402 annotator.annotate(&time_expr),
2403 Some(DataType::Time {
2404 precision: None,
2405 timezone: false
2406 })
2407 );
2408
2409 let ts_expr = Expression::Literal(Box::new(Literal::Timestamp(
2411 "2024-01-15 10:30:00".to_string(),
2412 )));
2413 assert_eq!(
2414 annotator.annotate(&ts_expr),
2415 Some(DataType::Timestamp {
2416 precision: None,
2417 timezone: false
2418 })
2419 );
2420 }
2421
2422 #[test]
2423 fn test_logical_operations() {
2424 let mut annotator = TypeAnnotator::new(None, None);
2425
2426 let and_expr = Expression::And(Box::new(BinaryOp::new(
2428 make_bool_literal(true),
2429 make_bool_literal(false),
2430 )));
2431 assert_eq!(annotator.annotate(&and_expr), Some(DataType::Boolean));
2432
2433 let or_expr = Expression::Or(Box::new(BinaryOp::new(
2435 make_bool_literal(true),
2436 make_bool_literal(false),
2437 )));
2438 assert_eq!(annotator.annotate(&or_expr), Some(DataType::Boolean));
2439
2440 let not_expr = Expression::Not(Box::new(crate::expressions::UnaryOp::new(
2442 make_bool_literal(true),
2443 )));
2444 assert_eq!(annotator.annotate(¬_expr), Some(DataType::Boolean));
2445 }
2446
2447 #[test]
2452 fn test_subscript_array_type() {
2453 let mut annotator = TypeAnnotator::new(None, None);
2454
2455 let arr = Expression::Array(Box::new(crate::expressions::Array {
2457 expressions: vec![make_int_literal(1), make_int_literal(2)],
2458 }));
2459 let subscript = Expression::Subscript(Box::new(crate::expressions::Subscript {
2460 this: arr,
2461 index: make_int_literal(0),
2462 }));
2463 assert_eq!(
2464 annotator.annotate(&subscript),
2465 Some(DataType::Int {
2466 length: None,
2467 integer_spelling: false
2468 })
2469 );
2470 }
2471
2472 #[test]
2473 fn test_subscript_map_type() {
2474 let mut annotator = TypeAnnotator::new(None, None);
2475
2476 let map = Expression::Map(Box::new(crate::expressions::Map {
2478 keys: vec![make_string_literal("a")],
2479 values: vec![make_int_literal(1)],
2480 }));
2481 let subscript = Expression::Subscript(Box::new(crate::expressions::Subscript {
2482 this: map,
2483 index: make_string_literal("a"),
2484 }));
2485 assert_eq!(
2486 annotator.annotate(&subscript),
2487 Some(DataType::Int {
2488 length: None,
2489 integer_spelling: false
2490 })
2491 );
2492 }
2493
2494 #[test]
2495 fn test_struct_type() {
2496 let mut annotator = TypeAnnotator::new(None, None);
2497
2498 let struct_expr = Expression::Struct(Box::new(crate::expressions::Struct {
2500 fields: vec![
2501 (Some("name".to_string()), make_string_literal("Alice")),
2502 (Some("age".to_string()), make_int_literal(30)),
2503 ],
2504 }));
2505 let result = annotator.annotate(&struct_expr);
2506 assert!(matches!(result, Some(DataType::Struct { fields, .. }) if fields.len() == 2));
2507 }
2508
2509 #[test]
2510 fn test_map_type() {
2511 let mut annotator = TypeAnnotator::new(None, None);
2512
2513 let map_expr = Expression::Map(Box::new(crate::expressions::Map {
2515 keys: vec![make_string_literal("a"), make_string_literal("b")],
2516 values: vec![make_int_literal(1), make_int_literal(2)],
2517 }));
2518 let result = annotator.annotate(&map_expr);
2519 assert!(matches!(
2520 result,
2521 Some(DataType::Map { key_type, value_type })
2522 if matches!(*key_type, DataType::VarChar { .. })
2523 && matches!(*value_type, DataType::Int { .. })
2524 ));
2525 }
2526
2527 #[test]
2528 fn test_explode_array_type() {
2529 let mut annotator = TypeAnnotator::new(None, None);
2530
2531 let arr = Expression::Array(Box::new(crate::expressions::Array {
2533 expressions: vec![make_int_literal(1), make_int_literal(2)],
2534 }));
2535 let explode = Expression::Explode(Box::new(crate::expressions::UnaryFunc {
2536 this: arr,
2537 original_name: None,
2538 inferred_type: None,
2539 }));
2540 assert_eq!(
2541 annotator.annotate(&explode),
2542 Some(DataType::Int {
2543 length: None,
2544 integer_spelling: false
2545 })
2546 );
2547 }
2548
2549 #[test]
2550 fn test_unnest_array_type() {
2551 let mut annotator = TypeAnnotator::new(None, None);
2552
2553 let arr = Expression::Array(Box::new(crate::expressions::Array {
2555 expressions: vec![make_string_literal("a"), make_string_literal("b")],
2556 }));
2557 let unnest = Expression::Unnest(Box::new(crate::expressions::UnnestFunc {
2558 this: arr,
2559 expressions: Vec::new(),
2560 with_ordinality: false,
2561 alias: None,
2562 offset_alias: None,
2563 inferred_type: None,
2564 }));
2565 assert_eq!(
2566 annotator.annotate(&unnest),
2567 Some(DataType::VarChar {
2568 length: None,
2569 parenthesized_length: false
2570 })
2571 );
2572 }
2573
2574 #[test]
2575 fn test_set_operation_type() {
2576 let mut annotator = TypeAnnotator::new(None, None);
2577
2578 let select = Expression::Select(Box::new(crate::expressions::Select::default()));
2580 let union = Expression::Union(Box::new(crate::expressions::Union {
2581 left: select.clone(),
2582 right: select.clone(),
2583 all: false,
2584 distinct: false,
2585 with: None,
2586 order_by: None,
2587 limit: None,
2588 offset: None,
2589 by_name: false,
2590 side: None,
2591 kind: None,
2592 corresponding: false,
2593 strict: false,
2594 on_columns: Vec::new(),
2595 distribute_by: None,
2596 sort_by: None,
2597 cluster_by: None,
2598 }));
2599 assert_eq!(annotator.annotate(&union), None);
2600 }
2601
2602 #[test]
2603 fn test_floor_ceil_input_dependent_types() {
2604 use crate::expressions::{CeilFunc, FloorFunc};
2605
2606 let mut annotator = TypeAnnotator::new(None, None);
2607
2608 let floor_int = Expression::Floor(Box::new(FloorFunc {
2610 this: make_int_literal(42),
2611 scale: None,
2612 to: None,
2613 }));
2614 assert_eq!(
2615 annotator.annotate(&floor_int),
2616 Some(DataType::Double {
2617 precision: None,
2618 scale: None,
2619 })
2620 );
2621
2622 let ceil_int = Expression::Ceil(Box::new(CeilFunc {
2623 this: make_int_literal(42),
2624 decimals: None,
2625 to: None,
2626 }));
2627 assert_eq!(
2628 annotator.annotate(&ceil_int),
2629 Some(DataType::Double {
2630 precision: None,
2631 scale: None,
2632 })
2633 );
2634
2635 let floor_float = Expression::Floor(Box::new(FloorFunc {
2637 this: make_float_literal(3.14),
2638 scale: None,
2639 to: None,
2640 }));
2641 assert_eq!(
2642 annotator.annotate(&floor_float),
2643 Some(DataType::Double {
2644 precision: None,
2645 scale: None,
2646 })
2647 );
2648
2649 let floor_fn =
2651 Expression::Function(Box::new(Function::new("FLOOR", vec![make_int_literal(1)])));
2652 assert_eq!(
2653 annotator.annotate(&floor_fn),
2654 Some(DataType::Int {
2655 length: None,
2656 integer_spelling: false,
2657 })
2658 );
2659 }
2660
2661 #[test]
2662 fn test_sign_preserves_input_type() {
2663 use crate::expressions::UnaryFunc;
2664
2665 let mut annotator = TypeAnnotator::new(None, None);
2666
2667 let sign_int = Expression::Sign(Box::new(UnaryFunc {
2669 this: make_int_literal(42),
2670 original_name: None,
2671 inferred_type: None,
2672 }));
2673 assert_eq!(
2674 annotator.annotate(&sign_int),
2675 Some(DataType::Int {
2676 length: None,
2677 integer_spelling: false,
2678 })
2679 );
2680
2681 let sign_float = Expression::Sign(Box::new(UnaryFunc {
2683 this: make_float_literal(3.14),
2684 original_name: None,
2685 inferred_type: None,
2686 }));
2687 assert_eq!(
2688 annotator.annotate(&sign_float),
2689 Some(DataType::Double {
2690 precision: None,
2691 scale: None,
2692 })
2693 );
2694
2695 let sign_cast = Expression::Sign(Box::new(UnaryFunc {
2697 this: Expression::Cast(Box::new(Cast {
2698 this: make_int_literal(42),
2699 to: DataType::Int {
2700 length: None,
2701 integer_spelling: false,
2702 },
2703 format: None,
2704 trailing_comments: Vec::new(),
2705 double_colon_syntax: false,
2706 default: None,
2707 inferred_type: None,
2708 })),
2709 original_name: None,
2710 inferred_type: None,
2711 }));
2712 assert_eq!(
2713 annotator.annotate(&sign_cast),
2714 Some(DataType::Int {
2715 length: None,
2716 integer_spelling: false,
2717 })
2718 );
2719 }
2720
2721 #[test]
2722 fn test_date_format_types() {
2723 use crate::expressions::{DateFormatFunc, TimeToStr};
2724
2725 let mut annotator = TypeAnnotator::new(None, None);
2726
2727 let date_fmt = Expression::DateFormat(Box::new(DateFormatFunc {
2729 this: make_string_literal("2024-01-01"),
2730 format: make_string_literal("%Y-%m-%d"),
2731 }));
2732 assert_eq!(
2733 annotator.annotate(&date_fmt),
2734 Some(DataType::VarChar {
2735 length: None,
2736 parenthesized_length: false,
2737 })
2738 );
2739
2740 let format_date = Expression::FormatDate(Box::new(DateFormatFunc {
2742 this: make_string_literal("2024-01-01"),
2743 format: make_string_literal("%Y-%m-%d"),
2744 }));
2745 assert_eq!(
2746 annotator.annotate(&format_date),
2747 Some(DataType::VarChar {
2748 length: None,
2749 parenthesized_length: false,
2750 })
2751 );
2752
2753 let time_to_str = Expression::TimeToStr(Box::new(TimeToStr {
2755 this: Box::new(make_string_literal("2024-01-01")),
2756 format: "%Y-%m-%d".to_string(),
2757 culture: None,
2758 zone: None,
2759 }));
2760 assert_eq!(
2761 annotator.annotate(&time_to_str),
2762 Some(DataType::VarChar {
2763 length: None,
2764 parenthesized_length: false,
2765 })
2766 );
2767
2768 let date_fmt_fn = Expression::Function(Box::new(Function::new(
2770 "DATE_FORMAT",
2771 vec![
2772 make_string_literal("2024-01-01"),
2773 make_string_literal("%Y-%m-%d"),
2774 ],
2775 )));
2776 assert_eq!(
2777 annotator.annotate(&date_fmt_fn),
2778 Some(DataType::VarChar {
2779 length: None,
2780 parenthesized_length: false,
2781 })
2782 );
2783 }
2784
2785 #[test]
2788 fn test_annotate_in_place_sets_type_on_root() {
2789 let mut expr = Expression::Add(Box::new(BinaryOp::new(
2791 make_int_literal(1),
2792 make_int_literal(2),
2793 )));
2794 annotate_types(&mut expr, None, None);
2795 assert_eq!(
2796 expr.inferred_type(),
2797 Some(&DataType::Int {
2798 length: None,
2799 integer_spelling: false,
2800 })
2801 );
2802 }
2803
2804 #[test]
2805 fn test_annotate_in_place_sets_types_on_children() {
2806 let inner_add = Expression::Add(Box::new(BinaryOp::new(
2809 make_int_literal(1),
2810 make_float_literal(2.5),
2811 )));
2812 let inner_sub = Expression::Sub(Box::new(BinaryOp::new(
2813 make_int_literal(3),
2814 make_int_literal(4),
2815 )));
2816 let mut expr = Expression::Add(Box::new(BinaryOp::new(inner_add, inner_sub)));
2817 annotate_types(&mut expr, None, None);
2818
2819 assert_eq!(
2821 expr.inferred_type(),
2822 Some(&DataType::Double {
2823 precision: None,
2824 scale: None,
2825 })
2826 );
2827
2828 if let Expression::Add(op) = &expr {
2830 assert_eq!(
2832 op.left.inferred_type(),
2833 Some(&DataType::Double {
2834 precision: None,
2835 scale: None,
2836 })
2837 );
2838 assert_eq!(
2840 op.right.inferred_type(),
2841 Some(&DataType::Int {
2842 length: None,
2843 integer_spelling: false,
2844 })
2845 );
2846 } else {
2847 panic!("Expected Add expression");
2848 }
2849 }
2850
2851 #[test]
2852 fn test_annotate_in_place_comparison() {
2853 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
2854 make_int_literal(1),
2855 make_int_literal(2),
2856 )));
2857 annotate_types(&mut expr, None, None);
2858 assert_eq!(expr.inferred_type(), Some(&DataType::Boolean));
2859 }
2860
2861 #[test]
2862 fn test_annotate_in_place_cast() {
2863 let mut expr = Expression::Cast(Box::new(Cast {
2864 this: make_int_literal(42),
2865 to: DataType::VarChar {
2866 length: None,
2867 parenthesized_length: false,
2868 },
2869 trailing_comments: vec![],
2870 double_colon_syntax: false,
2871 format: None,
2872 default: None,
2873 inferred_type: None,
2874 }));
2875 annotate_types(&mut expr, None, None);
2876 assert_eq!(
2877 expr.inferred_type(),
2878 Some(&DataType::VarChar {
2879 length: None,
2880 parenthesized_length: false,
2881 })
2882 );
2883 }
2884
2885 #[test]
2886 fn test_annotate_in_place_nested_expression() {
2887 let add = Expression::Add(Box::new(BinaryOp::new(
2889 make_int_literal(1),
2890 make_int_literal(2),
2891 )));
2892 let mut expr = Expression::Gt(Box::new(BinaryOp::new(add, make_int_literal(0))));
2893 annotate_types(&mut expr, None, None);
2894
2895 assert_eq!(expr.inferred_type(), Some(&DataType::Boolean));
2896
2897 if let Expression::Gt(op) = &expr {
2899 assert_eq!(
2900 op.left.inferred_type(),
2901 Some(&DataType::Int {
2902 length: None,
2903 integer_spelling: false,
2904 })
2905 );
2906 }
2907 }
2908
2909 #[test]
2910 fn test_annotate_in_place_parsed_sql() {
2911 use crate::parser::Parser;
2912 let mut expr =
2913 Parser::parse_sql("SELECT 1 + 2.0, 'hello', TRUE").expect("parse failed")[0].clone();
2914 annotate_types(&mut expr, None, None);
2915
2916 assert!(expr.inferred_type().is_none());
2920 }
2921
2922 #[test]
2923 fn test_inferred_type_json_roundtrip() {
2924 let mut expr = Expression::Add(Box::new(BinaryOp::new(
2925 make_int_literal(1),
2926 make_int_literal(2),
2927 )));
2928 annotate_types(&mut expr, None, None);
2929
2930 let json = serde_json::to_string(&expr).expect("serialize failed");
2932 assert!(json.contains("inferred_type"));
2934
2935 let deserialized: Expression = serde_json::from_str(&json).expect("deserialize failed");
2937 assert_eq!(
2938 deserialized.inferred_type(),
2939 Some(&DataType::Int {
2940 length: None,
2941 integer_spelling: false,
2942 })
2943 );
2944 }
2945
2946 #[test]
2947 fn test_inferred_type_none_not_serialized() {
2948 let expr = Expression::Add(Box::new(BinaryOp::new(
2950 make_int_literal(1),
2951 make_int_literal(2),
2952 )));
2953 let json = serde_json::to_string(&expr).expect("serialize failed");
2954 assert!(!json.contains("inferred_type"));
2955 }
2956
2957 #[test]
2958 fn test_annotate_if_func_bigquery_node_and_alias_type() {
2959 let mut schema = MappingSchema::with_dialect(DialectType::BigQuery);
2960 schema
2961 .add_table(
2962 "t",
2963 &[("col1".to_string(), DataType::String { length: None })],
2964 None,
2965 )
2966 .unwrap();
2967
2968 let mut expr = parse_one(
2969 "SELECT IF(col1 IS NOT NULL, 1, 0) AS x FROM t",
2970 DialectType::BigQuery,
2971 )
2972 .unwrap();
2973 annotate_types(&mut expr, Some(&schema), Some(DialectType::BigQuery));
2974
2975 let Expression::Select(select) = &expr else {
2976 panic!("expected select");
2977 };
2978 let Expression::Alias(alias) = &select.expressions[0] else {
2979 panic!("expected alias");
2980 };
2981
2982 assert_eq!(
2983 alias.this.inferred_type(),
2984 Some(&DataType::Int {
2985 length: None,
2986 integer_spelling: false,
2987 })
2988 );
2989 assert_eq!(
2990 select.expressions[0].inferred_type(),
2991 Some(&DataType::Int {
2992 length: None,
2993 integer_spelling: false,
2994 })
2995 );
2996 }
2997
2998 #[test]
2999 fn test_annotate_nvl2_node_type() {
3000 let mut expr = parse_one("SELECT NVL2(a, 1, 0) AS x", DialectType::Generic).unwrap();
3001 annotate_types(&mut expr, None, None);
3002
3003 let Expression::Select(select) = &expr else {
3004 panic!("expected select");
3005 };
3006 let Expression::Alias(alias) = &select.expressions[0] else {
3007 panic!("expected alias");
3008 };
3009
3010 assert_eq!(
3011 alias.this.inferred_type(),
3012 Some(&DataType::Int {
3013 length: None,
3014 integer_spelling: false,
3015 })
3016 );
3017 }
3018
3019 #[test]
3020 fn test_annotate_count_node_type() {
3021 let mut expr = parse_one("SELECT COUNT(1) AS x", DialectType::Generic).unwrap();
3022 annotate_types(&mut expr, None, None);
3023
3024 let Expression::Select(select) = &expr else {
3025 panic!("expected select");
3026 };
3027 let Expression::Alias(alias) = &select.expressions[0] else {
3028 panic!("expected alias");
3029 };
3030
3031 assert_eq!(
3032 alias.this.inferred_type(),
3033 Some(&DataType::BigInt { length: None })
3034 );
3035 }
3036
3037 #[test]
3038 fn test_annotate_group_concat_node_type() {
3039 let mut expr = parse_one("SELECT GROUP_CONCAT(a) AS x", DialectType::Generic).unwrap();
3040 annotate_types(&mut expr, None, None);
3041
3042 let Expression::Select(select) = &expr else {
3043 panic!("expected select");
3044 };
3045 let Expression::Alias(alias) = &select.expressions[0] else {
3046 panic!("expected alias");
3047 };
3048
3049 assert_eq!(
3050 alias.this.inferred_type(),
3051 Some(&DataType::VarChar {
3052 length: None,
3053 parenthesized_length: false,
3054 })
3055 );
3056 }
3057
3058 #[test]
3059 fn test_annotate_sum_if_generic_aggregate_type() {
3060 let mut expr =
3061 parse_one("SELECT SUM_IF(1, a > 0) AS x FROM t", DialectType::Generic).unwrap();
3062 annotate_types(&mut expr, None, None);
3063
3064 let Expression::Select(select) = &expr else {
3065 panic!("expected select");
3066 };
3067 let Expression::Alias(alias) = &select.expressions[0] else {
3068 panic!("expected alias");
3069 };
3070
3071 assert_eq!(
3072 select.expressions[0].inferred_type(),
3073 Some(&DataType::BigInt { length: None })
3074 );
3075 assert_eq!(
3076 alias.this.inferred_type(),
3077 Some(&DataType::BigInt { length: None })
3078 );
3079 }
3080}