Edit on GitHub

# sqlglot.optimizer.annotate_types

View Source

      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            exp.Quarter,
    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            self.annotate_scope(scope)
    355        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions
    356
    357    def annotate_scope(self, scope: Scope) -> None:
    358        selects = {}
    359        for name, source in scope.sources.items():
    360            if not isinstance(source, Scope):
    361                continue
    362            if isinstance(source.expression, exp.UDTF):
    363                values = []
    364
    365                if isinstance(source.expression, exp.Lateral):
    366                    if isinstance(source.expression.this, exp.Explode):
    367                        values = [source.expression.this.this]
    368                elif isinstance(source.expression, exp.Unnest):
    369                    values = [source.expression]
    370                else:
    371                    values = source.expression.expressions[0].expressions
    372
    373                if not values:
    374                    continue
    375
    376                selects[name] = {
    377                    alias: column
    378                    for alias, column in zip(
    379                        source.expression.alias_column_names,
    380                        values,
    381                    )
    382                }
    383            else:
    384                selects[name] = {
    385                    select.alias_or_name: select for select in source.expression.selects
    386                }
    387
    388        # First annotate the current scope's column references
    389        for col in scope.columns:
    390            if not col.table:
    391                continue
    392
    393            source = scope.sources.get(col.table)
    394            if isinstance(source, exp.Table):
    395                self._set_type(col, self.schema.get_column_type(source, col))
    396            elif source:
    397                if col.table in selects and col.name in selects[col.table]:
    398                    self._set_type(col, selects[col.table][col.name].type)
    399                elif isinstance(source.expression, exp.Unnest):
    400                    self._set_type(col, source.expression.type)
    401
    402        # Then (possibly) annotate the remaining expressions in the scope
    403        self._maybe_annotate(scope.expression)
    404
    405    def _maybe_annotate(self, expression: E) -> E:
    406        if id(expression) in self._visited:
    407            return expression  # We've already inferred the expression's type
    408
    409        annotator = self.annotators.get(expression.__class__)
    410
    411        return (
    412            annotator(self, expression)
    413            if annotator
    414            else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN)
    415        )
    416
    417    def _annotate_args(self, expression: E) -> E:
    418        for value in expression.iter_expressions():
    419            self._maybe_annotate(value)
    420
    421        return expression
    422
    423    def _maybe_coerce(
    424        self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type
    425    ) -> exp.DataType | exp.DataType.Type:
    426        type1_value = type1.this if isinstance(type1, exp.DataType) else type1
    427        type2_value = type2.this if isinstance(type2, exp.DataType) else type2
    428
    429        # We propagate the NULL / UNKNOWN types upwards if found
    430        if exp.DataType.Type.NULL in (type1_value, type2_value):
    431            return exp.DataType.Type.NULL
    432        if exp.DataType.Type.UNKNOWN in (type1_value, type2_value):
    433            return exp.DataType.Type.UNKNOWN
    434
    435        return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value
    436
    437    def _annotate_binary(self, expression: B) -> B:
    438        self._annotate_args(expression)
    439
    440        left, right = expression.left, expression.right
    441        left_type, right_type = left.type.this, right.type.this  # type: ignore
    442
    443        if isinstance(expression, exp.Connector):
    444            if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL:
    445                self._set_type(expression, exp.DataType.Type.NULL)
    446            elif exp.DataType.Type.NULL in (left_type, right_type):
    447                self._set_type(
    448                    expression,
    449                    exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")),
    450                )
    451            else:
    452                self._set_type(expression, exp.DataType.Type.BOOLEAN)
    453        elif isinstance(expression, exp.Predicate):
    454            self._set_type(expression, exp.DataType.Type.BOOLEAN)
    455        elif (left_type, right_type) in self.binary_coercions:
    456            self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right))
    457        else:
    458            self._set_type(expression, self._maybe_coerce(left_type, right_type))
    459
    460        return expression
    461
    462    def _annotate_unary(self, expression: E) -> E:
    463        self._annotate_args(expression)
    464
    465        if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren):
    466            self._set_type(expression, exp.DataType.Type.BOOLEAN)
    467        else:
    468            self._set_type(expression, expression.this.type)
    469
    470        return expression
    471
    472    def _annotate_literal(self, expression: exp.Literal) -> exp.Literal:
    473        if expression.is_string:
    474            self._set_type(expression, exp.DataType.Type.VARCHAR)
    475        elif expression.is_int:
    476            self._set_type(expression, exp.DataType.Type.INT)
    477        else:
    478            self._set_type(expression, exp.DataType.Type.DOUBLE)
    479
    480        return expression
    481
    482    def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E:
    483        self._set_type(expression, target_type)
    484        return self._annotate_args(expression)
    485
    486    @t.no_type_check
    487    def _annotate_by_args(
    488        self,
    489        expression: E,
    490        *args: str,
    491        promote: bool = False,
    492        array: bool = False,
    493    ) -> E:
    494        self._annotate_args(expression)
    495
    496        expressions: t.List[exp.Expression] = []
    497        for arg in args:
    498            arg_expr = expression.args.get(arg)
    499            expressions.extend(expr for expr in ensure_list(arg_expr) if expr)
    500
    501        last_datatype = None
    502        for expr in expressions:
    503            expr_type = expr.type
    504
    505            # Stop at the first nested data type found - we don't want to _maybe_coerce nested types
    506            if expr_type.args.get("nested"):
    507                last_datatype = expr_type
    508                break
    509
    510            if not expr_type.is_type(exp.DataType.Type.NULL, exp.DataType.Type.UNKNOWN):
    511                last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type)
    512
    513        self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN)
    514
    515        if promote:
    516            if expression.type.this in exp.DataType.INTEGER_TYPES:
    517                self._set_type(expression, exp.DataType.Type.BIGINT)
    518            elif expression.type.this in exp.DataType.FLOAT_TYPES:
    519                self._set_type(expression, exp.DataType.Type.DOUBLE)
    520
    521        if array:
    522            self._set_type(
    523                expression,
    524                exp.DataType(
    525                    this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True
    526                ),
    527            )
    528
    529        return expression
    530
    531    def _annotate_timeunit(
    532        self, expression: exp.TimeUnit | exp.DateTrunc
    533    ) -> exp.TimeUnit | exp.DateTrunc:
    534        self._annotate_args(expression)
    535
    536        if expression.this.type.this in exp.DataType.TEXT_TYPES:
    537            datatype = _coerce_date_literal(expression.this, expression.unit)
    538        elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES:
    539            datatype = _coerce_date(expression.this, expression.unit)
    540        else:
    541            datatype = exp.DataType.Type.UNKNOWN
    542
    543        self._set_type(expression, datatype)
    544        return expression
    545
    546    def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket:
    547        self._annotate_args(expression)
    548
    549        bracket_arg = expression.expressions[0]
    550        this = expression.this
    551
    552        if isinstance(bracket_arg, exp.Slice):
    553            self._set_type(expression, this.type)
    554        elif this.type.is_type(exp.DataType.Type.ARRAY):
    555            self._set_type(expression, seq_get(this.type.expressions, 0))
    556        elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys:
    557            index = this.keys.index(bracket_arg)
    558            value = seq_get(this.values, index)
    559            self._set_type(expression, value.type if value else None)
    560        else:
    561            self._set_type(expression, exp.DataType.Type.UNKNOWN)
    562
    563        return expression
    564
    565    def _annotate_div(self, expression: exp.Div) -> exp.Div:
    566        self._annotate_args(expression)
    567
    568        left_type, right_type = expression.left.type.this, expression.right.type.this  # type: ignore
    569
    570        if (
    571            expression.args.get("typed")
    572            and left_type in exp.DataType.INTEGER_TYPES
    573            and right_type in exp.DataType.INTEGER_TYPES
    574        ):
    575            self._set_type(expression, exp.DataType.Type.BIGINT)
    576        else:
    577            self._set_type(expression, self._maybe_coerce(left_type, right_type))
    578            if expression.type and expression.type.this not in exp.DataType.REAL_TYPES:
    579                self._set_type(
    580                    expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE)
    581                )
    582
    583        return expression
    584
    585    def _annotate_dot(self, expression: exp.Dot) -> exp.Dot:
    586        self._annotate_args(expression)
    587        self._set_type(expression, None)
    588        this_type = expression.this.type
    589
    590        if this_type and this_type.is_type(exp.DataType.Type.STRUCT):
    591            for e in this_type.expressions:
    592                if e.name == expression.expression.name:
    593                    self._set_type(expression, e.kind)
    594                    break
    595
    596        return expression
    597
    598    def _annotate_explode(self, expression: exp.Explode) -> exp.Explode:
    599        self._annotate_args(expression)
    600        self._set_type(expression, seq_get(expression.this.type.expressions, 0))
    601        return expression
    602
    603    def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest:
    604        self._annotate_args(expression)
    605        child = seq_get(expression.expressions, 0)
    606
    607        if child and child.is_type(exp.DataType.Type.ARRAY):
    608            expr_type = seq_get(child.type.expressions, 0)
    609        else:
    610            expr_type = None
    611
    612        self._set_type(expression, expr_type)
    613        return expression
    614
    615    def _annotate_struct_value(
    616        self, expression: exp.Expression
    617    ) -> t.Optional[exp.DataType] | exp.ColumnDef:
    618        alias = expression.args.get("alias")
    619        if alias:
    620            return exp.ColumnDef(this=alias.copy(), kind=expression.type)
    621
    622        # Case: key = value or key := value
    623        if expression.expression:
    624            return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type)
    625
    626        return expression.type
    627
    628    def _annotate_struct(self, expression: exp.Struct) -> exp.Struct:
    629        self._annotate_args(expression)
    630        self._set_type(
    631            expression,
    632            exp.DataType(
    633                this=exp.DataType.Type.STRUCT,
    634                expressions=[self._annotate_struct_value(expr) for expr in expression.expressions],
    635                nested=True,
    636            ),
    637        )
    638        return expression
    639
    640    @t.overload
    641    def _annotate_map(self, expression: exp.Map) -> exp.Map: ...
    642
    643    @t.overload
    644    def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ...
    645
    646    def _annotate_map(self, expression):
    647        self._annotate_args(expression)
    648
    649        keys = expression.args.get("keys")
    650        values = expression.args.get("values")
    651
    652        map_type = exp.DataType(this=exp.DataType.Type.MAP)
    653        if isinstance(keys, exp.Array) and isinstance(values, exp.Array):
    654            key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN
    655            value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN
    656
    657            if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN:
    658                map_type.set("expressions", [key_type, value_type])
    659                map_type.set("nested", True)
    660
    661        self._set_type(expression, map_type)
    662        return expression
    663
    664    def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap:
    665        self._annotate_args(expression)
    666
    667        map_type = exp.DataType(this=exp.DataType.Type.MAP)
    668        arg = expression.this
    669        if arg.is_type(exp.DataType.Type.STRUCT):
    670            for coldef in arg.type.expressions:
    671                kind = coldef.kind
    672                if kind != exp.DataType.Type.UNKNOWN:
    673                    map_type.set("expressions", [exp.DataType.build("varchar"), kind])
    674                    map_type.set("nested", True)
    675                    break
    676
    677        self._set_type(expression, map_type)
    678        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: View Source

    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.

def swap_args( func: Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]) -> Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]: View Source

    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

def swap_all( coercions: Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]]) -> Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]]: View Source

    93def swap_all(coercions: BinaryCoercions) -> BinaryCoercions:
    94    return {**coercions, **{(b, a): swap_args(func) for (a, b), func in coercions.items()}}

class TypeAnnotator: View Source

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

    332    def __init__(
    333        self,
    334        schema: Schema,
    335        annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
    336        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
    337        binary_coercions: t.Optional[BinaryCoercions] = None,
    338    ) -> None:
    339        self.schema = schema
    340        self.annotators = annotators or self.ANNOTATORS
    341        self.coerces_to = coerces_to or self.COERCES_TO
    342        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
    343
    344        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
    345        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.ArraySize'>, <class 'sqlglot.expressions.Length'>, <class 'sqlglot.expressions.Count'>, <class 'sqlglot.expressions.ApproxDistinct'>}, <Type.BOOLEAN: 'BOOLEAN'>: {<class 'sqlglot.expressions.Between'>, <class 'sqlglot.expressions.In'>, <class 'sqlglot.expressions.RegexpLike'>, <class 'sqlglot.expressions.Boolean'>}, <Type.DATE: 'DATE'>: {<class 'sqlglot.expressions.TimeStrToDate'>, <class 'sqlglot.expressions.StrToDate'>, <class 'sqlglot.expressions.Date'>, <class 'sqlglot.expressions.CurrentDate'>, <class 'sqlglot.expressions.TsOrDsToDate'>, <class 'sqlglot.expressions.DateFromParts'>, <class 'sqlglot.expressions.DateStrToDate'>, <class 'sqlglot.expressions.DiToDate'>}, <Type.DATETIME: 'DATETIME'>: {<class 'sqlglot.expressions.CurrentDatetime'>, <class 'sqlglot.expressions.DatetimeAdd'>, <class 'sqlglot.expressions.DatetimeSub'>}, <Type.DOUBLE: 'DOUBLE'>: {<class 'sqlglot.expressions.Div'>, <class 'sqlglot.expressions.Variance'>, <class 'sqlglot.expressions.ApproxQuantile'>, <class 'sqlglot.expressions.Pow'>, <class 'sqlglot.expressions.Quantile'>, <class 'sqlglot.expressions.SafeDivide'>, <class 'sqlglot.expressions.VariancePop'>, <class 'sqlglot.expressions.StddevSamp'>, <class 'sqlglot.expressions.Exp'>, <class 'sqlglot.expressions.Stddev'>, <class 'sqlglot.expressions.Log'>, <class 'sqlglot.expressions.Round'>, <class 'sqlglot.expressions.Avg'>, <class 'sqlglot.expressions.StddevPop'>, <class 'sqlglot.expressions.Ln'>, <class 'sqlglot.expressions.Sqrt'>}, <Type.INT: 'INT'>: {<class 'sqlglot.expressions.Sign'>, <class 'sqlglot.expressions.TimeDiff'>, <class 'sqlglot.expressions.Extract'>, <class 'sqlglot.expressions.StrPosition'>, <class 'sqlglot.expressions.DateDiff'>, <class 'sqlglot.expressions.Ceil'>, <class 'sqlglot.expressions.DateToDi'>, <class 'sqlglot.expressions.TimestampDiff'>, <class 'sqlglot.expressions.TsOrDiToDi'>, <class 'sqlglot.expressions.DatetimeDiff'>, <class 'sqlglot.expressions.Levenshtein'>, <class 'sqlglot.expressions.Floor'>}, <Type.JSON: 'JSON'>: {<class 'sqlglot.expressions.ParseJSON'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<class 'sqlglot.expressions.StrToTime'>, <class 'sqlglot.expressions.TimeSub'>, <class 'sqlglot.expressions.TimestampAdd'>, <class 'sqlglot.expressions.TimeAdd'>, <class 'sqlglot.expressions.UnixToTime'>, <class 'sqlglot.expressions.TimestampSub'>, <class 'sqlglot.expressions.CurrentTimestamp'>, <class 'sqlglot.expressions.TimeStrToTime'>, <class 'sqlglot.expressions.CurrentTime'>}, <Type.TINYINT: 'TINYINT'>: {<class 'sqlglot.expressions.Day'>, <class 'sqlglot.expressions.Week'>, <class 'sqlglot.expressions.Quarter'>, <class 'sqlglot.expressions.Month'>, <class 'sqlglot.expressions.Year'>}, <Type.VARCHAR: 'VARCHAR'>: {<class 'sqlglot.expressions.ArrayConcat'>, <class 'sqlglot.expressions.Lower'>, <class 'sqlglot.expressions.GroupConcat'>, <class 'sqlglot.expressions.TimeToTimeStr'>, <class 'sqlglot.expressions.TsOrDsToDateStr'>, <class 'sqlglot.expressions.TimeToStr'>, <class 'sqlglot.expressions.DateToDateStr'>, <class 'sqlglot.expressions.UnixToStr'>, <class 'sqlglot.expressions.UnixToTimeStr'>, <class 'sqlglot.expressions.Upper'>, <class 'sqlglot.expressions.Substring'>, <class 'sqlglot.expressions.Trim'>, <class 'sqlglot.expressions.ConcatWs'>, <class 'sqlglot.expressions.Initcap'>, <class 'sqlglot.expressions.Concat'>}}
ANNOTATORS: Dict = {<class 'sqlglot.expressions.Alias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseNot'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Neg'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Not'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Paren'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.PivotAlias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Unary'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Add'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.And'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.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.ArraySize'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Length'>: <function _annotate_with_type_lambda.<locals>.<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.Between'>: <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.TimeStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Date'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateFromParts'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DiToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDatetime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Variance'>: <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.VariancePop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevSamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Exp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Stddev'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Log'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Round'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Avg'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevPop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ln'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sqrt'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sign'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Extract'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrPosition'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDiToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Levenshtein'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ParseJSON'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <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.TimeStrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Day'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Week'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quarter'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Month'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Year'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArrayConcat'>: <function TypeAnnotator.<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.TimeToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Upper'>: <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.ConcatWs'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Initcap'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Concat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Abs'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Anonymous'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Array'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Bracket'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Cast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Case'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Coalesce'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DataType'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateAdd'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateSub'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateTrunc'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Distinct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Explode'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Filter'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.GenerateDateArray'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.If'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Interval'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Least'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Literal'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Map'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Max'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Min'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Null'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Nullif'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Struct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Sum'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Timestamp'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.TryCast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Unnest'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function TypeAnnotator.<lambda>>}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>}
COERCES_TO: Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]] = {<Type.TEXT: 'TEXT'>: set(), <Type.NVARCHAR: 'NVARCHAR'>: {<Type.TEXT: 'TEXT'>}, <Type.VARCHAR: 'VARCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>}, <Type.NCHAR: 'NCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>}, <Type.CHAR: 'CHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>}, <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.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>}, <Type.TINYINT: 'TINYINT'>: {<Type.SMALLINT: 'SMALLINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>}, <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.VARCHAR: 'VARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <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.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MONEY: 'MONEY'>): <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.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MONEY: 'MONEY'>): <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.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MONEY: 'MONEY'>): <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.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MONEY: 'MONEY'>): <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.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MONEY: 'MONEY'>): <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.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MONEY: 'MONEY'>): <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.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DATE: 'DATE'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.DATE: 'DATE'>): <function TypeAnnotator.<lambda>>}
schema
annotators
coerces_to
binary_coercions
def annotate(self, expression: ~E) -> ~E: View Source

    353    def annotate(self, expression: E) -> E:
    354        for scope in traverse_scope(expression):
    355            self.annotate_scope(scope)
    356        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions

def annotate_scope(self, scope: sqlglot.optimizer.scope.Scope) -> None: View Source

    358    def annotate_scope(self, scope: Scope) -> None:
    359        selects = {}
    360        for name, source in scope.sources.items():
    361            if not isinstance(source, Scope):
    362                continue
    363            if isinstance(source.expression, exp.UDTF):
    364                values = []
    365
    366                if isinstance(source.expression, exp.Lateral):
    367                    if isinstance(source.expression.this, exp.Explode):
    368                        values = [source.expression.this.this]
    369                elif isinstance(source.expression, exp.Unnest):
    370                    values = [source.expression]
    371                else:
    372                    values = source.expression.expressions[0].expressions
    373
    374                if not values:
    375                    continue
    376
    377                selects[name] = {
    378                    alias: column
    379                    for alias, column in zip(
    380                        source.expression.alias_column_names,
    381                        values,
    382                    )
    383                }
    384            else:
    385                selects[name] = {
    386                    select.alias_or_name: select for select in source.expression.selects
    387                }
    388
    389        # First annotate the current scope's column references
    390        for col in scope.columns:
    391            if not col.table:
    392                continue
    393
    394            source = scope.sources.get(col.table)
    395            if isinstance(source, exp.Table):
    396                self._set_type(col, self.schema.get_column_type(source, col))
    397            elif source:
    398                if col.table in selects and col.name in selects[col.table]:
    399                    self._set_type(col, selects[col.table][col.name].type)
    400                elif isinstance(source.expression, exp.Unnest):
    401                    self._set_type(col, source.expression.type)
    402
    403        # Then (possibly) annotate the remaining expressions in the scope
    404        self._maybe_annotate(scope.expression)