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