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