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.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.Type: 316 type1_value = type1.this if isinstance(type1, exp.DataType) else type1 317 type2_value = type2.this if isinstance(type2, exp.DataType) else type2 318 319 # We propagate the UNKNOWN type upwards if found 320 if exp.DataType.Type.UNKNOWN in (type1_value, type2_value): 321 return exp.DataType.Type.UNKNOWN 322 323 return t.cast( 324 exp.DataType.Type, 325 type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value, 326 ) 327 328 def _annotate_binary(self, expression: B) -> B: 329 self._annotate_args(expression) 330 331 left, right = expression.left, expression.right 332 left_type, right_type = left.type.this, right.type.this # type: ignore 333 334 if isinstance(expression, (exp.Connector, exp.Predicate)): 335 self._set_type(expression, exp.DataType.Type.BOOLEAN) 336 elif (left_type, right_type) in self.binary_coercions: 337 self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right)) 338 else: 339 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 340 341 return expression 342 343 def _annotate_unary(self, expression: E) -> E: 344 self._annotate_args(expression) 345 346 if isinstance(expression, exp.Not): 347 self._set_type(expression, exp.DataType.Type.BOOLEAN) 348 else: 349 self._set_type(expression, expression.this.type) 350 351 return expression 352 353 def _annotate_literal(self, expression: exp.Literal) -> exp.Literal: 354 if expression.is_string: 355 self._set_type(expression, exp.DataType.Type.VARCHAR) 356 elif expression.is_int: 357 self._set_type(expression, exp.DataType.Type.INT) 358 else: 359 self._set_type(expression, exp.DataType.Type.DOUBLE) 360 361 return expression 362 363 def _annotate_with_type( 364 self, expression: E, target_type: exp.DataType | exp.DataType.Type 365 ) -> E: 366 self._set_type(expression, target_type) 367 return self._annotate_args(expression) 368 369 @t.no_type_check 370 def _annotate_by_args( 371 self, 372 expression: E, 373 *args: str, 374 promote: bool = False, 375 array: bool = False, 376 ) -> E: 377 self._annotate_args(expression) 378 379 expressions: t.List[exp.Expression] = [] 380 for arg in args: 381 arg_expr = expression.args.get(arg) 382 expressions.extend(expr for expr in ensure_list(arg_expr) if expr) 383 384 last_datatype = None 385 for expr in expressions: 386 expr_type = expr.type 387 388 # Stop at the first nested data type found - we don't want to _maybe_coerce nested types 389 if expr_type.args.get("nested"): 390 last_datatype = expr_type 391 break 392 393 if not expr_type.is_type(exp.DataType.Type.UNKNOWN): 394 last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type) 395 396 self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN) 397 398 if promote: 399 if expression.type.this in exp.DataType.INTEGER_TYPES: 400 self._set_type(expression, exp.DataType.Type.BIGINT) 401 elif expression.type.this in exp.DataType.FLOAT_TYPES: 402 self._set_type(expression, exp.DataType.Type.DOUBLE) 403 404 if array: 405 self._set_type( 406 expression, 407 exp.DataType( 408 this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True 409 ), 410 ) 411 412 return expression 413 414 def _annotate_timeunit( 415 self, expression: exp.TimeUnit | exp.DateTrunc 416 ) -> exp.TimeUnit | exp.DateTrunc: 417 self._annotate_args(expression) 418 419 if expression.this.type.this in exp.DataType.TEXT_TYPES: 420 datatype = _coerce_date_literal(expression.this, expression.unit) 421 elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES: 422 datatype = _coerce_date(expression.this, expression.unit) 423 else: 424 datatype = exp.DataType.Type.UNKNOWN 425 426 self._set_type(expression, datatype) 427 return expression 428 429 def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket: 430 self._annotate_args(expression) 431 432 bracket_arg = expression.expressions[0] 433 this = expression.this 434 435 if isinstance(bracket_arg, exp.Slice): 436 self._set_type(expression, this.type) 437 elif this.type.is_type(exp.DataType.Type.ARRAY): 438 self._set_type(expression, seq_get(this.type.expressions, 0)) 439 elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys: 440 index = this.keys.index(bracket_arg) 441 value = seq_get(this.values, index) 442 self._set_type(expression, value.type if value else None) 443 else: 444 self._set_type(expression, exp.DataType.Type.UNKNOWN) 445 446 return expression 447 448 def _annotate_div(self, expression: exp.Div) -> exp.Div: 449 self._annotate_args(expression) 450 451 left_type, right_type = expression.left.type.this, expression.right.type.this # type: ignore 452 453 if ( 454 expression.args.get("typed") 455 and left_type in exp.DataType.INTEGER_TYPES 456 and right_type in exp.DataType.INTEGER_TYPES 457 ): 458 self._set_type(expression, exp.DataType.Type.BIGINT) 459 else: 460 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 461 if expression.type and expression.type.this not in exp.DataType.REAL_TYPES: 462 self._set_type( 463 expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE) 464 ) 465 466 return expression 467 468 def _annotate_dot(self, expression: exp.Dot) -> exp.Dot: 469 self._annotate_args(expression) 470 self._set_type(expression, None) 471 this_type = expression.this.type 472 473 if this_type and this_type.is_type(exp.DataType.Type.STRUCT): 474 for e in this_type.expressions: 475 if e.name == expression.expression.name: 476 self._set_type(expression, e.kind) 477 break 478 479 return expression 480 481 def _annotate_explode(self, expression: exp.Explode) -> exp.Explode: 482 self._annotate_args(expression) 483 self._set_type(expression, seq_get(expression.this.type.expressions, 0)) 484 return expression 485 486 def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest: 487 self._annotate_args(expression) 488 child = seq_get(expression.expressions, 0) 489 490 if child and child.is_type(exp.DataType.Type.ARRAY): 491 expr_type = seq_get(child.type.expressions, 0) 492 else: 493 expr_type = None 494 495 self._set_type(expression, expr_type) 496 return expression 497 498 def _annotate_struct_value( 499 self, expression: exp.Expression 500 ) -> t.Optional[exp.DataType] | exp.ColumnDef: 501 alias = expression.args.get("alias") 502 if alias: 503 return exp.ColumnDef(this=alias.copy(), kind=expression.type) 504 505 # Case: key = value or key := value 506 if expression.expression: 507 return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type) 508 509 return expression.type 510 511 def _annotate_struct(self, expression: exp.Struct) -> exp.Struct: 512 self._annotate_args(expression) 513 self._set_type( 514 expression, 515 exp.DataType( 516 this=exp.DataType.Type.STRUCT, 517 expressions=[self._annotate_struct_value(expr) for expr in expression.expressions], 518 nested=True, 519 ), 520 ) 521 return expression 522 523 @t.overload 524 def _annotate_map(self, expression: exp.Map) -> exp.Map: ... 525 526 @t.overload 527 def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ... 528 529 def _annotate_map(self, expression): 530 self._annotate_args(expression) 531 532 keys = expression.args.get("keys") 533 values = expression.args.get("values") 534 535 map_type = exp.DataType(this=exp.DataType.Type.MAP) 536 if isinstance(keys, exp.Array) and isinstance(values, exp.Array): 537 key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN 538 value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN 539 540 if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN: 541 map_type.set("expressions", [key_type, value_type]) 542 map_type.set("nested", True) 543 544 self._set_type(expression, map_type) 545 return expression 546 547 def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap: 548 self._annotate_args(expression) 549 550 map_type = exp.DataType(this=exp.DataType.Type.MAP) 551 arg = expression.this 552 if arg.is_type(exp.DataType.Type.STRUCT): 553 for coldef in arg.type.expressions: 554 kind = coldef.kind 555 if kind != exp.DataType.Type.UNKNOWN: 556 map_type.set("expressions", [exp.DataType.build("varchar"), kind]) 557 map_type.set("nested", True) 558 break 559 560 self._set_type(expression, map_type) 561 return expression 562 563 def _annotate_extract(self, expression: exp.Extract) -> exp.Extract: 564 self._annotate_args(expression) 565 part = expression.name 566 if part == "TIME": 567 self._set_type(expression, exp.DataType.Type.TIME) 568 elif part == "DATE": 569 self._set_type(expression, exp.DataType.Type.DATE) 570 else: 571 self._set_type(expression, exp.DataType.Type.INT) 572 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.Dialect, Type[sqlglot.dialects.dialect.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.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.Type: 317 type1_value = type1.this if isinstance(type1, exp.DataType) else type1 318 type2_value = type2.this if isinstance(type2, exp.DataType) else type2 319 320 # We propagate the UNKNOWN type upwards if found 321 if exp.DataType.Type.UNKNOWN in (type1_value, type2_value): 322 return exp.DataType.Type.UNKNOWN 323 324 return t.cast( 325 exp.DataType.Type, 326 type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value, 327 ) 328 329 def _annotate_binary(self, expression: B) -> B: 330 self._annotate_args(expression) 331 332 left, right = expression.left, expression.right 333 left_type, right_type = left.type.this, right.type.this # type: ignore 334 335 if isinstance(expression, (exp.Connector, exp.Predicate)): 336 self._set_type(expression, exp.DataType.Type.BOOLEAN) 337 elif (left_type, right_type) in self.binary_coercions: 338 self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right)) 339 else: 340 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 341 342 return expression 343 344 def _annotate_unary(self, expression: E) -> E: 345 self._annotate_args(expression) 346 347 if isinstance(expression, exp.Not): 348 self._set_type(expression, exp.DataType.Type.BOOLEAN) 349 else: 350 self._set_type(expression, expression.this.type) 351 352 return expression 353 354 def _annotate_literal(self, expression: exp.Literal) -> exp.Literal: 355 if expression.is_string: 356 self._set_type(expression, exp.DataType.Type.VARCHAR) 357 elif expression.is_int: 358 self._set_type(expression, exp.DataType.Type.INT) 359 else: 360 self._set_type(expression, exp.DataType.Type.DOUBLE) 361 362 return expression 363 364 def _annotate_with_type( 365 self, expression: E, target_type: exp.DataType | exp.DataType.Type 366 ) -> E: 367 self._set_type(expression, target_type) 368 return self._annotate_args(expression) 369 370 @t.no_type_check 371 def _annotate_by_args( 372 self, 373 expression: E, 374 *args: str, 375 promote: bool = False, 376 array: bool = False, 377 ) -> E: 378 self._annotate_args(expression) 379 380 expressions: t.List[exp.Expression] = [] 381 for arg in args: 382 arg_expr = expression.args.get(arg) 383 expressions.extend(expr for expr in ensure_list(arg_expr) if expr) 384 385 last_datatype = None 386 for expr in expressions: 387 expr_type = expr.type 388 389 # Stop at the first nested data type found - we don't want to _maybe_coerce nested types 390 if expr_type.args.get("nested"): 391 last_datatype = expr_type 392 break 393 394 if not expr_type.is_type(exp.DataType.Type.UNKNOWN): 395 last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type) 396 397 self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN) 398 399 if promote: 400 if expression.type.this in exp.DataType.INTEGER_TYPES: 401 self._set_type(expression, exp.DataType.Type.BIGINT) 402 elif expression.type.this in exp.DataType.FLOAT_TYPES: 403 self._set_type(expression, exp.DataType.Type.DOUBLE) 404 405 if array: 406 self._set_type( 407 expression, 408 exp.DataType( 409 this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True 410 ), 411 ) 412 413 return expression 414 415 def _annotate_timeunit( 416 self, expression: exp.TimeUnit | exp.DateTrunc 417 ) -> exp.TimeUnit | exp.DateTrunc: 418 self._annotate_args(expression) 419 420 if expression.this.type.this in exp.DataType.TEXT_TYPES: 421 datatype = _coerce_date_literal(expression.this, expression.unit) 422 elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES: 423 datatype = _coerce_date(expression.this, expression.unit) 424 else: 425 datatype = exp.DataType.Type.UNKNOWN 426 427 self._set_type(expression, datatype) 428 return expression 429 430 def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket: 431 self._annotate_args(expression) 432 433 bracket_arg = expression.expressions[0] 434 this = expression.this 435 436 if isinstance(bracket_arg, exp.Slice): 437 self._set_type(expression, this.type) 438 elif this.type.is_type(exp.DataType.Type.ARRAY): 439 self._set_type(expression, seq_get(this.type.expressions, 0)) 440 elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys: 441 index = this.keys.index(bracket_arg) 442 value = seq_get(this.values, index) 443 self._set_type(expression, value.type if value else None) 444 else: 445 self._set_type(expression, exp.DataType.Type.UNKNOWN) 446 447 return expression 448 449 def _annotate_div(self, expression: exp.Div) -> exp.Div: 450 self._annotate_args(expression) 451 452 left_type, right_type = expression.left.type.this, expression.right.type.this # type: ignore 453 454 if ( 455 expression.args.get("typed") 456 and left_type in exp.DataType.INTEGER_TYPES 457 and right_type in exp.DataType.INTEGER_TYPES 458 ): 459 self._set_type(expression, exp.DataType.Type.BIGINT) 460 else: 461 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 462 if expression.type and expression.type.this not in exp.DataType.REAL_TYPES: 463 self._set_type( 464 expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE) 465 ) 466 467 return expression 468 469 def _annotate_dot(self, expression: exp.Dot) -> exp.Dot: 470 self._annotate_args(expression) 471 self._set_type(expression, None) 472 this_type = expression.this.type 473 474 if this_type and this_type.is_type(exp.DataType.Type.STRUCT): 475 for e in this_type.expressions: 476 if e.name == expression.expression.name: 477 self._set_type(expression, e.kind) 478 break 479 480 return expression 481 482 def _annotate_explode(self, expression: exp.Explode) -> exp.Explode: 483 self._annotate_args(expression) 484 self._set_type(expression, seq_get(expression.this.type.expressions, 0)) 485 return expression 486 487 def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest: 488 self._annotate_args(expression) 489 child = seq_get(expression.expressions, 0) 490 491 if child and child.is_type(exp.DataType.Type.ARRAY): 492 expr_type = seq_get(child.type.expressions, 0) 493 else: 494 expr_type = None 495 496 self._set_type(expression, expr_type) 497 return expression 498 499 def _annotate_struct_value( 500 self, expression: exp.Expression 501 ) -> t.Optional[exp.DataType] | exp.ColumnDef: 502 alias = expression.args.get("alias") 503 if alias: 504 return exp.ColumnDef(this=alias.copy(), kind=expression.type) 505 506 # Case: key = value or key := value 507 if expression.expression: 508 return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type) 509 510 return expression.type 511 512 def _annotate_struct(self, expression: exp.Struct) -> exp.Struct: 513 self._annotate_args(expression) 514 self._set_type( 515 expression, 516 exp.DataType( 517 this=exp.DataType.Type.STRUCT, 518 expressions=[self._annotate_struct_value(expr) for expr in expression.expressions], 519 nested=True, 520 ), 521 ) 522 return expression 523 524 @t.overload 525 def _annotate_map(self, expression: exp.Map) -> exp.Map: ... 526 527 @t.overload 528 def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ... 529 530 def _annotate_map(self, expression): 531 self._annotate_args(expression) 532 533 keys = expression.args.get("keys") 534 values = expression.args.get("values") 535 536 map_type = exp.DataType(this=exp.DataType.Type.MAP) 537 if isinstance(keys, exp.Array) and isinstance(values, exp.Array): 538 key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN 539 value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN 540 541 if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN: 542 map_type.set("expressions", [key_type, value_type]) 543 map_type.set("nested", True) 544 545 self._set_type(expression, map_type) 546 return expression 547 548 def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap: 549 self._annotate_args(expression) 550 551 map_type = exp.DataType(this=exp.DataType.Type.MAP) 552 arg = expression.this 553 if arg.is_type(exp.DataType.Type.STRUCT): 554 for coldef in arg.type.expressions: 555 kind = coldef.kind 556 if kind != exp.DataType.Type.UNKNOWN: 557 map_type.set("expressions", [exp.DataType.build("varchar"), kind]) 558 map_type.set("nested", True) 559 break 560 561 self._set_type(expression, map_type) 562 return expression 563 564 def _annotate_extract(self, expression: exp.Extract) -> exp.Extract: 565 self._annotate_args(expression) 566 part = expression.name 567 if part == "TIME": 568 self._set_type(expression, exp.DataType.Type.TIME) 569 elif part == "DATE": 570 self._set_type(expression, exp.DataType.Type.DATE) 571 else: 572 self._set_type(expression, exp.DataType.Type.INT) 573 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.Dialect, Type[sqlglot.dialects.dialect.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.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.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}, <Type.CHAR: 'CHAR'>: {<Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>}, <Type.DOUBLE: 'DOUBLE'>: set(), <Type.FLOAT: 'FLOAT'>: {<Type.DOUBLE: 'DOUBLE'>}, <Type.DECIMAL: 'DECIMAL'>: {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.BIGINT: 'BIGINT'>: {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.INT: 'INT'>: {<Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.TINYINT: 'TINYINT'>: {<Type.SMALLINT: 'SMALLINT'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>, <Type.DECIMAL: 'DECIMAL'>}, <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.DATETIME: 'DATETIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.NULL: 'NULL'>: {<Type.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>, <Type.DATETIME: 'DATETIME'>, <Type.TINYINT: 'TINYINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATE: 'DATE'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>}}
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.NVARCHAR: 'NVARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <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.INTERVAL: 'INTERVAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NAME: 'NAME'>): <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.NCHAR: 'NCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <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.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.TINYINT: 'TINYINT'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <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.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.TINYINT: 'TINYINT'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <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.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.TINYINT: 'TINYINT'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL64: 'DECIMAL64'>): <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.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.TINYINT: 'TINYINT'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL64: 'DECIMAL64'>): <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.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.TINYINT: 'TINYINT'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL64: 'DECIMAL64'>): <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.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL32: 'DECIMAL32'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.TINYINT: 'TINYINT'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL256: 'DECIMAL256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <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.MONEY: 'MONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <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.MONEY: 'MONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <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.MONEY: 'MONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <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.MONEY: 'MONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <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.MONEY: 'MONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL64: 'DECIMAL64'>, <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.MONEY: 'MONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL32: 'DECIMAL32'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL256: 'DECIMAL256'>, <Type.VARCHAR: 'VARCHAR'>): <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)