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