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.Datetime, 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.TIME: { 201 exp.Time, 202 }, 203 exp.DataType.Type.TIMESTAMP: { 204 exp.CurrentTime, 205 exp.CurrentTimestamp, 206 exp.StrToTime, 207 exp.TimeAdd, 208 exp.TimeStrToTime, 209 exp.TimeSub, 210 exp.TimestampAdd, 211 exp.TimestampSub, 212 exp.UnixToTime, 213 }, 214 exp.DataType.Type.TINYINT: { 215 exp.Day, 216 exp.Month, 217 exp.Week, 218 exp.Year, 219 exp.Quarter, 220 }, 221 exp.DataType.Type.VARCHAR: { 222 exp.ArrayConcat, 223 exp.Concat, 224 exp.ConcatWs, 225 exp.DateToDateStr, 226 exp.GroupConcat, 227 exp.Initcap, 228 exp.Lower, 229 exp.Substring, 230 exp.TimeToStr, 231 exp.TimeToTimeStr, 232 exp.Trim, 233 exp.TsOrDsToDateStr, 234 exp.UnixToStr, 235 exp.UnixToTimeStr, 236 exp.Upper, 237 }, 238 } 239 240 ANNOTATORS: t.Dict = { 241 **{ 242 expr_type: lambda self, e: self._annotate_unary(e) 243 for expr_type in subclasses(exp.__name__, (exp.Unary, exp.Alias)) 244 }, 245 **{ 246 expr_type: lambda self, e: self._annotate_binary(e) 247 for expr_type in subclasses(exp.__name__, exp.Binary) 248 }, 249 **{ 250 expr_type: _annotate_with_type_lambda(data_type) 251 for data_type, expressions in TYPE_TO_EXPRESSIONS.items() 252 for expr_type in expressions 253 }, 254 exp.Abs: lambda self, e: self._annotate_by_args(e, "this"), 255 exp.Anonymous: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 256 exp.Array: lambda self, e: self._annotate_by_args(e, "expressions", array=True), 257 exp.ArrayAgg: lambda self, e: self._annotate_by_args(e, "this", array=True), 258 exp.ArrayConcat: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 259 exp.Bracket: lambda self, e: self._annotate_bracket(e), 260 exp.Cast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 261 exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"), 262 exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 263 exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()), 264 exp.DateAdd: lambda self, e: self._annotate_timeunit(e), 265 exp.DateSub: lambda self, e: self._annotate_timeunit(e), 266 exp.DateTrunc: lambda self, e: self._annotate_timeunit(e), 267 exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"), 268 exp.Div: lambda self, e: self._annotate_div(e), 269 exp.Dot: lambda self, e: self._annotate_dot(e), 270 exp.Explode: lambda self, e: self._annotate_explode(e), 271 exp.Filter: lambda self, e: self._annotate_by_args(e, "this"), 272 exp.GenerateDateArray: lambda self, e: self._annotate_with_type( 273 e, exp.DataType.build("ARRAY<DATE>") 274 ), 275 exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"), 276 exp.Interval: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.INTERVAL), 277 exp.Least: lambda self, e: self._annotate_by_args(e, "expressions"), 278 exp.Literal: lambda self, e: self._annotate_literal(e), 279 exp.Map: lambda self, e: self._annotate_map(e), 280 exp.Max: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 281 exp.Min: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 282 exp.Null: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.NULL), 283 exp.Nullif: lambda self, e: self._annotate_by_args(e, "this", "expression"), 284 exp.PropertyEQ: lambda self, e: self._annotate_by_args(e, "expression"), 285 exp.Slice: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 286 exp.Struct: lambda self, e: self._annotate_struct(e), 287 exp.Sum: lambda self, e: self._annotate_by_args(e, "this", "expressions", promote=True), 288 exp.Timestamp: lambda self, e: self._annotate_with_type( 289 e, 290 exp.DataType.Type.TIMESTAMPTZ if e.args.get("with_tz") else exp.DataType.Type.TIMESTAMP, 291 ), 292 exp.ToMap: lambda self, e: self._annotate_to_map(e), 293 exp.TryCast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 294 exp.Unnest: lambda self, e: self._annotate_unnest(e), 295 exp.VarMap: lambda self, e: self._annotate_map(e), 296 } 297 298 NESTED_TYPES = { 299 exp.DataType.Type.ARRAY, 300 } 301 302 # Specifies what types a given type can be coerced into (autofilled) 303 COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {} 304 305 # Coercion functions for binary operations. 306 # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type. 307 BINARY_COERCIONS: BinaryCoercions = { 308 **swap_all( 309 { 310 (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal( 311 l, r.args.get("unit") 312 ) 313 for t in exp.DataType.TEXT_TYPES 314 } 315 ), 316 **swap_all( 317 { 318 # text + numeric will yield the numeric type to match most dialects' semantics 319 (text, numeric): lambda l, r: t.cast( 320 exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type 321 ) 322 for text in exp.DataType.TEXT_TYPES 323 for numeric in exp.DataType.NUMERIC_TYPES 324 } 325 ), 326 **swap_all( 327 { 328 (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date( 329 l, r.args.get("unit") 330 ), 331 } 332 ), 333 } 334 335 def __init__( 336 self, 337 schema: Schema, 338 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 339 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 340 binary_coercions: t.Optional[BinaryCoercions] = None, 341 ) -> None: 342 self.schema = schema 343 self.annotators = annotators or self.ANNOTATORS 344 self.coerces_to = coerces_to or self.COERCES_TO 345 self.binary_coercions = binary_coercions or self.BINARY_COERCIONS 346 347 # Caches the ids of annotated sub-Expressions, to ensure we only visit them once 348 self._visited: t.Set[int] = set() 349 350 def _set_type( 351 self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type] 352 ) -> None: 353 expression.type = target_type or exp.DataType.Type.UNKNOWN # type: ignore 354 self._visited.add(id(expression)) 355 356 def annotate(self, expression: E) -> E: 357 for scope in traverse_scope(expression): 358 self.annotate_scope(scope) 359 return self._maybe_annotate(expression) # This takes care of non-traversable expressions 360 361 def annotate_scope(self, scope: Scope) -> None: 362 selects = {} 363 for name, source in scope.sources.items(): 364 if not isinstance(source, Scope): 365 continue 366 if isinstance(source.expression, exp.UDTF): 367 values = [] 368 369 if isinstance(source.expression, exp.Lateral): 370 if isinstance(source.expression.this, exp.Explode): 371 values = [source.expression.this.this] 372 elif isinstance(source.expression, exp.Unnest): 373 values = [source.expression] 374 else: 375 values = source.expression.expressions[0].expressions 376 377 if not values: 378 continue 379 380 selects[name] = { 381 alias: column 382 for alias, column in zip( 383 source.expression.alias_column_names, 384 values, 385 ) 386 } 387 else: 388 selects[name] = { 389 select.alias_or_name: select for select in source.expression.selects 390 } 391 392 # First annotate the current scope's column references 393 for col in scope.columns: 394 if not col.table: 395 continue 396 397 source = scope.sources.get(col.table) 398 if isinstance(source, exp.Table): 399 self._set_type(col, self.schema.get_column_type(source, col)) 400 elif source: 401 if col.table in selects and col.name in selects[col.table]: 402 self._set_type(col, selects[col.table][col.name].type) 403 elif isinstance(source.expression, exp.Unnest): 404 self._set_type(col, source.expression.type) 405 406 # Then (possibly) annotate the remaining expressions in the scope 407 self._maybe_annotate(scope.expression) 408 409 def _maybe_annotate(self, expression: E) -> E: 410 if id(expression) in self._visited: 411 return expression # We've already inferred the expression's type 412 413 annotator = self.annotators.get(expression.__class__) 414 415 return ( 416 annotator(self, expression) 417 if annotator 418 else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN) 419 ) 420 421 def _annotate_args(self, expression: E) -> E: 422 for value in expression.iter_expressions(): 423 self._maybe_annotate(value) 424 425 return expression 426 427 def _maybe_coerce( 428 self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type 429 ) -> exp.DataType | exp.DataType.Type: 430 type1_value = type1.this if isinstance(type1, exp.DataType) else type1 431 type2_value = type2.this if isinstance(type2, exp.DataType) else type2 432 433 # We propagate the NULL / UNKNOWN types upwards if found 434 if exp.DataType.Type.NULL in (type1_value, type2_value): 435 return exp.DataType.Type.NULL 436 if exp.DataType.Type.UNKNOWN in (type1_value, type2_value): 437 return exp.DataType.Type.UNKNOWN 438 439 return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value 440 441 def _annotate_binary(self, expression: B) -> B: 442 self._annotate_args(expression) 443 444 left, right = expression.left, expression.right 445 left_type, right_type = left.type.this, right.type.this # type: ignore 446 447 if isinstance(expression, exp.Connector): 448 if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL: 449 self._set_type(expression, exp.DataType.Type.NULL) 450 elif exp.DataType.Type.NULL in (left_type, right_type): 451 self._set_type( 452 expression, 453 exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")), 454 ) 455 else: 456 self._set_type(expression, exp.DataType.Type.BOOLEAN) 457 elif isinstance(expression, exp.Predicate): 458 self._set_type(expression, exp.DataType.Type.BOOLEAN) 459 elif (left_type, right_type) in self.binary_coercions: 460 self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right)) 461 else: 462 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 463 464 return expression 465 466 def _annotate_unary(self, expression: E) -> E: 467 self._annotate_args(expression) 468 469 if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren): 470 self._set_type(expression, exp.DataType.Type.BOOLEAN) 471 else: 472 self._set_type(expression, expression.this.type) 473 474 return expression 475 476 def _annotate_literal(self, expression: exp.Literal) -> exp.Literal: 477 if expression.is_string: 478 self._set_type(expression, exp.DataType.Type.VARCHAR) 479 elif expression.is_int: 480 self._set_type(expression, exp.DataType.Type.INT) 481 else: 482 self._set_type(expression, exp.DataType.Type.DOUBLE) 483 484 return expression 485 486 def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E: 487 self._set_type(expression, target_type) 488 return self._annotate_args(expression) 489 490 @t.no_type_check 491 def _annotate_by_args( 492 self, 493 expression: E, 494 *args: str, 495 promote: bool = False, 496 array: bool = False, 497 ) -> E: 498 self._annotate_args(expression) 499 500 expressions: t.List[exp.Expression] = [] 501 for arg in args: 502 arg_expr = expression.args.get(arg) 503 expressions.extend(expr for expr in ensure_list(arg_expr) if expr) 504 505 last_datatype = None 506 for expr in expressions: 507 expr_type = expr.type 508 509 # Stop at the first nested data type found - we don't want to _maybe_coerce nested types 510 if expr_type.args.get("nested"): 511 last_datatype = expr_type 512 break 513 514 if not expr_type.is_type(exp.DataType.Type.NULL, exp.DataType.Type.UNKNOWN): 515 last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type) 516 517 self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN) 518 519 if promote: 520 if expression.type.this in exp.DataType.INTEGER_TYPES: 521 self._set_type(expression, exp.DataType.Type.BIGINT) 522 elif expression.type.this in exp.DataType.FLOAT_TYPES: 523 self._set_type(expression, exp.DataType.Type.DOUBLE) 524 525 if array: 526 self._set_type( 527 expression, 528 exp.DataType( 529 this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True 530 ), 531 ) 532 533 return expression 534 535 def _annotate_timeunit( 536 self, expression: exp.TimeUnit | exp.DateTrunc 537 ) -> exp.TimeUnit | exp.DateTrunc: 538 self._annotate_args(expression) 539 540 if expression.this.type.this in exp.DataType.TEXT_TYPES: 541 datatype = _coerce_date_literal(expression.this, expression.unit) 542 elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES: 543 datatype = _coerce_date(expression.this, expression.unit) 544 else: 545 datatype = exp.DataType.Type.UNKNOWN 546 547 self._set_type(expression, datatype) 548 return expression 549 550 def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket: 551 self._annotate_args(expression) 552 553 bracket_arg = expression.expressions[0] 554 this = expression.this 555 556 if isinstance(bracket_arg, exp.Slice): 557 self._set_type(expression, this.type) 558 elif this.type.is_type(exp.DataType.Type.ARRAY): 559 self._set_type(expression, seq_get(this.type.expressions, 0)) 560 elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys: 561 index = this.keys.index(bracket_arg) 562 value = seq_get(this.values, index) 563 self._set_type(expression, value.type if value else None) 564 else: 565 self._set_type(expression, exp.DataType.Type.UNKNOWN) 566 567 return expression 568 569 def _annotate_div(self, expression: exp.Div) -> exp.Div: 570 self._annotate_args(expression) 571 572 left_type, right_type = expression.left.type.this, expression.right.type.this # type: ignore 573 574 if ( 575 expression.args.get("typed") 576 and left_type in exp.DataType.INTEGER_TYPES 577 and right_type in exp.DataType.INTEGER_TYPES 578 ): 579 self._set_type(expression, exp.DataType.Type.BIGINT) 580 else: 581 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 582 if expression.type and expression.type.this not in exp.DataType.REAL_TYPES: 583 self._set_type( 584 expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE) 585 ) 586 587 return expression 588 589 def _annotate_dot(self, expression: exp.Dot) -> exp.Dot: 590 self._annotate_args(expression) 591 self._set_type(expression, None) 592 this_type = expression.this.type 593 594 if this_type and this_type.is_type(exp.DataType.Type.STRUCT): 595 for e in this_type.expressions: 596 if e.name == expression.expression.name: 597 self._set_type(expression, e.kind) 598 break 599 600 return expression 601 602 def _annotate_explode(self, expression: exp.Explode) -> exp.Explode: 603 self._annotate_args(expression) 604 self._set_type(expression, seq_get(expression.this.type.expressions, 0)) 605 return expression 606 607 def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest: 608 self._annotate_args(expression) 609 child = seq_get(expression.expressions, 0) 610 611 if child and child.is_type(exp.DataType.Type.ARRAY): 612 expr_type = seq_get(child.type.expressions, 0) 613 else: 614 expr_type = None 615 616 self._set_type(expression, expr_type) 617 return expression 618 619 def _annotate_struct_value( 620 self, expression: exp.Expression 621 ) -> t.Optional[exp.DataType] | exp.ColumnDef: 622 alias = expression.args.get("alias") 623 if alias: 624 return exp.ColumnDef(this=alias.copy(), kind=expression.type) 625 626 # Case: key = value or key := value 627 if expression.expression: 628 return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type) 629 630 return expression.type 631 632 def _annotate_struct(self, expression: exp.Struct) -> exp.Struct: 633 self._annotate_args(expression) 634 self._set_type( 635 expression, 636 exp.DataType( 637 this=exp.DataType.Type.STRUCT, 638 expressions=[self._annotate_struct_value(expr) for expr in expression.expressions], 639 nested=True, 640 ), 641 ) 642 return expression 643 644 @t.overload 645 def _annotate_map(self, expression: exp.Map) -> exp.Map: ... 646 647 @t.overload 648 def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ... 649 650 def _annotate_map(self, expression): 651 self._annotate_args(expression) 652 653 keys = expression.args.get("keys") 654 values = expression.args.get("values") 655 656 map_type = exp.DataType(this=exp.DataType.Type.MAP) 657 if isinstance(keys, exp.Array) and isinstance(values, exp.Array): 658 key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN 659 value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN 660 661 if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN: 662 map_type.set("expressions", [key_type, value_type]) 663 map_type.set("nested", True) 664 665 self._set_type(expression, map_type) 666 return expression 667 668 def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap: 669 self._annotate_args(expression) 670 671 map_type = exp.DataType(this=exp.DataType.Type.MAP) 672 arg = expression.this 673 if arg.is_type(exp.DataType.Type.STRUCT): 674 for coldef in arg.type.expressions: 675 kind = coldef.kind 676 if kind != exp.DataType.Type.UNKNOWN: 677 map_type.set("expressions", [exp.DataType.build("varchar"), kind]) 678 map_type.set("nested", True) 679 break 680 681 self._set_type(expression, map_type) 682 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.Datetime, 163 exp.DatetimeAdd, 164 exp.DatetimeSub, 165 }, 166 exp.DataType.Type.DOUBLE: { 167 exp.ApproxQuantile, 168 exp.Avg, 169 exp.Div, 170 exp.Exp, 171 exp.Ln, 172 exp.Log, 173 exp.Pow, 174 exp.Quantile, 175 exp.Round, 176 exp.SafeDivide, 177 exp.Sqrt, 178 exp.Stddev, 179 exp.StddevPop, 180 exp.StddevSamp, 181 exp.Variance, 182 exp.VariancePop, 183 }, 184 exp.DataType.Type.INT: { 185 exp.Ceil, 186 exp.DatetimeDiff, 187 exp.DateDiff, 188 exp.Extract, 189 exp.TimestampDiff, 190 exp.TimeDiff, 191 exp.DateToDi, 192 exp.Floor, 193 exp.Levenshtein, 194 exp.Sign, 195 exp.StrPosition, 196 exp.TsOrDiToDi, 197 }, 198 exp.DataType.Type.JSON: { 199 exp.ParseJSON, 200 }, 201 exp.DataType.Type.TIME: { 202 exp.Time, 203 }, 204 exp.DataType.Type.TIMESTAMP: { 205 exp.CurrentTime, 206 exp.CurrentTimestamp, 207 exp.StrToTime, 208 exp.TimeAdd, 209 exp.TimeStrToTime, 210 exp.TimeSub, 211 exp.TimestampAdd, 212 exp.TimestampSub, 213 exp.UnixToTime, 214 }, 215 exp.DataType.Type.TINYINT: { 216 exp.Day, 217 exp.Month, 218 exp.Week, 219 exp.Year, 220 exp.Quarter, 221 }, 222 exp.DataType.Type.VARCHAR: { 223 exp.ArrayConcat, 224 exp.Concat, 225 exp.ConcatWs, 226 exp.DateToDateStr, 227 exp.GroupConcat, 228 exp.Initcap, 229 exp.Lower, 230 exp.Substring, 231 exp.TimeToStr, 232 exp.TimeToTimeStr, 233 exp.Trim, 234 exp.TsOrDsToDateStr, 235 exp.UnixToStr, 236 exp.UnixToTimeStr, 237 exp.Upper, 238 }, 239 } 240 241 ANNOTATORS: t.Dict = { 242 **{ 243 expr_type: lambda self, e: self._annotate_unary(e) 244 for expr_type in subclasses(exp.__name__, (exp.Unary, exp.Alias)) 245 }, 246 **{ 247 expr_type: lambda self, e: self._annotate_binary(e) 248 for expr_type in subclasses(exp.__name__, exp.Binary) 249 }, 250 **{ 251 expr_type: _annotate_with_type_lambda(data_type) 252 for data_type, expressions in TYPE_TO_EXPRESSIONS.items() 253 for expr_type in expressions 254 }, 255 exp.Abs: lambda self, e: self._annotate_by_args(e, "this"), 256 exp.Anonymous: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 257 exp.Array: lambda self, e: self._annotate_by_args(e, "expressions", array=True), 258 exp.ArrayAgg: lambda self, e: self._annotate_by_args(e, "this", array=True), 259 exp.ArrayConcat: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 260 exp.Bracket: lambda self, e: self._annotate_bracket(e), 261 exp.Cast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 262 exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"), 263 exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 264 exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()), 265 exp.DateAdd: lambda self, e: self._annotate_timeunit(e), 266 exp.DateSub: lambda self, e: self._annotate_timeunit(e), 267 exp.DateTrunc: lambda self, e: self._annotate_timeunit(e), 268 exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"), 269 exp.Div: lambda self, e: self._annotate_div(e), 270 exp.Dot: lambda self, e: self._annotate_dot(e), 271 exp.Explode: lambda self, e: self._annotate_explode(e), 272 exp.Filter: lambda self, e: self._annotate_by_args(e, "this"), 273 exp.GenerateDateArray: lambda self, e: self._annotate_with_type( 274 e, exp.DataType.build("ARRAY<DATE>") 275 ), 276 exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"), 277 exp.Interval: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.INTERVAL), 278 exp.Least: lambda self, e: self._annotate_by_args(e, "expressions"), 279 exp.Literal: lambda self, e: self._annotate_literal(e), 280 exp.Map: lambda self, e: self._annotate_map(e), 281 exp.Max: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 282 exp.Min: lambda self, e: self._annotate_by_args(e, "this", "expressions"), 283 exp.Null: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.NULL), 284 exp.Nullif: lambda self, e: self._annotate_by_args(e, "this", "expression"), 285 exp.PropertyEQ: lambda self, e: self._annotate_by_args(e, "expression"), 286 exp.Slice: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.UNKNOWN), 287 exp.Struct: lambda self, e: self._annotate_struct(e), 288 exp.Sum: lambda self, e: self._annotate_by_args(e, "this", "expressions", promote=True), 289 exp.Timestamp: lambda self, e: self._annotate_with_type( 290 e, 291 exp.DataType.Type.TIMESTAMPTZ if e.args.get("with_tz") else exp.DataType.Type.TIMESTAMP, 292 ), 293 exp.ToMap: lambda self, e: self._annotate_to_map(e), 294 exp.TryCast: lambda self, e: self._annotate_with_type(e, e.args["to"]), 295 exp.Unnest: lambda self, e: self._annotate_unnest(e), 296 exp.VarMap: lambda self, e: self._annotate_map(e), 297 } 298 299 NESTED_TYPES = { 300 exp.DataType.Type.ARRAY, 301 } 302 303 # Specifies what types a given type can be coerced into (autofilled) 304 COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {} 305 306 # Coercion functions for binary operations. 307 # Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type. 308 BINARY_COERCIONS: BinaryCoercions = { 309 **swap_all( 310 { 311 (t, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date_literal( 312 l, r.args.get("unit") 313 ) 314 for t in exp.DataType.TEXT_TYPES 315 } 316 ), 317 **swap_all( 318 { 319 # text + numeric will yield the numeric type to match most dialects' semantics 320 (text, numeric): lambda l, r: t.cast( 321 exp.DataType.Type, l.type if l.type in exp.DataType.NUMERIC_TYPES else r.type 322 ) 323 for text in exp.DataType.TEXT_TYPES 324 for numeric in exp.DataType.NUMERIC_TYPES 325 } 326 ), 327 **swap_all( 328 { 329 (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): lambda l, r: _coerce_date( 330 l, r.args.get("unit") 331 ), 332 } 333 ), 334 } 335 336 def __init__( 337 self, 338 schema: Schema, 339 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 340 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 341 binary_coercions: t.Optional[BinaryCoercions] = None, 342 ) -> None: 343 self.schema = schema 344 self.annotators = annotators or self.ANNOTATORS 345 self.coerces_to = coerces_to or self.COERCES_TO 346 self.binary_coercions = binary_coercions or self.BINARY_COERCIONS 347 348 # Caches the ids of annotated sub-Expressions, to ensure we only visit them once 349 self._visited: t.Set[int] = set() 350 351 def _set_type( 352 self, expression: exp.Expression, target_type: t.Optional[exp.DataType | exp.DataType.Type] 353 ) -> None: 354 expression.type = target_type or exp.DataType.Type.UNKNOWN # type: ignore 355 self._visited.add(id(expression)) 356 357 def annotate(self, expression: E) -> E: 358 for scope in traverse_scope(expression): 359 self.annotate_scope(scope) 360 return self._maybe_annotate(expression) # This takes care of non-traversable expressions 361 362 def annotate_scope(self, scope: Scope) -> None: 363 selects = {} 364 for name, source in scope.sources.items(): 365 if not isinstance(source, Scope): 366 continue 367 if isinstance(source.expression, exp.UDTF): 368 values = [] 369 370 if isinstance(source.expression, exp.Lateral): 371 if isinstance(source.expression.this, exp.Explode): 372 values = [source.expression.this.this] 373 elif isinstance(source.expression, exp.Unnest): 374 values = [source.expression] 375 else: 376 values = source.expression.expressions[0].expressions 377 378 if not values: 379 continue 380 381 selects[name] = { 382 alias: column 383 for alias, column in zip( 384 source.expression.alias_column_names, 385 values, 386 ) 387 } 388 else: 389 selects[name] = { 390 select.alias_or_name: select for select in source.expression.selects 391 } 392 393 # First annotate the current scope's column references 394 for col in scope.columns: 395 if not col.table: 396 continue 397 398 source = scope.sources.get(col.table) 399 if isinstance(source, exp.Table): 400 self._set_type(col, self.schema.get_column_type(source, col)) 401 elif source: 402 if col.table in selects and col.name in selects[col.table]: 403 self._set_type(col, selects[col.table][col.name].type) 404 elif isinstance(source.expression, exp.Unnest): 405 self._set_type(col, source.expression.type) 406 407 # Then (possibly) annotate the remaining expressions in the scope 408 self._maybe_annotate(scope.expression) 409 410 def _maybe_annotate(self, expression: E) -> E: 411 if id(expression) in self._visited: 412 return expression # We've already inferred the expression's type 413 414 annotator = self.annotators.get(expression.__class__) 415 416 return ( 417 annotator(self, expression) 418 if annotator 419 else self._annotate_with_type(expression, exp.DataType.Type.UNKNOWN) 420 ) 421 422 def _annotate_args(self, expression: E) -> E: 423 for value in expression.iter_expressions(): 424 self._maybe_annotate(value) 425 426 return expression 427 428 def _maybe_coerce( 429 self, type1: exp.DataType | exp.DataType.Type, type2: exp.DataType | exp.DataType.Type 430 ) -> exp.DataType | exp.DataType.Type: 431 type1_value = type1.this if isinstance(type1, exp.DataType) else type1 432 type2_value = type2.this if isinstance(type2, exp.DataType) else type2 433 434 # We propagate the NULL / UNKNOWN types upwards if found 435 if exp.DataType.Type.NULL in (type1_value, type2_value): 436 return exp.DataType.Type.NULL 437 if exp.DataType.Type.UNKNOWN in (type1_value, type2_value): 438 return exp.DataType.Type.UNKNOWN 439 440 return type2_value if type2_value in self.coerces_to.get(type1_value, {}) else type1_value 441 442 def _annotate_binary(self, expression: B) -> B: 443 self._annotate_args(expression) 444 445 left, right = expression.left, expression.right 446 left_type, right_type = left.type.this, right.type.this # type: ignore 447 448 if isinstance(expression, exp.Connector): 449 if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL: 450 self._set_type(expression, exp.DataType.Type.NULL) 451 elif exp.DataType.Type.NULL in (left_type, right_type): 452 self._set_type( 453 expression, 454 exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")), 455 ) 456 else: 457 self._set_type(expression, exp.DataType.Type.BOOLEAN) 458 elif isinstance(expression, exp.Predicate): 459 self._set_type(expression, exp.DataType.Type.BOOLEAN) 460 elif (left_type, right_type) in self.binary_coercions: 461 self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right)) 462 else: 463 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 464 465 return expression 466 467 def _annotate_unary(self, expression: E) -> E: 468 self._annotate_args(expression) 469 470 if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren): 471 self._set_type(expression, exp.DataType.Type.BOOLEAN) 472 else: 473 self._set_type(expression, expression.this.type) 474 475 return expression 476 477 def _annotate_literal(self, expression: exp.Literal) -> exp.Literal: 478 if expression.is_string: 479 self._set_type(expression, exp.DataType.Type.VARCHAR) 480 elif expression.is_int: 481 self._set_type(expression, exp.DataType.Type.INT) 482 else: 483 self._set_type(expression, exp.DataType.Type.DOUBLE) 484 485 return expression 486 487 def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E: 488 self._set_type(expression, target_type) 489 return self._annotate_args(expression) 490 491 @t.no_type_check 492 def _annotate_by_args( 493 self, 494 expression: E, 495 *args: str, 496 promote: bool = False, 497 array: bool = False, 498 ) -> E: 499 self._annotate_args(expression) 500 501 expressions: t.List[exp.Expression] = [] 502 for arg in args: 503 arg_expr = expression.args.get(arg) 504 expressions.extend(expr for expr in ensure_list(arg_expr) if expr) 505 506 last_datatype = None 507 for expr in expressions: 508 expr_type = expr.type 509 510 # Stop at the first nested data type found - we don't want to _maybe_coerce nested types 511 if expr_type.args.get("nested"): 512 last_datatype = expr_type 513 break 514 515 if not expr_type.is_type(exp.DataType.Type.NULL, exp.DataType.Type.UNKNOWN): 516 last_datatype = self._maybe_coerce(last_datatype or expr_type, expr_type) 517 518 self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN) 519 520 if promote: 521 if expression.type.this in exp.DataType.INTEGER_TYPES: 522 self._set_type(expression, exp.DataType.Type.BIGINT) 523 elif expression.type.this in exp.DataType.FLOAT_TYPES: 524 self._set_type(expression, exp.DataType.Type.DOUBLE) 525 526 if array: 527 self._set_type( 528 expression, 529 exp.DataType( 530 this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True 531 ), 532 ) 533 534 return expression 535 536 def _annotate_timeunit( 537 self, expression: exp.TimeUnit | exp.DateTrunc 538 ) -> exp.TimeUnit | exp.DateTrunc: 539 self._annotate_args(expression) 540 541 if expression.this.type.this in exp.DataType.TEXT_TYPES: 542 datatype = _coerce_date_literal(expression.this, expression.unit) 543 elif expression.this.type.this in exp.DataType.TEMPORAL_TYPES: 544 datatype = _coerce_date(expression.this, expression.unit) 545 else: 546 datatype = exp.DataType.Type.UNKNOWN 547 548 self._set_type(expression, datatype) 549 return expression 550 551 def _annotate_bracket(self, expression: exp.Bracket) -> exp.Bracket: 552 self._annotate_args(expression) 553 554 bracket_arg = expression.expressions[0] 555 this = expression.this 556 557 if isinstance(bracket_arg, exp.Slice): 558 self._set_type(expression, this.type) 559 elif this.type.is_type(exp.DataType.Type.ARRAY): 560 self._set_type(expression, seq_get(this.type.expressions, 0)) 561 elif isinstance(this, (exp.Map, exp.VarMap)) and bracket_arg in this.keys: 562 index = this.keys.index(bracket_arg) 563 value = seq_get(this.values, index) 564 self._set_type(expression, value.type if value else None) 565 else: 566 self._set_type(expression, exp.DataType.Type.UNKNOWN) 567 568 return expression 569 570 def _annotate_div(self, expression: exp.Div) -> exp.Div: 571 self._annotate_args(expression) 572 573 left_type, right_type = expression.left.type.this, expression.right.type.this # type: ignore 574 575 if ( 576 expression.args.get("typed") 577 and left_type in exp.DataType.INTEGER_TYPES 578 and right_type in exp.DataType.INTEGER_TYPES 579 ): 580 self._set_type(expression, exp.DataType.Type.BIGINT) 581 else: 582 self._set_type(expression, self._maybe_coerce(left_type, right_type)) 583 if expression.type and expression.type.this not in exp.DataType.REAL_TYPES: 584 self._set_type( 585 expression, self._maybe_coerce(expression.type, exp.DataType.Type.DOUBLE) 586 ) 587 588 return expression 589 590 def _annotate_dot(self, expression: exp.Dot) -> exp.Dot: 591 self._annotate_args(expression) 592 self._set_type(expression, None) 593 this_type = expression.this.type 594 595 if this_type and this_type.is_type(exp.DataType.Type.STRUCT): 596 for e in this_type.expressions: 597 if e.name == expression.expression.name: 598 self._set_type(expression, e.kind) 599 break 600 601 return expression 602 603 def _annotate_explode(self, expression: exp.Explode) -> exp.Explode: 604 self._annotate_args(expression) 605 self._set_type(expression, seq_get(expression.this.type.expressions, 0)) 606 return expression 607 608 def _annotate_unnest(self, expression: exp.Unnest) -> exp.Unnest: 609 self._annotate_args(expression) 610 child = seq_get(expression.expressions, 0) 611 612 if child and child.is_type(exp.DataType.Type.ARRAY): 613 expr_type = seq_get(child.type.expressions, 0) 614 else: 615 expr_type = None 616 617 self._set_type(expression, expr_type) 618 return expression 619 620 def _annotate_struct_value( 621 self, expression: exp.Expression 622 ) -> t.Optional[exp.DataType] | exp.ColumnDef: 623 alias = expression.args.get("alias") 624 if alias: 625 return exp.ColumnDef(this=alias.copy(), kind=expression.type) 626 627 # Case: key = value or key := value 628 if expression.expression: 629 return exp.ColumnDef(this=expression.this.copy(), kind=expression.expression.type) 630 631 return expression.type 632 633 def _annotate_struct(self, expression: exp.Struct) -> exp.Struct: 634 self._annotate_args(expression) 635 self._set_type( 636 expression, 637 exp.DataType( 638 this=exp.DataType.Type.STRUCT, 639 expressions=[self._annotate_struct_value(expr) for expr in expression.expressions], 640 nested=True, 641 ), 642 ) 643 return expression 644 645 @t.overload 646 def _annotate_map(self, expression: exp.Map) -> exp.Map: ... 647 648 @t.overload 649 def _annotate_map(self, expression: exp.VarMap) -> exp.VarMap: ... 650 651 def _annotate_map(self, expression): 652 self._annotate_args(expression) 653 654 keys = expression.args.get("keys") 655 values = expression.args.get("values") 656 657 map_type = exp.DataType(this=exp.DataType.Type.MAP) 658 if isinstance(keys, exp.Array) and isinstance(values, exp.Array): 659 key_type = seq_get(keys.type.expressions, 0) or exp.DataType.Type.UNKNOWN 660 value_type = seq_get(values.type.expressions, 0) or exp.DataType.Type.UNKNOWN 661 662 if key_type != exp.DataType.Type.UNKNOWN and value_type != exp.DataType.Type.UNKNOWN: 663 map_type.set("expressions", [key_type, value_type]) 664 map_type.set("nested", True) 665 666 self._set_type(expression, map_type) 667 return expression 668 669 def _annotate_to_map(self, expression: exp.ToMap) -> exp.ToMap: 670 self._annotate_args(expression) 671 672 map_type = exp.DataType(this=exp.DataType.Type.MAP) 673 arg = expression.this 674 if arg.is_type(exp.DataType.Type.STRUCT): 675 for coldef in arg.type.expressions: 676 kind = coldef.kind 677 if kind != exp.DataType.Type.UNKNOWN: 678 map_type.set("expressions", [exp.DataType.build("varchar"), kind]) 679 map_type.set("nested", True) 680 break 681 682 self._set_type(expression, map_type) 683 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)
336 def __init__( 337 self, 338 schema: Schema, 339 annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, 340 coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, 341 binary_coercions: t.Optional[BinaryCoercions] = None, 342 ) -> None: 343 self.schema = schema 344 self.annotators = annotators or self.ANNOTATORS 345 self.coerces_to = coerces_to or self.COERCES_TO 346 self.binary_coercions = binary_coercions or self.BINARY_COERCIONS 347 348 # Caches the ids of annotated sub-Expressions, to ensure we only visit them once 349 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.Count'>, <class 'sqlglot.expressions.Length'>, <class 'sqlglot.expressions.ArraySize'>, <class 'sqlglot.expressions.ApproxDistinct'>}, <Type.BOOLEAN: 'BOOLEAN'>: {<class 'sqlglot.expressions.RegexpLike'>, <class 'sqlglot.expressions.Boolean'>, <class 'sqlglot.expressions.In'>, <class 'sqlglot.expressions.Between'>}, <Type.DATE: 'DATE'>: {<class 'sqlglot.expressions.CurrentDate'>, <class 'sqlglot.expressions.DateStrToDate'>, <class 'sqlglot.expressions.TimeStrToDate'>, <class 'sqlglot.expressions.DiToDate'>, <class 'sqlglot.expressions.DateFromParts'>, <class 'sqlglot.expressions.StrToDate'>, <class 'sqlglot.expressions.TsOrDsToDate'>, <class 'sqlglot.expressions.Date'>}, <Type.DATETIME: 'DATETIME'>: {<class 'sqlglot.expressions.Datetime'>, <class 'sqlglot.expressions.CurrentDatetime'>, <class 'sqlglot.expressions.DatetimeSub'>, <class 'sqlglot.expressions.DatetimeAdd'>}, <Type.DOUBLE: 'DOUBLE'>: {<class 'sqlglot.expressions.Round'>, <class 'sqlglot.expressions.StddevPop'>, <class 'sqlglot.expressions.Div'>, <class 'sqlglot.expressions.SafeDivide'>, <class 'sqlglot.expressions.Pow'>, <class 'sqlglot.expressions.Avg'>, <class 'sqlglot.expressions.Stddev'>, <class 'sqlglot.expressions.Exp'>, <class 'sqlglot.expressions.Sqrt'>, <class 'sqlglot.expressions.Log'>, <class 'sqlglot.expressions.Ln'>, <class 'sqlglot.expressions.ApproxQuantile'>, <class 'sqlglot.expressions.VariancePop'>, <class 'sqlglot.expressions.Quantile'>, <class 'sqlglot.expressions.Variance'>, <class 'sqlglot.expressions.StddevSamp'>}, <Type.INT: 'INT'>: {<class 'sqlglot.expressions.TimestampDiff'>, <class 'sqlglot.expressions.Ceil'>, <class 'sqlglot.expressions.Sign'>, <class 'sqlglot.expressions.DateDiff'>, <class 'sqlglot.expressions.Floor'>, <class 'sqlglot.expressions.Extract'>, <class 'sqlglot.expressions.TsOrDiToDi'>, <class 'sqlglot.expressions.StrPosition'>, <class 'sqlglot.expressions.DatetimeDiff'>, <class 'sqlglot.expressions.TimeDiff'>, <class 'sqlglot.expressions.Levenshtein'>, <class 'sqlglot.expressions.DateToDi'>}, <Type.JSON: 'JSON'>: {<class 'sqlglot.expressions.ParseJSON'>}, <Type.TIME: 'TIME'>: {<class 'sqlglot.expressions.Time'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<class 'sqlglot.expressions.TimeStrToTime'>, <class 'sqlglot.expressions.TimestampSub'>, <class 'sqlglot.expressions.UnixToTime'>, <class 'sqlglot.expressions.TimestampAdd'>, <class 'sqlglot.expressions.StrToTime'>, <class 'sqlglot.expressions.CurrentTimestamp'>, <class 'sqlglot.expressions.TimeAdd'>, <class 'sqlglot.expressions.TimeSub'>, <class 'sqlglot.expressions.CurrentTime'>}, <Type.TINYINT: 'TINYINT'>: {<class 'sqlglot.expressions.Year'>, <class 'sqlglot.expressions.Week'>, <class 'sqlglot.expressions.Quarter'>, <class 'sqlglot.expressions.Month'>, <class 'sqlglot.expressions.Day'>}, <Type.VARCHAR: 'VARCHAR'>: {<class 'sqlglot.expressions.Substring'>, <class 'sqlglot.expressions.Upper'>, <class 'sqlglot.expressions.DateToDateStr'>, <class 'sqlglot.expressions.Lower'>, <class 'sqlglot.expressions.Initcap'>, <class 'sqlglot.expressions.UnixToStr'>, <class 'sqlglot.expressions.GroupConcat'>, <class 'sqlglot.expressions.UnixToTimeStr'>, <class 'sqlglot.expressions.ArrayConcat'>, <class 'sqlglot.expressions.TimeToTimeStr'>, <class 'sqlglot.expressions.TimeToStr'>, <class 'sqlglot.expressions.TsOrDsToDateStr'>, <class 'sqlglot.expressions.ConcatWs'>, <class 'sqlglot.expressions.Trim'>, <class 'sqlglot.expressions.Concat'>}}
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.Count'>: <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.ApproxDistinct'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Boolean'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.In'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Between'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DiToDate'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateFromParts'>: <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.Datetime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDatetime'>: <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.Round'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevPop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.SafeDivide'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Avg'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Stddev'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Exp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sqrt'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Log'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ln'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ApproxQuantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.VariancePop'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quantile'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Variance'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StddevSamp'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Sign'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Extract'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDiToDi'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrPosition'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DatetimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeDiff'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Levenshtein'>: <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.Time'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.StrToTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentTimestamp'>: <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.CurrentTime'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Year'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Week'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Quarter'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Month'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Day'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Substring'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Upper'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.DateToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Lower'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Initcap'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.UnixToTimeStr'>: <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.TimeToStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDateStr'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.ConcatWs'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Trim'>: <function _annotate_with_type_lambda.<locals>.<lambda>>, <class 'sqlglot.expressions.Concat'>: <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.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>}, <Type.NCHAR: 'NCHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>}, <Type.CHAR: 'CHAR'>: {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.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.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.INT: 'INT'>: {<Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>}, <Type.SMALLINT: 'SMALLINT'>: {<Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT: 'INT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.TINYINT: 'TINYINT'>: {<Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT: 'INT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>}, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <Type.TIMESTAMP: 'TIMESTAMP'>: {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATETIME: 'DATETIME'>: {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <Type.DATE: 'DATE'>: {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATETIME: 'DATETIME'>}}
BINARY_COERCIONS: Dict[Tuple[sqlglot.expressions.DataType.Type, sqlglot.expressions.DataType.Type], Callable[[sqlglot.expressions.Expression, sqlglot.expressions.Expression], sqlglot.expressions.DataType.Type]] =
{(<Type.NVARCHAR: 'NVARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <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.NAME: 'NAME'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.TEXT: 'TEXT'>): <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.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NVARCHAR: 'NVARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TEXT: 'TEXT'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NCHAR: 'NCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.CHAR: 'CHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.NAME: 'NAME'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT: 'INT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MEDIUMINT: 'MEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT256: 'UINT256'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.TINYINT: 'TINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UBIGINT: 'UBIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIGINT: 'BIGINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.MONEY: 'MONEY'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DECIMAL: 'DECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLINT: 'SMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.USMALLINT: 'USMALLINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UTINYINT: 'UTINYINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.BIT: 'BIT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.SMALLMONEY: 'SMALLMONEY'>): <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.BIGDECIMAL: 'BIGDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.INT128: 'INT128'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.FLOAT: 'FLOAT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UINT: 'UINT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.DOUBLE: 'DOUBLE'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.VARCHAR: 'VARCHAR'>, <Type.UDECIMAL: 'UDECIMAL'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NVARCHAR: 'NVARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.TEXT: 'TEXT'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NCHAR: 'NCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.CHAR: 'CHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.NAME: 'NAME'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT: 'INT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT256: 'UINT256'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.TINYINT: 'TINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UBIGINT: 'UBIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIGINT: 'BIGINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.MONEY: 'MONEY'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DECIMAL: 'DECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLINT: 'SMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.USMALLINT: 'USMALLINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UTINYINT: 'UTINYINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.BIT: 'BIT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.SMALLMONEY: 'SMALLMONEY'>, <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.BIGDECIMAL: 'BIGDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.INT128: 'INT128'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.FLOAT: 'FLOAT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UINT: 'UINT'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DOUBLE: 'DOUBLE'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.UDECIMAL: 'UDECIMAL'>, <Type.VARCHAR: 'VARCHAR'>): <function TypeAnnotator.<dictcomp>.<lambda>>, (<Type.DATE: 'DATE'>, <Type.INTERVAL: 'INTERVAL'>): <function TypeAnnotator.<lambda>>, (<Type.INTERVAL: 'INTERVAL'>, <Type.DATE: 'DATE'>): <function TypeAnnotator.<lambda>>}
362 def annotate_scope(self, scope: Scope) -> None: 363 selects = {} 364 for name, source in scope.sources.items(): 365 if not isinstance(source, Scope): 366 continue 367 if isinstance(source.expression, exp.UDTF): 368 values = [] 369 370 if isinstance(source.expression, exp.Lateral): 371 if isinstance(source.expression.this, exp.Explode): 372 values = [source.expression.this.this] 373 elif isinstance(source.expression, exp.Unnest): 374 values = [source.expression] 375 else: 376 values = source.expression.expressions[0].expressions 377 378 if not values: 379 continue 380 381 selects[name] = { 382 alias: column 383 for alias, column in zip( 384 source.expression.alias_column_names, 385 values, 386 ) 387 } 388 else: 389 selects[name] = { 390 select.alias_or_name: select for select in source.expression.selects 391 } 392 393 # First annotate the current scope's column references 394 for col in scope.columns: 395 if not col.table: 396 continue 397 398 source = scope.sources.get(col.table) 399 if isinstance(source, exp.Table): 400 self._set_type(col, self.schema.get_column_type(source, col)) 401 elif source: 402 if col.table in selects and col.name in selects[col.table]: 403 self._set_type(col, selects[col.table][col.name].type) 404 elif isinstance(source.expression, exp.Unnest): 405 self._set_type(col, source.expression.type) 406 407 # Then (possibly) annotate the remaining expressions in the scope 408 self._maybe_annotate(scope.expression)