Edit on GitHub

sqlglot.optimizer.annotate_types

  1from __future__ import annotations
  2
  3import functools
  4import typing as t
  5
  6from sqlglot import exp
  7from sqlglot.helper import (
  8    ensure_list,
  9    is_date_unit,
 10    is_iso_date,
 11    is_iso_datetime,
 12    seq_get,
 13)
 14from sqlglot.optimizer.scope import Scope, traverse_scope
 15from sqlglot.schema import Schema, ensure_schema
 16from sqlglot.dialects.dialect import Dialect
 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    from sqlglot.dialects.dialect import DialectType, AnnotatorsType
 28
 29
 30def annotate_types(
 31    expression: E,
 32    schema: t.Optional[t.Dict | Schema] = None,
 33    annotators: t.Optional[AnnotatorsType] = None,
 34    coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
 35    dialect: t.Optional[DialectType] = None,
 36) -> E:
 37    """
 38    Infers the types of an expression, annotating its AST accordingly.
 39
 40    Example:
 41        >>> import sqlglot
 42        >>> schema = {"y": {"cola": "SMALLINT"}}
 43        >>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x"
 44        >>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema)
 45        >>> annotated_expr.expressions[0].type.this  # Get the type of "x.cola + 2.5 AS cola"
 46        <Type.DOUBLE: 'DOUBLE'>
 47
 48    Args:
 49        expression: Expression to annotate.
 50        schema: Database schema.
 51        annotators: Maps expression type to corresponding annotation function.
 52        coerces_to: Maps expression type to set of types that it can be coerced into.
 53
 54    Returns:
 55        The expression annotated with types.
 56    """
 57
 58    schema = ensure_schema(schema)
 59
 60    return TypeAnnotator(schema, annotators, coerces_to, dialect=dialect).annotate(expression)
 61
 62
 63def _coerce_date_literal(l: exp.Expression, unit: t.Optional[exp.Expression]) -> exp.DataType.Type:
 64    date_text = l.name
 65    is_iso_date_ = is_iso_date(date_text)
 66
 67    if is_iso_date_ and is_date_unit(unit):
 68        return exp.DataType.Type.DATE
 69
 70    # An ISO date is also an ISO datetime, but not vice versa
 71    if is_iso_date_ or is_iso_datetime(date_text):
 72        return exp.DataType.Type.DATETIME
 73
 74    return exp.DataType.Type.UNKNOWN
 75
 76
 77def _coerce_date(l: exp.Expression, unit: t.Optional[exp.Expression]) -> exp.DataType.Type:
 78    if not is_date_unit(unit):
 79        return exp.DataType.Type.DATETIME
 80    return l.type.this if l.type else exp.DataType.Type.UNKNOWN
 81
 82
 83def swap_args(func: BinaryCoercionFunc) -> BinaryCoercionFunc:
 84    @functools.wraps(func)
 85    def _swapped(l: exp.Expression, r: exp.Expression) -> exp.DataType.Type:
 86        return func(r, l)
 87
 88    return _swapped
 89
 90
 91def swap_all(coercions: BinaryCoercions) -> BinaryCoercions:
 92    return {**coercions, **{(b, a): swap_args(func) for (a, b), func in coercions.items()}}
 93
 94
 95class _TypeAnnotator(type):
 96    def __new__(cls, clsname, bases, attrs):
 97        klass = super().__new__(cls, clsname, bases, attrs)
 98
 99        # Highest-to-lowest type precedence, as specified in Spark's docs (ANSI):
100        # https://spark.apache.org/docs/3.2.0/sql-ref-ansi-compliance.html
101        text_precedence = (
102            exp.DataType.Type.TEXT,
103            exp.DataType.Type.NVARCHAR,
104            exp.DataType.Type.VARCHAR,
105            exp.DataType.Type.NCHAR,
106            exp.DataType.Type.CHAR,
107        )
108        numeric_precedence = (
109            exp.DataType.Type.DOUBLE,
110            exp.DataType.Type.FLOAT,
111            exp.DataType.Type.DECIMAL,
112            exp.DataType.Type.BIGINT,
113            exp.DataType.Type.INT,
114            exp.DataType.Type.SMALLINT,
115            exp.DataType.Type.TINYINT,
116        )
117        timelike_precedence = (
118            exp.DataType.Type.TIMESTAMPLTZ,
119            exp.DataType.Type.TIMESTAMPTZ,
120            exp.DataType.Type.TIMESTAMP,
121            exp.DataType.Type.DATETIME,
122            exp.DataType.Type.DATE,
123        )
124
125        for type_precedence in (text_precedence, numeric_precedence, timelike_precedence):
126            coerces_to = set()
127            for data_type in type_precedence:
128                klass.COERCES_TO[data_type] = coerces_to.copy()
129                coerces_to |= {data_type}
130
131        # NULL can be coerced to any type, so e.g. NULL + 1 will have type INT
132        klass.COERCES_TO[exp.DataType.Type.NULL] = {
133            *text_precedence,
134            *numeric_precedence,
135            *timelike_precedence,
136        }
137
138        return klass
139
140
141class TypeAnnotator(metaclass=_TypeAnnotator):
142    NESTED_TYPES = {
143        exp.DataType.Type.ARRAY,
144    }
145
146    # Specifies what types a given type can be coerced into (autofilled)
147    COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {}
148
149    # Coercion functions for binary operations.
150    # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type.
151    BINARY_COERCIONS: BinaryCoercions = {
152        **swap_all(
153            {
154                (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal(
155                    l, r.args.get("unit")
156                )
157                for t in exp.DataType.TEXT_TYPES
158            }
159        ),
160        **swap_all(
161            {
162                # text + numeric will yield the numeric type to match most dialects' semantics
163                (text, numeric): lambda l, r: t.cast(
164                    exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type
165                )
166                for text in exp.DataType.TEXT_TYPES
167                for numeric in exp.DataType.NUMERIC_TYPES
168            }
169        ),
170        **swap_all(
171            {
172                (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date(
173                    l, r.args.get("unit")
174                ),
175            }
176        ),
177    }
178
179    def __init__(
180        self,
181        schema: Schema,
182        annotators: t.Optional[AnnotatorsType] = None,
183        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
184        binary_coercions: t.Optional[BinaryCoercions] = None,
185        dialect: t.Optional[DialectType] = None,
186    ) -> None:
187        self.schema = schema
188        self.annotators = annotators or Dialect.get_or_raise(dialect).ANNOTATORS
189        self.coerces_to = coerces_to or self.COERCES_TO
190        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
191
192        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
193        self._visited: t.Set[int] = set()
194
195        # Maps an exp.SetOperation's id (e.g. UNION) to its projection types. This is computed if the
196        # exp.SetOperation is the expression of a scope source, as selecting from it multiple times
197        # would reprocess the entire subtree to coerce the types of its operands' projections
198        self._setop_column_types: t.Dict[int, t.Dict[str, exp.DataType | exp.DataType.Type]] = {}
199
200    def _set_type(
201        self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type]
202    ) -> None:
203        expression.type = target_type or exp.DataType.Type.UNKNOWN  # type: ignore
204        self._visited.add(id(expression))
205
206    def annotate(self, expression: E) -> E:
207        for scope in traverse_scope(expression):
208            self.annotate_scope(scope)
209        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions
210
211    def annotate_scope(self, scope: Scope) -> None:
212        selects = {}
213        for name, source in scope.sources.items():
214            if not isinstance(source, Scope):
215                continue
216
217            expression = source.expression
218            if isinstance(expression, exp.UDTF):
219                values = []
220
221                if isinstance(expression, exp.Lateral):
222                    if isinstance(expression.this, exp.Explode):
223                        values = [expression.this.this]
224                elif isinstance(expression, exp.Unnest):
225                    values = [expression]
226                else:
227                    values = expression.expressions[0].expressions
228
229                if not values:
230                    continue
231
232                selects[name] = {
233                    alias: column.type
234                    for alias, column in zip(expression.alias_column_names, values)
235                }
236            elif isinstance(expression, exp.SetOperation) and len(expression.left.selects) == len(
237                expression.right.selects
238            ):
239                selects[name] = col_types = self._setop_column_types.setdefault(id(expression), {})
240
241                if not col_types:
242                    # Process a chain / sub-tree of set operations
243                    for set_op in expression.walk(
244                        prune=lambda n: not isinstance(n, (exp.SetOperation, exp.Subquery))
245                    ):
246                        if not isinstance(set_op, exp.SetOperation):
247                            continue
248
249                        if set_op.args.get("by_name"):
250                            r_type_by_select = {
251                                s.alias_or_name: s.type for s in set_op.right.selects
252                            }
253                            setop_cols = {
254                                s.alias_or_name: self._maybe_coerce(
255                                    t.cast(exp.DataType, s.type),
256                                    r_type_by_select.get(s.alias_or_name)
257                                    or exp.DataType.Type.UNKNOWN,
258                                )
259                                for s in set_op.left.selects
260                            }
261                        else:
262                            setop_cols = {
263                                ls.alias_or_name: self._maybe_coerce(
264                                    t.cast(exp.DataType, ls.type), t.cast(exp.DataType, rs.type)
265                                )
266                                for ls, rs in zip(set_op.left.selects, set_op.right.selects)
267                            }
268
269                        # Coerce intermediate results with the previously registered types, if they exist
270                        for col_name, col_type in setop_cols.items():
271                            col_types[col_name] = self._maybe_coerce(
272                                col_type, col_types.get(col_name, exp.DataType.Type.NULL)
273                            )
274
275            else:
276                selects[name] = {s.alias_or_name: s.type for s in expression.selects}
277
278        # First annotate the current scope's column references
279        for col in scope.columns:
280            if not col.table:
281                continue
282
283            source = scope.sources.get(col.table)
284            if isinstance(source, exp.Table):
285                self._set_type(col, self.schema.get_column_type(source, col))
286            elif source:
287                if col.table in selects and col.name in selects[col.table]:
288                    self._set_type(col, selects[col.table][col.name])
289                elif isinstance(source.expression, exp.Unnest):
290                    self._set_type(col, source.expression.type)
291
292        # Then (possibly) annotate the remaining expressions in the scope
293        self._maybe_annotate(scope.expression)
294
295    def _maybe_annotate(self, expression: E) -> E:
296        if id(expression) in self._visited:
297            return expression  # We've already inferred the expression's type
298
299        annotator = self.annotators.get(expression.__class__)
300
301        return (
302            annotator(self, expression)
303            if annotator
304            else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN)
305        )
306
307    def _annotate_args(self, expression: E) -> E:
308        for value in expression.iter_expressions():
309            self._maybe_annotate(value)
310
311        return expression
312
313    def _maybe_coerce(
314        self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type
315    ) -> exp.DataType | exp.DataType.Type:
316        """
317        Returns type2 if type1 can be coerced into it, otherwise type1.
318
319        If either type is parameterized (e.g. DECIMAL(18, 2) contains two parameters),
320        we assume type1 does not coerce into type2, so we also return it in this case.
321        """
322        if isinstance(type1, exp.DataType):
323            if type1.expressions:
324                return type1
325            type1_value = type1.this
326        else:
327            type1_value = type1
328
329        if isinstance(type2, exp.DataType):
330            if type2.expressions:
331                return type1
332            type2_value = type2.this
333        else:
334            type2_value = type2
335
336        # We propagate the UNKNOWN type upwards if found
337        if exp.DataType.Type.UNKNOWN in (type1_value, type2_value):
338            return exp.DataType.Type.UNKNOWN
339
340        return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value
341
342    def _annotate_binary(self, expression: B) -> B:
343        self._annotate_args(expression)
344
345        left, right = expression.left, expression.right
346        left_type, right_type = left.type.this, right.type.this  # type: ignore
347
348        if isinstance(expression, (exp.Connector, exp.Predicate)):
349            self._set_type(expression, exp.DataType.Type.BOOLEAN)
350        elif (left_type, right_type) in self.binary_coercions:
351            self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right))
352        else:
353            self._set_type(expression, self._maybe_coerce(left_type, right_type))
354
355        return expression
356
357    def _annotate_unary(self, expression: E) -> E:
358        self._annotate_args(expression)
359
360        if isinstance(expression, exp.Not):
361            self._set_type(expression, exp.DataType.Type.BOOLEAN)
362        else:
363            self._set_type(expression, expression.this.type)
364
365        return expression
366
367    def _annotate_literal(self, expression: exp.Literal) -> exp.Literal:
368        if expression.is_string:
369            self._set_type(expression, exp.DataType.Type.VARCHAR)
370        elif expression.is_int:
371            self._set_type(expression, exp.DataType.Type.INT)
372        else:
373            self._set_type(expression, exp.DataType.Type.DOUBLE)
374
375        return expression
376
377    def _annotate_with_type(
378        self, expression: E, target_type: exp.DataType | exp.DataType.Type
379    ) -> E:
380        self._set_type(expression, target_type)
381        return self._annotate_args(expression)
382
383    @t.no_type_check
384    def _annotate_by_args(
385        self,
386        expression: E,
387        *args: str,
388        promote: bool = False,
389        array: bool = False,
390    ) -> E:
391        self._annotate_args(expression)
392
393        expressions: t.List[exp.Expression] = []
394        for arg in args:
395            arg_expr = expression.args.get(arg)
396            expressions.extend(expr for expr in ensure_list(arg_expr) if expr)
397
398        last_datatype = None
399        for expr in expressions:
400            expr_type = expr.type
401
402            # Stop at the first nested data type found - we don't want to _maybe_coerce nested types
403            if expr_type.args.get("nested"):
404                last_datatype = expr_type
405                break
406
407            if not expr_type.is_type(exp.DataType.Type.UNKNOWN):
408                last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type)
409
410        self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN)
411
412        if promote:
413            if expression.type.this in exp.DataType.INTEGER_TYPES:
414                self._set_type(expression, exp.DataType.Type.BIGINT)
415            elif expression.type.this in exp.DataType.FLOAT_TYPES:
416                self._set_type(expression, exp.DataType.Type.DOUBLE)
417
418        if array:
419            self._set_type(
420                expression,
421                exp.DataType(
422                    this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True
423                ),
424            )
425
426        return expression
427
428    def _annotate_timeunit(
429        self, expression: exp.TimeUnit | exp.DateTrunc
430    ) -> exp.TimeUnit | exp.DateTrunc:
431        self._annotate_args(expression)
432
433        if expression.this.type.this in exp.DataType.TEXT_TYPES:
434            datatype = _coerce_date_literal(expression.this, expression.unit)
435        elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES:
436            datatype = _coerce_date(expression.this, expression.unit)
437        else:
438            datatype = exp.DataType.Type.UNKNOWN
439
440        self._set_type(expression, datatype)
441        return expression
442
443    def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket:
444        self._annotate_args(expression)
445
446        bracket_arg = expression.expressions[0]
447        this = expression.this
448
449        if isinstance(bracket_arg, exp.Slice):
450            self._set_type(expression, this.type)
451        elif this.type.is_type(exp.DataType.Type.ARRAY):
452            self._set_type(expression, seq_get(this.type.expressions, 0))
453        elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys:
454            index = this.keys.index(bracket_arg)
455            value = seq_get(this.values, index)
456            self._set_type(expression, value.type if value else None)
457        else:
458            self._set_type(expression, exp.DataType.Type.UNKNOWN)
459
460        return expression
461
462    def _annotate_div(self, expression: exp.Div) -> exp.Div:
463        self._annotate_args(expression)
464
465        left_type, right_type = expression.left.type.this, expression.right.type.this  # type: ignore
466
467        if (
468            expression.args.get("typed")
469            and left_type in exp.DataType.INTEGER_TYPES
470            and right_type in exp.DataType.INTEGER_TYPES
471        ):
472            self._set_type(expression, exp.DataType.Type.BIGINT)
473        else:
474            self._set_type(expression, self._maybe_coerce(left_type, right_type))
475            if expression.type and expression.type.this not in exp.DataType.REAL_TYPES:
476                self._set_type(
477                    expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE)
478                )
479
480        return expression
481
482    def _annotate_dot(self, expression: exp.Dot) -> exp.Dot:
483        self._annotate_args(expression)
484        self._set_type(expression, None)
485        this_type = expression.this.type
486
487        if this_type and this_type.is_type(exp.DataType.Type.STRUCT):
488            for e in this_type.expressions:
489                if e.name == expression.expression.name:
490                    self._set_type(expression, e.kind)
491                    break
492
493        return expression
494
495    def _annotate_explode(self, expression: exp.Explode) -> exp.Explode:
496        self._annotate_args(expression)
497        self._set_type(expression, seq_get(expression.this.type.expressions, 0))
498        return expression
499
500    def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest:
501        self._annotate_args(expression)
502        child = seq_get(expression.expressions, 0)
503
504        if child and child.is_type(exp.DataType.Type.ARRAY):
505            expr_type = seq_get(child.type.expressions, 0)
506        else:
507            expr_type = None
508
509        self._set_type(expression, expr_type)
510        return expression
511
512    def _annotate_struct_value(
513        self, expression: exp.Expression
514    ) -> t.Optional[exp.DataType] | exp.ColumnDef:
515        alias = expression.args.get("alias")
516        if alias:
517            return exp.ColumnDef(this=alias.copy(), kind=expression.type)
518
519        # Case: key = value or key := value
520        if expression.expression:
521            return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type)
522
523        return expression.type
524
525    def _annotate_struct(self, expression: exp.Struct) -> exp.Struct:
526        self._annotate_args(expression)
527        self._set_type(
528            expression,
529            exp.DataType(
530                this=exp.DataType.Type.STRUCT,
531                expressions=[self._annotate_struct_value(expr) for expr in expression.expressions],
532                nested=True,
533            ),
534        )
535        return expression
536
537    @t.overload
538    def _annotate_map(self, expression: exp.Map) -> exp.Map: ...
539
540    @t.overload
541    def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ...
542
543    def _annotate_map(self, expression):
544        self._annotate_args(expression)
545
546        keys = expression.args.get("keys")
547        values = expression.args.get("values")
548
549        map_type = exp.DataType(this=exp.DataType.Type.MAP)
550        if isinstance(keys, exp.Array) and isinstance(values, exp.Array):
551            key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN
552            value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN
553
554            if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN:
555                map_type.set("expressions", [key_type, value_type])
556                map_type.set("nested", True)
557
558        self._set_type(expression, map_type)
559        return expression
560
561    def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap:
562        self._annotate_args(expression)
563
564        map_type = exp.DataType(this=exp.DataType.Type.MAP)
565        arg = expression.this
566        if arg.is_type(exp.DataType.Type.STRUCT):
567            for coldef in arg.type.expressions:
568                kind = coldef.kind
569                if kind != exp.DataType.Type.UNKNOWN:
570                    map_type.set("expressions", [exp.DataType.build("varchar"), kind])
571                    map_type.set("nested", True)
572                    break
573
574        self._set_type(expression, map_type)
575        return expression
576
577    def _annotate_extract(self, expression: exp.Extract) -> exp.Extract:
578        self._annotate_args(expression)
579        part = expression.name
580        if part == "TIME":
581            self._set_type(expression, exp.DataType.Type.TIME)
582        elif part == "DATE":
583            self._set_type(expression, exp.DataType.Type.DATE)
584        else:
585            self._set_type(expression, exp.DataType.Type.INT)
586        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, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> ~E:
31def annotate_types(
32    expression: E,
33    schema: t.Optional[t.Dict | Schema] = None,
34    annotators: t.Optional[AnnotatorsType] = None,
35    coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
36    dialect: t.Optional[DialectType] = None,
37) -> E:
38    """
39    Infers the types of an expression, annotating its AST accordingly.
40
41    Example:
42        >>> import sqlglot
43        >>> schema = {"y": {"cola": "SMALLINT"}}
44        >>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x"
45        >>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema)
46        >>> annotated_expr.expressions[0].type.this  # Get the type of "x.cola + 2.5 AS cola"
47        <Type.DOUBLE: 'DOUBLE'>
48
49    Args:
50        expression: Expression to annotate.
51        schema: Database schema.
52        annotators: Maps expression type to corresponding annotation function.
53        coerces_to: Maps expression type to set of types that it can be coerced into.
54
55    Returns:
56        The expression annotated with types.
57    """
58
59    schema = ensure_schema(schema)
60
61    return TypeAnnotator(schema, annotators, coerces_to, dialect=dialect).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.

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
92def swap_all(coercions: BinaryCoercions) -> BinaryCoercions:
93    return {**coercions, **{(b, a): swap_args(func) for (a, b), func in coercions.items()}}
class TypeAnnotator:
142class TypeAnnotator(metaclass=_TypeAnnotator):
143    NESTED_TYPES = {
144        exp.DataType.Type.ARRAY,
145    }
146
147    # Specifies what types a given type can be coerced into (autofilled)
148    COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {}
149
150    # Coercion functions for binary operations.
151    # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type.
152    BINARY_COERCIONS: BinaryCoercions = {
153        **swap_all(
154            {
155                (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal(
156                    l, r.args.get("unit")
157                )
158                for t in exp.DataType.TEXT_TYPES
159            }
160        ),
161        **swap_all(
162            {
163                # text + numeric will yield the numeric type to match most dialects' semantics
164                (text, numeric): lambda l, r: t.cast(
165                    exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type
166                )
167                for text in exp.DataType.TEXT_TYPES
168                for numeric in exp.DataType.NUMERIC_TYPES
169            }
170        ),
171        **swap_all(
172            {
173                (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date(
174                    l, r.args.get("unit")
175                ),
176            }
177        ),
178    }
179
180    def __init__(
181        self,
182        schema: Schema,
183        annotators: t.Optional[AnnotatorsType] = None,
184        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
185        binary_coercions: t.Optional[BinaryCoercions] = None,
186        dialect: t.Optional[DialectType] = None,
187    ) -> None:
188        self.schema = schema
189        self.annotators = annotators or Dialect.get_or_raise(dialect).ANNOTATORS
190        self.coerces_to = coerces_to or self.COERCES_TO
191        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
192
193        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
194        self._visited: t.Set[int] = set()
195
196        # Maps an exp.SetOperation's id (e.g. UNION) to its projection types. This is computed if the
197        # exp.SetOperation is the expression of a scope source, as selecting from it multiple times
198        # would reprocess the entire subtree to coerce the types of its operands' projections
199        self._setop_column_types: t.Dict[int, t.Dict[str, exp.DataType | exp.DataType.Type]] = {}
200
201    def _set_type(
202        self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type]
203    ) -> None:
204        expression.type = target_type or exp.DataType.Type.UNKNOWN  # type: ignore
205        self._visited.add(id(expression))
206
207    def annotate(self, expression: E) -> E:
208        for scope in traverse_scope(expression):
209            self.annotate_scope(scope)
210        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions
211
212    def annotate_scope(self, scope: Scope) -> None:
213        selects = {}
214        for name, source in scope.sources.items():
215            if not isinstance(source, Scope):
216                continue
217
218            expression = source.expression
219            if isinstance(expression, exp.UDTF):
220                values = []
221
222                if isinstance(expression, exp.Lateral):
223                    if isinstance(expression.this, exp.Explode):
224                        values = [expression.this.this]
225                elif isinstance(expression, exp.Unnest):
226                    values = [expression]
227                else:
228                    values = expression.expressions[0].expressions
229
230                if not values:
231                    continue
232
233                selects[name] = {
234                    alias: column.type
235                    for alias, column in zip(expression.alias_column_names, values)
236                }
237            elif isinstance(expression, exp.SetOperation) and len(expression.left.selects) == len(
238                expression.right.selects
239            ):
240                selects[name] = col_types = self._setop_column_types.setdefault(id(expression), {})
241
242                if not col_types:
243                    # Process a chain / sub-tree of set operations
244                    for set_op in expression.walk(
245                        prune=lambda n: not isinstance(n, (exp.SetOperation, exp.Subquery))
246                    ):
247                        if not isinstance(set_op, exp.SetOperation):
248                            continue
249
250                        if set_op.args.get("by_name"):
251                            r_type_by_select = {
252                                s.alias_or_name: s.type for s in set_op.right.selects
253                            }
254                            setop_cols = {
255                                s.alias_or_name: self._maybe_coerce(
256                                    t.cast(exp.DataType, s.type),
257                                    r_type_by_select.get(s.alias_or_name)
258                                    or exp.DataType.Type.UNKNOWN,
259                                )
260                                for s in set_op.left.selects
261                            }
262                        else:
263                            setop_cols = {
264                                ls.alias_or_name: self._maybe_coerce(
265                                    t.cast(exp.DataType, ls.type), t.cast(exp.DataType, rs.type)
266                                )
267                                for ls, rs in zip(set_op.left.selects, set_op.right.selects)
268                            }
269
270                        # Coerce intermediate results with the previously registered types, if they exist
271                        for col_name, col_type in setop_cols.items():
272                            col_types[col_name] = self._maybe_coerce(
273                                col_type, col_types.get(col_name, exp.DataType.Type.NULL)
274                            )
275
276            else:
277                selects[name] = {s.alias_or_name: s.type for s in expression.selects}
278
279        # First annotate the current scope's column references
280        for col in scope.columns:
281            if not col.table:
282                continue
283
284            source = scope.sources.get(col.table)
285            if isinstance(source, exp.Table):
286                self._set_type(col, self.schema.get_column_type(source, col))
287            elif source:
288                if col.table in selects and col.name in selects[col.table]:
289                    self._set_type(col, selects[col.table][col.name])
290                elif isinstance(source.expression, exp.Unnest):
291                    self._set_type(col, source.expression.type)
292
293        # Then (possibly) annotate the remaining expressions in the scope
294        self._maybe_annotate(scope.expression)
295
296    def _maybe_annotate(self, expression: E) -> E:
297        if id(expression) in self._visited:
298            return expression  # We've already inferred the expression's type
299
300        annotator = self.annotators.get(expression.__class__)
301
302        return (
303            annotator(self, expression)
304            if annotator
305            else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN)
306        )
307
308    def _annotate_args(self, expression: E) -> E:
309        for value in expression.iter_expressions():
310            self._maybe_annotate(value)
311
312        return expression
313
314    def _maybe_coerce(
315        self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type
316    ) -> exp.DataType | exp.DataType.Type:
317        """
318        Returns type2 if type1 can be coerced into it, otherwise type1.
319
320        If either type is parameterized (e.g. DECIMAL(18, 2) contains two parameters),
321        we assume type1 does not coerce into type2, so we also return it in this case.
322        """
323        if isinstance(type1, exp.DataType):
324            if type1.expressions:
325                return type1
326            type1_value = type1.this
327        else:
328            type1_value = type1
329
330        if isinstance(type2, exp.DataType):
331            if type2.expressions:
332                return type1
333            type2_value = type2.this
334        else:
335            type2_value = type2
336
337        # We propagate the UNKNOWN type upwards if found
338        if exp.DataType.Type.UNKNOWN in (type1_value, type2_value):
339            return exp.DataType.Type.UNKNOWN
340
341        return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value
342
343    def _annotate_binary(self, expression: B) -> B:
344        self._annotate_args(expression)
345
346        left, right = expression.left, expression.right
347        left_type, right_type = left.type.this, right.type.this  # type: ignore
348
349        if isinstance(expression, (exp.Connector, exp.Predicate)):
350            self._set_type(expression, exp.DataType.Type.BOOLEAN)
351        elif (left_type, right_type) in self.binary_coercions:
352            self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right))
353        else:
354            self._set_type(expression, self._maybe_coerce(left_type, right_type))
355
356        return expression
357
358    def _annotate_unary(self, expression: E) -> E:
359        self._annotate_args(expression)
360
361        if isinstance(expression, exp.Not):
362            self._set_type(expression, exp.DataType.Type.BOOLEAN)
363        else:
364            self._set_type(expression, expression.this.type)
365
366        return expression
367
368    def _annotate_literal(self, expression: exp.Literal) -> exp.Literal:
369        if expression.is_string:
370            self._set_type(expression, exp.DataType.Type.VARCHAR)
371        elif expression.is_int:
372            self._set_type(expression, exp.DataType.Type.INT)
373        else:
374            self._set_type(expression, exp.DataType.Type.DOUBLE)
375
376        return expression
377
378    def _annotate_with_type(
379        self, expression: E, target_type: exp.DataType | exp.DataType.Type
380    ) -> E:
381        self._set_type(expression, target_type)
382        return self._annotate_args(expression)
383
384    @t.no_type_check
385    def _annotate_by_args(
386        self,
387        expression: E,
388        *args: str,
389        promote: bool = False,
390        array: bool = False,
391    ) -> E:
392        self._annotate_args(expression)
393
394        expressions: t.List[exp.Expression] = []
395        for arg in args:
396            arg_expr = expression.args.get(arg)
397            expressions.extend(expr for expr in ensure_list(arg_expr) if expr)
398
399        last_datatype = None
400        for expr in expressions:
401            expr_type = expr.type
402
403            # Stop at the first nested data type found - we don't want to _maybe_coerce nested types
404            if expr_type.args.get("nested"):
405                last_datatype = expr_type
406                break
407
408            if not expr_type.is_type(exp.DataType.Type.UNKNOWN):
409                last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type)
410
411        self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN)
412
413        if promote:
414            if expression.type.this in exp.DataType.INTEGER_TYPES:
415                self._set_type(expression, exp.DataType.Type.BIGINT)
416            elif expression.type.this in exp.DataType.FLOAT_TYPES:
417                self._set_type(expression, exp.DataType.Type.DOUBLE)
418
419        if array:
420            self._set_type(
421                expression,
422                exp.DataType(
423                    this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True
424                ),
425            )
426
427        return expression
428
429    def _annotate_timeunit(
430        self, expression: exp.TimeUnit | exp.DateTrunc
431    ) -> exp.TimeUnit | exp.DateTrunc:
432        self._annotate_args(expression)
433
434        if expression.this.type.this in exp.DataType.TEXT_TYPES:
435            datatype = _coerce_date_literal(expression.this, expression.unit)
436        elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES:
437            datatype = _coerce_date(expression.this, expression.unit)
438        else:
439            datatype = exp.DataType.Type.UNKNOWN
440
441        self._set_type(expression, datatype)
442        return expression
443
444    def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket:
445        self._annotate_args(expression)
446
447        bracket_arg = expression.expressions[0]
448        this = expression.this
449
450        if isinstance(bracket_arg, exp.Slice):
451            self._set_type(expression, this.type)
452        elif this.type.is_type(exp.DataType.Type.ARRAY):
453            self._set_type(expression, seq_get(this.type.expressions, 0))
454        elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys:
455            index = this.keys.index(bracket_arg)
456            value = seq_get(this.values, index)
457            self._set_type(expression, value.type if value else None)
458        else:
459            self._set_type(expression, exp.DataType.Type.UNKNOWN)
460
461        return expression
462
463    def _annotate_div(self, expression: exp.Div) -> exp.Div:
464        self._annotate_args(expression)
465
466        left_type, right_type = expression.left.type.this, expression.right.type.this  # type: ignore
467
468        if (
469            expression.args.get("typed")
470            and left_type in exp.DataType.INTEGER_TYPES
471            and right_type in exp.DataType.INTEGER_TYPES
472        ):
473            self._set_type(expression, exp.DataType.Type.BIGINT)
474        else:
475            self._set_type(expression, self._maybe_coerce(left_type, right_type))
476            if expression.type and expression.type.this not in exp.DataType.REAL_TYPES:
477                self._set_type(
478                    expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE)
479                )
480
481        return expression
482
483    def _annotate_dot(self, expression: exp.Dot) -> exp.Dot:
484        self._annotate_args(expression)
485        self._set_type(expression, None)
486        this_type = expression.this.type
487
488        if this_type and this_type.is_type(exp.DataType.Type.STRUCT):
489            for e in this_type.expressions:
490                if e.name == expression.expression.name:
491                    self._set_type(expression, e.kind)
492                    break
493
494        return expression
495
496    def _annotate_explode(self, expression: exp.Explode) -> exp.Explode:
497        self._annotate_args(expression)
498        self._set_type(expression, seq_get(expression.this.type.expressions, 0))
499        return expression
500
501    def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest:
502        self._annotate_args(expression)
503        child = seq_get(expression.expressions, 0)
504
505        if child and child.is_type(exp.DataType.Type.ARRAY):
506            expr_type = seq_get(child.type.expressions, 0)
507        else:
508            expr_type = None
509
510        self._set_type(expression, expr_type)
511        return expression
512
513    def _annotate_struct_value(
514        self, expression: exp.Expression
515    ) -> t.Optional[exp.DataType] | exp.ColumnDef:
516        alias = expression.args.get("alias")
517        if alias:
518            return exp.ColumnDef(this=alias.copy(), kind=expression.type)
519
520        # Case: key = value or key := value
521        if expression.expression:
522            return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type)
523
524        return expression.type
525
526    def _annotate_struct(self, expression: exp.Struct) -> exp.Struct:
527        self._annotate_args(expression)
528        self._set_type(
529            expression,
530            exp.DataType(
531                this=exp.DataType.Type.STRUCT,
532                expressions=[self._annotate_struct_value(expr) for expr in expression.expressions],
533                nested=True,
534            ),
535        )
536        return expression
537
538    @t.overload
539    def _annotate_map(self, expression: exp.Map) -> exp.Map: ...
540
541    @t.overload
542    def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ...
543
544    def _annotate_map(self, expression):
545        self._annotate_args(expression)
546
547        keys = expression.args.get("keys")
548        values = expression.args.get("values")
549
550        map_type = exp.DataType(this=exp.DataType.Type.MAP)
551        if isinstance(keys, exp.Array) and isinstance(values, exp.Array):
552            key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN
553            value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN
554
555            if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN:
556                map_type.set("expressions", [key_type, value_type])
557                map_type.set("nested", True)
558
559        self._set_type(expression, map_type)
560        return expression
561
562    def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap:
563        self._annotate_args(expression)
564
565        map_type = exp.DataType(this=exp.DataType.Type.MAP)
566        arg = expression.this
567        if arg.is_type(exp.DataType.Type.STRUCT):
568            for coldef in arg.type.expressions:
569                kind = coldef.kind
570                if kind != exp.DataType.Type.UNKNOWN:
571                    map_type.set("expressions", [exp.DataType.build("varchar"), kind])
572                    map_type.set("nested", True)
573                    break
574
575        self._set_type(expression, map_type)
576        return expression
577
578    def _annotate_extract(self, expression: exp.Extract) -> exp.Extract:
579        self._annotate_args(expression)
580        part = expression.name
581        if part == "TIME":
582            self._set_type(expression, exp.DataType.Type.TIME)
583        elif part == "DATE":
584            self._set_type(expression, exp.DataType.Type.DATE)
585        else:
586            self._set_type(expression, exp.DataType.Type.INT)
587        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, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None)
180    def __init__(
181        self,
182        schema: Schema,
183        annotators: t.Optional[AnnotatorsType] = None,
184        coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
185        binary_coercions: t.Optional[BinaryCoercions] = None,
186        dialect: t.Optional[DialectType] = None,
187    ) -> None:
188        self.schema = schema
189        self.annotators = annotators or Dialect.get_or_raise(dialect).ANNOTATORS
190        self.coerces_to = coerces_to or self.COERCES_TO
191        self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
192
193        # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
194        self._visited: t.Set[int] = set()
195
196        # Maps an exp.SetOperation's id (e.g. UNION) to its projection types. This is computed if the
197        # exp.SetOperation is the expression of a scope source, as selecting from it multiple times
198        # would reprocess the entire subtree to coerce the types of its operands' projections
199        self._setop_column_types: t.Dict[int, t.Dict[str, exp.DataType | exp.DataType.Type]] = {}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>}
COERCES_TO: Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]] = {<Type.TEXT: 'TEXT'>: set(), <Type.NVARCHAR: 'NVARCHAR'>: {<Type.TEXT: 'TEXT'>}, <Type.VARCHAR: 'VARCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>}, <Type.NCHAR: 'NCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.CHAR: 'CHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.DOUBLE: 'DOUBLE'>: set(), <Type.FLOAT: 'FLOAT'>: {<Type.DOUBLE: 'DOUBLE'>}, <Type.DECIMAL: 'DECIMAL'>: {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.BIGINT: 'BIGINT'>: {<Type.DECIMAL: 'DECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.INT: 'INT'>: {<Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.TINYINT: 'TINYINT'>: {<Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATETIME: 'DATETIME'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATE: 'DATE'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.NULL: 'NULL'>: {<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TINYINT: 'TINYINT'>, <Type.DATE: 'DATE'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>, <Type.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME: 'DATETIME'>, <Type.DOUBLE: 'DOUBLE'>}}
BINARY_COERCIONS: Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]] = {(<Type.NCHAR: 'NCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL128: 'DECIMAL128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UDOUBLE: 'UDOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL64: 'DECIMAL64'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL128: 'DECIMAL128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UDOUBLE: 'UDOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL128: 'DECIMAL128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UDOUBLE: 'UDOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL64: 'DECIMAL64'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL128: 'DECIMAL128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UDOUBLE: 'UDOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL128: 'DECIMAL128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UDOUBLE: 'UDOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL128: 'DECIMAL128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UDOUBLE: 'UDOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL128: 'DECIMAL128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDOUBLE: 'UDOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL128: 'DECIMAL128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDOUBLE: 'UDOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL128: 'DECIMAL128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDOUBLE: 'UDOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL128: 'DECIMAL128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDOUBLE: 'UDOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL128: 'DECIMAL128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDOUBLE: 'UDOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL128: 'DECIMAL128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDOUBLE: 'UDOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <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:
207    def annotate(self, expression: E) -> E:
208        for scope in traverse_scope(expression):
209            self.annotate_scope(scope)
210        return self._maybe_annotate(expression)  # This takes care of non-traversable expressions
def annotate_scope(self, scope: sqlglot.optimizer.scope.Scope) -> None:
212    def annotate_scope(self, scope: Scope) -> None:
213        selects = {}
214        for name, source in scope.sources.items():
215            if not isinstance(source, Scope):
216                continue
217
218            expression = source.expression
219            if isinstance(expression, exp.UDTF):
220                values = []
221
222                if isinstance(expression, exp.Lateral):
223                    if isinstance(expression.this, exp.Explode):
224                        values = [expression.this.this]
225                elif isinstance(expression, exp.Unnest):
226                    values = [expression]
227                else:
228                    values = expression.expressions[0].expressions
229
230                if not values:
231                    continue
232
233                selects[name] = {
234                    alias: column.type
235                    for alias, column in zip(expression.alias_column_names, values)
236                }
237            elif isinstance(expression, exp.SetOperation) and len(expression.left.selects) == len(
238                expression.right.selects
239            ):
240                selects[name] = col_types = self._setop_column_types.setdefault(id(expression), {})
241
242                if not col_types:
243                    # Process a chain / sub-tree of set operations
244                    for set_op in expression.walk(
245                        prune=lambda n: not isinstance(n, (exp.SetOperation, exp.Subquery))
246                    ):
247                        if not isinstance(set_op, exp.SetOperation):
248                            continue
249
250                        if set_op.args.get("by_name"):
251                            r_type_by_select = {
252                                s.alias_or_name: s.type for s in set_op.right.selects
253                            }
254                            setop_cols = {
255                                s.alias_or_name: self._maybe_coerce(
256                                    t.cast(exp.DataType, s.type),
257                                    r_type_by_select.get(s.alias_or_name)
258                                    or exp.DataType.Type.UNKNOWN,
259                                )
260                                for s in set_op.left.selects
261                            }
262                        else:
263                            setop_cols = {
264                                ls.alias_or_name: self._maybe_coerce(
265                                    t.cast(exp.DataType, ls.type), t.cast(exp.DataType, rs.type)
266                                )
267                                for ls, rs in zip(set_op.left.selects, set_op.right.selects)
268                            }
269
270                        # Coerce intermediate results with the previously registered types, if they exist
271                        for col_name, col_type in setop_cols.items():
272                            col_types[col_name] = self._maybe_coerce(
273                                col_type, col_types.get(col_name, exp.DataType.Type.NULL)
274                            )
275
276            else:
277                selects[name] = {s.alias_or_name: s.type for s in expression.selects}
278
279        # First annotate the current scope's column references
280        for col in scope.columns:
281            if not col.table:
282                continue
283
284            source = scope.sources.get(col.table)
285            if isinstance(source, exp.Table):
286                self._set_type(col, self.schema.get_column_type(source, col))
287            elif source:
288                if col.table in selects and col.name in selects[col.table]:
289                    self._set_type(col, selects[col.table][col.name])
290                elif isinstance(source.expression, exp.Unnest):
291                    self._set_type(col, source.expression.type)
292
293        # Then (possibly) annotate the remaining expressions in the scope
294        self._maybe_annotate(scope.expression)