Edit on GitHub

sqlglot.optimizer.annotate_types

  1from __future__ import annotations
  2
  3import functools
  4import typing as t
  5
  6from sqlglot import exp
  7from sqlglot.helper import (
  8    ensure_list,
  9    is_date_unit,
 10    is_iso_date,
 11    is_iso_datetime,
 12    seq_get,
 13    subclasses,
 14)
 15from sqlglot.optimizer.scope import Scope, traverse_scope
 16from sqlglot.schema import Schema, ensure_schema
 17
 18if t.TYPE_CHECKING:
 19    from sqlglot._typing import B, E
 20
 21    BinaryCoercionFunc = t.Callable[[exp.Expression, exp.Expression], exp.DataType.Type]
 22    BinaryCoercions = t.Dict[
 23        t.Tuple[exp.DataType.Type, exp.DataType.Type],
 24        BinaryCoercionFunc,
 25    ]
 26
 27
 28def annotate_types(
 29    expression: E,
 30    schema: t.Optional[t.Dict | Schema] = None,
 31    annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
 32    coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
 33) -> E:
 34    """
 35    Infers the types of an expression, annotating its AST accordingly.
 36
 37    Example:
 38        >>> import sqlglot
 39        >>> schema = {"y": {"cola": "SMALLINT"}}
 40        >>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x"
 41        >>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema)
 42        >>> annotated_expr.expressions[0].type.this  # Get the type of "x.cola + 2.5 AS cola"
 43        <Type.DOUBLE: 'DOUBLE'>
 44
 45    Args:
 46        expression: Expression to annotate.
 47        schema: Database schema.
 48        annotators: Maps expression type to corresponding annotation function.
 49        coerces_to: Maps expression type to set of types that it can be coerced into.
 50
 51    Returns:
 52        The expression annotated with types.
 53    """
 54
 55    schema = ensure_schema(schema)
 56
 57    return TypeAnnotator(schema, annotators, coerces_to).annotate(expression)
 58
 59
 60def _annotate_with_type_lambda(data_type: exp.DataType.Type) -> t.Callable[[TypeAnnotator, E], E]:
 61    return lambda self, e: self._annotate_with_type(e, data_type)
 62
 63
 64def _coerce_date_literal(l: exp.Expression, unit: t.Optional[exp.Expression]) -> exp.DataType.Type:
 65    date_text = l.name
 66    is_iso_date_ = is_iso_date(date_text)
 67
 68    if is_iso_date_ and is_date_unit(unit):
 69        return exp.DataType.Type.DATE
 70
 71    # An ISO date is also an ISO datetime, but not vice versa
 72    if is_iso_date_ or is_iso_datetime(date_text):
 73        return exp.DataType.Type.DATETIME
 74
 75    return exp.DataType.Type.UNKNOWN
 76
 77
 78def _coerce_date(l: exp.Expression, unit: t.Optional[exp.Expression]) -> exp.DataType.Type:
 79    if not is_date_unit(unit):
 80        return exp.DataType.Type.DATETIME
 81    return l.type.this if l.type else exp.DataType.Type.UNKNOWN
 82
 83
 84def swap_args(func: BinaryCoercionFunc) -> BinaryCoercionFunc:
 85    @functools.wraps(func)
 86    def _swapped(l: exp.Expression, r: exp.Expression) -> exp.DataType.Type:
 87        return func(r, l)
 88
 89    return _swapped
 90
 91
 92def swap_all(coercions: BinaryCoercions) -> BinaryCoercions:
 93    return {**coercions, **{(b, a): swap_args(func) for (a, b), func in coercions.items()}}
 94
 95
 96class _TypeAnnotator(type):
 97    def __new__(cls, clsname, bases, attrs):
 98        klass = super().__new__(cls, clsname, bases, attrs)
 99
100        # Highest-to-lowest type precedence, as specified in Spark's docs (ANSI):
101        # https://spark.apache.org/docs/3.2.0/sql-ref-ansi-compliance.html
102        text_precedence = (
103            exp.DataType.Type.TEXT,
104            exp.DataType.Type.NVARCHAR,
105            exp.DataType.Type.VARCHAR,
106            exp.DataType.Type.NCHAR,
107            exp.DataType.Type.CHAR,
108        )
109        numeric_precedence = (
110            exp.DataType.Type.DOUBLE,
111            exp.DataType.Type.FLOAT,
112            exp.DataType.Type.DECIMAL,
113            exp.DataType.Type.BIGINT,
114            exp.DataType.Type.INT,
115            exp.DataType.Type.SMALLINT,
116            exp.DataType.Type.TINYINT,
117        )
118        timelike_precedence = (
119            exp.DataType.Type.TIMESTAMPLTZ,
120            exp.DataType.Type.TIMESTAMPTZ,
121            exp.DataType.Type.TIMESTAMP,
122            exp.DataType.Type.DATETIME,
123            exp.DataType.Type.DATE,
124        )
125
126        for type_precedence in (text_precedence, numeric_precedence, timelike_precedence):
127            coerces_to = set()
128            for data_type in type_precedence:
129                klass.COERCES_TO[data_type] = coerces_to.copy()
130                coerces_to |= {data_type}
131
132        return klass
133
134
135class TypeAnnotator(metaclass=_TypeAnnotator):
136    TYPE_TO_EXPRESSIONS: t.Dict[exp.DataType.Type, t.Set[t.Type[exp.Expression]]] = {
137        exp.DataType.Type.BIGINT: {
138            exp.ApproxDistinct,
139            exp.ArraySize,
140            exp.Count,
141            exp.Length,
142        },
143        exp.DataType.Type.BOOLEAN: {
144            exp.Between,
145            exp.Boolean,
146            exp.In,
147            exp.RegexpLike,
148        },
149        exp.DataType.Type.DATE: {
150            exp.CurrentDate,
151            exp.Date,
152            exp.DateFromParts,
153            exp.DateStrToDate,
154            exp.DiToDate,
155            exp.StrToDate,
156            exp.TimeStrToDate,
157            exp.TsOrDsToDate,
158        },
159        exp.DataType.Type.DATETIME: {
160            exp.CurrentDatetime,
161            exp.Datetime,
162            exp.DatetimeAdd,
163            exp.DatetimeSub,
164        },
165        exp.DataType.Type.DOUBLE: {
166            exp.ApproxQuantile,
167            exp.Avg,
168            exp.Div,
169            exp.Exp,
170            exp.Ln,
171            exp.Log,
172            exp.Pow,
173            exp.Quantile,
174            exp.Round,
175            exp.SafeDivide,
176            exp.Sqrt,
177            exp.Stddev,
178            exp.StddevPop,
179            exp.StddevSamp,
180            exp.Variance,
181            exp.VariancePop,
182        },
183        exp.DataType.Type.INT: {
184            exp.Ceil,
185            exp.DatetimeDiff,
186            exp.DateDiff,
187            exp.Extract,
188            exp.TimestampDiff,
189            exp.TimeDiff,
190            exp.DateToDi,
191            exp.Floor,
192            exp.Levenshtein,
193            exp.Sign,
194            exp.StrPosition,
195            exp.TsOrDiToDi,
196        },
197        exp.DataType.Type.JSON: {
198            exp.ParseJSON,
199        },
200        exp.DataType.Type.TIME: {
201            exp.Time,
202        },
203        exp.DataType.Type.TIMESTAMP: {
204            exp.CurrentTime,
205            exp.CurrentTimestamp,
206            exp.StrToTime,
207            exp.TimeAdd,
208            exp.TimeStrToTime,
209            exp.TimeSub,
210            exp.TimestampAdd,
211            exp.TimestampSub,
212            exp.UnixToTime,
213        },
214        exp.DataType.Type.TINYINT: {
215            exp.Day,
216            exp.Month,
217            exp.Week,
218            exp.Year,
219            exp.Quarter,
220        },
221        exp.DataType.Type.VARCHAR: {
222            exp.ArrayConcat,
223            exp.Concat,
224            exp.ConcatWs,
225            exp.DateToDateStr,
226            exp.GroupConcat,
227            exp.Initcap,
228            exp.Lower,
229            exp.Substring,
230            exp.TimeToStr,
231            exp.TimeToTimeStr,
232            exp.Trim,
233            exp.TsOrDsToDateStr,
234            exp.UnixToStr,
235            exp.UnixToTimeStr,
236            exp.Upper,
237        },
238    }
239
240    ANNOTATORS: t.Dict = {
241        **{
242            expr_type: lambda self, e: self._annotate_unary(e)
243            for expr_type in subclasses(exp.__name__, (exp.Unary, exp.Alias))
244        },
245        **{
246            expr_type: lambda self, e: self._annotate_binary(e)
247            for expr_type in subclasses(exp.__name__, exp.Binary)
248        },
249        **{
250            expr_type: _annotate_with_type_lambda(data_type)
251            for data_type, expressions in TYPE_TO_EXPRESSIONS.items()
252            for expr_type in expressions
253        },
254        exp.Abs: lambda self, e: self._annotate_by_args(e, "this"),
255        exp.Anonymous: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN),
256        exp.Array: lambda self, e: self._annotate_by_args(e, "expressions", array=True),
257        exp.ArrayAgg: lambda self, e: self._annotate_by_args(e, "this", array=True),
258        exp.ArrayConcat: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
259        exp.Bracket: lambda self, e: self._annotate_bracket(e),
260        exp.Cast: lambda self, e: self._annotate_with_type(e, e.args["to"]),
261        exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"),
262        exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
263        exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()),
264        exp.DateAdd: lambda self, e: self._annotate_timeunit(e),
265        exp.DateSub: lambda self, e: self._annotate_timeunit(e),
266        exp.DateTrunc: lambda self, e: self._annotate_timeunit(e),
267        exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"),
268        exp.Div: lambda self, e: self._annotate_div(e),
269        exp.Dot: lambda self, e: self._annotate_dot(e),
270        exp.Explode: lambda self, e: self._annotate_explode(e),
271        exp.Filter: lambda self, e: self._annotate_by_args(e, "this"),
272        exp.GenerateDateArray: lambda self, e: self._annotate_with_type(
273            e, exp.DataType.build("ARRAY<DATE>")
274        ),
275        exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"),
276        exp.Interval: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.INTERVAL),
277        exp.Least: lambda self, e: self._annotate_by_args(e, "expressions"),
278        exp.Literal: lambda self, e: self._annotate_literal(e),
279        exp.Map: lambda self, e: self._annotate_map(e),
280        exp.Max: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
281        exp.Min: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
282        exp.Null: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.NULL),
283        exp.Nullif: lambda self, e: self._annotate_by_args(e, "this", "expression"),
284        exp.PropertyEQ: lambda self, e: self._annotate_by_args(e, "expression"),
285        exp.Slice: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN),
286        exp.Struct: lambda self, e: self._annotate_struct(e),
287        exp.Sum: lambda self, e: self._annotate_by_args(e, "this", "expressions", promote=True),
288        exp.Timestamp: lambda self, e: self._annotate_with_type(
289            e,
290            exp.DataType.Type.TIMESTAMPTZ if e.args.get("with_tz") else exp.DataType.Type.TIMESTAMP,
291        ),
292        exp.ToMap: lambda self, e: self._annotate_to_map(e),
293        exp.TryCast: lambda self, e: self._annotate_with_type(e, e.args["to"]),
294        exp.Unnest: lambda self, e: self._annotate_unnest(e),
295        exp.VarMap: lambda self, e: self._annotate_map(e),
296    }
297
298    NESTED_TYPES = {
299        exp.DataType.Type.ARRAY,
300    }
301
302    # Specifies what types a given type can be coerced into (autofilled)
303    COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {}
304
305    # Coercion functions for binary operations.
306    # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type.
307    BINARY_COERCIONS: BinaryCoercions = {
308        **swap_all(
309            {
310                (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal(
311                    l, r.args.get("unit")
312                )
313                for t in exp.DataType.TEXT_TYPES
314            }
315        ),
316        **swap_all(
317            {
318                # text + numeric will yield the numeric type to match most dialects' semantics
319                (text, numeric): lambda l, r: t.cast(
320                    exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type
321                )
322                for text in exp.DataType.TEXT_TYPES
323                for numeric in exp.DataType.NUMERIC_TYPES
324            }
325        ),
326        **swap_all(
327            {
328                (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date(
329                    l, r.args.get("unit")
330                ),
331            }
332        ),
333    }
334
335    def __init__(
336        self,
337        schema: Schema,
338        annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
339        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
340        binary_coercions: t.Optional[BinaryCoercions] = None,
341    ) -> None:
342        self.schema = schema
343        self.annotators = annotators or self.ANNOTATORS
344        self.coerces_to = coerces_to or self.COERCES_TO
345        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
346
347        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
348        self._visited: t.Set[int] = set()
349
350    def _set_type(
351        self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type]
352    ) -> None:
353        expression.type = target_type or exp.DataType.Type.UNKNOWN  # type: ignore
354        self._visited.add(id(expression))
355
356    def annotate(self, expression: E) -> E:
357        for scope in traverse_scope(expression):
358            self.annotate_scope(scope)
359        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions
360
361    def annotate_scope(self, scope: Scope) -> None:
362        selects = {}
363        for name, source in scope.sources.items():
364            if not isinstance(source, Scope):
365                continue
366            if isinstance(source.expression, exp.UDTF):
367                values = []
368
369                if isinstance(source.expression, exp.Lateral):
370                    if isinstance(source.expression.this, exp.Explode):
371                        values = [source.expression.this.this]
372                elif isinstance(source.expression, exp.Unnest):
373                    values = [source.expression]
374                else:
375                    values = source.expression.expressions[0].expressions
376
377                if not values:
378                    continue
379
380                selects[name] = {
381                    alias: column
382                    for alias, column in zip(
383                        source.expression.alias_column_names,
384                        values,
385                    )
386                }
387            else:
388                selects[name] = {
389                    select.alias_or_name: select for select in source.expression.selects
390                }
391
392        # First annotate the current scope's column references
393        for col in scope.columns:
394            if not col.table:
395                continue
396
397            source = scope.sources.get(col.table)
398            if isinstance(source, exp.Table):
399                self._set_type(col, self.schema.get_column_type(source, col))
400            elif source:
401                if col.table in selects and col.name in selects[col.table]:
402                    self._set_type(col, selects[col.table][col.name].type)
403                elif isinstance(source.expression, exp.Unnest):
404                    self._set_type(col, source.expression.type)
405
406        # Then (possibly) annotate the remaining expressions in the scope
407        self._maybe_annotate(scope.expression)
408
409    def _maybe_annotate(self, expression: E) -> E:
410        if id(expression) in self._visited:
411            return expression  # We've already inferred the expression's type
412
413        annotator = self.annotators.get(expression.__class__)
414
415        return (
416            annotator(self, expression)
417            if annotator
418            else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN)
419        )
420
421    def _annotate_args(self, expression: E) -> E:
422        for value in expression.iter_expressions():
423            self._maybe_annotate(value)
424
425        return expression
426
427    def _maybe_coerce(
428        self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type
429    ) -> exp.DataType | exp.DataType.Type:
430        type1_value = type1.this if isinstance(type1, exp.DataType) else type1
431        type2_value = type2.this if isinstance(type2, exp.DataType) else type2
432
433        # We propagate the NULL / UNKNOWN types upwards if found
434        if exp.DataType.Type.NULL in (type1_value, type2_value):
435            return exp.DataType.Type.NULL
436        if exp.DataType.Type.UNKNOWN in (type1_value, type2_value):
437            return exp.DataType.Type.UNKNOWN
438
439        return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value
440
441    def _annotate_binary(self, expression: B) -> B:
442        self._annotate_args(expression)
443
444        left, right = expression.left, expression.right
445        left_type, right_type = left.type.this, right.type.this  # type: ignore
446
447        if isinstance(expression, exp.Connector):
448            if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL:
449                self._set_type(expression, exp.DataType.Type.NULL)
450            elif exp.DataType.Type.NULL in (left_type, right_type):
451                self._set_type(
452                    expression,
453                    exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")),
454                )
455            else:
456                self._set_type(expression, exp.DataType.Type.BOOLEAN)
457        elif isinstance(expression, exp.Predicate):
458            self._set_type(expression, exp.DataType.Type.BOOLEAN)
459        elif (left_type, right_type) in self.binary_coercions:
460            self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right))
461        else:
462            self._set_type(expression, self._maybe_coerce(left_type, right_type))
463
464        return expression
465
466    def _annotate_unary(self, expression: E) -> E:
467        self._annotate_args(expression)
468
469        if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren):
470            self._set_type(expression, exp.DataType.Type.BOOLEAN)
471        else:
472            self._set_type(expression, expression.this.type)
473
474        return expression
475
476    def _annotate_literal(self, expression: exp.Literal) -> exp.Literal:
477        if expression.is_string:
478            self._set_type(expression, exp.DataType.Type.VARCHAR)
479        elif expression.is_int:
480            self._set_type(expression, exp.DataType.Type.INT)
481        else:
482            self._set_type(expression, exp.DataType.Type.DOUBLE)
483
484        return expression
485
486    def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E:
487        self._set_type(expression, target_type)
488        return self._annotate_args(expression)
489
490    @t.no_type_check
491    def _annotate_by_args(
492        self,
493        expression: E,
494        *args: str,
495        promote: bool = False,
496        array: bool = False,
497    ) -> E:
498        self._annotate_args(expression)
499
500        expressions: t.List[exp.Expression] = []
501        for arg in args:
502            arg_expr = expression.args.get(arg)
503            expressions.extend(expr for expr in ensure_list(arg_expr) if expr)
504
505        last_datatype = None
506        for expr in expressions:
507            expr_type = expr.type
508
509            # Stop at the first nested data type found - we don't want to _maybe_coerce nested types
510            if expr_type.args.get("nested"):
511                last_datatype = expr_type
512                break
513
514            if not expr_type.is_type(exp.DataType.Type.NULL, exp.DataType.Type.UNKNOWN):
515                last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type)
516
517        self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN)
518
519        if promote:
520            if expression.type.this in exp.DataType.INTEGER_TYPES:
521                self._set_type(expression, exp.DataType.Type.BIGINT)
522            elif expression.type.this in exp.DataType.FLOAT_TYPES:
523                self._set_type(expression, exp.DataType.Type.DOUBLE)
524
525        if array:
526            self._set_type(
527                expression,
528                exp.DataType(
529                    this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True
530                ),
531            )
532
533        return expression
534
535    def _annotate_timeunit(
536        self, expression: exp.TimeUnit | exp.DateTrunc
537    ) -> exp.TimeUnit | exp.DateTrunc:
538        self._annotate_args(expression)
539
540        if expression.this.type.this in exp.DataType.TEXT_TYPES:
541            datatype = _coerce_date_literal(expression.this, expression.unit)
542        elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES:
543            datatype = _coerce_date(expression.this, expression.unit)
544        else:
545            datatype = exp.DataType.Type.UNKNOWN
546
547        self._set_type(expression, datatype)
548        return expression
549
550    def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket:
551        self._annotate_args(expression)
552
553        bracket_arg = expression.expressions[0]
554        this = expression.this
555
556        if isinstance(bracket_arg, exp.Slice):
557            self._set_type(expression, this.type)
558        elif this.type.is_type(exp.DataType.Type.ARRAY):
559            self._set_type(expression, seq_get(this.type.expressions, 0))
560        elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys:
561            index = this.keys.index(bracket_arg)
562            value = seq_get(this.values, index)
563            self._set_type(expression, value.type if value else None)
564        else:
565            self._set_type(expression, exp.DataType.Type.UNKNOWN)
566
567        return expression
568
569    def _annotate_div(self, expression: exp.Div) -> exp.Div:
570        self._annotate_args(expression)
571
572        left_type, right_type = expression.left.type.this, expression.right.type.this  # type: ignore
573
574        if (
575            expression.args.get("typed")
576            and left_type in exp.DataType.INTEGER_TYPES
577            and right_type in exp.DataType.INTEGER_TYPES
578        ):
579            self._set_type(expression, exp.DataType.Type.BIGINT)
580        else:
581            self._set_type(expression, self._maybe_coerce(left_type, right_type))
582            if expression.type and expression.type.this not in exp.DataType.REAL_TYPES:
583                self._set_type(
584                    expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE)
585                )
586
587        return expression
588
589    def _annotate_dot(self, expression: exp.Dot) -> exp.Dot:
590        self._annotate_args(expression)
591        self._set_type(expression, None)
592        this_type = expression.this.type
593
594        if this_type and this_type.is_type(exp.DataType.Type.STRUCT):
595            for e in this_type.expressions:
596                if e.name == expression.expression.name:
597                    self._set_type(expression, e.kind)
598                    break
599
600        return expression
601
602    def _annotate_explode(self, expression: exp.Explode) -> exp.Explode:
603        self._annotate_args(expression)
604        self._set_type(expression, seq_get(expression.this.type.expressions, 0))
605        return expression
606
607    def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest:
608        self._annotate_args(expression)
609        child = seq_get(expression.expressions, 0)
610
611        if child and child.is_type(exp.DataType.Type.ARRAY):
612            expr_type = seq_get(child.type.expressions, 0)
613        else:
614            expr_type = None
615
616        self._set_type(expression, expr_type)
617        return expression
618
619    def _annotate_struct_value(
620        self, expression: exp.Expression
621    ) -> t.Optional[exp.DataType] | exp.ColumnDef:
622        alias = expression.args.get("alias")
623        if alias:
624            return exp.ColumnDef(this=alias.copy(), kind=expression.type)
625
626        # Case: key = value or key := value
627        if expression.expression:
628            return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type)
629
630        return expression.type
631
632    def _annotate_struct(self, expression: exp.Struct) -> exp.Struct:
633        self._annotate_args(expression)
634        self._set_type(
635            expression,
636            exp.DataType(
637                this=exp.DataType.Type.STRUCT,
638                expressions=[self._annotate_struct_value(expr) for expr in expression.expressions],
639                nested=True,
640            ),
641        )
642        return expression
643
644    @t.overload
645    def _annotate_map(self, expression: exp.Map) -> exp.Map: ...
646
647    @t.overload
648    def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ...
649
650    def _annotate_map(self, expression):
651        self._annotate_args(expression)
652
653        keys = expression.args.get("keys")
654        values = expression.args.get("values")
655
656        map_type = exp.DataType(this=exp.DataType.Type.MAP)
657        if isinstance(keys, exp.Array) and isinstance(values, exp.Array):
658            key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN
659            value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN
660
661            if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN:
662                map_type.set("expressions", [key_type, value_type])
663                map_type.set("nested", True)
664
665        self._set_type(expression, map_type)
666        return expression
667
668    def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap:
669        self._annotate_args(expression)
670
671        map_type = exp.DataType(this=exp.DataType.Type.MAP)
672        arg = expression.this
673        if arg.is_type(exp.DataType.Type.STRUCT):
674            for coldef in arg.type.expressions:
675                kind = coldef.kind
676                if kind != exp.DataType.Type.UNKNOWN:
677                    map_type.set("expressions", [exp.DataType.build("varchar"), kind])
678                    map_type.set("nested", True)
679                    break
680
681        self._set_type(expression, map_type)
682        return expression
def annotate_types( expression: ~E, schema: Union[Dict, sqlglot.schema.Schema, NoneType] = None, annotators: Optional[Dict[Type[~E], Callable[[TypeAnnotator, ~E], ~E]]] = None, coerces_to: Optional[Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]]] = None) -> ~E:
29def annotate_types(
30    expression: E,
31    schema: t.Optional[t.Dict | Schema] = None,
32    annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
33    coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
34) -> E:
35    """
36    Infers the types of an expression, annotating its AST accordingly.
37
38    Example:
39        >>> import sqlglot
40        >>> schema = {"y": {"cola": "SMALLINT"}}
41        >>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x"
42        >>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema)
43        >>> annotated_expr.expressions[0].type.this  # Get the type of "x.cola + 2.5 AS cola"
44        <Type.DOUBLE: 'DOUBLE'>
45
46    Args:
47        expression: Expression to annotate.
48        schema: Database schema.
49        annotators: Maps expression type to corresponding annotation function.
50        coerces_to: Maps expression type to set of types that it can be coerced into.
51
52    Returns:
53        The expression annotated with types.
54    """
55
56    schema = ensure_schema(schema)
57
58    return TypeAnnotator(schema, annotators, coerces_to).annotate(expression)

Infers the types of an expression, annotating its AST accordingly.

Example:
>>> import sqlglot
>>> schema = {"y": {"cola": "SMALLINT"}}
>>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x"
>>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema)
>>> annotated_expr.expressions[0].type.this  # Get the type of "x.cola + 2.5 AS cola"
<Type.DOUBLE: 'DOUBLE'>
Arguments:
  • expression: Expression to annotate.
  • schema: Database schema.
  • annotators: Maps expression type to corresponding annotation function.
  • coerces_to: Maps expression type to set of types that it can be coerced into.
Returns:

The expression annotated with types.

85def swap_args(func: BinaryCoercionFunc) -> BinaryCoercionFunc:
86    @functools.wraps(func)
87    def _swapped(l: exp.Expression, r: exp.Expression) -> exp.DataType.Type:
88        return func(r, l)
89
90    return _swapped
93def swap_all(coercions: BinaryCoercions) -> BinaryCoercions:
94    return {**coercions, **{(b, a): swap_args(func) for (a, b), func in coercions.items()}}
class TypeAnnotator:
136class TypeAnnotator(metaclass=_TypeAnnotator):
137    TYPE_TO_EXPRESSIONS: t.Dict[exp.DataType.Type, t.Set[t.Type[exp.Expression]]] = {
138        exp.DataType.Type.BIGINT: {
139            exp.ApproxDistinct,
140            exp.ArraySize,
141            exp.Count,
142            exp.Length,
143        },
144        exp.DataType.Type.BOOLEAN: {
145            exp.Between,
146            exp.Boolean,
147            exp.In,
148            exp.RegexpLike,
149        },
150        exp.DataType.Type.DATE: {
151            exp.CurrentDate,
152            exp.Date,
153            exp.DateFromParts,
154            exp.DateStrToDate,
155            exp.DiToDate,
156            exp.StrToDate,
157            exp.TimeStrToDate,
158            exp.TsOrDsToDate,
159        },
160        exp.DataType.Type.DATETIME: {
161            exp.CurrentDatetime,
162            exp.Datetime,
163            exp.DatetimeAdd,
164            exp.DatetimeSub,
165        },
166        exp.DataType.Type.DOUBLE: {
167            exp.ApproxQuantile,
168            exp.Avg,
169            exp.Div,
170            exp.Exp,
171            exp.Ln,
172            exp.Log,
173            exp.Pow,
174            exp.Quantile,
175            exp.Round,
176            exp.SafeDivide,
177            exp.Sqrt,
178            exp.Stddev,
179            exp.StddevPop,
180            exp.StddevSamp,
181            exp.Variance,
182            exp.VariancePop,
183        },
184        exp.DataType.Type.INT: {
185            exp.Ceil,
186            exp.DatetimeDiff,
187            exp.DateDiff,
188            exp.Extract,
189            exp.TimestampDiff,
190            exp.TimeDiff,
191            exp.DateToDi,
192            exp.Floor,
193            exp.Levenshtein,
194            exp.Sign,
195            exp.StrPosition,
196            exp.TsOrDiToDi,
197        },
198        exp.DataType.Type.JSON: {
199            exp.ParseJSON,
200        },
201        exp.DataType.Type.TIME: {
202            exp.Time,
203        },
204        exp.DataType.Type.TIMESTAMP: {
205            exp.CurrentTime,
206            exp.CurrentTimestamp,
207            exp.StrToTime,
208            exp.TimeAdd,
209            exp.TimeStrToTime,
210            exp.TimeSub,
211            exp.TimestampAdd,
212            exp.TimestampSub,
213            exp.UnixToTime,
214        },
215        exp.DataType.Type.TINYINT: {
216            exp.Day,
217            exp.Month,
218            exp.Week,
219            exp.Year,
220            exp.Quarter,
221        },
222        exp.DataType.Type.VARCHAR: {
223            exp.ArrayConcat,
224            exp.Concat,
225            exp.ConcatWs,
226            exp.DateToDateStr,
227            exp.GroupConcat,
228            exp.Initcap,
229            exp.Lower,
230            exp.Substring,
231            exp.TimeToStr,
232            exp.TimeToTimeStr,
233            exp.Trim,
234            exp.TsOrDsToDateStr,
235            exp.UnixToStr,
236            exp.UnixToTimeStr,
237            exp.Upper,
238        },
239    }
240
241    ANNOTATORS: t.Dict = {
242        **{
243            expr_type: lambda self, e: self._annotate_unary(e)
244            for expr_type in subclasses(exp.__name__, (exp.Unary, exp.Alias))
245        },
246        **{
247            expr_type: lambda self, e: self._annotate_binary(e)
248            for expr_type in subclasses(exp.__name__, exp.Binary)
249        },
250        **{
251            expr_type: _annotate_with_type_lambda(data_type)
252            for data_type, expressions in TYPE_TO_EXPRESSIONS.items()
253            for expr_type in expressions
254        },
255        exp.Abs: lambda self, e: self._annotate_by_args(e, "this"),
256        exp.Anonymous: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN),
257        exp.Array: lambda self, e: self._annotate_by_args(e, "expressions", array=True),
258        exp.ArrayAgg: lambda self, e: self._annotate_by_args(e, "this", array=True),
259        exp.ArrayConcat: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
260        exp.Bracket: lambda self, e: self._annotate_bracket(e),
261        exp.Cast: lambda self, e: self._annotate_with_type(e, e.args["to"]),
262        exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"),
263        exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
264        exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()),
265        exp.DateAdd: lambda self, e: self._annotate_timeunit(e),
266        exp.DateSub: lambda self, e: self._annotate_timeunit(e),
267        exp.DateTrunc: lambda self, e: self._annotate_timeunit(e),
268        exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"),
269        exp.Div: lambda self, e: self._annotate_div(e),
270        exp.Dot: lambda self, e: self._annotate_dot(e),
271        exp.Explode: lambda self, e: self._annotate_explode(e),
272        exp.Filter: lambda self, e: self._annotate_by_args(e, "this"),
273        exp.GenerateDateArray: lambda self, e: self._annotate_with_type(
274            e, exp.DataType.build("ARRAY<DATE>")
275        ),
276        exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"),
277        exp.Interval: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.INTERVAL),
278        exp.Least: lambda self, e: self._annotate_by_args(e, "expressions"),
279        exp.Literal: lambda self, e: self._annotate_literal(e),
280        exp.Map: lambda self, e: self._annotate_map(e),
281        exp.Max: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
282        exp.Min: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
283        exp.Null: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.NULL),
284        exp.Nullif: lambda self, e: self._annotate_by_args(e, "this", "expression"),
285        exp.PropertyEQ: lambda self, e: self._annotate_by_args(e, "expression"),
286        exp.Slice: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN),
287        exp.Struct: lambda self, e: self._annotate_struct(e),
288        exp.Sum: lambda self, e: self._annotate_by_args(e, "this", "expressions", promote=True),
289        exp.Timestamp: lambda self, e: self._annotate_with_type(
290            e,
291            exp.DataType.Type.TIMESTAMPTZ if e.args.get("with_tz") else exp.DataType.Type.TIMESTAMP,
292        ),
293        exp.ToMap: lambda self, e: self._annotate_to_map(e),
294        exp.TryCast: lambda self, e: self._annotate_with_type(e, e.args["to"]),
295        exp.Unnest: lambda self, e: self._annotate_unnest(e),
296        exp.VarMap: lambda self, e: self._annotate_map(e),
297    }
298
299    NESTED_TYPES = {
300        exp.DataType.Type.ARRAY,
301    }
302
303    # Specifies what types a given type can be coerced into (autofilled)
304    COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {}
305
306    # Coercion functions for binary operations.
307    # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type.
308    BINARY_COERCIONS: BinaryCoercions = {
309        **swap_all(
310            {
311                (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal(
312                    l, r.args.get("unit")
313                )
314                for t in exp.DataType.TEXT_TYPES
315            }
316        ),
317        **swap_all(
318            {
319                # text + numeric will yield the numeric type to match most dialects' semantics
320                (text, numeric): lambda l, r: t.cast(
321                    exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type
322                )
323                for text in exp.DataType.TEXT_TYPES
324                for numeric in exp.DataType.NUMERIC_TYPES
325            }
326        ),
327        **swap_all(
328            {
329                (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date(
330                    l, r.args.get("unit")
331                ),
332            }
333        ),
334    }
335
336    def __init__(
337        self,
338        schema: Schema,
339        annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
340        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
341        binary_coercions: t.Optional[BinaryCoercions] = None,
342    ) -> None:
343        self.schema = schema
344        self.annotators = annotators or self.ANNOTATORS
345        self.coerces_to = coerces_to or self.COERCES_TO
346        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
347
348        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
349        self._visited: t.Set[int] = set()
350
351    def _set_type(
352        self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type]
353    ) -> None:
354        expression.type = target_type or exp.DataType.Type.UNKNOWN  # type: ignore
355        self._visited.add(id(expression))
356
357    def annotate(self, expression: E) -> E:
358        for scope in traverse_scope(expression):
359            self.annotate_scope(scope)
360        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions
361
362    def annotate_scope(self, scope: Scope) -> None:
363        selects = {}
364        for name, source in scope.sources.items():
365            if not isinstance(source, Scope):
366                continue
367            if isinstance(source.expression, exp.UDTF):
368                values = []
369
370                if isinstance(source.expression, exp.Lateral):
371                    if isinstance(source.expression.this, exp.Explode):
372                        values = [source.expression.this.this]
373                elif isinstance(source.expression, exp.Unnest):
374                    values = [source.expression]
375                else:
376                    values = source.expression.expressions[0].expressions
377
378                if not values:
379                    continue
380
381                selects[name] = {
382                    alias: column
383                    for alias, column in zip(
384                        source.expression.alias_column_names,
385                        values,
386                    )
387                }
388            else:
389                selects[name] = {
390                    select.alias_or_name: select for select in source.expression.selects
391                }
392
393        # First annotate the current scope's column references
394        for col in scope.columns:
395            if not col.table:
396                continue
397
398            source = scope.sources.get(col.table)
399            if isinstance(source, exp.Table):
400                self._set_type(col, self.schema.get_column_type(source, col))
401            elif source:
402                if col.table in selects and col.name in selects[col.table]:
403                    self._set_type(col, selects[col.table][col.name].type)
404                elif isinstance(source.expression, exp.Unnest):
405                    self._set_type(col, source.expression.type)
406
407        # Then (possibly) annotate the remaining expressions in the scope
408        self._maybe_annotate(scope.expression)
409
410    def _maybe_annotate(self, expression: E) -> E:
411        if id(expression) in self._visited:
412            return expression  # We've already inferred the expression's type
413
414        annotator = self.annotators.get(expression.__class__)
415
416        return (
417            annotator(self, expression)
418            if annotator
419            else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN)
420        )
421
422    def _annotate_args(self, expression: E) -> E:
423        for value in expression.iter_expressions():
424            self._maybe_annotate(value)
425
426        return expression
427
428    def _maybe_coerce(
429        self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type
430    ) -> exp.DataType | exp.DataType.Type:
431        type1_value = type1.this if isinstance(type1, exp.DataType) else type1
432        type2_value = type2.this if isinstance(type2, exp.DataType) else type2
433
434        # We propagate the NULL / UNKNOWN types upwards if found
435        if exp.DataType.Type.NULL in (type1_value, type2_value):
436            return exp.DataType.Type.NULL
437        if exp.DataType.Type.UNKNOWN in (type1_value, type2_value):
438            return exp.DataType.Type.UNKNOWN
439
440        return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value
441
442    def _annotate_binary(self, expression: B) -> B:
443        self._annotate_args(expression)
444
445        left, right = expression.left, expression.right
446        left_type, right_type = left.type.this, right.type.this  # type: ignore
447
448        if isinstance(expression, exp.Connector):
449            if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL:
450                self._set_type(expression, exp.DataType.Type.NULL)
451            elif exp.DataType.Type.NULL in (left_type, right_type):
452                self._set_type(
453                    expression,
454                    exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")),
455                )
456            else:
457                self._set_type(expression, exp.DataType.Type.BOOLEAN)
458        elif isinstance(expression, exp.Predicate):
459            self._set_type(expression, exp.DataType.Type.BOOLEAN)
460        elif (left_type, right_type) in self.binary_coercions:
461            self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right))
462        else:
463            self._set_type(expression, self._maybe_coerce(left_type, right_type))
464
465        return expression
466
467    def _annotate_unary(self, expression: E) -> E:
468        self._annotate_args(expression)
469
470        if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren):
471            self._set_type(expression, exp.DataType.Type.BOOLEAN)
472        else:
473            self._set_type(expression, expression.this.type)
474
475        return expression
476
477    def _annotate_literal(self, expression: exp.Literal) -> exp.Literal:
478        if expression.is_string:
479            self._set_type(expression, exp.DataType.Type.VARCHAR)
480        elif expression.is_int:
481            self._set_type(expression, exp.DataType.Type.INT)
482        else:
483            self._set_type(expression, exp.DataType.Type.DOUBLE)
484
485        return expression
486
487    def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E:
488        self._set_type(expression, target_type)
489        return self._annotate_args(expression)
490
491    @t.no_type_check
492    def _annotate_by_args(
493        self,
494        expression: E,
495        *args: str,
496        promote: bool = False,
497        array: bool = False,
498    ) -> E:
499        self._annotate_args(expression)
500
501        expressions: t.List[exp.Expression] = []
502        for arg in args:
503            arg_expr = expression.args.get(arg)
504            expressions.extend(expr for expr in ensure_list(arg_expr) if expr)
505
506        last_datatype = None
507        for expr in expressions:
508            expr_type = expr.type
509
510            # Stop at the first nested data type found - we don't want to _maybe_coerce nested types
511            if expr_type.args.get("nested"):
512                last_datatype = expr_type
513                break
514
515            if not expr_type.is_type(exp.DataType.Type.NULL, exp.DataType.Type.UNKNOWN):
516                last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type)
517
518        self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN)
519
520        if promote:
521            if expression.type.this in exp.DataType.INTEGER_TYPES:
522                self._set_type(expression, exp.DataType.Type.BIGINT)
523            elif expression.type.this in exp.DataType.FLOAT_TYPES:
524                self._set_type(expression, exp.DataType.Type.DOUBLE)
525
526        if array:
527            self._set_type(
528                expression,
529                exp.DataType(
530                    this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True
531                ),
532            )
533
534        return expression
535
536    def _annotate_timeunit(
537        self, expression: exp.TimeUnit | exp.DateTrunc
538    ) -> exp.TimeUnit | exp.DateTrunc:
539        self._annotate_args(expression)
540
541        if expression.this.type.this in exp.DataType.TEXT_TYPES:
542            datatype = _coerce_date_literal(expression.this, expression.unit)
543        elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES:
544            datatype = _coerce_date(expression.this, expression.unit)
545        else:
546            datatype = exp.DataType.Type.UNKNOWN
547
548        self._set_type(expression, datatype)
549        return expression
550
551    def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket:
552        self._annotate_args(expression)
553
554        bracket_arg = expression.expressions[0]
555        this = expression.this
556
557        if isinstance(bracket_arg, exp.Slice):
558            self._set_type(expression, this.type)
559        elif this.type.is_type(exp.DataType.Type.ARRAY):
560            self._set_type(expression, seq_get(this.type.expressions, 0))
561        elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys:
562            index = this.keys.index(bracket_arg)
563            value = seq_get(this.values, index)
564            self._set_type(expression, value.type if value else None)
565        else:
566            self._set_type(expression, exp.DataType.Type.UNKNOWN)
567
568        return expression
569
570    def _annotate_div(self, expression: exp.Div) -> exp.Div:
571        self._annotate_args(expression)
572
573        left_type, right_type = expression.left.type.this, expression.right.type.this  # type: ignore
574
575        if (
576            expression.args.get("typed")
577            and left_type in exp.DataType.INTEGER_TYPES
578            and right_type in exp.DataType.INTEGER_TYPES
579        ):
580            self._set_type(expression, exp.DataType.Type.BIGINT)
581        else:
582            self._set_type(expression, self._maybe_coerce(left_type, right_type))
583            if expression.type and expression.type.this not in exp.DataType.REAL_TYPES:
584                self._set_type(
585                    expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE)
586                )
587
588        return expression
589
590    def _annotate_dot(self, expression: exp.Dot) -> exp.Dot:
591        self._annotate_args(expression)
592        self._set_type(expression, None)
593        this_type = expression.this.type
594
595        if this_type and this_type.is_type(exp.DataType.Type.STRUCT):
596            for e in this_type.expressions:
597                if e.name == expression.expression.name:
598                    self._set_type(expression, e.kind)
599                    break
600
601        return expression
602
603    def _annotate_explode(self, expression: exp.Explode) -> exp.Explode:
604        self._annotate_args(expression)
605        self._set_type(expression, seq_get(expression.this.type.expressions, 0))
606        return expression
607
608    def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest:
609        self._annotate_args(expression)
610        child = seq_get(expression.expressions, 0)
611
612        if child and child.is_type(exp.DataType.Type.ARRAY):
613            expr_type = seq_get(child.type.expressions, 0)
614        else:
615            expr_type = None
616
617        self._set_type(expression, expr_type)
618        return expression
619
620    def _annotate_struct_value(
621        self, expression: exp.Expression
622    ) -> t.Optional[exp.DataType] | exp.ColumnDef:
623        alias = expression.args.get("alias")
624        if alias:
625            return exp.ColumnDef(this=alias.copy(), kind=expression.type)
626
627        # Case: key = value or key := value
628        if expression.expression:
629            return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type)
630
631        return expression.type
632
633    def _annotate_struct(self, expression: exp.Struct) -> exp.Struct:
634        self._annotate_args(expression)
635        self._set_type(
636            expression,
637            exp.DataType(
638                this=exp.DataType.Type.STRUCT,
639                expressions=[self._annotate_struct_value(expr) for expr in expression.expressions],
640                nested=True,
641            ),
642        )
643        return expression
644
645    @t.overload
646    def _annotate_map(self, expression: exp.Map) -> exp.Map: ...
647
648    @t.overload
649    def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ...
650
651    def _annotate_map(self, expression):
652        self._annotate_args(expression)
653
654        keys = expression.args.get("keys")
655        values = expression.args.get("values")
656
657        map_type = exp.DataType(this=exp.DataType.Type.MAP)
658        if isinstance(keys, exp.Array) and isinstance(values, exp.Array):
659            key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN
660            value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN
661
662            if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN:
663                map_type.set("expressions", [key_type, value_type])
664                map_type.set("nested", True)
665
666        self._set_type(expression, map_type)
667        return expression
668
669    def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap:
670        self._annotate_args(expression)
671
672        map_type = exp.DataType(this=exp.DataType.Type.MAP)
673        arg = expression.this
674        if arg.is_type(exp.DataType.Type.STRUCT):
675            for coldef in arg.type.expressions:
676                kind = coldef.kind
677                if kind != exp.DataType.Type.UNKNOWN:
678                    map_type.set("expressions", [exp.DataType.build("varchar"), kind])
679                    map_type.set("nested", True)
680                    break
681
682        self._set_type(expression, map_type)
683        return expression
TypeAnnotator( schema: sqlglot.schema.Schema, annotators: Optional[Dict[Type[~E], Callable[[TypeAnnotator, ~E], ~E]]] = None, coerces_to: Optional[Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]]] = None, binary_coercions: Optional[Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]]] = None)
336    def __init__(
337        self,
338        schema: Schema,
339        annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
340        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
341        binary_coercions: t.Optional[BinaryCoercions] = None,
342    ) -> None:
343        self.schema = schema
344        self.annotators = annotators or self.ANNOTATORS
345        self.coerces_to = coerces_to or self.COERCES_TO
346        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
347
348        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
349        self._visited: t.Set[int] = set()
TYPE_TO_EXPRESSIONS: Dict[sqlglot.expressions.DataType.Type, Set[Type[sqlglot.expressions.Expression]]] = {<Type.BIGINT: 'BIGINT'>: {<class 'sqlglot.expressions.ApproxDistinct'>, <class 'sqlglot.expressions.Count'>, <class 'sqlglot.expressions.Length'>, <class 'sqlglot.expressions.ArraySize'>}, <Type.BOOLEAN: 'BOOLEAN'>: {<class 'sqlglot.expressions.Boolean'>, <class 'sqlglot.expressions.In'>, <class 'sqlglot.expressions.RegexpLike'>, <class 'sqlglot.expressions.Between'>}, <Type.DATE: 'DATE'>: {<class 'sqlglot.expressions.Date'>, <class 'sqlglot.expressions.StrToDate'>, <class 'sqlglot.expressions.CurrentDate'>, <class 'sqlglot.expressions.DateStrToDate'>, <class 'sqlglot.expressions.DiToDate'>, <class 'sqlglot.expressions.DateFromParts'>, <class 'sqlglot.expressions.TimeStrToDate'>, <class 'sqlglot.expressions.TsOrDsToDate'>}, <Type.DATETIME: 'DATETIME'>: {<class 'sqlglot.expressions.Datetime'>, <class 'sqlglot.expressions.CurrentDatetime'>, <class 'sqlglot.expressions.DatetimeSub'>, <class 'sqlglot.expressions.DatetimeAdd'>}, <Type.DOUBLE: 'DOUBLE'>: {<class 'sqlglot.expressions.Ln'>, <class 'sqlglot.expressions.Avg'>, <class 'sqlglot.expressions.ApproxQuantile'>, <class 'sqlglot.expressions.VariancePop'>, <class 'sqlglot.expressions.Quantile'>, <class 'sqlglot.expressions.SafeDivide'>, <class 'sqlglot.expressions.Variance'>, <class 'sqlglot.expressions.StddevSamp'>, <class 'sqlglot.expressions.Exp'>, <class 'sqlglot.expressions.Round'>, <class 'sqlglot.expressions.StddevPop'>, <class 'sqlglot.expressions.Pow'>, <class 'sqlglot.expressions.Stddev'>, <class 'sqlglot.expressions.Sqrt'>, <class 'sqlglot.expressions.Div'>, <class 'sqlglot.expressions.Log'>}, <Type.INT: 'INT'>: {<class 'sqlglot.expressions.Extract'>, <class 'sqlglot.expressions.TsOrDiToDi'>, <class 'sqlglot.expressions.DatetimeDiff'>, <class 'sqlglot.expressions.DateToDi'>, <class 'sqlglot.expressions.Levenshtein'>, <class 'sqlglot.expressions.StrPosition'>, <class 'sqlglot.expressions.Ceil'>, <class 'sqlglot.expressions.DateDiff'>, <class 'sqlglot.expressions.TimestampDiff'>, <class 'sqlglot.expressions.Sign'>, <class 'sqlglot.expressions.Floor'>, <class 'sqlglot.expressions.TimeDiff'>}, <Type.JSON: 'JSON'>: {<class 'sqlglot.expressions.ParseJSON'>}, <Type.TIME: 'TIME'>: {<class 'sqlglot.expressions.Time'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<class 'sqlglot.expressions.TimeSub'>, <class 'sqlglot.expressions.TimeAdd'>, <class 'sqlglot.expressions.TimeStrToTime'>, <class 'sqlglot.expressions.TimestampSub'>, <class 'sqlglot.expressions.UnixToTime'>, <class 'sqlglot.expressions.TimestampAdd'>, <class 'sqlglot.expressions.CurrentTimestamp'>, <class 'sqlglot.expressions.CurrentTime'>, <class 'sqlglot.expressions.StrToTime'>}, <Type.TINYINT: 'TINYINT'>: {<class 'sqlglot.expressions.Quarter'>, <class 'sqlglot.expressions.Month'>, <class 'sqlglot.expressions.Year'>, <class 'sqlglot.expressions.Week'>, <class 'sqlglot.expressions.Day'>}, <Type.VARCHAR: 'VARCHAR'>: {<class 'sqlglot.expressions.TimeToTimeStr'>, <class 'sqlglot.expressions.ArrayConcat'>, <class 'sqlglot.expressions.TimeToStr'>, <class 'sqlglot.expressions.DateToDateStr'>, <class 'sqlglot.expressions.GroupConcat'>, <class 'sqlglot.expressions.Initcap'>, <class 'sqlglot.expressions.Trim'>, <class 'sqlglot.expressions.UnixToStr'>, <class 'sqlglot.expressions.Lower'>, <class 'sqlglot.expressions.Substring'>, <class 'sqlglot.expressions.Upper'>, <class 'sqlglot.expressions.TsOrDsToDateStr'>, <class 'sqlglot.expressions.ConcatWs'>, <class 'sqlglot.expressions.UnixToTimeStr'>, <class 'sqlglot.expressions.Concat'>}}
ANNOTATORS: Dict = {<class 'sqlglot.expressions.Alias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseNot'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Neg'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Not'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Paren'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.PivotAlias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Unary'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Add'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.And'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayContainsAll'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Binary'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseAnd'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseLeftShift'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseOr'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseRightShift'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseXor'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Collate'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Connector'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Corr'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.CovarPop'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.CovarSamp'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.DPipe'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Distance'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Div'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Dot'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.EQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Escape'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.GT'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.GTE'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Glob'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ILikeAny'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.IntDiv'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Is'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONArrayContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBExtract'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBExtractScalar'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONExtract'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Kwarg'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LT'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LTE'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Like'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LikeAny'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Mod'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Mul'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NullSafeEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Operator'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Or'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Overlaps'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Pow'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.PropertyEQ'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.RegexpILike'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.RegexpLike'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SimilarTo'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Slice'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Sub'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Xor'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ApproxDistinct'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Count'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Length'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArraySize'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Boolean'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.In'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Between'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Date'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DiToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateFromParts'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Datetime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDatetime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ln'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Avg'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ApproxQuantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.VariancePop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SafeDivide'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Variance'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevSamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Exp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Round'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevPop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Stddev'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sqrt'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Log'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Extract'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDiToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Levenshtein'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrPosition'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sign'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ParseJSON'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Time'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTimestamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quarter'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Month'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Year'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Week'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Day'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArrayConcat'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Initcap'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Trim'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Lower'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Substring'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Upper'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ConcatWs'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Concat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Abs'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Anonymous'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Array'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Bracket'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Cast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Case'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Coalesce'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DataType'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateAdd'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateSub'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateTrunc'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Distinct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Explode'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Filter'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.GenerateDateArray'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.If'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Interval'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Least'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Literal'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Map'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Max'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Min'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Null'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Nullif'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Struct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Sum'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Timestamp'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.TryCast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Unnest'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function TypeAnnotator.<lambda>>}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>}
COERCES_TO: Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]] = {<Type.TEXT: 'TEXT'>: set(), <Type.NVARCHAR: 'NVARCHAR'>: {<Type.TEXT: 'TEXT'>}, <Type.VARCHAR: 'VARCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>}, <Type.NCHAR: 'NCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.CHAR: 'CHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.DOUBLE: 'DOUBLE'>: set(), <Type.FLOAT: 'FLOAT'>: {<Type.DOUBLE: 'DOUBLE'>}, <Type.DECIMAL: 'DECIMAL'>: {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}, <Type.BIGINT: 'BIGINT'>: {<Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}, <Type.INT: 'INT'>: {<Type.DECIMAL: 'DECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.DOUBLE: 'DOUBLE'>, <Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>}, <Type.TINYINT: 'TINYINT'>: {<Type.DOUBLE: 'DOUBLE'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>}, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATETIME: 'DATETIME'>: {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATE: 'DATE'>: {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}}
BINARY_COERCIONS: Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]] = {(<Type.VARCHAR: 'VARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DATE: 'DATE'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.DATE: 'DATE'>): <function TypeAnnotator.<lambda>>}
schema
annotators
coerces_to
binary_coercions
def annotate(self, expression: ~E) -> ~E:
357    def annotate(self, expression: E) -> E:
358        for scope in traverse_scope(expression):
359            self.annotate_scope(scope)
360        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions
def annotate_scope(self, scope: sqlglot.optimizer.scope.Scope) -> None:
362    def annotate_scope(self, scope: Scope) -> None:
363        selects = {}
364        for name, source in scope.sources.items():
365            if not isinstance(source, Scope):
366                continue
367            if isinstance(source.expression, exp.UDTF):
368                values = []
369
370                if isinstance(source.expression, exp.Lateral):
371                    if isinstance(source.expression.this, exp.Explode):
372                        values = [source.expression.this.this]
373                elif isinstance(source.expression, exp.Unnest):
374                    values = [source.expression]
375                else:
376                    values = source.expression.expressions[0].expressions
377
378                if not values:
379                    continue
380
381                selects[name] = {
382                    alias: column
383                    for alias, column in zip(
384                        source.expression.alias_column_names,
385                        values,
386                    )
387                }
388            else:
389                selects[name] = {
390                    select.alias_or_name: select for select in source.expression.selects
391                }
392
393        # First annotate the current scope's column references
394        for col in scope.columns:
395            if not col.table:
396                continue
397
398            source = scope.sources.get(col.table)
399            if isinstance(source, exp.Table):
400                self._set_type(col, self.schema.get_column_type(source, col))
401            elif source:
402                if col.table in selects and col.name in selects[col.table]:
403                    self._set_type(col, selects[col.table][col.name].type)
404                elif isinstance(source.expression, exp.Unnest):
405                    self._set_type(col, source.expression.type)
406
407        # Then (possibly) annotate the remaining expressions in the scope
408        self._maybe_annotate(scope.expression)