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

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

TypeAnnotator( schema: sqlglot.schema.Schema, annotators: Optional[Dict[Type[~E], Callable[[TypeAnnotator, ~E], ~E]]] = None, coerces_to: Optional[Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]]] = None, binary_coercions: Optional[Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]]] = None) View Source

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

TYPE_TO_EXPRESSIONS: Dict[sqlglot.expressions.DataType.Type, Set[Type[sqlglot.expressions.Expression]]] = {<Type.BIGINT: 'BIGINT'>: {<class 'sqlglot.expressions.ApproxDistinct'>, <class 'sqlglot.expressions.Count'>, <class 'sqlglot.expressions.Length'>, <class 'sqlglot.expressions.ArraySize'>}, <Type.BOOLEAN: 'BOOLEAN'>: {<class 'sqlglot.expressions.Boolean'>, <class 'sqlglot.expressions.In'>, <class 'sqlglot.expressions.RegexpLike'>, <class 'sqlglot.expressions.Between'>}, <Type.DATE: 'DATE'>: {<class 'sqlglot.expressions.Date'>, <class 'sqlglot.expressions.StrToDate'>, <class 'sqlglot.expressions.CurrentDate'>, <class 'sqlglot.expressions.DateStrToDate'>, <class 'sqlglot.expressions.DiToDate'>, <class 'sqlglot.expressions.DateFromParts'>, <class 'sqlglot.expressions.TimeStrToDate'>, <class 'sqlglot.expressions.TsOrDsToDate'>}, <Type.DATETIME: 'DATETIME'>: {<class 'sqlglot.expressions.Datetime'>, <class 'sqlglot.expressions.CurrentDatetime'>, <class 'sqlglot.expressions.DatetimeSub'>, <class 'sqlglot.expressions.DatetimeAdd'>}, <Type.DOUBLE: 'DOUBLE'>: {<class 'sqlglot.expressions.Ln'>, <class 'sqlglot.expressions.Avg'>, <class 'sqlglot.expressions.ApproxQuantile'>, <class 'sqlglot.expressions.VariancePop'>, <class 'sqlglot.expressions.Quantile'>, <class 'sqlglot.expressions.SafeDivide'>, <class 'sqlglot.expressions.Variance'>, <class 'sqlglot.expressions.StddevSamp'>, <class 'sqlglot.expressions.Exp'>, <class 'sqlglot.expressions.Round'>, <class 'sqlglot.expressions.StddevPop'>, <class 'sqlglot.expressions.Pow'>, <class 'sqlglot.expressions.Stddev'>, <class 'sqlglot.expressions.Sqrt'>, <class 'sqlglot.expressions.Div'>, <class 'sqlglot.expressions.Log'>}, <Type.INT: 'INT'>: {<class 'sqlglot.expressions.Extract'>, <class 'sqlglot.expressions.TsOrDiToDi'>, <class 'sqlglot.expressions.DatetimeDiff'>, <class 'sqlglot.expressions.DateToDi'>, <class 'sqlglot.expressions.Levenshtein'>, <class 'sqlglot.expressions.StrPosition'>, <class 'sqlglot.expressions.Ceil'>, <class 'sqlglot.expressions.DateDiff'>, <class 'sqlglot.expressions.TimestampDiff'>, <class 'sqlglot.expressions.Sign'>, <class 'sqlglot.expressions.Floor'>, <class 'sqlglot.expressions.TimeDiff'>}, <Type.JSON: 'JSON'>: {<class 'sqlglot.expressions.ParseJSON'>}, <Type.TIME: 'TIME'>: {<class 'sqlglot.expressions.Time'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<class 'sqlglot.expressions.TimeSub'>, <class 'sqlglot.expressions.TimeAdd'>, <class 'sqlglot.expressions.TimeStrToTime'>, <class 'sqlglot.expressions.TimestampSub'>, <class 'sqlglot.expressions.UnixToTime'>, <class 'sqlglot.expressions.TimestampAdd'>, <class 'sqlglot.expressions.CurrentTimestamp'>, <class 'sqlglot.expressions.CurrentTime'>, <class 'sqlglot.expressions.StrToTime'>}, <Type.TINYINT: 'TINYINT'>: {<class 'sqlglot.expressions.Quarter'>, <class 'sqlglot.expressions.Month'>, <class 'sqlglot.expressions.Year'>, <class 'sqlglot.expressions.Week'>, <class 'sqlglot.expressions.Day'>}, <Type.VARCHAR: 'VARCHAR'>: {<class 'sqlglot.expressions.TimeToTimeStr'>, <class 'sqlglot.expressions.ArrayConcat'>, <class 'sqlglot.expressions.TimeToStr'>, <class 'sqlglot.expressions.DateToDateStr'>, <class 'sqlglot.expressions.GroupConcat'>, <class 'sqlglot.expressions.Initcap'>, <class 'sqlglot.expressions.Trim'>, <class 'sqlglot.expressions.UnixToStr'>, <class 'sqlglot.expressions.Lower'>, <class 'sqlglot.expressions.Substring'>, <class 'sqlglot.expressions.Upper'>, <class 'sqlglot.expressions.TsOrDsToDateStr'>, <class 'sqlglot.expressions.ConcatWs'>, <class 'sqlglot.expressions.UnixToTimeStr'>, <class 'sqlglot.expressions.Concat'>}}
ANNOTATORS: Dict = {<class 'sqlglot.expressions.Alias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseNot'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Neg'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Not'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Paren'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.PivotAlias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Unary'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Add'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.And'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayContainsAll'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Binary'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseAnd'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseLeftShift'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseOr'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseRightShift'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseXor'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Collate'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Connector'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Corr'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.CovarPop'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.CovarSamp'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.DPipe'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Distance'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Div'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Dot'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.EQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Escape'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.GT'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.GTE'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Glob'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ILikeAny'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.IntDiv'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Is'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONArrayContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBExtract'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBExtractScalar'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONExtract'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Kwarg'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LT'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LTE'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Like'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LikeAny'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Mod'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Mul'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NullSafeEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Operator'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Or'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Overlaps'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Pow'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.PropertyEQ'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.RegexpILike'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.RegexpLike'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SimilarTo'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Slice'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Sub'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Xor'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ApproxDistinct'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Count'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Length'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArraySize'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Boolean'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.In'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Between'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Date'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DiToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateFromParts'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Datetime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDatetime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ln'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Avg'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ApproxQuantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.VariancePop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SafeDivide'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Variance'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevSamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Exp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Round'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevPop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Stddev'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sqrt'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Log'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Extract'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDiToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Levenshtein'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrPosition'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sign'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ParseJSON'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Time'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTimestamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quarter'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Month'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Year'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Week'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Day'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArrayConcat'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Initcap'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Trim'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Lower'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Substring'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Upper'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ConcatWs'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Concat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Abs'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Anonymous'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Array'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Bracket'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Cast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Case'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Coalesce'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DataType'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateAdd'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateSub'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateTrunc'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Distinct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Explode'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Filter'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.GenerateDateArray'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.If'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Interval'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Least'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Literal'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Map'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Max'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Min'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Null'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Nullif'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Struct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Sum'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Timestamp'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.TryCast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Unnest'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function TypeAnnotator.<lambda>>}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>}
COERCES_TO: Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]] = {<Type.TEXT: 'TEXT'>: set(), <Type.NVARCHAR: 'NVARCHAR'>: {<Type.TEXT: 'TEXT'>}, <Type.VARCHAR: 'VARCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>}, <Type.NCHAR: 'NCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.CHAR: 'CHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.DOUBLE: 'DOUBLE'>: set(), <Type.FLOAT: 'FLOAT'>: {<Type.DOUBLE: 'DOUBLE'>}, <Type.DECIMAL: 'DECIMAL'>: {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}, <Type.BIGINT: 'BIGINT'>: {<Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}, <Type.INT: 'INT'>: {<Type.DECIMAL: 'DECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.DOUBLE: 'DOUBLE'>, <Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>}, <Type.TINYINT: 'TINYINT'>: {<Type.DOUBLE: 'DOUBLE'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>}, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATETIME: 'DATETIME'>: {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATE: 'DATE'>: {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}}
BINARY_COERCIONS: Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]] = {(<Type.VARCHAR: 'VARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DATE: 'DATE'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.DATE: 'DATE'>): <function TypeAnnotator.<lambda>>}
schema
annotators
coerces_to
binary_coercions
def annotate(self, expression: ~E) -> ~E: View Source

    357    def annotate(self, expression: E) -> E:
    358        for scope in traverse_scope(expression):
    359            self.annotate_scope(scope)
    360        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions

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

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