sqlglot.optimizer.annotate_types API documentation

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

    330    def __init__(
    331        self,
    332        schema: Schema,
    333        annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
    334        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
    335        binary_coercions: t.Optional[BinaryCoercions] = None,
    336    ) -> None:
    337        self.schema = schema
    338        self.annotators = annotators or self.ANNOTATORS
    339        self.coerces_to = coerces_to or self.COERCES_TO
    340        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
    341
    342        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
    343        self._visited: t.Set[int] = set()

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.Boolean'>, <class 'sqlglot.expressions.RegexpLike'>, <class 'sqlglot.expressions.In'>, <class 'sqlglot.expressions.Between'>}, <Type.DATE: 'DATE'>: {<class 'sqlglot.expressions.CurrentDate'>, <class 'sqlglot.expressions.DiToDate'>, <class 'sqlglot.expressions.Date'>, <class 'sqlglot.expressions.TimeStrToDate'>, <class 'sqlglot.expressions.StrToDate'>, <class 'sqlglot.expressions.TsOrDsToDate'>, <class 'sqlglot.expressions.DateStrToDate'>, <class 'sqlglot.expressions.DateFromParts'>}, <Type.DATETIME: 'DATETIME'>: {<class 'sqlglot.expressions.DatetimeSub'>, <class 'sqlglot.expressions.CurrentDatetime'>, <class 'sqlglot.expressions.DatetimeAdd'>}, <Type.DOUBLE: 'DOUBLE'>: {<class 'sqlglot.expressions.Exp'>, <class 'sqlglot.expressions.Pow'>, <class 'sqlglot.expressions.Round'>, <class 'sqlglot.expressions.Log'>, <class 'sqlglot.expressions.Stddev'>, <class 'sqlglot.expressions.StddevPop'>, <class 'sqlglot.expressions.Ln'>, <class 'sqlglot.expressions.Sqrt'>, <class 'sqlglot.expressions.VariancePop'>, <class 'sqlglot.expressions.Variance'>, <class 'sqlglot.expressions.ApproxQuantile'>, <class 'sqlglot.expressions.Quantile'>, <class 'sqlglot.expressions.Avg'>, <class 'sqlglot.expressions.SafeDivide'>, <class 'sqlglot.expressions.Div'>, <class 'sqlglot.expressions.StddevSamp'>}, <Type.INT: 'INT'>: {<class 'sqlglot.expressions.Extract'>, <class 'sqlglot.expressions.TimeDiff'>, <class 'sqlglot.expressions.TsOrDiToDi'>, <class 'sqlglot.expressions.DateDiff'>, <class 'sqlglot.expressions.Ceil'>, <class 'sqlglot.expressions.Levenshtein'>, <class 'sqlglot.expressions.DateToDi'>, <class 'sqlglot.expressions.Floor'>, <class 'sqlglot.expressions.Sign'>, <class 'sqlglot.expressions.StrPosition'>, <class 'sqlglot.expressions.TimestampDiff'>, <class 'sqlglot.expressions.DatetimeDiff'>}, <Type.JSON: 'JSON'>: {<class 'sqlglot.expressions.ParseJSON'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<class 'sqlglot.expressions.CurrentTime'>, <class 'sqlglot.expressions.UnixToTime'>, <class 'sqlglot.expressions.TimeStrToTime'>, <class 'sqlglot.expressions.TimeSub'>, <class 'sqlglot.expressions.TimeAdd'>, <class 'sqlglot.expressions.StrToTime'>, <class 'sqlglot.expressions.TimestampSub'>, <class 'sqlglot.expressions.CurrentTimestamp'>, <class 'sqlglot.expressions.TimestampAdd'>}, <Type.TINYINT: 'TINYINT'>: {<class 'sqlglot.expressions.Month'>, <class 'sqlglot.expressions.Day'>, <class 'sqlglot.expressions.Week'>, <class 'sqlglot.expressions.Year'>}, <Type.VARCHAR: 'VARCHAR'>: {<class 'sqlglot.expressions.Concat'>, <class 'sqlglot.expressions.ArrayConcat'>, <class 'sqlglot.expressions.UnixToTimeStr'>, <class 'sqlglot.expressions.Substring'>, <class 'sqlglot.expressions.Trim'>, <class 'sqlglot.expressions.Initcap'>, <class 'sqlglot.expressions.TsOrDsToDateStr'>, <class 'sqlglot.expressions.UnixToStr'>, <class 'sqlglot.expressions.DateToDateStr'>, <class 'sqlglot.expressions.TimeToTimeStr'>, <class 'sqlglot.expressions.Upper'>, <class 'sqlglot.expressions.Lower'>, <class 'sqlglot.expressions.GroupConcat'>, <class 'sqlglot.expressions.ConcatWs'>, <class 'sqlglot.expressions.TimeToStr'>}}
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.Boolean'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.In'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Between'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DiToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Date'>: <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.TsOrDsToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateFromParts'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeSub'>: <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.Exp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Round'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Log'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Stddev'>: <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.VariancePop'>: <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.Avg'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SafeDivide'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevSamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Extract'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDiToDi'>: <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.Levenshtein'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sign'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrPosition'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ParseJSON'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTimestamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Month'>: <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.Year'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Concat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArrayConcat'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.UnixToTimeStr'>: <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.Initcap'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Upper'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Lower'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ConcatWs'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <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.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.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>}, <Type.NCHAR: 'NCHAR'>: {<Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.CHAR: 'CHAR'>: {<Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.DOUBLE: 'DOUBLE'>: set(), <Type.FLOAT: 'FLOAT'>: {<Type.DOUBLE: 'DOUBLE'>}, <Type.DECIMAL: 'DECIMAL'>: {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.BIGINT: 'BIGINT'>: {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.INT: 'INT'>: {<Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.FLOAT: 'FLOAT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.TINYINT: 'TINYINT'>: {<Type.FLOAT: 'FLOAT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.DATETIME: 'DATETIME'>: {<Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.DATE: 'DATE'>: {<Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>}}
BINARY_COERCIONS: Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]] = {(<Type.NVARCHAR: 'NVARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MONEY: 'MONEY'>): <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.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.TINYINT: 'TINYINT'>): <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.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MONEY: 'MONEY'>): <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.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.TINYINT: 'TINYINT'>): <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.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MONEY: 'MONEY'>): <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.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.TINYINT: 'TINYINT'>): <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.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MONEY: 'MONEY'>): <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.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.TINYINT: 'TINYINT'>): <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.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MONEY: 'MONEY'>): <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.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.TINYINT: 'TINYINT'>): <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.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MONEY: 'MONEY'>): <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.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.TINYINT: 'TINYINT'>): <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.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.SMALLINT: 'SMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.SMALLINT: 'SMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.SMALLINT: 'SMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <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.SMALLINT: 'SMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <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

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