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.
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 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]] = {}
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>>}
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)