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 subclasses, 14) 15from sqlglot.optimizer.scope import Scope, traverse_scope 16from sqlglot.schema import Schema, ensure_schema 17 18if t.TYPE_CHECKING: 19 from sqlglot._typing import B, E 20 21 BinaryCoercionFunc = t.Callable[[exp.Expression, exp.Expression], exp.DataType.Type] 22 BinaryCoercions = t.Dict[ 23 t.Tuple[exp.DataType.Type, exp.DataType.Type], 24 BinaryCoercionFunc, 25 ] 26 27 28def annotate_types( 29 expression: E, 30 schema: t.Optional[t.Dict | Schema] = None, 31 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 32 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 33) -> E: 34 """ 35 Infers the types of an expression, annotating its AST accordingly. 36 37 Example: 38 >>> import sqlglot 39 >>> schema = {"y": {"cola": "SMALLINT"}} 40 >>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x" 41 >>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema) 42 >>> annotated_expr.expressions[0].type.this # Get the type of "x.cola + 2.5 AS cola" 43 <Type.DOUBLE: 'DOUBLE'> 44 45 Args: 46 expression: Expression to annotate. 47 schema: Database schema. 48 annotators: Maps expression type to corresponding annotation function. 49 coerces_to: Maps expression type to set of types that it can be coerced into. 50 51 Returns: 52 The expression annotated with types. 53 """ 54 55 schema = ensure_schema(schema) 56 57 return TypeAnnotator(schema, annotators, coerces_to).annotate(expression) 58 59 60def _annotate_with_type_lambda(data_type: exp.DataType.Type) -> t.Callable[[TypeAnnotator, E], E]: 61 return lambda self, e: self._annotate_with_type(e, data_type) 62 63 64def _coerce_date_literal(l: exp.Expression, unit: t.Optional[exp.Expression]) -> exp.DataType.Type: 65 date_text = l.name 66 is_iso_date_ = is_iso_date(date_text) 67 68 if is_iso_date_ and is_date_unit(unit): 69 return exp.DataType.Type.DATE 70 71 # An ISO date is also an ISO datetime, but not vice versa 72 if is_iso_date_ or is_iso_datetime(date_text): 73 return exp.DataType.Type.DATETIME 74 75 return exp.DataType.Type.UNKNOWN 76 77 78def _coerce_date(l: exp.Expression, unit: t.Optional[exp.Expression]) -> exp.DataType.Type: 79 if not is_date_unit(unit): 80 return exp.DataType.Type.DATETIME 81 return l.type.this if l.type else exp.DataType.Type.UNKNOWN 82 83 84def swap_args(func: BinaryCoercionFunc) -> BinaryCoercionFunc: 85 @functools.wraps(func) 86 def _swapped(l: exp.Expression, r: exp.Expression) -> exp.DataType.Type: 87 return func(r, l) 88 89 return _swapped 90 91 92def swap_all(coercions: BinaryCoercions) -> BinaryCoercions: 93 return {**coercions, **{(b, a): swap_args(func) for (a, b), func in coercions.items()}} 94 95 96class _TypeAnnotator(type): 97 def __new__(cls, clsname, bases, attrs): 98 klass = super().__new__(cls, clsname, bases, attrs) 99 100 # Highest-to-lowest type precedence, as specified in Spark's docs (ANSI): 101 # https://spark.apache.org/docs/3.2.0/sql-ref-ansi-compliance.html 102 text_precedence = ( 103 exp.DataType.Type.TEXT, 104 exp.DataType.Type.NVARCHAR, 105 exp.DataType.Type.VARCHAR, 106 exp.DataType.Type.NCHAR, 107 exp.DataType.Type.CHAR, 108 ) 109 numeric_precedence = ( 110 exp.DataType.Type.DOUBLE, 111 exp.DataType.Type.FLOAT, 112 exp.DataType.Type.DECIMAL, 113 exp.DataType.Type.BIGINT, 114 exp.DataType.Type.INT, 115 exp.DataType.Type.SMALLINT, 116 exp.DataType.Type.TINYINT, 117 ) 118 timelike_precedence = ( 119 exp.DataType.Type.TIMESTAMPLTZ, 120 exp.DataType.Type.TIMESTAMPTZ, 121 exp.DataType.Type.TIMESTAMP, 122 exp.DataType.Type.DATETIME, 123 exp.DataType.Type.DATE, 124 ) 125 126 for type_precedence in (text_precedence, numeric_precedence, timelike_precedence): 127 coerces_to = set() 128 for data_type in type_precedence: 129 klass.COERCES_TO[data_type] = coerces_to.copy() 130 coerces_to |= {data_type} 131 132 return klass 133 134 135class TypeAnnotator(metaclass=_TypeAnnotator): 136 TYPE_TO_EXPRESSIONS: t.Dict[exp.DataType.Type, t.Set[t.Type[exp.Expression]]] = { 137 exp.DataType.Type.BIGINT: { 138 exp.ApproxDistinct, 139 exp.ArraySize, 140 exp.Count, 141 exp.Length, 142 }, 143 exp.DataType.Type.BOOLEAN: { 144 exp.Between, 145 exp.Boolean, 146 exp.In, 147 exp.RegexpLike, 148 }, 149 exp.DataType.Type.DATE: { 150 exp.CurrentDate, 151 exp.Date, 152 exp.DateFromParts, 153 exp.DateStrToDate, 154 exp.DiToDate, 155 exp.StrToDate, 156 exp.TimeStrToDate, 157 exp.TsOrDsToDate, 158 }, 159 exp.DataType.Type.DATETIME: { 160 exp.CurrentDatetime, 161 exp.DatetimeAdd, 162 exp.DatetimeSub, 163 }, 164 exp.DataType.Type.DOUBLE: { 165 exp.ApproxQuantile, 166 exp.Avg, 167 exp.Div, 168 exp.Exp, 169 exp.Ln, 170 exp.Log, 171 exp.Pow, 172 exp.Quantile, 173 exp.Round, 174 exp.SafeDivide, 175 exp.Sqrt, 176 exp.Stddev, 177 exp.StddevPop, 178 exp.StddevSamp, 179 exp.Variance, 180 exp.VariancePop, 181 }, 182 exp.DataType.Type.INT: { 183 exp.Ceil, 184 exp.DatetimeDiff, 185 exp.DateDiff, 186 exp.Extract, 187 exp.TimestampDiff, 188 exp.TimeDiff, 189 exp.DateToDi, 190 exp.Floor, 191 exp.Levenshtein, 192 exp.Sign, 193 exp.StrPosition, 194 exp.TsOrDiToDi, 195 }, 196 exp.DataType.Type.JSON: { 197 exp.ParseJSON, 198 }, 199 exp.DataType.Type.TIMESTAMP: { 200 exp.CurrentTime, 201 exp.CurrentTimestamp, 202 exp.StrToTime, 203 exp.TimeAdd, 204 exp.TimeStrToTime, 205 exp.TimeSub, 206 exp.TimestampAdd, 207 exp.TimestampSub, 208 exp.UnixToTime, 209 }, 210 exp.DataType.Type.TINYINT: { 211 exp.Day, 212 exp.Month, 213 exp.Week, 214 exp.Year, 215 exp.Quarter, 216 }, 217 exp.DataType.Type.VARCHAR: { 218 exp.ArrayConcat, 219 exp.Concat, 220 exp.ConcatWs, 221 exp.DateToDateStr, 222 exp.GroupConcat, 223 exp.Initcap, 224 exp.Lower, 225 exp.Substring, 226 exp.TimeToStr, 227 exp.TimeToTimeStr, 228 exp.Trim, 229 exp.TsOrDsToDateStr, 230 exp.UnixToStr, 231 exp.UnixToTimeStr, 232 exp.Upper, 233 }, 234 } 235 236 ANNOTATORS: t.Dict = { 237 **{ 238 expr_type: lambda self, e: self._annotate_unary(e) 239 for expr_type in subclasses(exp.__name__, (exp.Unary, exp.Alias)) 240 }, 241 **{ 242 expr_type: lambda self, e: self._annotate_binary(e) 243 for expr_type in subclasses(exp.__name__, exp.Binary) 244 }, 245 **{ 246 expr_type: _annotate_with_type_lambda(data_type) 247 for data_type, expressions in TYPE_TO_EXPRESSIONS.items() 248 for expr_type in expressions 249 }, 250 exp.Abs: lambda self, e: self._annotate_by_args(e, "this"), 251 exp.Anonymous: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 252 exp.Array: lambda self, e: self._annotate_by_args(e, "expressions", array=True), 253 exp.ArrayAgg: lambda self, e: self._annotate_by_args(e, "this", array=True), 254 exp.ArrayConcat: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 255 exp.Bracket: lambda self, e: self._annotate_bracket(e), 256 exp.Cast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 257 exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"), 258 exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 259 exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()), 260 exp.DateAdd: lambda self, e: self._annotate_timeunit(e), 261 exp.DateSub: lambda self, e: self._annotate_timeunit(e), 262 exp.DateTrunc: lambda self, e: self._annotate_timeunit(e), 263 exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"), 264 exp.Div: lambda self, e: self._annotate_div(e), 265 exp.Dot: lambda self, e: self._annotate_dot(e), 266 exp.Explode: lambda self, e: self._annotate_explode(e), 267 exp.Filter: lambda self, e: self._annotate_by_args(e, "this"), 268 exp.GenerateDateArray: lambda self, e: self._annotate_with_type( 269 e, exp.DataType.build("ARRAY<DATE>") 270 ), 271 exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"), 272 exp.Interval: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.INTERVAL), 273 exp.Least: lambda self, e: self._annotate_by_args(e, "expressions"), 274 exp.Literal: lambda self, e: self._annotate_literal(e), 275 exp.Map: lambda self, e: self._annotate_map(e), 276 exp.Max: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 277 exp.Min: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 278 exp.Null: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.NULL), 279 exp.Nullif: lambda self, e: self._annotate_by_args(e, "this", "expression"), 280 exp.PropertyEQ: lambda self, e: self._annotate_by_args(e, "expression"), 281 exp.Slice: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 282 exp.Struct: lambda self, e: self._annotate_struct(e), 283 exp.Sum: lambda self, e: self._annotate_by_args(e, "this", "expressions", promote=True), 284 exp.Timestamp: lambda self, e: self._annotate_with_type( 285 e, 286 exp.DataType.Type.TIMESTAMPTZ if e.args.get("with_tz") else exp.DataType.Type.TIMESTAMP, 287 ), 288 exp.ToMap: lambda self, e: self._annotate_to_map(e), 289 exp.TryCast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 290 exp.Unnest: lambda self, e: self._annotate_unnest(e), 291 exp.VarMap: lambda self, e: self._annotate_map(e), 292 } 293 294 NESTED_TYPES = { 295 exp.DataType.Type.ARRAY, 296 } 297 298 # Specifies what types a given type can be coerced into (autofilled) 299 COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {} 300 301 # Coercion functions for binary operations. 302 # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type. 303 BINARY_COERCIONS: BinaryCoercions = { 304 **swap_all( 305 { 306 (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal( 307 l, r.args.get("unit") 308 ) 309 for t in exp.DataType.TEXT_TYPES 310 } 311 ), 312 **swap_all( 313 { 314 # text + numeric will yield the numeric type to match most dialects' semantics 315 (text, numeric): lambda l, r: t.cast( 316 exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type 317 ) 318 for text in exp.DataType.TEXT_TYPES 319 for numeric in exp.DataType.NUMERIC_TYPES 320 } 321 ), 322 **swap_all( 323 { 324 (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date( 325 l, r.args.get("unit") 326 ), 327 } 328 ), 329 } 330 331 def __init__( 332 self, 333 schema: Schema, 334 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 335 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 336 binary_coercions: t.Optional[BinaryCoercions] = None, 337 ) -> None: 338 self.schema = schema 339 self.annotators = annotators or self.ANNOTATORS 340 self.coerces_to = coerces_to or self.COERCES_TO 341 self.binary_coercions = binary_coercions or self.BINARY_COERCIONS 342 343 # Caches the ids of annotated sub-Expressions, to ensure we only visit them once 344 self._visited: t.Set[int] = set() 345 346 def _set_type( 347 self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type] 348 ) -> None: 349 expression.type = target_type or exp.DataType.Type.UNKNOWN # type: ignore 350 self._visited.add(id(expression)) 351 352 def annotate(self, expression: E) -> E: 353 for scope in traverse_scope(expression): 354 self.annotate_scope(scope) 355 return self._maybe_annotate(expression) # This takes care of non-traversable expressions 356 357 def annotate_scope(self, scope: Scope) -> None: 358 selects = {} 359 for name, source in scope.sources.items(): 360 if not isinstance(source, Scope): 361 continue 362 if isinstance(source.expression, exp.UDTF): 363 values = [] 364 365 if isinstance(source.expression, exp.Lateral): 366 if isinstance(source.expression.this, exp.Explode): 367 values = [source.expression.this.this] 368 elif isinstance(source.expression, exp.Unnest): 369 values = [source.expression] 370 else: 371 values = source.expression.expressions[0].expressions 372 373 if not values: 374 continue 375 376 selects[name] = { 377 alias: column 378 for alias, column in zip( 379 source.expression.alias_column_names, 380 values, 381 ) 382 } 383 else: 384 selects[name] = { 385 select.alias_or_name: select for select in source.expression.selects 386 } 387 388 # First annotate the current scope's column references 389 for col in scope.columns: 390 if not col.table: 391 continue 392 393 source = scope.sources.get(col.table) 394 if isinstance(source, exp.Table): 395 self._set_type(col, self.schema.get_column_type(source, col)) 396 elif source: 397 if col.table in selects and col.name in selects[col.table]: 398 self._set_type(col, selects[col.table][col.name].type) 399 elif isinstance(source.expression, exp.Unnest): 400 self._set_type(col, source.expression.type) 401 402 # Then (possibly) annotate the remaining expressions in the scope 403 self._maybe_annotate(scope.expression) 404 405 def _maybe_annotate(self, expression: E) -> E: 406 if id(expression) in self._visited: 407 return expression # We've already inferred the expression's type 408 409 annotator = self.annotators.get(expression.__class__) 410 411 return ( 412 annotator(self, expression) 413 if annotator 414 else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN) 415 ) 416 417 def _annotate_args(self, expression: E) -> E: 418 for value in expression.iter_expressions(): 419 self._maybe_annotate(value) 420 421 return expression 422 423 def _maybe_coerce( 424 self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type 425 ) -> exp.DataType | exp.DataType.Type: 426 type1_value = type1.this if isinstance(type1, exp.DataType) else type1 427 type2_value = type2.this if isinstance(type2, exp.DataType) else type2 428 429 # We propagate the NULL / UNKNOWN types upwards if found 430 if exp.DataType.Type.NULL in (type1_value, type2_value): 431 return exp.DataType.Type.NULL 432 if exp.DataType.Type.UNKNOWN in (type1_value, type2_value): 433 return exp.DataType.Type.UNKNOWN 434 435 return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value 436 437 def _annotate_binary(self, expression: B) -> B: 438 self._annotate_args(expression) 439 440 left, right = expression.left, expression.right 441 left_type, right_type = left.type.this, right.type.this # type: ignore 442 443 if isinstance(expression, exp.Connector): 444 if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL: 445 self._set_type(expression, exp.DataType.Type.NULL) 446 elif exp.DataType.Type.NULL in (left_type, right_type): 447 self._set_type( 448 expression, 449 exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")), 450 ) 451 else: 452 self._set_type(expression, exp.DataType.Type.BOOLEAN) 453 elif isinstance(expression, exp.Predicate): 454 self._set_type(expression, exp.DataType.Type.BOOLEAN) 455 elif (left_type, right_type) in self.binary_coercions: 456 self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right)) 457 else: 458 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 459 460 return expression 461 462 def _annotate_unary(self, expression: E) -> E: 463 self._annotate_args(expression) 464 465 if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren): 466 self._set_type(expression, exp.DataType.Type.BOOLEAN) 467 else: 468 self._set_type(expression, expression.this.type) 469 470 return expression 471 472 def _annotate_literal(self, expression: exp.Literal) -> exp.Literal: 473 if expression.is_string: 474 self._set_type(expression, exp.DataType.Type.VARCHAR) 475 elif expression.is_int: 476 self._set_type(expression, exp.DataType.Type.INT) 477 else: 478 self._set_type(expression, exp.DataType.Type.DOUBLE) 479 480 return expression 481 482 def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E: 483 self._set_type(expression, target_type) 484 return self._annotate_args(expression) 485 486 @t.no_type_check 487 def _annotate_by_args( 488 self, 489 expression: E, 490 *args: str, 491 promote: bool = False, 492 array: bool = False, 493 ) -> E: 494 self._annotate_args(expression) 495 496 expressions: t.List[exp.Expression] = [] 497 for arg in args: 498 arg_expr = expression.args.get(arg) 499 expressions.extend(expr for expr in ensure_list(arg_expr) if expr) 500 501 last_datatype = None 502 for expr in expressions: 503 expr_type = expr.type 504 505 # Stop at the first nested data type found - we don't want to _maybe_coerce nested types 506 if expr_type.args.get("nested"): 507 last_datatype = expr_type 508 break 509 510 if not expr_type.is_type(exp.DataType.Type.NULL, exp.DataType.Type.UNKNOWN): 511 last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type) 512 513 self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN) 514 515 if promote: 516 if expression.type.this in exp.DataType.INTEGER_TYPES: 517 self._set_type(expression, exp.DataType.Type.BIGINT) 518 elif expression.type.this in exp.DataType.FLOAT_TYPES: 519 self._set_type(expression, exp.DataType.Type.DOUBLE) 520 521 if array: 522 self._set_type( 523 expression, 524 exp.DataType( 525 this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True 526 ), 527 ) 528 529 return expression 530 531 def _annotate_timeunit( 532 self, expression: exp.TimeUnit | exp.DateTrunc 533 ) -> exp.TimeUnit | exp.DateTrunc: 534 self._annotate_args(expression) 535 536 if expression.this.type.this in exp.DataType.TEXT_TYPES: 537 datatype = _coerce_date_literal(expression.this, expression.unit) 538 elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES: 539 datatype = _coerce_date(expression.this, expression.unit) 540 else: 541 datatype = exp.DataType.Type.UNKNOWN 542 543 self._set_type(expression, datatype) 544 return expression 545 546 def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket: 547 self._annotate_args(expression) 548 549 bracket_arg = expression.expressions[0] 550 this = expression.this 551 552 if isinstance(bracket_arg, exp.Slice): 553 self._set_type(expression, this.type) 554 elif this.type.is_type(exp.DataType.Type.ARRAY): 555 self._set_type(expression, seq_get(this.type.expressions, 0)) 556 elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys: 557 index = this.keys.index(bracket_arg) 558 value = seq_get(this.values, index) 559 self._set_type(expression, value.type if value else None) 560 else: 561 self._set_type(expression, exp.DataType.Type.UNKNOWN) 562 563 return expression 564 565 def _annotate_div(self, expression: exp.Div) -> exp.Div: 566 self._annotate_args(expression) 567 568 left_type, right_type = expression.left.type.this, expression.right.type.this # type: ignore 569 570 if ( 571 expression.args.get("typed") 572 and left_type in exp.DataType.INTEGER_TYPES 573 and right_type in exp.DataType.INTEGER_TYPES 574 ): 575 self._set_type(expression, exp.DataType.Type.BIGINT) 576 else: 577 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 578 if expression.type and expression.type.this not in exp.DataType.REAL_TYPES: 579 self._set_type( 580 expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE) 581 ) 582 583 return expression 584 585 def _annotate_dot(self, expression: exp.Dot) -> exp.Dot: 586 self._annotate_args(expression) 587 self._set_type(expression, None) 588 this_type = expression.this.type 589 590 if this_type and this_type.is_type(exp.DataType.Type.STRUCT): 591 for e in this_type.expressions: 592 if e.name == expression.expression.name: 593 self._set_type(expression, e.kind) 594 break 595 596 return expression 597 598 def _annotate_explode(self, expression: exp.Explode) -> exp.Explode: 599 self._annotate_args(expression) 600 self._set_type(expression, seq_get(expression.this.type.expressions, 0)) 601 return expression 602 603 def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest: 604 self._annotate_args(expression) 605 child = seq_get(expression.expressions, 0) 606 607 if child and child.is_type(exp.DataType.Type.ARRAY): 608 expr_type = seq_get(child.type.expressions, 0) 609 else: 610 expr_type = None 611 612 self._set_type(expression, expr_type) 613 return expression 614 615 def _annotate_struct_value( 616 self, expression: exp.Expression 617 ) -> t.Optional[exp.DataType] | exp.ColumnDef: 618 alias = expression.args.get("alias") 619 if alias: 620 return exp.ColumnDef(this=alias.copy(), kind=expression.type) 621 622 # Case: key = value or key := value 623 if expression.expression: 624 return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type) 625 626 return expression.type 627 628 def _annotate_struct(self, expression: exp.Struct) -> exp.Struct: 629 self._annotate_args(expression) 630 self._set_type( 631 expression, 632 exp.DataType( 633 this=exp.DataType.Type.STRUCT, 634 expressions=[self._annotate_struct_value(expr) for expr in expression.expressions], 635 nested=True, 636 ), 637 ) 638 return expression 639 640 @t.overload 641 def _annotate_map(self, expression: exp.Map) -> exp.Map: ... 642 643 @t.overload 644 def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ... 645 646 def _annotate_map(self, expression): 647 self._annotate_args(expression) 648 649 keys = expression.args.get("keys") 650 values = expression.args.get("values") 651 652 map_type = exp.DataType(this=exp.DataType.Type.MAP) 653 if isinstance(keys, exp.Array) and isinstance(values, exp.Array): 654 key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN 655 value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN 656 657 if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN: 658 map_type.set("expressions", [key_type, value_type]) 659 map_type.set("nested", True) 660 661 self._set_type(expression, map_type) 662 return expression 663 664 def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap: 665 self._annotate_args(expression) 666 667 map_type = exp.DataType(this=exp.DataType.Type.MAP) 668 arg = expression.this 669 if arg.is_type(exp.DataType.Type.STRUCT): 670 for coldef in arg.type.expressions: 671 kind = coldef.kind 672 if kind != exp.DataType.Type.UNKNOWN: 673 map_type.set("expressions", [exp.DataType.build("varchar"), kind]) 674 map_type.set("nested", True) 675 break 676 677 self._set_type(expression, map_type) 678 return expression
def
annotate_types( expression: ~E, schema: Union[Dict, sqlglot.schema.Schema, NoneType] = None, annotators: Optional[Dict[Type[~E], Callable[[TypeAnnotator, ~E], ~E]]] = None, coerces_to: Optional[Dict[sqlglot.expressions.DataType.Type, Set[sqlglot.expressions.DataType.Type]]] = None) -> ~E:
29def annotate_types( 30 expression: E, 31 schema: t.Optional[t.Dict | Schema] = None, 32 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 33 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 34) -> E: 35 """ 36 Infers the types of an expression, annotating its AST accordingly. 37 38 Example: 39 >>> import sqlglot 40 >>> schema = {"y": {"cola": "SMALLINT"}} 41 >>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x" 42 >>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema) 43 >>> annotated_expr.expressions[0].type.this # Get the type of "x.cola + 2.5 AS cola" 44 <Type.DOUBLE: 'DOUBLE'> 45 46 Args: 47 expression: Expression to annotate. 48 schema: Database schema. 49 annotators: Maps expression type to corresponding annotation function. 50 coerces_to: Maps expression type to set of types that it can be coerced into. 51 52 Returns: 53 The expression annotated with types. 54 """ 55 56 schema = ensure_schema(schema) 57 58 return TypeAnnotator(schema, annotators, coerces_to).annotate(expression)
Infers the types of an expression, annotating its AST accordingly.
Example:
>>> import sqlglot >>> schema = {"y": {"cola": "SMALLINT"}} >>> sql = "SELECT x.cola + 2.5 AS cola FROM (SELECT y.cola AS cola FROM y AS y) AS x" >>> annotated_expr = annotate_types(sqlglot.parse_one(sql), schema=schema) >>> annotated_expr.expressions[0].type.this # Get the type of "x.cola + 2.5 AS cola" <Type.DOUBLE: 'DOUBLE'>
Arguments:
- expression: Expression to annotate.
- schema: Database schema.
- annotators: Maps expression type to corresponding annotation function.
- coerces_to: Maps expression type to set of types that it can be coerced into.
Returns:
The expression annotated with types.
def
swap_args( func: Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]) -> Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]:
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:
136class TypeAnnotator(metaclass=_TypeAnnotator): 137 TYPE_TO_EXPRESSIONS: t.Dict[exp.DataType.Type, t.Set[t.Type[exp.Expression]]] = { 138 exp.DataType.Type.BIGINT: { 139 exp.ApproxDistinct, 140 exp.ArraySize, 141 exp.Count, 142 exp.Length, 143 }, 144 exp.DataType.Type.BOOLEAN: { 145 exp.Between, 146 exp.Boolean, 147 exp.In, 148 exp.RegexpLike, 149 }, 150 exp.DataType.Type.DATE: { 151 exp.CurrentDate, 152 exp.Date, 153 exp.DateFromParts, 154 exp.DateStrToDate, 155 exp.DiToDate, 156 exp.StrToDate, 157 exp.TimeStrToDate, 158 exp.TsOrDsToDate, 159 }, 160 exp.DataType.Type.DATETIME: { 161 exp.CurrentDatetime, 162 exp.DatetimeAdd, 163 exp.DatetimeSub, 164 }, 165 exp.DataType.Type.DOUBLE: { 166 exp.ApproxQuantile, 167 exp.Avg, 168 exp.Div, 169 exp.Exp, 170 exp.Ln, 171 exp.Log, 172 exp.Pow, 173 exp.Quantile, 174 exp.Round, 175 exp.SafeDivide, 176 exp.Sqrt, 177 exp.Stddev, 178 exp.StddevPop, 179 exp.StddevSamp, 180 exp.Variance, 181 exp.VariancePop, 182 }, 183 exp.DataType.Type.INT: { 184 exp.Ceil, 185 exp.DatetimeDiff, 186 exp.DateDiff, 187 exp.Extract, 188 exp.TimestampDiff, 189 exp.TimeDiff, 190 exp.DateToDi, 191 exp.Floor, 192 exp.Levenshtein, 193 exp.Sign, 194 exp.StrPosition, 195 exp.TsOrDiToDi, 196 }, 197 exp.DataType.Type.JSON: { 198 exp.ParseJSON, 199 }, 200 exp.DataType.Type.TIMESTAMP: { 201 exp.CurrentTime, 202 exp.CurrentTimestamp, 203 exp.StrToTime, 204 exp.TimeAdd, 205 exp.TimeStrToTime, 206 exp.TimeSub, 207 exp.TimestampAdd, 208 exp.TimestampSub, 209 exp.UnixToTime, 210 }, 211 exp.DataType.Type.TINYINT: { 212 exp.Day, 213 exp.Month, 214 exp.Week, 215 exp.Year, 216 exp.Quarter, 217 }, 218 exp.DataType.Type.VARCHAR: { 219 exp.ArrayConcat, 220 exp.Concat, 221 exp.ConcatWs, 222 exp.DateToDateStr, 223 exp.GroupConcat, 224 exp.Initcap, 225 exp.Lower, 226 exp.Substring, 227 exp.TimeToStr, 228 exp.TimeToTimeStr, 229 exp.Trim, 230 exp.TsOrDsToDateStr, 231 exp.UnixToStr, 232 exp.UnixToTimeStr, 233 exp.Upper, 234 }, 235 } 236 237 ANNOTATORS: t.Dict = { 238 **{ 239 expr_type: lambda self, e: self._annotate_unary(e) 240 for expr_type in subclasses(exp.__name__, (exp.Unary, exp.Alias)) 241 }, 242 **{ 243 expr_type: lambda self, e: self._annotate_binary(e) 244 for expr_type in subclasses(exp.__name__, exp.Binary) 245 }, 246 **{ 247 expr_type: _annotate_with_type_lambda(data_type) 248 for data_type, expressions in TYPE_TO_EXPRESSIONS.items() 249 for expr_type in expressions 250 }, 251 exp.Abs: lambda self, e: self._annotate_by_args(e, "this"), 252 exp.Anonymous: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 253 exp.Array: lambda self, e: self._annotate_by_args(e, "expressions", array=True), 254 exp.ArrayAgg: lambda self, e: self._annotate_by_args(e, "this", array=True), 255 exp.ArrayConcat: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 256 exp.Bracket: lambda self, e: self._annotate_bracket(e), 257 exp.Cast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 258 exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"), 259 exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 260 exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()), 261 exp.DateAdd: lambda self, e: self._annotate_timeunit(e), 262 exp.DateSub: lambda self, e: self._annotate_timeunit(e), 263 exp.DateTrunc: lambda self, e: self._annotate_timeunit(e), 264 exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"), 265 exp.Div: lambda self, e: self._annotate_div(e), 266 exp.Dot: lambda self, e: self._annotate_dot(e), 267 exp.Explode: lambda self, e: self._annotate_explode(e), 268 exp.Filter: lambda self, e: self._annotate_by_args(e, "this"), 269 exp.GenerateDateArray: lambda self, e: self._annotate_with_type( 270 e, exp.DataType.build("ARRAY<DATE>") 271 ), 272 exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"), 273 exp.Interval: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.INTERVAL), 274 exp.Least: lambda self, e: self._annotate_by_args(e, "expressions"), 275 exp.Literal: lambda self, e: self._annotate_literal(e), 276 exp.Map: lambda self, e: self._annotate_map(e), 277 exp.Max: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 278 exp.Min: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 279 exp.Null: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.NULL), 280 exp.Nullif: lambda self, e: self._annotate_by_args(e, "this", "expression"), 281 exp.PropertyEQ: lambda self, e: self._annotate_by_args(e, "expression"), 282 exp.Slice: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 283 exp.Struct: lambda self, e: self._annotate_struct(e), 284 exp.Sum: lambda self, e: self._annotate_by_args(e, "this", "expressions", promote=True), 285 exp.Timestamp: lambda self, e: self._annotate_with_type( 286 e, 287 exp.DataType.Type.TIMESTAMPTZ if e.args.get("with_tz") else exp.DataType.Type.TIMESTAMP, 288 ), 289 exp.ToMap: lambda self, e: self._annotate_to_map(e), 290 exp.TryCast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 291 exp.Unnest: lambda self, e: self._annotate_unnest(e), 292 exp.VarMap: lambda self, e: self._annotate_map(e), 293 } 294 295 NESTED_TYPES = { 296 exp.DataType.Type.ARRAY, 297 } 298 299 # Specifies what types a given type can be coerced into (autofilled) 300 COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {} 301 302 # Coercion functions for binary operations. 303 # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type. 304 BINARY_COERCIONS: BinaryCoercions = { 305 **swap_all( 306 { 307 (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal( 308 l, r.args.get("unit") 309 ) 310 for t in exp.DataType.TEXT_TYPES 311 } 312 ), 313 **swap_all( 314 { 315 # text + numeric will yield the numeric type to match most dialects' semantics 316 (text, numeric): lambda l, r: t.cast( 317 exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type 318 ) 319 for text in exp.DataType.TEXT_TYPES 320 for numeric in exp.DataType.NUMERIC_TYPES 321 } 322 ), 323 **swap_all( 324 { 325 (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date( 326 l, r.args.get("unit") 327 ), 328 } 329 ), 330 } 331 332 def __init__( 333 self, 334 schema: Schema, 335 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 336 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 337 binary_coercions: t.Optional[BinaryCoercions] = None, 338 ) -> None: 339 self.schema = schema 340 self.annotators = annotators or self.ANNOTATORS 341 self.coerces_to = coerces_to or self.COERCES_TO 342 self.binary_coercions = binary_coercions or self.BINARY_COERCIONS 343 344 # Caches the ids of annotated sub-Expressions, to ensure we only visit them once 345 self._visited: t.Set[int] = set() 346 347 def _set_type( 348 self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type] 349 ) -> None: 350 expression.type = target_type or exp.DataType.Type.UNKNOWN # type: ignore 351 self._visited.add(id(expression)) 352 353 def annotate(self, expression: E) -> E: 354 for scope in traverse_scope(expression): 355 self.annotate_scope(scope) 356 return self._maybe_annotate(expression) # This takes care of non-traversable expressions 357 358 def annotate_scope(self, scope: Scope) -> None: 359 selects = {} 360 for name, source in scope.sources.items(): 361 if not isinstance(source, Scope): 362 continue 363 if isinstance(source.expression, exp.UDTF): 364 values = [] 365 366 if isinstance(source.expression, exp.Lateral): 367 if isinstance(source.expression.this, exp.Explode): 368 values = [source.expression.this.this] 369 elif isinstance(source.expression, exp.Unnest): 370 values = [source.expression] 371 else: 372 values = source.expression.expressions[0].expressions 373 374 if not values: 375 continue 376 377 selects[name] = { 378 alias: column 379 for alias, column in zip( 380 source.expression.alias_column_names, 381 values, 382 ) 383 } 384 else: 385 selects[name] = { 386 select.alias_or_name: select for select in source.expression.selects 387 } 388 389 # First annotate the current scope's column references 390 for col in scope.columns: 391 if not col.table: 392 continue 393 394 source = scope.sources.get(col.table) 395 if isinstance(source, exp.Table): 396 self._set_type(col, self.schema.get_column_type(source, col)) 397 elif source: 398 if col.table in selects and col.name in selects[col.table]: 399 self._set_type(col, selects[col.table][col.name].type) 400 elif isinstance(source.expression, exp.Unnest): 401 self._set_type(col, source.expression.type) 402 403 # Then (possibly) annotate the remaining expressions in the scope 404 self._maybe_annotate(scope.expression) 405 406 def _maybe_annotate(self, expression: E) -> E: 407 if id(expression) in self._visited: 408 return expression # We've already inferred the expression's type 409 410 annotator = self.annotators.get(expression.__class__) 411 412 return ( 413 annotator(self, expression) 414 if annotator 415 else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN) 416 ) 417 418 def _annotate_args(self, expression: E) -> E: 419 for value in expression.iter_expressions(): 420 self._maybe_annotate(value) 421 422 return expression 423 424 def _maybe_coerce( 425 self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type 426 ) -> exp.DataType | exp.DataType.Type: 427 type1_value = type1.this if isinstance(type1, exp.DataType) else type1 428 type2_value = type2.this if isinstance(type2, exp.DataType) else type2 429 430 # We propagate the NULL / UNKNOWN types upwards if found 431 if exp.DataType.Type.NULL in (type1_value, type2_value): 432 return exp.DataType.Type.NULL 433 if exp.DataType.Type.UNKNOWN in (type1_value, type2_value): 434 return exp.DataType.Type.UNKNOWN 435 436 return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value 437 438 def _annotate_binary(self, expression: B) -> B: 439 self._annotate_args(expression) 440 441 left, right = expression.left, expression.right 442 left_type, right_type = left.type.this, right.type.this # type: ignore 443 444 if isinstance(expression, exp.Connector): 445 if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL: 446 self._set_type(expression, exp.DataType.Type.NULL) 447 elif exp.DataType.Type.NULL in (left_type, right_type): 448 self._set_type( 449 expression, 450 exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")), 451 ) 452 else: 453 self._set_type(expression, exp.DataType.Type.BOOLEAN) 454 elif isinstance(expression, exp.Predicate): 455 self._set_type(expression, exp.DataType.Type.BOOLEAN) 456 elif (left_type, right_type) in self.binary_coercions: 457 self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right)) 458 else: 459 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 460 461 return expression 462 463 def _annotate_unary(self, expression: E) -> E: 464 self._annotate_args(expression) 465 466 if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren): 467 self._set_type(expression, exp.DataType.Type.BOOLEAN) 468 else: 469 self._set_type(expression, expression.this.type) 470 471 return expression 472 473 def _annotate_literal(self, expression: exp.Literal) -> exp.Literal: 474 if expression.is_string: 475 self._set_type(expression, exp.DataType.Type.VARCHAR) 476 elif expression.is_int: 477 self._set_type(expression, exp.DataType.Type.INT) 478 else: 479 self._set_type(expression, exp.DataType.Type.DOUBLE) 480 481 return expression 482 483 def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E: 484 self._set_type(expression, target_type) 485 return self._annotate_args(expression) 486 487 @t.no_type_check 488 def _annotate_by_args( 489 self, 490 expression: E, 491 *args: str, 492 promote: bool = False, 493 array: bool = False, 494 ) -> E: 495 self._annotate_args(expression) 496 497 expressions: t.List[exp.Expression] = [] 498 for arg in args: 499 arg_expr = expression.args.get(arg) 500 expressions.extend(expr for expr in ensure_list(arg_expr) if expr) 501 502 last_datatype = None 503 for expr in expressions: 504 expr_type = expr.type 505 506 # Stop at the first nested data type found - we don't want to _maybe_coerce nested types 507 if expr_type.args.get("nested"): 508 last_datatype = expr_type 509 break 510 511 if not expr_type.is_type(exp.DataType.Type.NULL, exp.DataType.Type.UNKNOWN): 512 last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type) 513 514 self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN) 515 516 if promote: 517 if expression.type.this in exp.DataType.INTEGER_TYPES: 518 self._set_type(expression, exp.DataType.Type.BIGINT) 519 elif expression.type.this in exp.DataType.FLOAT_TYPES: 520 self._set_type(expression, exp.DataType.Type.DOUBLE) 521 522 if array: 523 self._set_type( 524 expression, 525 exp.DataType( 526 this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True 527 ), 528 ) 529 530 return expression 531 532 def _annotate_timeunit( 533 self, expression: exp.TimeUnit | exp.DateTrunc 534 ) -> exp.TimeUnit | exp.DateTrunc: 535 self._annotate_args(expression) 536 537 if expression.this.type.this in exp.DataType.TEXT_TYPES: 538 datatype = _coerce_date_literal(expression.this, expression.unit) 539 elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES: 540 datatype = _coerce_date(expression.this, expression.unit) 541 else: 542 datatype = exp.DataType.Type.UNKNOWN 543 544 self._set_type(expression, datatype) 545 return expression 546 547 def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket: 548 self._annotate_args(expression) 549 550 bracket_arg = expression.expressions[0] 551 this = expression.this 552 553 if isinstance(bracket_arg, exp.Slice): 554 self._set_type(expression, this.type) 555 elif this.type.is_type(exp.DataType.Type.ARRAY): 556 self._set_type(expression, seq_get(this.type.expressions, 0)) 557 elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys: 558 index = this.keys.index(bracket_arg) 559 value = seq_get(this.values, index) 560 self._set_type(expression, value.type if value else None) 561 else: 562 self._set_type(expression, exp.DataType.Type.UNKNOWN) 563 564 return expression 565 566 def _annotate_div(self, expression: exp.Div) -> exp.Div: 567 self._annotate_args(expression) 568 569 left_type, right_type = expression.left.type.this, expression.right.type.this # type: ignore 570 571 if ( 572 expression.args.get("typed") 573 and left_type in exp.DataType.INTEGER_TYPES 574 and right_type in exp.DataType.INTEGER_TYPES 575 ): 576 self._set_type(expression, exp.DataType.Type.BIGINT) 577 else: 578 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 579 if expression.type and expression.type.this not in exp.DataType.REAL_TYPES: 580 self._set_type( 581 expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE) 582 ) 583 584 return expression 585 586 def _annotate_dot(self, expression: exp.Dot) -> exp.Dot: 587 self._annotate_args(expression) 588 self._set_type(expression, None) 589 this_type = expression.this.type 590 591 if this_type and this_type.is_type(exp.DataType.Type.STRUCT): 592 for e in this_type.expressions: 593 if e.name == expression.expression.name: 594 self._set_type(expression, e.kind) 595 break 596 597 return expression 598 599 def _annotate_explode(self, expression: exp.Explode) -> exp.Explode: 600 self._annotate_args(expression) 601 self._set_type(expression, seq_get(expression.this.type.expressions, 0)) 602 return expression 603 604 def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest: 605 self._annotate_args(expression) 606 child = seq_get(expression.expressions, 0) 607 608 if child and child.is_type(exp.DataType.Type.ARRAY): 609 expr_type = seq_get(child.type.expressions, 0) 610 else: 611 expr_type = None 612 613 self._set_type(expression, expr_type) 614 return expression 615 616 def _annotate_struct_value( 617 self, expression: exp.Expression 618 ) -> t.Optional[exp.DataType] | exp.ColumnDef: 619 alias = expression.args.get("alias") 620 if alias: 621 return exp.ColumnDef(this=alias.copy(), kind=expression.type) 622 623 # Case: key = value or key := value 624 if expression.expression: 625 return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type) 626 627 return expression.type 628 629 def _annotate_struct(self, expression: exp.Struct) -> exp.Struct: 630 self._annotate_args(expression) 631 self._set_type( 632 expression, 633 exp.DataType( 634 this=exp.DataType.Type.STRUCT, 635 expressions=[self._annotate_struct_value(expr) for expr in expression.expressions], 636 nested=True, 637 ), 638 ) 639 return expression 640 641 @t.overload 642 def _annotate_map(self, expression: exp.Map) -> exp.Map: ... 643 644 @t.overload 645 def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ... 646 647 def _annotate_map(self, expression): 648 self._annotate_args(expression) 649 650 keys = expression.args.get("keys") 651 values = expression.args.get("values") 652 653 map_type = exp.DataType(this=exp.DataType.Type.MAP) 654 if isinstance(keys, exp.Array) and isinstance(values, exp.Array): 655 key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN 656 value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN 657 658 if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN: 659 map_type.set("expressions", [key_type, value_type]) 660 map_type.set("nested", True) 661 662 self._set_type(expression, map_type) 663 return expression 664 665 def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap: 666 self._annotate_args(expression) 667 668 map_type = exp.DataType(this=exp.DataType.Type.MAP) 669 arg = expression.this 670 if arg.is_type(exp.DataType.Type.STRUCT): 671 for coldef in arg.type.expressions: 672 kind = coldef.kind 673 if kind != exp.DataType.Type.UNKNOWN: 674 map_type.set("expressions", [exp.DataType.build("varchar"), kind]) 675 map_type.set("nested", True) 676 break 677 678 self._set_type(expression, map_type) 679 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)
332 def __init__( 333 self, 334 schema: Schema, 335 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 336 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 337 binary_coercions: t.Optional[BinaryCoercions] = None, 338 ) -> None: 339 self.schema = schema 340 self.annotators = annotators or self.ANNOTATORS 341 self.coerces_to = coerces_to or self.COERCES_TO 342 self.binary_coercions = binary_coercions or self.BINARY_COERCIONS 343 344 # Caches the ids of annotated sub-Expressions, to ensure we only visit them once 345 self._visited: t.Set[int] = set()
TYPE_TO_EXPRESSIONS: Dict[sqlglot.expressions.DataType.Type, Set[Type[sqlglot.expressions.Expression]]] =
{<Type.BIGINT: 'BIGINT'>: {<class 'sqlglot.expressions.ApproxDistinct'>, <class 'sqlglot.expressions.Length'>, <class 'sqlglot.expressions.ArraySize'>, <class 'sqlglot.expressions.Count'>}, <Type.BOOLEAN: 'BOOLEAN'>: {<class 'sqlglot.expressions.Boolean'>, <class 'sqlglot.expressions.Between'>, <class 'sqlglot.expressions.RegexpLike'>, <class 'sqlglot.expressions.In'>}, <Type.DATE: 'DATE'>: {<class 'sqlglot.expressions.DateStrToDate'>, <class 'sqlglot.expressions.DateFromParts'>, <class 'sqlglot.expressions.CurrentDate'>, <class 'sqlglot.expressions.DiToDate'>, <class 'sqlglot.expressions.TimeStrToDate'>, <class 'sqlglot.expressions.StrToDate'>, <class 'sqlglot.expressions.TsOrDsToDate'>, <class 'sqlglot.expressions.Date'>}, <Type.DATETIME: 'DATETIME'>: {<class 'sqlglot.expressions.DatetimeSub'>, <class 'sqlglot.expressions.DatetimeAdd'>, <class 'sqlglot.expressions.CurrentDatetime'>}, <Type.DOUBLE: 'DOUBLE'>: {<class 'sqlglot.expressions.Round'>, <class 'sqlglot.expressions.StddevPop'>, <class 'sqlglot.expressions.Log'>, <class 'sqlglot.expressions.Exp'>, <class 'sqlglot.expressions.Pow'>, <class 'sqlglot.expressions.Stddev'>, <class 'sqlglot.expressions.Ln'>, <class 'sqlglot.expressions.Avg'>, <class 'sqlglot.expressions.Div'>, <class 'sqlglot.expressions.Sqrt'>, <class 'sqlglot.expressions.VariancePop'>, <class 'sqlglot.expressions.Variance'>, <class 'sqlglot.expressions.ApproxQuantile'>, <class 'sqlglot.expressions.Quantile'>, <class 'sqlglot.expressions.StddevSamp'>, <class 'sqlglot.expressions.SafeDivide'>}, <Type.INT: 'INT'>: {<class 'sqlglot.expressions.TsOrDiToDi'>, <class 'sqlglot.expressions.Extract'>, <class 'sqlglot.expressions.Levenshtein'>, <class 'sqlglot.expressions.DatetimeDiff'>, <class 'sqlglot.expressions.DateDiff'>, <class 'sqlglot.expressions.Ceil'>, <class 'sqlglot.expressions.TimeDiff'>, <class 'sqlglot.expressions.Floor'>, <class 'sqlglot.expressions.Sign'>, <class 'sqlglot.expressions.StrPosition'>, <class 'sqlglot.expressions.TimestampDiff'>, <class 'sqlglot.expressions.DateToDi'>}, <Type.JSON: 'JSON'>: {<class 'sqlglot.expressions.ParseJSON'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<class 'sqlglot.expressions.TimestampAdd'>, <class 'sqlglot.expressions.CurrentTime'>, <class 'sqlglot.expressions.UnixToTime'>, <class 'sqlglot.expressions.TimeStrToTime'>, <class 'sqlglot.expressions.StrToTime'>, <class 'sqlglot.expressions.TimeAdd'>, <class 'sqlglot.expressions.TimeSub'>, <class 'sqlglot.expressions.TimestampSub'>, <class 'sqlglot.expressions.CurrentTimestamp'>}, <Type.TINYINT: 'TINYINT'>: {<class 'sqlglot.expressions.Week'>, <class 'sqlglot.expressions.Month'>, <class 'sqlglot.expressions.Quarter'>, <class 'sqlglot.expressions.Day'>, <class 'sqlglot.expressions.Year'>}, <Type.VARCHAR: 'VARCHAR'>: {<class 'sqlglot.expressions.DateToDateStr'>, <class 'sqlglot.expressions.Concat'>, <class 'sqlglot.expressions.Substring'>, <class 'sqlglot.expressions.Trim'>, <class 'sqlglot.expressions.UnixToTimeStr'>, <class 'sqlglot.expressions.UnixToStr'>, <class 'sqlglot.expressions.Initcap'>, <class 'sqlglot.expressions.ArrayConcat'>, <class 'sqlglot.expressions.TimeToTimeStr'>, <class 'sqlglot.expressions.TsOrDsToDateStr'>, <class 'sqlglot.expressions.Lower'>, <class 'sqlglot.expressions.Upper'>, <class 'sqlglot.expressions.TimeToStr'>, <class 'sqlglot.expressions.GroupConcat'>, <class 'sqlglot.expressions.ConcatWs'>}}
ANNOTATORS: Dict =
{<class 'sqlglot.expressions.Alias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseNot'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Neg'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Not'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Paren'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.PivotAlias'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Unary'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Add'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.And'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayContainsAll'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Binary'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseAnd'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseLeftShift'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseOr'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseRightShift'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.BitwiseXor'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Collate'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Connector'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Corr'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.CovarPop'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.CovarSamp'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.DPipe'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Distance'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Div'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Dot'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.EQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Escape'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.GT'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.GTE'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Glob'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ILikeAny'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.IntDiv'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Is'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONArrayContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBContains'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBExtract'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONBExtractScalar'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONExtract'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Kwarg'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LT'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LTE'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Like'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.LikeAny'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Mod'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Mul'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NullSafeEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Operator'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Or'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Overlaps'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Pow'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.PropertyEQ'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.RegexpILike'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.RegexpLike'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SimilarTo'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Slice'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Sub'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.Xor'>: <function TypeAnnotator.<dictcomp>.<lambda>>, <class 'sqlglot.expressions.ApproxDistinct'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Length'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArraySize'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Count'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Boolean'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Between'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.In'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateFromParts'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DiToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Date'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDatetime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Round'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevPop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Log'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Exp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Stddev'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ln'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Avg'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sqrt'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.VariancePop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Variance'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ApproxQuantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevSamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SafeDivide'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDiToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Extract'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Levenshtein'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sign'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrPosition'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ParseJSON'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTimestamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Week'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Month'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quarter'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Day'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Year'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Concat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Substring'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Trim'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Initcap'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ArrayConcat'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.TimeToTimeStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Lower'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Upper'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ConcatWs'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Abs'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Anonymous'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Array'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Bracket'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Cast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Case'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Coalesce'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DataType'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateAdd'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateSub'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.DateTrunc'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Distinct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Explode'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Filter'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.GenerateDateArray'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.If'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Interval'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Least'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Literal'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Map'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Max'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Min'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Null'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Nullif'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Struct'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Sum'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Timestamp'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.TryCast'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.Unnest'>: <function TypeAnnotator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function TypeAnnotator.<lambda>>}
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.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.CHAR: 'CHAR'>: {<Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <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.DOUBLE: 'DOUBLE'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>}, <Type.TINYINT: 'TINYINT'>: {<Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>}, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATETIME: 'DATETIME'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>}, <Type.DATE: 'DATE'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>}}
BINARY_COERCIONS: Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]] =
{(<Type.VARCHAR: 'VARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <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.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <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.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLINT: 'SMALLINT'>): <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.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLINT: 'SMALLINT'>): <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.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLINT: 'SMALLINT'>): <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.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT256: 'INT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT128: 'UINT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <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.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <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.INT: 'INT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <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.INT: 'INT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <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.INT: 'INT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <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.INT: 'INT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <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.INT: 'INT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT256: 'INT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT128: 'UINT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <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.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <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>>}
358 def annotate_scope(self, scope: Scope) -> None: 359 selects = {} 360 for name, source in scope.sources.items(): 361 if not isinstance(source, Scope): 362 continue 363 if isinstance(source.expression, exp.UDTF): 364 values = [] 365 366 if isinstance(source.expression, exp.Lateral): 367 if isinstance(source.expression.this, exp.Explode): 368 values = [source.expression.this.this] 369 elif isinstance(source.expression, exp.Unnest): 370 values = [source.expression] 371 else: 372 values = source.expression.expressions[0].expressions 373 374 if not values: 375 continue 376 377 selects[name] = { 378 alias: column 379 for alias, column in zip( 380 source.expression.alias_column_names, 381 values, 382 ) 383 } 384 else: 385 selects[name] = { 386 select.alias_or_name: select for select in source.expression.selects 387 } 388 389 # First annotate the current scope's column references 390 for col in scope.columns: 391 if not col.table: 392 continue 393 394 source = scope.sources.get(col.table) 395 if isinstance(source, exp.Table): 396 self._set_type(col, self.schema.get_column_type(source, col)) 397 elif source: 398 if col.table in selects and col.name in selects[col.table]: 399 self._set_type(col, selects[col.table][col.name].type) 400 elif isinstance(source.expression, exp.Unnest): 401 self._set_type(col, source.expression.type) 402 403 # Then (possibly) annotate the remaining expressions in the scope 404 self._maybe_annotate(scope.expression)