sqlglot expressions core - base classes, traits, operators, and helpers.
1"""sqlglot expressions core - base classes, traits, operators, and helpers.""" 2 3from __future__ import annotations 4 5import datetime 6import logging 7import math 8import numbers 9import re 10import sys 11import textwrap 12import typing as t 13from collections import deque 14from copy import deepcopy 15from decimal import Decimal 16from functools import reduce 17from collections.abc import Iterator, Sequence, Collection, Mapping, MutableMapping 18from sqlglot._typing import E, T 19from sqlglot.errors import ParseError 20from sqlglot.helper import ( 21 camel_to_snake_case, 22 ensure_list, 23 seq_get, 24 to_bool, 25 trait, 26) 27 28from sqlglot.tokenizer_core import Token 29from builtins import type as Type 30from sqlglot._typing import GeneratorNoDialectArgs, ParserNoDialectArgs 31 32if t.TYPE_CHECKING: 33 from typing_extensions import Self, Unpack, Concatenate 34 from sqlglot.dialects.dialect import DialectType 35 from sqlglot.expressions.datatypes import DATA_TYPE, DataType, DType, Interval 36 from sqlglot.expressions.query import Select 37 from sqlglot._typing import P 38 39 R = t.TypeVar("R") 40 41logger = logging.getLogger("sqlglot") 42 43SQLGLOT_META: str = "sqlglot.meta" 44SQLGLOT_ANONYMOUS = "sqlglot.anonymous" 45TABLE_PARTS = ("this", "db", "catalog") 46COLUMN_PARTS = ("this", "table", "db", "catalog") 47POSITION_META_KEYS: tuple[str, ...] = ("line", "col", "start", "end") 48UNITTEST: bool = "unittest" in sys.modules or "pytest" in sys.modules 49 50 51@trait 52class Expr: 53 """ 54 The base class for all expressions in a syntax tree. Each Expr encapsulates any necessary 55 context, such as its child expressions, their names (arg keys), and whether a given child expression 56 is optional or not. 57 58 Attributes: 59 key: a unique key for each class in the Expr hierarchy. This is useful for hashing 60 and representing expressions as strings. 61 arg_types: determines the arguments (child nodes) supported by an expression. It maps 62 arg keys to booleans that indicate whether the corresponding args are optional. 63 parent: a reference to the parent expression (or None, in case of root expressions). 64 arg_key: the arg key an expression is associated with, i.e. the name its parent expression 65 uses to refer to it. 66 index: the index of an expression if it is inside of a list argument in its parent. 67 comments: a list of comments that are associated with a given expression. This is used in 68 order to preserve comments when transpiling SQL code. 69 type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the 70 optimizer, in order to enable some transformations that require type information. 71 meta: a dictionary that can be used to store useful metadata for a given expression. 72 73 Example: 74 >>> class Foo(Expr): 75 ... arg_types = {"this": True, "expression": False} 76 77 The above definition informs us that Foo is an Expr that requires an argument called 78 "this" and may also optionally receive an argument called "expression". 79 80 Args: 81 args: a mapping used for retrieving the arguments of an expression, given their arg keys. 82 """ 83 84 key: t.ClassVar[str] = "expression" 85 arg_types: t.ClassVar[dict[str, bool]] = {"this": True} 86 required_args: t.ClassVar[set[str]] = {"this"} 87 is_var_len_args: t.ClassVar[bool] = False 88 _hash_raw_args: t.ClassVar[bool] = False 89 is_subquery: t.ClassVar[bool] = False 90 is_cast: t.ClassVar[bool] = False 91 92 args: dict[str, t.Any] 93 parent: Expr | None 94 arg_key: str | None 95 index: int | None 96 comments: list[str] | None 97 _type: DataType | None 98 _meta: dict[str, t.Any] | None 99 _hash: int | None 100 101 @classmethod 102 def __init_subclass__(cls, **kwargs: t.Any) -> None: 103 super().__init_subclass__(**kwargs) 104 # When an Expr class is created, its key is automatically set 105 # to be the lowercase version of the class' name. 106 cls.key = cls.__name__.lower() 107 cls.required_args = {k for k, v in cls.arg_types.items() if v} 108 # This is so that docstrings are not inherited in pdoc 109 setattr(cls, "__doc__", getattr(cls, "__doc__", None) or "") 110 111 is_primitive: t.ClassVar[bool] = False 112 113 def __init__(self, **args: object) -> None: 114 self.args: dict[str, t.Any] = args 115 self.parent: Expr | None = None 116 self.arg_key: str | None = None 117 self.index: int | None = None 118 self.comments: list[str] | None = None 119 self._type: DataType | None = None 120 self._meta: dict[str, t.Any] | None = None 121 self._hash: int | None = None 122 123 if not self.is_primitive: 124 for arg_key, value in self.args.items(): 125 self._set_parent(arg_key, value) 126 127 @property 128 def this(self) -> t.Any: 129 raise NotImplementedError 130 131 @property 132 def expression(self) -> t.Any: 133 raise NotImplementedError 134 135 @property 136 def expressions(self) -> list[t.Any]: 137 raise NotImplementedError 138 139 def text(self, key: str) -> str: 140 raise NotImplementedError 141 142 @property 143 def is_string(self) -> bool: 144 raise NotImplementedError 145 146 @property 147 def is_number(self) -> bool: 148 raise NotImplementedError 149 150 def to_py(self) -> t.Any: 151 raise NotImplementedError 152 153 @property 154 def is_int(self) -> bool: 155 raise NotImplementedError 156 157 @property 158 def is_star(self) -> bool: 159 raise NotImplementedError 160 161 @property 162 def alias(self) -> str: 163 raise NotImplementedError 164 165 @property 166 def alias_column_names(self) -> list[str]: 167 raise NotImplementedError 168 169 @property 170 def name(self) -> str: 171 raise NotImplementedError 172 173 @property 174 def alias_or_name(self) -> str: 175 raise NotImplementedError 176 177 @property 178 def output_name(self) -> str: 179 raise NotImplementedError 180 181 @property 182 def type(self) -> DataType | None: 183 raise NotImplementedError 184 185 @type.setter 186 def type(self, dtype: DataType | DType | str | None) -> None: 187 raise NotImplementedError 188 189 def is_type(self, *dtypes: DATA_TYPE) -> bool: 190 raise NotImplementedError 191 192 def is_leaf(self) -> bool: 193 raise NotImplementedError 194 195 @property 196 def meta(self) -> dict[str, t.Any]: 197 raise NotImplementedError 198 199 def __deepcopy__(self, memo: t.Any) -> Expr: 200 raise NotImplementedError 201 202 def copy(self: E) -> E: 203 raise NotImplementedError 204 205 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 206 raise NotImplementedError 207 208 def pop_comments(self) -> list[str]: 209 raise NotImplementedError 210 211 def append(self, arg_key: str, value: t.Any) -> None: 212 raise NotImplementedError 213 214 def set( 215 self, 216 arg_key: str, 217 value: object, 218 index: int | None = None, 219 overwrite: bool = True, 220 ) -> None: 221 raise NotImplementedError 222 223 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 224 raise NotImplementedError 225 226 @property 227 def depth(self) -> int: 228 raise NotImplementedError 229 230 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 231 raise NotImplementedError 232 233 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 234 raise NotImplementedError 235 236 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 237 raise NotImplementedError 238 239 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 240 raise NotImplementedError 241 242 @property 243 def parent_select(self) -> Select | None: 244 raise NotImplementedError 245 246 @property 247 def same_parent(self) -> bool: 248 raise NotImplementedError 249 250 def root(self) -> Expr: 251 raise NotImplementedError 252 253 def walk( 254 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 255 ) -> Iterator[Expr]: 256 raise NotImplementedError 257 258 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 259 raise NotImplementedError 260 261 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 262 raise NotImplementedError 263 264 def unnest(self) -> Expr: 265 raise NotImplementedError 266 267 def unalias(self) -> Expr: 268 raise NotImplementedError 269 270 def unnest_operands(self) -> tuple[Expr, ...]: 271 raise NotImplementedError 272 273 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 274 raise NotImplementedError 275 276 def to_s(self) -> str: 277 raise NotImplementedError 278 279 def sql( 280 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 281 ) -> str: 282 raise NotImplementedError 283 284 def transform( 285 self, fun: t.Callable, *args: object, copy: bool = True, **kwargs: object 286 ) -> t.Any: 287 raise NotImplementedError 288 289 def replace(self, expression: T) -> T: 290 raise NotImplementedError 291 292 def pop(self: E) -> E: 293 raise NotImplementedError 294 295 def assert_is(self, type_: Type[E]) -> E: 296 raise NotImplementedError 297 298 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 299 raise NotImplementedError 300 301 def dump(self) -> list[dict[str, t.Any]]: 302 """ 303 Dump this Expr to a JSON-serializable dict. 304 """ 305 from sqlglot.serde import dump 306 307 return dump(self) 308 309 @classmethod 310 def load(cls, obj: list[dict[str, Any]] | None) -> Expr: 311 """ 312 Load a dict (as returned by `Expr.dump`) into an Expr instance. 313 """ 314 from sqlglot.serde import load 315 316 result = load(obj) 317 assert isinstance(result, Expr) 318 return result 319 320 def and_( 321 self, 322 *expressions: ExpOrStr | None, 323 dialect: DialectType = None, 324 copy: bool = True, 325 wrap: bool = True, 326 **opts: Unpack[ParserNoDialectArgs], 327 ) -> Condition: 328 raise NotImplementedError 329 330 def or_( 331 self, 332 *expressions: ExpOrStr | None, 333 dialect: DialectType = None, 334 copy: bool = True, 335 wrap: bool = True, 336 **opts: Unpack[ParserNoDialectArgs], 337 ) -> Condition: 338 raise NotImplementedError 339 340 def not_(self, copy: bool = True) -> Not: 341 raise NotImplementedError 342 343 def update_positions( 344 self: E, 345 other: Token | Expr | None = None, 346 line: int | None = None, 347 col: int | None = None, 348 start: int | None = None, 349 end: int | None = None, 350 ) -> E: 351 raise NotImplementedError 352 353 def as_( 354 self, 355 alias: str | Identifier, 356 quoted: bool | None = None, 357 dialect: DialectType = None, 358 copy: bool = True, 359 table: bool | Sequence[str | Identifier] = False, 360 **opts: Unpack[ParserNoDialectArgs], 361 ) -> Expr: 362 raise NotImplementedError 363 364 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 365 raise NotImplementedError 366 367 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 368 raise NotImplementedError 369 370 def __iter__(self) -> Iterator: 371 raise NotImplementedError 372 373 def isin( 374 self, 375 *expressions: t.Any, 376 query: ExpOrStr | None = None, 377 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 378 dialect: DialectType = None, 379 copy: bool = True, 380 **opts: Unpack[ParserNoDialectArgs], 381 ) -> In: 382 raise NotImplementedError 383 384 def between( 385 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 386 ) -> Between: 387 raise NotImplementedError 388 389 def is_(self, other: ExpOrStr) -> Is: 390 raise NotImplementedError 391 392 def like(self, other: ExpOrStr) -> Like: 393 raise NotImplementedError 394 395 def ilike(self, other: ExpOrStr) -> ILike: 396 raise NotImplementedError 397 398 def eq(self, other: t.Any) -> EQ: 399 raise NotImplementedError 400 401 def neq(self, other: t.Any) -> NEQ: 402 raise NotImplementedError 403 404 def rlike(self, other: ExpOrStr) -> RegexpLike: 405 raise NotImplementedError 406 407 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 408 raise NotImplementedError 409 410 def asc(self, nulls_first: bool = True) -> Ordered: 411 raise NotImplementedError 412 413 def desc(self, nulls_first: bool = False) -> Ordered: 414 raise NotImplementedError 415 416 def __lt__(self, other: t.Any) -> LT: 417 raise NotImplementedError 418 419 def __le__(self, other: t.Any) -> LTE: 420 raise NotImplementedError 421 422 def __gt__(self, other: t.Any) -> GT: 423 raise NotImplementedError 424 425 def __ge__(self, other: t.Any) -> GTE: 426 raise NotImplementedError 427 428 def __add__(self, other: t.Any) -> Add: 429 raise NotImplementedError 430 431 def __radd__(self, other: t.Any) -> Add: 432 raise NotImplementedError 433 434 def __sub__(self, other: t.Any) -> Sub: 435 raise NotImplementedError 436 437 def __rsub__(self, other: t.Any) -> Sub: 438 raise NotImplementedError 439 440 def __mul__(self, other: t.Any) -> Mul: 441 raise NotImplementedError 442 443 def __rmul__(self, other: t.Any) -> Mul: 444 raise NotImplementedError 445 446 def __truediv__(self, other: t.Any) -> Div: 447 raise NotImplementedError 448 449 def __rtruediv__(self, other: t.Any) -> Div: 450 raise NotImplementedError 451 452 def __floordiv__(self, other: t.Any) -> IntDiv: 453 raise NotImplementedError 454 455 def __rfloordiv__(self, other: t.Any) -> IntDiv: 456 raise NotImplementedError 457 458 def __mod__(self, other: t.Any) -> Mod: 459 raise NotImplementedError 460 461 def __rmod__(self, other: t.Any) -> Mod: 462 raise NotImplementedError 463 464 def __pow__(self, other: t.Any) -> Pow: 465 raise NotImplementedError 466 467 def __rpow__(self, other: t.Any) -> Pow: 468 raise NotImplementedError 469 470 def __and__(self, other: t.Any) -> And: 471 raise NotImplementedError 472 473 def __rand__(self, other: t.Any) -> And: 474 raise NotImplementedError 475 476 def __or__(self, other: t.Any) -> Or: 477 raise NotImplementedError 478 479 def __ror__(self, other: t.Any) -> Or: 480 raise NotImplementedError 481 482 def __neg__(self) -> Neg: 483 raise NotImplementedError 484 485 def __invert__(self) -> Not: 486 raise NotImplementedError 487 488 def pipe( 489 self, func: t.Callable[Concatenate[Self, P], R], *args: P.args, **kwargs: P.kwargs 490 ) -> R: 491 """Apply a function to `Self` (the current instance) and return the result. 492 493 Doing `expr.pipe(func, *args, **kwargs)` is equivalent to `func(expr, *args, **kwargs)`. 494 495 It allows you to chain operations in a fluent way on any given function that takes `Self` as its first argument. 496 497 Tip: 498 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 499 500 Args: 501 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 502 *args: Additional positional arguments to pass to `func` after `Self`. 503 **kwargs: Additional keyword arguments to pass to `func`. 504 505 Returns: 506 The result of applying `func` to `Self` with the given arguments. 507 """ 508 return func(self, *args, **kwargs) 509 510 def apply( 511 self, func: t.Callable[Concatenate[Self, P], t.Any], *args: P.args, **kwargs: P.kwargs 512 ) -> Self: 513 """Apply a function to `Self` (the current instance) for side effects, and return `Self`. 514 515 Useful for inspecting intermediate expressions in a method chain by simply adding/removing `apply` calls, especially when combined with `pipe`. 516 517 Tip: 518 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 519 520 Args: 521 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 522 *args: Additional positional arguments to pass to `func` after `Self`. 523 **kwargs: Additional keyword arguments to pass to `func`. 524 525 Returns: 526 The same instance. 527 """ 528 func(self, *args, **kwargs) 529 return self 530 531 532class Expression(Expr): 533 __slots__ = ( 534 "args", 535 "parent", 536 "arg_key", 537 "index", 538 "comments", 539 "_type", 540 "_meta", 541 "_hash", 542 ) 543 544 def __eq__(self, other: object) -> bool: 545 return self is other or (type(self) is type(other) and hash(self) == hash(other)) 546 547 def __ne__(self, other: object) -> bool: 548 return not self.__eq__(other) 549 550 def __hash__(self) -> int: 551 if self._hash is None: 552 nodes: list[Expr] = [] 553 queue: deque[Expr] = deque() 554 queue.append(self) 555 556 while queue: 557 node = queue.popleft() 558 nodes.append(node) 559 560 for child in node.iter_expressions(): 561 if child._hash is None: 562 queue.append(child) 563 564 for node in reversed(nodes): 565 hash_ = hash(node.key) 566 567 if node._hash_raw_args: 568 for k, v in sorted(node.args.items()): 569 if v: 570 hash_ = hash((hash_, k, v)) 571 else: 572 for k, v in sorted(node.args.items()): 573 vt = type(v) 574 575 if vt is list: 576 for x in v: 577 if x is not None and x is not False: 578 hash_ = hash((hash_, k, x.lower() if type(x) is str else x)) 579 else: 580 hash_ = hash((hash_, k)) 581 elif v is not None and v is not False: 582 hash_ = hash((hash_, k, v.lower() if vt is str else v)) 583 584 node._hash = hash_ 585 assert self._hash 586 return self._hash 587 588 def __reduce__( 589 self, 590 ) -> tuple[ 591 t.Callable[[list[dict[str, t.Any]] | None], Expr | DType | None], 592 tuple[list[dict[str, t.Any]]], 593 ]: 594 from sqlglot.serde import dump, load 595 596 return (load, (dump(self),)) 597 598 @property 599 def this(self) -> t.Any: 600 """ 601 Retrieves the argument with key "this". 602 """ 603 return self.args.get("this") 604 605 @property 606 def expression(self) -> t.Any: 607 """ 608 Retrieves the argument with key "expression". 609 """ 610 return self.args.get("expression") 611 612 @property 613 def expressions(self) -> list[t.Any]: 614 """ 615 Retrieves the argument with key "expressions". 616 """ 617 return self.args.get("expressions") or [] 618 619 def text(self, key: str) -> str: 620 """ 621 Returns a textual representation of the argument corresponding to "key". This can only be used 622 for args that are strings or leaf Expr instances, such as identifiers and literals. 623 """ 624 field = self.args.get(key) 625 if isinstance(field, str): 626 return field 627 if isinstance(field, (Identifier, Literal, Var)): 628 return field.this 629 if isinstance(field, (Star, Null)): 630 return field.name 631 return "" 632 633 @property 634 def is_string(self) -> bool: 635 """ 636 Checks whether a Literal expression is a string. 637 """ 638 return isinstance(self, Literal) and self.args["is_string"] 639 640 @property 641 def is_number(self) -> bool: 642 """ 643 Checks whether a Literal expression is a number. 644 """ 645 return (isinstance(self, Literal) and not self.args["is_string"]) or ( 646 isinstance(self, Neg) and self.this.is_number 647 ) 648 649 def to_py(self) -> t.Any: 650 """ 651 Returns a Python object equivalent of the SQL node. 652 """ 653 raise ValueError(f"{self} cannot be converted to a Python object.") 654 655 @property 656 def is_int(self) -> bool: 657 """ 658 Checks whether an expression is an integer. 659 """ 660 return self.is_number and isinstance(self.to_py(), int) 661 662 @property 663 def is_star(self) -> bool: 664 """Checks whether an expression is a star.""" 665 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star)) 666 667 @property 668 def alias(self) -> str: 669 """ 670 Returns the alias of the expression, or an empty string if it's not aliased. 671 """ 672 alias = self.args.get("alias") 673 if isinstance(alias, Expression): 674 return alias.name 675 return self.text("alias") 676 677 @property 678 def alias_column_names(self) -> list[str]: 679 table_alias = self.args.get("alias") 680 if not table_alias: 681 return [] 682 return [c.name for c in table_alias.args.get("columns") or []] 683 684 @property 685 def name(self) -> str: 686 return self.text("this") 687 688 @property 689 def alias_or_name(self) -> str: 690 return self.alias or self.name 691 692 @property 693 def output_name(self) -> str: 694 """ 695 Name of the output column if this expression is a selection. 696 697 If the Expr has no output name, an empty string is returned. 698 699 Example: 700 >>> from sqlglot import parse_one 701 >>> parse_one("SELECT a").expressions[0].output_name 702 'a' 703 >>> parse_one("SELECT b AS c").expressions[0].output_name 704 'c' 705 >>> parse_one("SELECT 1 + 2").expressions[0].output_name 706 '' 707 """ 708 return "" 709 710 @property 711 def type(self) -> DataType | None: 712 if self.is_cast: 713 return self._type or self.to # type: ignore[attr-defined] 714 return self._type 715 716 @type.setter 717 def type(self, dtype: DataType | DType | str | None) -> None: 718 if dtype and type(dtype).__name__ != "DataType": 719 from sqlglot.expressions.datatypes import DataType as _DataType 720 721 dtype = _DataType.build(dtype) 722 self._type = dtype # type: ignore[assignment] 723 724 def is_type(self, *dtypes: DATA_TYPE) -> bool: 725 t = self._type 726 return t is not None and t.is_type(*dtypes) 727 728 def is_leaf(self) -> bool: 729 return not any((isinstance(v, Expr) or type(v) is list) and v for v in self.args.values()) 730 731 @property 732 def meta(self) -> dict[str, t.Any]: 733 if self._meta is None: 734 self._meta = {} 735 return self._meta 736 737 def __deepcopy__(self, memo: t.Any) -> Expr: 738 root = self.__class__() 739 stack: list[tuple[Expr, Expr]] = [(self, root)] 740 741 while stack: 742 node, copy = stack.pop() 743 744 if node.comments is not None: 745 copy.comments = deepcopy(node.comments) 746 if node._type is not None: 747 copy._type = deepcopy(node._type) 748 if node._meta is not None: 749 copy._meta = deepcopy(node._meta) 750 if node._hash is not None: 751 copy._hash = node._hash 752 753 for k, vs in node.args.items(): 754 if isinstance(vs, Expr): 755 stack.append((vs, vs.__class__())) 756 copy.set(k, stack[-1][-1]) 757 elif type(vs) is list: 758 copy.args[k] = [] 759 760 for v in vs: 761 if isinstance(v, Expr): 762 stack.append((v, v.__class__())) 763 copy.append(k, stack[-1][-1]) 764 else: 765 copy.append(k, v) 766 else: 767 copy.args[k] = vs 768 769 return root 770 771 def copy(self: E) -> E: 772 """ 773 Returns a deep copy of the expression. 774 """ 775 return deepcopy(self) 776 777 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 778 if self.comments is None: 779 self.comments = [] 780 781 if comments: 782 for comment in comments: 783 _, *meta = comment.split(SQLGLOT_META) 784 if meta: 785 for kv in "".join(meta).split(","): 786 k, *v = kv.split("=") 787 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 788 789 if not prepend: 790 self.comments.append(comment) 791 792 if prepend: 793 self.comments = comments + self.comments 794 795 def pop_comments(self) -> list[str]: 796 comments = self.comments or [] 797 self.comments = None 798 return comments 799 800 def append(self, arg_key: str, value: t.Any) -> None: 801 """ 802 Appends value to arg_key if it's a list or sets it as a new list. 803 804 Args: 805 arg_key (str): name of the list expression arg 806 value (Any): value to append to the list 807 """ 808 if type(self.args.get(arg_key)) is not list: 809 self.args[arg_key] = [] 810 self._set_parent(arg_key, value) 811 values = self.args[arg_key] 812 if isinstance(value, Expr): 813 value.index = len(values) 814 values.append(value) 815 816 def set( 817 self, 818 arg_key: str, 819 value: object, 820 index: int | None = None, 821 overwrite: bool = True, 822 ) -> None: 823 """ 824 Sets arg_key to value. 825 826 Args: 827 arg_key: name of the expression arg. 828 value: value to set the arg to. 829 index: if the arg is a list, this specifies what position to add the value in it. 830 overwrite: assuming an index is given, this determines whether to overwrite the 831 list entry instead of only inserting a new value (i.e., like list.insert). 832 """ 833 node: Expr | None = self 834 835 while node and node._hash is not None: 836 node._hash = None 837 node = node.parent 838 839 if index is not None: 840 expressions = self.args.get(arg_key) or [] 841 842 if seq_get(expressions, index) is None: 843 return 844 845 if value is None: 846 expressions.pop(index) 847 for v in expressions[index:]: 848 v.index = v.index - 1 849 return 850 851 if isinstance(value, list): 852 expressions.pop(index) 853 expressions[index:index] = value 854 elif overwrite: 855 expressions[index] = value 856 else: 857 expressions.insert(index, value) 858 859 value = expressions 860 elif value is None: 861 self.args.pop(arg_key, None) 862 return 863 864 self.args[arg_key] = value 865 self._set_parent(arg_key, value, index) 866 867 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 868 if isinstance(value, Expr): 869 value.parent = self 870 value.arg_key = arg_key 871 value.index = index 872 elif isinstance(value, list): 873 for i, v in enumerate(value): 874 if isinstance(v, Expr): 875 v.parent = self 876 v.arg_key = arg_key 877 v.index = i 878 879 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 880 """Set multiples keyword arguments at once, using `.set()` method. 881 882 Args: 883 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 884 Returns: 885 Self: The same `Expression` with the updated arguments. 886 """ 887 if kwargs: 888 for k, v in kwargs.items(): 889 self.set(k, v) 890 return self 891 892 @property 893 def depth(self) -> int: 894 """ 895 Returns the depth of this tree. 896 """ 897 if self.parent: 898 return self.parent.depth + 1 899 return 0 900 901 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 902 """Yields the key and expression for all arguments, exploding list args.""" 903 for vs in reversed(self.args.values()) if reverse else self.args.values(): 904 if isinstance(vs, list): 905 for v in reversed(vs) if reverse else vs: 906 if isinstance(v, Expr): 907 yield t.cast(E, v) 908 elif isinstance(vs, Expr): 909 yield t.cast(E, vs) 910 911 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 912 """ 913 Returns the first node in this tree which matches at least one of 914 the specified types. 915 916 Args: 917 expression_types: the expression type(s) to match. 918 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 919 920 Returns: 921 The node which matches the criteria or None if no such node was found. 922 """ 923 return next(self.find_all(*expression_types, bfs=bfs), None) 924 925 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 926 """ 927 Returns a generator object which visits all nodes in this tree and only 928 yields those that match at least one of the specified expression types. 929 930 Args: 931 expression_types: the expression type(s) to match. 932 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 933 934 Returns: 935 The generator object. 936 """ 937 for expression in self.walk(bfs=bfs): 938 if isinstance(expression, expression_types): 939 yield expression 940 941 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 942 """ 943 Returns a nearest parent matching expression_types. 944 945 Args: 946 expression_types: the expression type(s) to match. 947 948 Returns: 949 The parent node. 950 """ 951 ancestor = self.parent 952 while ancestor and not isinstance(ancestor, expression_types): 953 ancestor = ancestor.parent 954 return ancestor # type: ignore[return-value] 955 956 @property 957 def parent_select(self) -> Select | None: 958 """ 959 Returns the parent select statement. 960 """ 961 from sqlglot.expressions.query import Select as _Select 962 963 return self.find_ancestor(_Select) 964 965 @property 966 def same_parent(self) -> bool: 967 """Returns if the parent is the same class as itself.""" 968 return type(self.parent) is self.__class__ 969 970 def root(self) -> Expr: 971 """ 972 Returns the root expression of this tree. 973 """ 974 expression: Expr = self 975 while expression.parent: 976 expression = expression.parent 977 return expression 978 979 def walk( 980 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 981 ) -> Iterator[Expr]: 982 """ 983 Returns a generator object which visits all nodes in this tree. 984 985 Args: 986 bfs: if set to True the BFS traversal order will be applied, 987 otherwise the DFS traversal will be used instead. 988 prune: callable that returns True if the generator should stop traversing 989 this branch of the tree. 990 991 Returns: 992 the generator object. 993 """ 994 if bfs: 995 yield from self.bfs(prune=prune) 996 else: 997 yield from self.dfs(prune=prune) 998 999 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1000 """ 1001 Returns a generator object which visits all nodes in this tree in 1002 the DFS (Depth-first) order. 1003 1004 Returns: 1005 The generator object. 1006 """ 1007 stack = [self] 1008 1009 while stack: 1010 node = stack.pop() 1011 yield node 1012 if prune and prune(node): 1013 continue 1014 for v in node.iter_expressions(reverse=True): 1015 stack.append(v) 1016 1017 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1018 """ 1019 Returns a generator object which visits all nodes in this tree in 1020 the BFS (Breadth-first) order. 1021 1022 Returns: 1023 The generator object. 1024 """ 1025 queue: deque[Expr] = deque() 1026 queue.append(self) 1027 1028 while queue: 1029 node = queue.popleft() 1030 yield node 1031 if prune and prune(node): 1032 continue 1033 for v in node.iter_expressions(): 1034 queue.append(v) 1035 1036 def unnest(self) -> Expr: 1037 """ 1038 Returns the first non parenthesis child or self. 1039 """ 1040 expression = self 1041 while type(expression) is Paren: 1042 expression = expression.this 1043 return expression 1044 1045 def unalias(self) -> Expr: 1046 """ 1047 Returns the inner expression if this is an Alias. 1048 """ 1049 if isinstance(self, Alias): 1050 return self.this 1051 return self 1052 1053 def unnest_operands(self) -> tuple[Expr, ...]: 1054 """ 1055 Returns unnested operands as a tuple. 1056 """ 1057 return tuple(arg.unnest() for arg in self.iter_expressions()) 1058 1059 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1060 """ 1061 Returns a generator which yields child nodes whose parents are the same class. 1062 1063 A AND B AND C -> [A, B, C] 1064 """ 1065 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1066 if type(node) is not self.__class__: 1067 yield node.unnest() if unnest and not node.is_subquery else node 1068 1069 def __str__(self) -> str: 1070 return self.sql() 1071 1072 def __repr__(self) -> str: 1073 return _to_s(self) 1074 1075 def to_s(self) -> str: 1076 """ 1077 Same as __repr__, but includes additional information which can be useful 1078 for debugging, like empty or missing args and the AST nodes' object IDs. 1079 """ 1080 return _to_s(self, verbose=True) 1081 1082 def sql( 1083 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1084 ) -> str: 1085 """ 1086 Returns SQL string representation of this tree. 1087 1088 Args: 1089 dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql"). 1090 opts: other `sqlglot.generator.Generator` options. 1091 1092 Returns: 1093 The SQL string. 1094 """ 1095 from sqlglot.dialects.dialect import Dialect 1096 1097 return Dialect.get_or_raise(dialect).generate(self, copy=copy, **opts) 1098 1099 def transform( 1100 self, fun: t.Callable, *args: object, copy: bool = True, **kwargs: object 1101 ) -> t.Any: 1102 """ 1103 Visits all tree nodes (excluding already transformed ones) 1104 and applies the given transformation function to each node. 1105 1106 Args: 1107 fun: a function which takes a node as an argument and returns a 1108 new transformed node or the same node without modifications. If the function 1109 returns None, then the corresponding node will be removed from the syntax tree. 1110 copy: if set to True a new tree instance is constructed, otherwise the tree is 1111 modified in place. 1112 1113 Returns: 1114 The transformed tree. 1115 """ 1116 root: t.Any = None 1117 new_node: t.Any = None 1118 1119 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1120 parent, arg_key, index = node.parent, node.arg_key, node.index 1121 new_node = fun(node, *args, **kwargs) 1122 1123 if not root: 1124 root = new_node 1125 elif parent and arg_key and new_node is not node: 1126 parent.set(arg_key, new_node, index) 1127 1128 assert root 1129 return root 1130 1131 def replace(self, expression: T) -> T: 1132 """ 1133 Swap out this expression with a new expression. 1134 1135 For example:: 1136 1137 >>> import sqlglot 1138 >>> tree = sqlglot.parse_one("SELECT x FROM tbl") 1139 >>> tree.find(sqlglot.exp.Column).replace(sqlglot.exp.column("y")) 1140 Column( 1141 this=Identifier(this=y, quoted=False)) 1142 >>> tree.sql() 1143 'SELECT y FROM tbl' 1144 1145 Args: 1146 expression (T): new node 1147 1148 Returns: 1149 T: The new expression or expressions. 1150 """ 1151 parent = self.parent 1152 1153 if not parent or parent is expression: 1154 return expression 1155 1156 key = self.arg_key 1157 1158 if key: 1159 value = parent.args.get(key) 1160 1161 if type(expression) is list and isinstance(value, Expr): 1162 # We are trying to replace an Expr with a list, so it's assumed that 1163 # the intention was to really replace the parent of this expression. 1164 if value.parent: 1165 value.parent.replace(expression) 1166 else: 1167 parent.set(key, expression, self.index) 1168 1169 if expression is not self: 1170 self.parent = None 1171 self.arg_key = None 1172 self.index = None 1173 1174 return expression 1175 1176 def pop(self: E) -> E: 1177 """ 1178 Remove this expression from its AST. 1179 1180 Returns: 1181 The popped expression. 1182 """ 1183 self.replace(None) 1184 return self 1185 1186 def assert_is(self, type_: Type[E]) -> E: 1187 """ 1188 Assert that this `Expr` is an instance of `type_`. 1189 1190 If it is NOT an instance of `type_`, this raises an assertion error. 1191 Otherwise, this returns this expression. 1192 1193 Examples: 1194 This is useful for type security in chained expressions: 1195 1196 >>> import sqlglot 1197 >>> sqlglot.parse_one("SELECT x from y").assert_is(sqlglot.exp.Select).select("z").sql() 1198 'SELECT x, z FROM y' 1199 """ 1200 if not isinstance(self, type_): 1201 raise AssertionError(f"{self} is not {type_}.") 1202 return self 1203 1204 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1205 """ 1206 Checks if this expression is valid (e.g. all mandatory args are set). 1207 1208 Args: 1209 args: a sequence of values that were used to instantiate a Func expression. This is used 1210 to check that the provided arguments don't exceed the function argument limit. 1211 1212 Returns: 1213 A list of error messages for all possible errors that were found. 1214 """ 1215 if UNITTEST: 1216 for k in self.args: 1217 if k not in self.arg_types: 1218 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1219 1220 errors: list[str] | None = None 1221 1222 for k in self.required_args: 1223 v = self.args.get(k) 1224 if v is None or (isinstance(v, list) and not v): 1225 if errors is None: 1226 errors = [] 1227 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1228 1229 if ( 1230 args 1231 and isinstance(self, Func) 1232 and len(args) > len(self.arg_types) 1233 and not self.is_var_len_args 1234 ): 1235 if errors is None: 1236 errors = [] 1237 errors.append( 1238 f"The number of provided arguments ({len(args)}) is greater than " 1239 f"the maximum number of supported arguments ({len(self.arg_types)})" 1240 ) 1241 1242 return errors or [] 1243 1244 def and_( 1245 self, 1246 *expressions: ExpOrStr | None, 1247 dialect: DialectType = None, 1248 copy: bool = True, 1249 wrap: bool = True, 1250 **opts: Unpack[ParserNoDialectArgs], 1251 ) -> Condition: 1252 """ 1253 AND this condition with one or multiple expressions. 1254 1255 Example: 1256 >>> condition("x=1").and_("y=1").sql() 1257 'x = 1 AND y = 1' 1258 1259 Args: 1260 *expressions: the SQL code strings to parse. 1261 If an `Expr` instance is passed, it will be used as-is. 1262 dialect: the dialect used to parse the input expression. 1263 copy: whether to copy the involved expressions (only applies to Exprs). 1264 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 1265 precedence issues, but can be turned off when the produced AST is too deep and 1266 causes recursion-related issues. 1267 opts: other options to use to parse the input expressions. 1268 1269 Returns: 1270 The new And condition. 1271 """ 1272 return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1273 1274 def or_( 1275 self, 1276 *expressions: ExpOrStr | None, 1277 dialect: DialectType = None, 1278 copy: bool = True, 1279 wrap: bool = True, 1280 **opts: Unpack[ParserNoDialectArgs], 1281 ) -> Condition: 1282 """ 1283 OR this condition with one or multiple expressions. 1284 1285 Example: 1286 >>> condition("x=1").or_("y=1").sql() 1287 'x = 1 OR y = 1' 1288 1289 Args: 1290 *expressions: the SQL code strings to parse. 1291 If an `Expr` instance is passed, it will be used as-is. 1292 dialect: the dialect used to parse the input expression. 1293 copy: whether to copy the involved expressions (only applies to Exprs). 1294 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 1295 precedence issues, but can be turned off when the produced AST is too deep and 1296 causes recursion-related issues. 1297 opts: other options to use to parse the input expressions. 1298 1299 Returns: 1300 The new Or condition. 1301 """ 1302 return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1303 1304 def not_(self, copy: bool = True) -> Not: 1305 """ 1306 Wrap this condition with NOT. 1307 1308 Example: 1309 >>> condition("x=1").not_().sql() 1310 'NOT x = 1' 1311 1312 Args: 1313 copy: whether to copy this object. 1314 1315 Returns: 1316 The new Not instance. 1317 """ 1318 return not_(self, copy=copy) 1319 1320 def update_positions( 1321 self: E, 1322 other: Token | Expr | None = None, 1323 line: int | None = None, 1324 col: int | None = None, 1325 start: int | None = None, 1326 end: int | None = None, 1327 ) -> E: 1328 """ 1329 Update this expression with positions from a token or other expression. 1330 1331 Args: 1332 other: a token or expression to update this expression with. 1333 line: the line number to use if other is None 1334 col: column number 1335 start: start char index 1336 end: end char index 1337 1338 Returns: 1339 The updated expression. 1340 """ 1341 if isinstance(other, Token): 1342 meta = self.meta 1343 meta["line"] = other.line 1344 meta["col"] = other.col 1345 meta["start"] = other.start 1346 meta["end"] = other.end 1347 elif other is not None: 1348 other_meta = other._meta 1349 if other_meta: 1350 meta = self.meta 1351 for k in POSITION_META_KEYS: 1352 if k in other_meta: 1353 meta[k] = other_meta[k] 1354 else: 1355 meta = self.meta 1356 meta["line"] = line 1357 meta["col"] = col 1358 meta["start"] = start 1359 meta["end"] = end 1360 return self 1361 1362 def as_( 1363 self, 1364 alias: str | Identifier, 1365 quoted: bool | None = None, 1366 dialect: DialectType = None, 1367 copy: bool = True, 1368 table: bool | Sequence[str | Identifier] = False, 1369 **opts: Unpack[ParserNoDialectArgs], 1370 ) -> Expr: 1371 return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, table=table, **opts) 1372 1373 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 1374 this = self.copy() 1375 other = convert(other, copy=True) 1376 if not isinstance(this, klass) and not isinstance(other, klass): 1377 this = _wrap(this, Binary) 1378 other = _wrap(other, Binary) 1379 if reverse: 1380 return klass(this=other, expression=this) 1381 return klass(this=this, expression=other) 1382 1383 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 1384 return Bracket( 1385 this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)] 1386 ) 1387 1388 def __iter__(self) -> Iterator: 1389 if "expressions" in self.arg_types: 1390 return iter(self.args.get("expressions") or []) 1391 # We define this because __getitem__ converts Expr into an iterable, which is 1392 # problematic because one can hit infinite loops if they do "for x in some_expr: ..." 1393 # See: https://peps.python.org/pep-0234/ 1394 raise TypeError(f"'{self.__class__.__name__}' object is not iterable") 1395 1396 def isin( 1397 self, 1398 *expressions: t.Any, 1399 query: ExpOrStr | None = None, 1400 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 1401 dialect: DialectType = None, 1402 copy: bool = True, 1403 **opts: Unpack[ParserNoDialectArgs], 1404 ) -> In: 1405 from sqlglot.expressions.query import Query 1406 1407 subquery: Expr | None = None 1408 if query: 1409 subquery = maybe_parse(query, dialect=dialect, copy=copy, **opts) 1410 if isinstance(subquery, Query): 1411 subquery = subquery.subquery(copy=False) 1412 unnest_list: list[ExpOrStr] = ensure_list(unnest) 1413 return In( 1414 this=maybe_copy(self, copy), 1415 expressions=[convert(e, copy=copy) for e in expressions], 1416 query=subquery, 1417 unnest=( 1418 _lazy_unnest( 1419 expressions=[ 1420 maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in unnest_list 1421 ] 1422 ) 1423 if unnest 1424 else None 1425 ), 1426 ) 1427 1428 def between( 1429 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 1430 ) -> Between: 1431 between = Between( 1432 this=maybe_copy(self, copy), 1433 low=convert(low, copy=copy), 1434 high=convert(high, copy=copy), 1435 ) 1436 if symmetric is not None: 1437 between.set("symmetric", symmetric) 1438 1439 return between 1440 1441 def is_(self, other: ExpOrStr) -> Is: 1442 return self._binop(Is, other) 1443 1444 def like(self, other: ExpOrStr) -> Like: 1445 return self._binop(Like, other) 1446 1447 def ilike(self, other: ExpOrStr) -> ILike: 1448 return self._binop(ILike, other) 1449 1450 def eq(self, other: t.Any) -> EQ: 1451 return self._binop(EQ, other) 1452 1453 def neq(self, other: t.Any) -> NEQ: 1454 return self._binop(NEQ, other) 1455 1456 def rlike(self, other: ExpOrStr) -> RegexpLike: 1457 return self._binop(RegexpLike, other) 1458 1459 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 1460 div = self._binop(Div, other) 1461 div.set("typed", typed) 1462 div.set("safe", safe) 1463 return div 1464 1465 def asc(self, nulls_first: bool = True) -> Ordered: 1466 return Ordered(this=self.copy(), nulls_first=nulls_first) 1467 1468 def desc(self, nulls_first: bool = False) -> Ordered: 1469 return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first) 1470 1471 def __lt__(self, other: t.Any) -> LT: 1472 return self._binop(LT, other) 1473 1474 def __le__(self, other: t.Any) -> LTE: 1475 return self._binop(LTE, other) 1476 1477 def __gt__(self, other: t.Any) -> GT: 1478 return self._binop(GT, other) 1479 1480 def __ge__(self, other: t.Any) -> GTE: 1481 return self._binop(GTE, other) 1482 1483 def __add__(self, other: t.Any) -> Add: 1484 return self._binop(Add, other) 1485 1486 def __radd__(self, other: t.Any) -> Add: 1487 return self._binop(Add, other, reverse=True) 1488 1489 def __sub__(self, other: t.Any) -> Sub: 1490 return self._binop(Sub, other) 1491 1492 def __rsub__(self, other: t.Any) -> Sub: 1493 return self._binop(Sub, other, reverse=True) 1494 1495 def __mul__(self, other: t.Any) -> Mul: 1496 return self._binop(Mul, other) 1497 1498 def __rmul__(self, other: t.Any) -> Mul: 1499 return self._binop(Mul, other, reverse=True) 1500 1501 def __truediv__(self, other: t.Any) -> Div: 1502 return self._binop(Div, other) 1503 1504 def __rtruediv__(self, other: t.Any) -> Div: 1505 return self._binop(Div, other, reverse=True) 1506 1507 def __floordiv__(self, other: t.Any) -> IntDiv: 1508 return self._binop(IntDiv, other) 1509 1510 def __rfloordiv__(self, other: t.Any) -> IntDiv: 1511 return self._binop(IntDiv, other, reverse=True) 1512 1513 def __mod__(self, other: t.Any) -> Mod: 1514 return self._binop(Mod, other) 1515 1516 def __rmod__(self, other: t.Any) -> Mod: 1517 return self._binop(Mod, other, reverse=True) 1518 1519 def __pow__(self, other: t.Any) -> Pow: 1520 return self._binop(Pow, other) 1521 1522 def __rpow__(self, other: t.Any) -> Pow: 1523 return self._binop(Pow, other, reverse=True) 1524 1525 def __and__(self, other: t.Any) -> And: 1526 return self._binop(And, other) 1527 1528 def __rand__(self, other: t.Any) -> And: 1529 return self._binop(And, other, reverse=True) 1530 1531 def __or__(self, other: t.Any) -> Or: 1532 return self._binop(Or, other) 1533 1534 def __ror__(self, other: t.Any) -> Or: 1535 return self._binop(Or, other, reverse=True) 1536 1537 def __neg__(self) -> Neg: 1538 return Neg(this=_wrap(self.copy(), Binary)) 1539 1540 def __invert__(self) -> Not: 1541 return not_(self.copy()) 1542 1543 1544IntoType = t.Union[Type[Expr], Collection[Type[Expr]]] 1545ExpOrStr = t.Union[int, str, Expr] 1546 1547 1548@trait 1549class Condition(Expr): 1550 """Logical conditions like x AND y, or simply x""" 1551 1552 1553@trait 1554class Predicate(Condition): 1555 """Relationships like x = y, x > 1, x >= y.""" 1556 1557 1558class Cache(Expression): 1559 arg_types = { 1560 "this": True, 1561 "lazy": False, 1562 "options": False, 1563 "expression": False, 1564 } 1565 1566 1567class Uncache(Expression): 1568 arg_types = {"this": True, "exists": False} 1569 1570 1571class Refresh(Expression): 1572 arg_types = {"this": True, "kind": True} 1573 1574 1575class LockingStatement(Expression): 1576 arg_types = {"this": True, "expression": True} 1577 1578 1579@trait 1580class ColumnConstraintKind(Expr): 1581 pass 1582 1583 1584@trait 1585class SubqueryPredicate(Predicate): 1586 pass 1587 1588 1589class All(Expression, SubqueryPredicate): 1590 pass 1591 1592 1593class Any(Expression, SubqueryPredicate): 1594 pass 1595 1596 1597@trait 1598class Binary(Condition): 1599 arg_types: t.ClassVar[dict[str, bool]] = {"this": True, "expression": True} 1600 1601 @property 1602 def left(self) -> Expr: 1603 return self.args["this"] 1604 1605 @property 1606 def right(self) -> Expr: 1607 return self.args["expression"] 1608 1609 1610@trait 1611class Connector(Binary): 1612 pass 1613 1614 1615@trait 1616class Func(Condition): 1617 """ 1618 The base class for all function expressions. 1619 1620 Attributes: 1621 is_var_len_args (bool): if set to True the last argument defined in arg_types will be 1622 treated as a variable length argument and the argument's value will be stored as a list. 1623 _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this 1624 function expression. These values are used to map this node to a name during parsing as 1625 well as to provide the function's name during SQL string generation. By default the SQL 1626 name is set to the expression's class name transformed to snake case. 1627 """ 1628 1629 is_var_len_args: t.ClassVar[bool] = False 1630 _sql_names: t.ClassVar[list[str]] = [] 1631 1632 @classmethod 1633 def from_arg_list(cls, args: Sequence[object]) -> Self: 1634 if cls.is_var_len_args: 1635 all_arg_keys = tuple(cls.arg_types) 1636 # If this function supports variable length argument treat the last argument as such. 1637 non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys 1638 num_non_var = len(non_var_len_arg_keys) 1639 1640 args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)} 1641 args_dict[all_arg_keys[-1]] = args[num_non_var:] 1642 else: 1643 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} 1644 1645 return cls(**args_dict) 1646 1647 @classmethod 1648 def sql_names(cls) -> list[str]: 1649 if cls is Func: 1650 raise NotImplementedError( 1651 "SQL name is only supported by concrete function implementations" 1652 ) 1653 if not cls._sql_names: 1654 return [camel_to_snake_case(cls.__name__)] 1655 return cls._sql_names 1656 1657 @classmethod 1658 def sql_name(cls) -> str: 1659 sql_names = cls.sql_names() 1660 assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}." 1661 return sql_names[0] 1662 1663 @classmethod 1664 def default_parser_mappings(cls) -> dict[str, t.Callable[[Sequence[object]], Self]]: 1665 return {name: cls.from_arg_list for name in cls.sql_names()} 1666 1667 1668@trait 1669class AggFunc(Func): 1670 pass 1671 1672 1673class Column(Expression, Condition): 1674 arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False} 1675 1676 @property 1677 def table(self) -> str: 1678 return self.text("table") 1679 1680 @property 1681 def db(self) -> str: 1682 return self.text("db") 1683 1684 @property 1685 def catalog(self) -> str: 1686 return self.text("catalog") 1687 1688 @property 1689 def output_name(self) -> str: 1690 return self.name 1691 1692 @property 1693 def parts(self) -> list[Identifier | Star]: 1694 """Return the parts of a column in order catalog, db, table, name.""" 1695 return [ 1696 self.args[part] for part in ("catalog", "db", "table", "this") if self.args.get(part) 1697 ] 1698 1699 def to_dot(self, include_dots: bool = True) -> Dot | Identifier | Star: 1700 """Converts the column into a dot expression.""" 1701 parts = self.parts 1702 parent = self.parent 1703 1704 if include_dots: 1705 while isinstance(parent, Dot): 1706 parts.append(parent.expression) 1707 parent = parent.parent 1708 1709 return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0] 1710 1711 1712class Literal(Expression, Condition): 1713 arg_types = {"this": True, "is_string": True} 1714 _hash_raw_args = True 1715 is_primitive = True 1716 1717 @classmethod 1718 def number(cls, number: object) -> Literal | Neg: 1719 lit = cls(this=str(number), is_string=False) 1720 try: 1721 to_py = lit.to_py() 1722 if not isinstance(to_py, str) and to_py < 0: 1723 lit.set("this", str(abs(to_py))) 1724 return Neg(this=lit) 1725 except Exception: 1726 pass 1727 return lit 1728 1729 @classmethod 1730 def string(cls, string: object) -> Literal: 1731 return cls(this=str(string), is_string=True) 1732 1733 @property 1734 def output_name(self) -> str: 1735 return self.name 1736 1737 def to_py(self) -> int | str | Decimal: 1738 if self.is_number: 1739 try: 1740 return int(self.this) 1741 except ValueError: 1742 return Decimal(self.this) 1743 return self.this 1744 1745 1746class Var(Expression): 1747 is_primitive = True 1748 1749 1750class WithinGroup(Expression): 1751 arg_types = {"this": True, "expression": False} 1752 1753 1754class Pseudocolumn(Column): 1755 pass 1756 1757 1758class Hint(Expression): 1759 arg_types = {"expressions": True} 1760 1761 1762class JoinHint(Expression): 1763 arg_types = {"this": True, "expressions": True} 1764 1765 1766class Identifier(Expression): 1767 arg_types = {"this": True, "quoted": False, "global_": False, "temporary": False} 1768 is_primitive = True 1769 _hash_raw_args = True 1770 1771 @property 1772 def quoted(self) -> bool: 1773 return bool(self.args.get("quoted")) 1774 1775 @property 1776 def output_name(self) -> str: 1777 return self.name 1778 1779 1780class Opclass(Expression): 1781 arg_types = {"this": True, "expression": True} 1782 1783 1784class Star(Expression): 1785 arg_types = {"except_": False, "replace": False, "rename": False} 1786 1787 @property 1788 def name(self) -> str: 1789 return "*" 1790 1791 @property 1792 def output_name(self) -> str: 1793 return self.name 1794 1795 1796class Parameter(Expression, Condition): 1797 arg_types = {"this": True, "expression": False} 1798 1799 1800class SessionParameter(Expression, Condition): 1801 arg_types = {"this": True, "kind": False} 1802 1803 1804class Placeholder(Expression, Condition): 1805 arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False} 1806 1807 @property 1808 def name(self) -> str: 1809 return self.text("this") or "?" 1810 1811 1812class Null(Expression, Condition): 1813 arg_types = {} 1814 1815 @property 1816 def name(self) -> str: 1817 return "NULL" 1818 1819 def to_py(self) -> t.Literal[None]: 1820 return None 1821 1822 1823class Boolean(Expression, Condition): 1824 is_primitive = True 1825 1826 def to_py(self) -> bool: 1827 return self.this 1828 1829 1830class Dot(Expression, Binary): 1831 @property 1832 def is_star(self) -> bool: 1833 return self.expression.is_star 1834 1835 @property 1836 def name(self) -> str: 1837 return self.expression.name 1838 1839 @property 1840 def output_name(self) -> str: 1841 return self.name 1842 1843 @classmethod 1844 def build(cls, expressions: Sequence[Expr]) -> Dot: 1845 """Build a Dot object with a sequence of expressions.""" 1846 if len(expressions) < 2: 1847 raise ValueError("Dot requires >= 2 expressions.") 1848 1849 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) 1850 1851 @property 1852 def parts(self) -> list[Expr]: 1853 """Return the parts of a table / column in order catalog, db, table.""" 1854 this, *parts = self.flatten() 1855 1856 parts.reverse() 1857 1858 for arg in COLUMN_PARTS: 1859 part = this.args.get(arg) 1860 1861 if isinstance(part, Expr): 1862 parts.append(part) 1863 1864 parts.reverse() 1865 return parts 1866 1867 1868class Kwarg(Expression, Binary): 1869 """Kwarg in special functions like func(kwarg => y).""" 1870 1871 1872class Alias(Expression): 1873 arg_types = {"this": True, "alias": False} 1874 1875 @property 1876 def output_name(self) -> str: 1877 return self.alias 1878 1879 1880class PivotAlias(Alias): 1881 pass 1882 1883 1884class PivotAny(Expression): 1885 arg_types = {"this": False} 1886 1887 1888class Aliases(Expression): 1889 arg_types = {"this": True, "expressions": True} 1890 1891 @property 1892 def aliases(self) -> list[Expr]: 1893 return self.expressions 1894 1895 1896class Bracket(Expression, Condition): 1897 # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator 1898 arg_types = { 1899 "this": True, 1900 "expressions": True, 1901 "offset": False, 1902 "safe": False, 1903 "returns_list_for_maps": False, 1904 "json_access": False, 1905 } 1906 1907 @property 1908 def output_name(self) -> str: 1909 if len(self.expressions) == 1: 1910 return self.expressions[0].output_name 1911 1912 return super().output_name 1913 1914 1915class ForIn(Expression): 1916 arg_types = {"this": True, "expression": True} 1917 1918 1919class IgnoreNulls(Expression): 1920 pass 1921 1922 1923class RespectNulls(Expression): 1924 pass 1925 1926 1927class HavingMax(Expression): 1928 arg_types = {"this": True, "expression": True, "max": True} 1929 1930 1931class SafeFunc(Expression, Func): 1932 pass 1933 1934 1935class Typeof(Expression, Func): 1936 pass 1937 1938 1939class ParameterizedAgg(Expression, AggFunc): 1940 arg_types = {"this": True, "expressions": True, "params": True} 1941 1942 1943class Anonymous(Expression, Func): 1944 arg_types = {"this": True, "expressions": False} 1945 is_var_len_args = True 1946 1947 @property 1948 def name(self) -> str: 1949 return self.this if isinstance(self.this, str) else self.this.name 1950 1951 1952class AnonymousAggFunc(Expression, AggFunc): 1953 arg_types = {"this": True, "expressions": False} 1954 is_var_len_args = True 1955 1956 1957class CombinedAggFunc(AnonymousAggFunc): 1958 arg_types = {"this": True, "expressions": False} 1959 1960 1961class CombinedParameterizedAgg(ParameterizedAgg): 1962 arg_types = {"this": True, "expressions": True, "params": True} 1963 1964 1965class HashAgg(Expression, AggFunc): 1966 arg_types = {"this": True, "expressions": False} 1967 is_var_len_args = True 1968 1969 1970class Hll(Expression, AggFunc): 1971 arg_types = {"this": True, "expressions": False} 1972 is_var_len_args = True 1973 1974 1975class ApproxDistinct(Expression, AggFunc): 1976 arg_types = {"this": True, "accuracy": False} 1977 _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"] 1978 1979 1980class Slice(Expression): 1981 arg_types = {"this": False, "expression": False, "step": False} 1982 1983 1984@trait 1985class TimeUnit(Expr): 1986 """Automatically converts unit arg into a var.""" 1987 1988 UNABBREVIATED_UNIT_NAME: t.ClassVar[dict[str, str]] = { 1989 "D": "DAY", 1990 "H": "HOUR", 1991 "M": "MINUTE", 1992 "MS": "MILLISECOND", 1993 "NS": "NANOSECOND", 1994 "Q": "QUARTER", 1995 "S": "SECOND", 1996 "US": "MICROSECOND", 1997 "W": "WEEK", 1998 "Y": "YEAR", 1999 } 2000 2001 VAR_LIKE: t.ClassVar[tuple[Type[Expr], ...]] = (Column, Literal, Var) 2002 2003 def __init__(self, **args: object) -> None: 2004 super().__init__(**args) 2005 2006 unit = self.args.get("unit") 2007 if ( 2008 unit 2009 and type(unit) in TimeUnit.VAR_LIKE 2010 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2011 ): 2012 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2013 self.args["unit"] = unit 2014 self._set_parent("unit", unit) 2015 elif type(unit).__name__ == "Week": 2016 unit.set("this", Var(this=unit.this.name.upper())) # type: ignore[union-attr] 2017 2018 @property 2019 def unit(self) -> Expr | None: 2020 return self.args.get("unit") 2021 2022 2023class _TimeUnit(Expression, TimeUnit): 2024 """Automatically converts unit arg into a var.""" 2025 2026 arg_types = {"unit": False} 2027 2028 2029@trait 2030class IntervalOp(TimeUnit): 2031 def interval(self) -> Interval: 2032 from sqlglot.expressions.datatypes import Interval 2033 2034 expr = self.expression 2035 return Interval( 2036 this=expr.copy() if expr is not None else None, 2037 unit=self.unit.copy() if self.unit else None, 2038 ) 2039 2040 2041class Filter(Expression): 2042 arg_types = {"this": True, "expression": True} 2043 2044 2045class Check(Expression): 2046 pass 2047 2048 2049class Ordered(Expression): 2050 arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False} 2051 2052 @property 2053 def name(self) -> str: 2054 return self.this.name 2055 2056 2057class Add(Expression, Binary): 2058 pass 2059 2060 2061class BitwiseAnd(Expression, Binary): 2062 arg_types = {"this": True, "expression": True, "padside": False} 2063 2064 2065class BitwiseLeftShift(Expression, Binary): 2066 arg_types = {"this": True, "expression": True, "requires_int128": False} 2067 2068 2069class BitwiseOr(Expression, Binary): 2070 arg_types = {"this": True, "expression": True, "padside": False} 2071 2072 2073class BitwiseRightShift(Expression, Binary): 2074 arg_types = {"this": True, "expression": True, "requires_int128": False} 2075 2076 2077class BitwiseXor(Expression, Binary): 2078 arg_types = {"this": True, "expression": True, "padside": False} 2079 2080 2081class Div(Expression, Binary): 2082 arg_types = {"this": True, "expression": True, "typed": False, "safe": False} 2083 2084 2085class Overlaps(Expression, Binary): 2086 pass 2087 2088 2089class ExtendsLeft(Expression, Binary): 2090 pass 2091 2092 2093class ExtendsRight(Expression, Binary): 2094 pass 2095 2096 2097class DPipe(Expression, Binary): 2098 arg_types = {"this": True, "expression": True, "safe": False} 2099 2100 2101class EQ(Expression, Binary, Predicate): 2102 pass 2103 2104 2105class NullSafeEQ(Expression, Binary, Predicate): 2106 pass 2107 2108 2109class NullSafeNEQ(Expression, Binary, Predicate): 2110 pass 2111 2112 2113class PropertyEQ(Expression, Binary): 2114 pass 2115 2116 2117class Distance(Expression, Binary): 2118 pass 2119 2120 2121class Escape(Expression, Binary): 2122 pass 2123 2124 2125class Glob(Expression, Binary, Predicate): 2126 pass 2127 2128 2129class GT(Expression, Binary, Predicate): 2130 pass 2131 2132 2133class GTE(Expression, Binary, Predicate): 2134 pass 2135 2136 2137class ILike(Expression, Binary, Predicate): 2138 pass 2139 2140 2141class IntDiv(Expression, Binary): 2142 pass 2143 2144 2145class Is(Expression, Binary, Predicate): 2146 pass 2147 2148 2149class Like(Expression, Binary, Predicate): 2150 pass 2151 2152 2153class Match(Expression, Binary, Predicate): 2154 pass 2155 2156 2157class LT(Expression, Binary, Predicate): 2158 pass 2159 2160 2161class LTE(Expression, Binary, Predicate): 2162 pass 2163 2164 2165class Mod(Expression, Binary): 2166 pass 2167 2168 2169class Mul(Expression, Binary): 2170 pass 2171 2172 2173class NEQ(Expression, Binary, Predicate): 2174 pass 2175 2176 2177class NestedJSONSelect(Expression, Binary): 2178 pass 2179 2180 2181class Operator(Expression, Binary): 2182 arg_types = {"this": True, "operator": True, "expression": True} 2183 2184 2185class SimilarTo(Expression, Binary, Predicate): 2186 pass 2187 2188 2189class Sub(Expression, Binary): 2190 pass 2191 2192 2193class Adjacent(Expression, Binary): 2194 pass 2195 2196 2197class Unary(Expression, Condition): 2198 pass 2199 2200 2201class BitwiseNot(Unary): 2202 pass 2203 2204 2205class Not(Unary): 2206 pass 2207 2208 2209class Paren(Unary): 2210 @property 2211 def output_name(self) -> str: 2212 return self.this.name 2213 2214 2215class Neg(Unary): 2216 def to_py(self) -> int | Decimal: 2217 if self.is_number: 2218 return self.this.to_py() * -1 2219 return super().to_py() 2220 2221 2222class AtIndex(Expression): 2223 arg_types = {"this": True, "expression": True} 2224 2225 2226class AtTimeZone(Expression): 2227 arg_types = {"this": True, "zone": True} 2228 2229 2230class FromTimeZone(Expression): 2231 arg_types = {"this": True, "zone": True} 2232 2233 2234class FormatPhrase(Expression): 2235 """Format override for a column in Teradata. 2236 Can be expanded to additional dialects as needed 2237 2238 https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT 2239 """ 2240 2241 arg_types = {"this": True, "format": True} 2242 2243 2244class Between(Expression, Predicate): 2245 arg_types = {"this": True, "low": True, "high": True, "symmetric": False} 2246 2247 2248class Distinct(Expression): 2249 arg_types = {"expressions": False, "on": False} 2250 2251 2252class In(Expression, Predicate): 2253 arg_types = { 2254 "this": True, 2255 "expressions": False, 2256 "query": False, 2257 "unnest": False, 2258 "field": False, 2259 "is_global": False, 2260 } 2261 2262 2263class And(Expression, Connector, Func): 2264 pass 2265 2266 2267class Or(Expression, Connector, Func): 2268 pass 2269 2270 2271class Xor(Expression, Connector, Func): 2272 arg_types = {"this": False, "expression": False, "expressions": False, "round_input": False} 2273 is_var_len_args = True 2274 2275 2276class Pow(Expression, Binary, Func): 2277 _sql_names = ["POWER", "POW"] 2278 2279 2280class RegexpLike(Expression, Binary, Func): 2281 arg_types = {"this": True, "expression": True, "flag": False, "full_match": False} 2282 2283 2284def not_( 2285 expression: ExpOrStr, 2286 dialect: DialectType = None, 2287 copy: bool = True, 2288 **opts: Unpack[ParserNoDialectArgs], 2289) -> Not: 2290 """ 2291 Wrap a condition with a NOT operator. 2292 2293 Example: 2294 >>> not_("this_suit='black'").sql() 2295 "NOT this_suit = 'black'" 2296 2297 Args: 2298 expression: the SQL code string to parse. 2299 If an Expr instance is passed, this is used as-is. 2300 dialect: the dialect used to parse the input expression. 2301 copy: whether to copy the expression or not. 2302 **opts: other options to use to parse the input expressions. 2303 2304 Returns: 2305 The new condition. 2306 """ 2307 this = condition( 2308 expression, 2309 dialect=dialect, 2310 copy=copy, 2311 **opts, 2312 ) 2313 return Not(this=_wrap(this, Connector)) 2314 2315 2316def _lazy_unnest(**kwargs: object) -> Expr: 2317 from sqlglot.expressions.array import Unnest 2318 2319 return Unnest(**kwargs) 2320 2321 2322def convert(value: t.Any, copy: bool = False) -> Expr: 2323 """Convert a python value into an expression object. 2324 2325 Raises an error if a conversion is not possible. 2326 2327 Args: 2328 value: A python object. 2329 copy: Whether to copy `value` (only applies to Exprs and collections). 2330 2331 Returns: 2332 The equivalent expression object. 2333 """ 2334 if isinstance(value, Expr): 2335 return maybe_copy(value, copy) 2336 if isinstance(value, str): 2337 return Literal.string(value) 2338 if isinstance(value, bool): 2339 return Boolean(this=value) 2340 if value is None or (isinstance(value, float) and math.isnan(value)): 2341 return Null() 2342 if isinstance(value, numbers.Number): 2343 return Literal.number(value) 2344 if isinstance(value, bytes): 2345 from sqlglot.expressions.query import HexString as _HexString 2346 2347 return _HexString(this=value.hex()) 2348 if isinstance(value, datetime.datetime): 2349 datetime_literal = Literal.string(value.isoformat(sep=" ")) 2350 2351 tz = None 2352 if value.tzinfo: 2353 # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles" 2354 # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot 2355 tz = Literal.string(str(value.tzinfo)) 2356 2357 from sqlglot.expressions.temporal import TimeStrToTime as _TimeStrToTime 2358 2359 return _TimeStrToTime(this=datetime_literal, zone=tz) 2360 if isinstance(value, datetime.date): 2361 date_literal = Literal.string(value.strftime("%Y-%m-%d")) 2362 from sqlglot.expressions.temporal import DateStrToDate as _DateStrToDate 2363 2364 return _DateStrToDate(this=date_literal) 2365 if isinstance(value, datetime.time): 2366 time_literal = Literal.string(value.isoformat()) 2367 from sqlglot.expressions.temporal import TsOrDsToTime as _TsOrDsToTime 2368 2369 return _TsOrDsToTime(this=time_literal) 2370 if isinstance(value, tuple): 2371 if hasattr(value, "_fields"): 2372 from sqlglot.expressions.array import Struct as _Struct 2373 2374 return _Struct( 2375 expressions=[ 2376 PropertyEQ( 2377 this=to_identifier(k), expression=convert(getattr(value, k), copy=copy) 2378 ) 2379 for k in value._fields 2380 ] 2381 ) 2382 from sqlglot.expressions.query import Tuple as _Tuple 2383 2384 return _Tuple(expressions=[convert(v, copy=copy) for v in value]) 2385 if isinstance(value, list): 2386 from sqlglot.expressions.array import Array as _Array 2387 2388 return _Array(expressions=[convert(v, copy=copy) for v in value]) 2389 if isinstance(value, dict): 2390 from sqlglot.expressions.array import Array as _Array, Map as _Map 2391 2392 return _Map( 2393 keys=_Array(expressions=[convert(k, copy=copy) for k in value]), 2394 values=_Array(expressions=[convert(v, copy=copy) for v in value.values()]), 2395 ) 2396 if hasattr(value, "__dict__"): 2397 from sqlglot.expressions.array import Struct as _Struct 2398 2399 return _Struct( 2400 expressions=[ 2401 PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy)) 2402 for k, v in value.__dict__.items() 2403 ] 2404 ) 2405 raise ValueError(f"Cannot convert {value}") 2406 2407 2408QUERY_MODIFIERS = { 2409 "match": False, 2410 "laterals": False, 2411 "joins": False, 2412 "connect": False, 2413 "pivots": False, 2414 "prewhere": False, 2415 "where": False, 2416 "group": False, 2417 "having": False, 2418 "qualify": False, 2419 "windows": False, 2420 "distribute": False, 2421 "sort": False, 2422 "cluster": False, 2423 "order": False, 2424 "limit": False, 2425 "offset": False, 2426 "locks": False, 2427 "sample": False, 2428 "settings": False, 2429 "format": False, 2430 "options": False, 2431} 2432 2433 2434TIMESTAMP_PARTS = { 2435 "year": False, 2436 "month": False, 2437 "day": False, 2438 "hour": False, 2439 "min": False, 2440 "sec": False, 2441 "nano": False, 2442} 2443 2444 2445@t.overload 2446def maybe_parse( 2447 sql_or_expression: int | str, 2448 *, 2449 into: Type[E], 2450 dialect: DialectType = None, 2451 prefix: str | None = None, 2452 copy: bool = False, 2453 **opts: Unpack[ParserNoDialectArgs], 2454) -> E: ... 2455 2456 2457@t.overload 2458def maybe_parse( 2459 sql_or_expression: int | str | E, 2460 *, 2461 into: IntoType | None = None, 2462 dialect: DialectType = None, 2463 prefix: str | None = None, 2464 copy: bool = False, 2465 **opts: Unpack[ParserNoDialectArgs], 2466) -> E: ... 2467 2468 2469def maybe_parse( 2470 sql_or_expression: ExpOrStr, 2471 *, 2472 into: IntoType | None = None, 2473 dialect: DialectType = None, 2474 prefix: str | None = None, 2475 copy: bool = False, 2476 **opts: Unpack[ParserNoDialectArgs], 2477) -> Expr: 2478 """Gracefully handle a possible string or expression. 2479 2480 Example: 2481 >>> maybe_parse("1") 2482 Literal(this=1, is_string=False) 2483 >>> maybe_parse(to_identifier("x")) 2484 Identifier(this=x, quoted=False) 2485 2486 Args: 2487 sql_or_expression: the SQL code string or an expression 2488 into: the SQLGlot Expr to parse into 2489 dialect: the dialect used to parse the input expressions (in the case that an 2490 input expression is a SQL string). 2491 prefix: a string to prefix the sql with before it gets parsed 2492 (automatically includes a space) 2493 copy: whether to copy the expression. 2494 **opts: other options to use to parse the input expressions (again, in the case 2495 that an input expression is a SQL string). 2496 2497 Returns: 2498 Expr: the parsed or given expression. 2499 """ 2500 if isinstance(sql_or_expression, Expr): 2501 if copy: 2502 return sql_or_expression.copy() 2503 return sql_or_expression 2504 2505 if sql_or_expression is None: 2506 raise ParseError("SQL cannot be None") 2507 2508 import sqlglot 2509 2510 sql = str(sql_or_expression) 2511 if prefix: 2512 sql = f"{prefix} {sql}" 2513 2514 return sqlglot.parse_one(sql, read=dialect, into=into, **opts) 2515 2516 2517@t.overload 2518def maybe_copy(instance: None, copy: bool = True) -> None: ... 2519 2520 2521@t.overload 2522def maybe_copy(instance: E, copy: bool = True) -> E: ... 2523 2524 2525def maybe_copy(instance, copy=True): 2526 return instance.copy() if copy and instance else instance 2527 2528 2529def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str: 2530 """Generate a textual representation of an Expr tree""" 2531 indent = "\n" + (" " * (level + 1)) 2532 delim = f",{indent}" 2533 2534 if isinstance(node, Expr): 2535 args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose} 2536 2537 if (node.type or verbose) and type(node).__name__ != "DataType": 2538 args["_type"] = node.type 2539 if node.comments or verbose: 2540 args["_comments"] = node.comments 2541 2542 if verbose: 2543 args["_id"] = id(node) 2544 2545 # Inline leaves for a more compact representation 2546 if node.is_leaf(): 2547 indent = "" 2548 delim = ", " 2549 2550 repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted) 2551 items = delim.join( 2552 [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()] 2553 ) 2554 return f"{node.__class__.__name__}({indent}{items})" 2555 2556 if isinstance(node, list): 2557 items = delim.join(_to_s(i, verbose, level + 1) for i in node) 2558 items = f"{indent}{items}" if items else "" 2559 return f"[{items}]" 2560 2561 # We use the representation of the string to avoid stripping out important whitespace 2562 if repr_str and isinstance(node, str): 2563 node = repr(node) 2564 2565 # Indent multiline strings to match the current level 2566 return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines()) 2567 2568 2569def _is_wrong_expression(expression, into): 2570 return isinstance(expression, Expr) and not isinstance(expression, into) 2571 2572 2573def _apply_builder( 2574 expression: ExpOrStr, 2575 instance: E, 2576 arg: str, 2577 copy: bool = True, 2578 prefix: str | None = None, 2579 into: Type[Expr] | None = None, 2580 dialect: DialectType = None, 2581 into_arg="this", 2582 **opts: Unpack[ParserNoDialectArgs], 2583) -> E: 2584 if _is_wrong_expression(expression, into) and into is not None: 2585 expression = into(**{into_arg: expression}) 2586 instance = maybe_copy(instance, copy) 2587 expression = maybe_parse( 2588 sql_or_expression=expression, 2589 prefix=prefix, 2590 into=into, 2591 dialect=dialect, 2592 **opts, 2593 ) 2594 instance.set(arg, expression) 2595 return instance 2596 2597 2598def _apply_child_list_builder( 2599 *expressions: ExpOrStr | None, 2600 instance: E, 2601 arg: str, 2602 append: bool = True, 2603 copy: bool = True, 2604 prefix: str | None = None, 2605 into: Type[Expr] | None = None, 2606 dialect: DialectType = None, 2607 properties: MutableMapping[str, object] | None = None, 2608 **opts: Unpack[ParserNoDialectArgs], 2609) -> E: 2610 instance = maybe_copy(instance, copy) 2611 parsed = [] 2612 properties = {} if properties is None else properties 2613 2614 for expression in expressions: 2615 if expression is not None: 2616 if _is_wrong_expression(expression, into) and into is not None: 2617 expression = into(expressions=[expression]) 2618 2619 expression = maybe_parse( 2620 expression, 2621 into=into, 2622 dialect=dialect, 2623 prefix=prefix, 2624 **opts, 2625 ) 2626 for k, v in expression.args.items(): 2627 if k == "expressions": 2628 parsed.extend(v) 2629 else: 2630 properties[k] = v 2631 2632 existing = instance.args.get(arg) 2633 if append and existing: 2634 parsed = existing.expressions + parsed 2635 if into is None: 2636 raise ValueError("`into` is required to use `_apply_child_list_builder`") 2637 child = into(expressions=parsed) 2638 for k, v in properties.items(): 2639 child.set(k, v) 2640 instance.set(arg, child) 2641 2642 return instance 2643 2644 2645def _apply_list_builder( 2646 *expressions: ExpOrStr | None, 2647 instance: E, 2648 arg: str, 2649 append: bool = True, 2650 copy: bool = True, 2651 prefix: str | None = None, 2652 into: Type[Expr] | None = None, 2653 dialect: DialectType = None, 2654 **opts: Unpack[ParserNoDialectArgs], 2655) -> E: 2656 inst = maybe_copy(instance, copy) 2657 2658 parsed = [ 2659 maybe_parse( 2660 sql_or_expression=expression, 2661 into=into, 2662 prefix=prefix, 2663 dialect=dialect, 2664 **opts, 2665 ) 2666 for expression in expressions 2667 if expression is not None 2668 ] 2669 2670 existing_expressions = inst.args.get(arg) 2671 if append and existing_expressions: 2672 parsed = existing_expressions + parsed 2673 2674 inst.set(arg, parsed) 2675 return inst 2676 2677 2678def _apply_conjunction_builder( 2679 *expressions: ExpOrStr | None, 2680 instance: E, 2681 arg: str, 2682 into: Type[Expr] | None = None, 2683 append: bool = True, 2684 copy: bool = True, 2685 dialect: DialectType = None, 2686 **opts: Unpack[ParserNoDialectArgs], 2687) -> E: 2688 filtered = [exp for exp in expressions if exp is not None and exp != ""] 2689 if not filtered: 2690 return instance 2691 2692 inst = maybe_copy(instance, copy) 2693 2694 existing = inst.args.get(arg) 2695 if append and existing is not None: 2696 filtered = [existing.this if into else existing] + filtered 2697 2698 node = and_(*filtered, dialect=dialect, copy=copy, **opts) 2699 2700 inst.set(arg, into(this=node) if into else node) 2701 return inst 2702 2703 2704def _combine( 2705 expressions: Sequence[ExpOrStr | None], 2706 operator: Type[Expr], 2707 dialect: DialectType = None, 2708 copy: bool = True, 2709 wrap: bool = True, 2710 **opts: Unpack[ParserNoDialectArgs], 2711) -> Expr: 2712 conditions = [ 2713 condition(expression, dialect=dialect, copy=copy, **opts) 2714 for expression in expressions 2715 if expression is not None 2716 ] 2717 2718 this, *rest = conditions 2719 if rest and wrap: 2720 this = _wrap(this, Connector) 2721 for expression in rest: 2722 this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression) 2723 2724 return this 2725 2726 2727@t.overload 2728def _wrap(expression: None, kind: Type[Expr]) -> None: ... 2729 2730 2731@t.overload 2732def _wrap(expression: E, kind: Type[Expr]) -> E | Paren: ... 2733 2734 2735def _wrap(expression: E | None, kind: Type[Expr]) -> E | None | Paren: 2736 return Paren(this=expression) if isinstance(expression, kind) else expression 2737 2738 2739def _apply_set_operation( 2740 *expressions: ExpOrStr, 2741 set_operation: Type, 2742 distinct: bool = True, 2743 dialect: DialectType = None, 2744 copy: bool = True, 2745 **opts: Unpack[ParserNoDialectArgs], 2746) -> t.Any: 2747 return reduce( 2748 lambda x, y: set_operation(this=x, expression=y, distinct=distinct, **opts), 2749 (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions), 2750 ) 2751 2752 2753SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$") 2754 2755 2756@t.overload 2757def to_identifier(name: None, quoted: bool | None = None, copy: bool = True) -> None: ... 2758 2759 2760@t.overload 2761def to_identifier( 2762 name: int | str | Identifier, quoted: bool | None = None, copy: bool = True 2763) -> Identifier: ... 2764 2765 2766def to_identifier(name, quoted=None, copy=True): 2767 """Builds an identifier. 2768 2769 Args: 2770 name: The name to turn into an identifier. 2771 quoted: Whether to force quote the identifier. 2772 copy: Whether to copy name if it's an Identifier. 2773 2774 Returns: 2775 The identifier ast node. 2776 """ 2777 2778 if name is None: 2779 return None 2780 2781 if isinstance(name, Identifier): 2782 identifier = maybe_copy(name, copy) 2783 elif isinstance(name, str): 2784 identifier = Identifier( 2785 this=name, 2786 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, 2787 ) 2788 else: 2789 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") 2790 return identifier 2791 2792 2793def condition( 2794 expression: ExpOrStr, 2795 dialect: DialectType = None, 2796 copy: bool = True, 2797 **opts: Unpack[ParserNoDialectArgs], 2798) -> Expr: 2799 """ 2800 Initialize a logical condition expression. 2801 2802 Example: 2803 >>> condition("x=1").sql() 2804 'x = 1' 2805 2806 This is helpful for composing larger logical syntax trees: 2807 >>> where = condition("x=1") 2808 >>> where = where.and_("y=1") 2809 >>> where.sql() 2810 'x = 1 AND y = 1' 2811 2812 Args: 2813 *expression: the SQL code string to parse. 2814 If an Expr instance is passed, this is used as-is. 2815 dialect: the dialect used to parse the input expression (in the case that the 2816 input expression is a SQL string). 2817 copy: Whether to copy `expression` (only applies to expressions). 2818 **opts: other options to use to parse the input expressions (again, in the case 2819 that the input expression is a SQL string). 2820 2821 Returns: 2822 The new Condition instance 2823 """ 2824 return maybe_parse( 2825 expression, 2826 into=Condition, 2827 dialect=dialect, 2828 copy=copy, 2829 **opts, 2830 ) 2831 2832 2833def and_( 2834 *expressions: ExpOrStr | None, 2835 dialect: DialectType = None, 2836 copy: bool = True, 2837 wrap: bool = True, 2838 **opts: Unpack[ParserNoDialectArgs], 2839) -> Condition: 2840 """ 2841 Combine multiple conditions with an AND logical operator. 2842 2843 Example: 2844 >>> and_("x=1", and_("y=1", "z=1")).sql() 2845 'x = 1 AND (y = 1 AND z = 1)' 2846 2847 Args: 2848 *expressions: the SQL code strings to parse. 2849 If an Expr instance is passed, this is used as-is. 2850 dialect: the dialect used to parse the input expression. 2851 copy: whether to copy `expressions` (only applies to Exprs). 2852 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2853 precedence issues, but can be turned off when the produced AST is too deep and 2854 causes recursion-related issues. 2855 **opts: other options to use to parse the input expressions. 2856 2857 Returns: 2858 The new condition 2859 """ 2860 return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts)) 2861 2862 2863def or_( 2864 *expressions: ExpOrStr | None, 2865 dialect: DialectType = None, 2866 copy: bool = True, 2867 wrap: bool = True, 2868 **opts: Unpack[ParserNoDialectArgs], 2869) -> Condition: 2870 """ 2871 Combine multiple conditions with an OR logical operator. 2872 2873 Example: 2874 >>> or_("x=1", or_("y=1", "z=1")).sql() 2875 'x = 1 OR (y = 1 OR z = 1)' 2876 2877 Args: 2878 *expressions: the SQL code strings to parse. 2879 If an Expr instance is passed, this is used as-is. 2880 dialect: the dialect used to parse the input expression. 2881 copy: whether to copy `expressions` (only applies to Exprs). 2882 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2883 precedence issues, but can be turned off when the produced AST is too deep and 2884 causes recursion-related issues. 2885 **opts: other options to use to parse the input expressions. 2886 2887 Returns: 2888 The new condition 2889 """ 2890 return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts)) 2891 2892 2893def xor( 2894 *expressions: ExpOrStr | None, 2895 dialect: DialectType = None, 2896 copy: bool = True, 2897 wrap: bool = True, 2898 **opts: Unpack[ParserNoDialectArgs], 2899) -> Condition: 2900 """ 2901 Combine multiple conditions with an XOR logical operator. 2902 2903 Example: 2904 >>> xor("x=1", xor("y=1", "z=1")).sql() 2905 'x = 1 XOR (y = 1 XOR z = 1)' 2906 2907 Args: 2908 *expressions: the SQL code strings to parse. 2909 If an Expr instance is passed, this is used as-is. 2910 dialect: the dialect used to parse the input expression. 2911 copy: whether to copy `expressions` (only applies to Exprs). 2912 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2913 precedence issues, but can be turned off when the produced AST is too deep and 2914 causes recursion-related issues. 2915 **opts: other options to use to parse the input expressions. 2916 2917 Returns: 2918 The new condition 2919 """ 2920 return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts)) 2921 2922 2923def paren(expression: ExpOrStr, copy: bool = True) -> Paren: 2924 """ 2925 Wrap an expression in parentheses. 2926 2927 Example: 2928 >>> paren("5 + 3").sql() 2929 '(5 + 3)' 2930 2931 Args: 2932 expression: the SQL code string to parse. 2933 If an Expr instance is passed, this is used as-is. 2934 copy: whether to copy the expression or not. 2935 2936 Returns: 2937 The wrapped expression. 2938 """ 2939 return Paren(this=maybe_parse(expression, copy=copy)) 2940 2941 2942def alias_( 2943 expression: ExpOrStr, 2944 alias: str | Identifier | None, 2945 table: bool | Sequence[str | Identifier] = False, 2946 quoted: bool | None = None, 2947 dialect: DialectType = None, 2948 copy: bool = True, 2949 **opts: Unpack[ParserNoDialectArgs], 2950) -> Expr: 2951 """Create an Alias expression. 2952 2953 Example: 2954 >>> alias_('foo', 'bar').sql() 2955 'foo AS bar' 2956 2957 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() 2958 '(SELECT 1, 2) AS bar(a, b)' 2959 2960 Args: 2961 expression: the SQL code strings to parse. 2962 If an Expr instance is passed, this is used as-is. 2963 alias: the alias name to use. If the name has 2964 special characters it is quoted. 2965 table: Whether to create a table alias, can also be a list of columns. 2966 quoted: whether to quote the alias 2967 dialect: the dialect used to parse the input expression. 2968 copy: Whether to copy the expression. 2969 **opts: other options to use to parse the input expressions. 2970 2971 Returns: 2972 Alias: the aliased expression 2973 """ 2974 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) 2975 alias = to_identifier(alias, quoted=quoted) 2976 2977 if table: 2978 from sqlglot.expressions.query import TableAlias as _TableAlias 2979 2980 table_alias = _TableAlias(this=alias) 2981 exp.set("alias", table_alias) 2982 2983 if not isinstance(table, bool): 2984 for column in table: 2985 table_alias.append("columns", to_identifier(column, quoted=quoted)) 2986 2987 return exp 2988 2989 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in 2990 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node 2991 # for the complete Window expression. 2992 # 2993 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls 2994 2995 if "alias" in exp.arg_types and type(exp).__name__ != "Window": 2996 exp.set("alias", alias) 2997 return exp 2998 return Alias(this=exp, alias=alias) 2999 3000 3001@t.overload 3002def column( 3003 col: str | Identifier, 3004 table: str | Identifier | None = None, 3005 db: str | Identifier | None = None, 3006 catalog: str | Identifier | None = None, 3007 *, 3008 fields: Collection[str | Identifier], 3009 quoted: bool | None = None, 3010 copy: bool = True, 3011) -> Dot: 3012 pass 3013 3014 3015@t.overload 3016def column( 3017 col: str | Identifier | Star, 3018 table: str | Identifier | None = None, 3019 db: str | Identifier | None = None, 3020 catalog: str | Identifier | None = None, 3021 *, 3022 fields: t.Literal[None] = None, 3023 quoted: bool | None = None, 3024 copy: bool = True, 3025) -> Column: 3026 pass 3027 3028 3029def column( 3030 col, 3031 table=None, 3032 db=None, 3033 catalog=None, 3034 *, 3035 fields=None, 3036 quoted=None, 3037 copy: bool = True, 3038): 3039 """ 3040 Build a Column. 3041 3042 Args: 3043 col: Column name. 3044 table: Table name. 3045 db: Database name. 3046 catalog: Catalog name. 3047 fields: Additional fields using dots. 3048 quoted: Whether to force quotes on the column's identifiers. 3049 copy: Whether to copy identifiers if passed in. 3050 3051 Returns: 3052 The new Column instance. 3053 """ 3054 if not isinstance(col, Star): 3055 col = to_identifier(col, quoted=quoted, copy=copy) 3056 3057 this: Column | Dot = Column( 3058 this=col, 3059 table=to_identifier(table, quoted=quoted, copy=copy), 3060 db=to_identifier(db, quoted=quoted, copy=copy), 3061 catalog=to_identifier(catalog, quoted=quoted, copy=copy), 3062 ) 3063 3064 if fields: 3065 this = Dot.build( 3066 (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields)) 3067 ) 3068 return this
52@trait 53class Expr: 54 """ 55 The base class for all expressions in a syntax tree. Each Expr encapsulates any necessary 56 context, such as its child expressions, their names (arg keys), and whether a given child expression 57 is optional or not. 58 59 Attributes: 60 key: a unique key for each class in the Expr hierarchy. This is useful for hashing 61 and representing expressions as strings. 62 arg_types: determines the arguments (child nodes) supported by an expression. It maps 63 arg keys to booleans that indicate whether the corresponding args are optional. 64 parent: a reference to the parent expression (or None, in case of root expressions). 65 arg_key: the arg key an expression is associated with, i.e. the name its parent expression 66 uses to refer to it. 67 index: the index of an expression if it is inside of a list argument in its parent. 68 comments: a list of comments that are associated with a given expression. This is used in 69 order to preserve comments when transpiling SQL code. 70 type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the 71 optimizer, in order to enable some transformations that require type information. 72 meta: a dictionary that can be used to store useful metadata for a given expression. 73 74 Example: 75 >>> class Foo(Expr): 76 ... arg_types = {"this": True, "expression": False} 77 78 The above definition informs us that Foo is an Expr that requires an argument called 79 "this" and may also optionally receive an argument called "expression". 80 81 Args: 82 args: a mapping used for retrieving the arguments of an expression, given their arg keys. 83 """ 84 85 key: t.ClassVar[str] = "expression" 86 arg_types: t.ClassVar[dict[str, bool]] = {"this": True} 87 required_args: t.ClassVar[set[str]] = {"this"} 88 is_var_len_args: t.ClassVar[bool] = False 89 _hash_raw_args: t.ClassVar[bool] = False 90 is_subquery: t.ClassVar[bool] = False 91 is_cast: t.ClassVar[bool] = False 92 93 args: dict[str, t.Any] 94 parent: Expr | None 95 arg_key: str | None 96 index: int | None 97 comments: list[str] | None 98 _type: DataType | None 99 _meta: dict[str, t.Any] | None 100 _hash: int | None 101 102 @classmethod 103 def __init_subclass__(cls, **kwargs: t.Any) -> None: 104 super().__init_subclass__(**kwargs) 105 # When an Expr class is created, its key is automatically set 106 # to be the lowercase version of the class' name. 107 cls.key = cls.__name__.lower() 108 cls.required_args = {k for k, v in cls.arg_types.items() if v} 109 # This is so that docstrings are not inherited in pdoc 110 setattr(cls, "__doc__", getattr(cls, "__doc__", None) or "") 111 112 is_primitive: t.ClassVar[bool] = False 113 114 def __init__(self, **args: object) -> None: 115 self.args: dict[str, t.Any] = args 116 self.parent: Expr | None = None 117 self.arg_key: str | None = None 118 self.index: int | None = None 119 self.comments: list[str] | None = None 120 self._type: DataType | None = None 121 self._meta: dict[str, t.Any] | None = None 122 self._hash: int | None = None 123 124 if not self.is_primitive: 125 for arg_key, value in self.args.items(): 126 self._set_parent(arg_key, value) 127 128 @property 129 def this(self) -> t.Any: 130 raise NotImplementedError 131 132 @property 133 def expression(self) -> t.Any: 134 raise NotImplementedError 135 136 @property 137 def expressions(self) -> list[t.Any]: 138 raise NotImplementedError 139 140 def text(self, key: str) -> str: 141 raise NotImplementedError 142 143 @property 144 def is_string(self) -> bool: 145 raise NotImplementedError 146 147 @property 148 def is_number(self) -> bool: 149 raise NotImplementedError 150 151 def to_py(self) -> t.Any: 152 raise NotImplementedError 153 154 @property 155 def is_int(self) -> bool: 156 raise NotImplementedError 157 158 @property 159 def is_star(self) -> bool: 160 raise NotImplementedError 161 162 @property 163 def alias(self) -> str: 164 raise NotImplementedError 165 166 @property 167 def alias_column_names(self) -> list[str]: 168 raise NotImplementedError 169 170 @property 171 def name(self) -> str: 172 raise NotImplementedError 173 174 @property 175 def alias_or_name(self) -> str: 176 raise NotImplementedError 177 178 @property 179 def output_name(self) -> str: 180 raise NotImplementedError 181 182 @property 183 def type(self) -> DataType | None: 184 raise NotImplementedError 185 186 @type.setter 187 def type(self, dtype: DataType | DType | str | None) -> None: 188 raise NotImplementedError 189 190 def is_type(self, *dtypes: DATA_TYPE) -> bool: 191 raise NotImplementedError 192 193 def is_leaf(self) -> bool: 194 raise NotImplementedError 195 196 @property 197 def meta(self) -> dict[str, t.Any]: 198 raise NotImplementedError 199 200 def __deepcopy__(self, memo: t.Any) -> Expr: 201 raise NotImplementedError 202 203 def copy(self: E) -> E: 204 raise NotImplementedError 205 206 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 207 raise NotImplementedError 208 209 def pop_comments(self) -> list[str]: 210 raise NotImplementedError 211 212 def append(self, arg_key: str, value: t.Any) -> None: 213 raise NotImplementedError 214 215 def set( 216 self, 217 arg_key: str, 218 value: object, 219 index: int | None = None, 220 overwrite: bool = True, 221 ) -> None: 222 raise NotImplementedError 223 224 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 225 raise NotImplementedError 226 227 @property 228 def depth(self) -> int: 229 raise NotImplementedError 230 231 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 232 raise NotImplementedError 233 234 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 235 raise NotImplementedError 236 237 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 238 raise NotImplementedError 239 240 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 241 raise NotImplementedError 242 243 @property 244 def parent_select(self) -> Select | None: 245 raise NotImplementedError 246 247 @property 248 def same_parent(self) -> bool: 249 raise NotImplementedError 250 251 def root(self) -> Expr: 252 raise NotImplementedError 253 254 def walk( 255 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 256 ) -> Iterator[Expr]: 257 raise NotImplementedError 258 259 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 260 raise NotImplementedError 261 262 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 263 raise NotImplementedError 264 265 def unnest(self) -> Expr: 266 raise NotImplementedError 267 268 def unalias(self) -> Expr: 269 raise NotImplementedError 270 271 def unnest_operands(self) -> tuple[Expr, ...]: 272 raise NotImplementedError 273 274 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 275 raise NotImplementedError 276 277 def to_s(self) -> str: 278 raise NotImplementedError 279 280 def sql( 281 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 282 ) -> str: 283 raise NotImplementedError 284 285 def transform( 286 self, fun: t.Callable, *args: object, copy: bool = True, **kwargs: object 287 ) -> t.Any: 288 raise NotImplementedError 289 290 def replace(self, expression: T) -> T: 291 raise NotImplementedError 292 293 def pop(self: E) -> E: 294 raise NotImplementedError 295 296 def assert_is(self, type_: Type[E]) -> E: 297 raise NotImplementedError 298 299 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 300 raise NotImplementedError 301 302 def dump(self) -> list[dict[str, t.Any]]: 303 """ 304 Dump this Expr to a JSON-serializable dict. 305 """ 306 from sqlglot.serde import dump 307 308 return dump(self) 309 310 @classmethod 311 def load(cls, obj: list[dict[str, Any]] | None) -> Expr: 312 """ 313 Load a dict (as returned by `Expr.dump`) into an Expr instance. 314 """ 315 from sqlglot.serde import load 316 317 result = load(obj) 318 assert isinstance(result, Expr) 319 return result 320 321 def and_( 322 self, 323 *expressions: ExpOrStr | None, 324 dialect: DialectType = None, 325 copy: bool = True, 326 wrap: bool = True, 327 **opts: Unpack[ParserNoDialectArgs], 328 ) -> Condition: 329 raise NotImplementedError 330 331 def or_( 332 self, 333 *expressions: ExpOrStr | None, 334 dialect: DialectType = None, 335 copy: bool = True, 336 wrap: bool = True, 337 **opts: Unpack[ParserNoDialectArgs], 338 ) -> Condition: 339 raise NotImplementedError 340 341 def not_(self, copy: bool = True) -> Not: 342 raise NotImplementedError 343 344 def update_positions( 345 self: E, 346 other: Token | Expr | None = None, 347 line: int | None = None, 348 col: int | None = None, 349 start: int | None = None, 350 end: int | None = None, 351 ) -> E: 352 raise NotImplementedError 353 354 def as_( 355 self, 356 alias: str | Identifier, 357 quoted: bool | None = None, 358 dialect: DialectType = None, 359 copy: bool = True, 360 table: bool | Sequence[str | Identifier] = False, 361 **opts: Unpack[ParserNoDialectArgs], 362 ) -> Expr: 363 raise NotImplementedError 364 365 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 366 raise NotImplementedError 367 368 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 369 raise NotImplementedError 370 371 def __iter__(self) -> Iterator: 372 raise NotImplementedError 373 374 def isin( 375 self, 376 *expressions: t.Any, 377 query: ExpOrStr | None = None, 378 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 379 dialect: DialectType = None, 380 copy: bool = True, 381 **opts: Unpack[ParserNoDialectArgs], 382 ) -> In: 383 raise NotImplementedError 384 385 def between( 386 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 387 ) -> Between: 388 raise NotImplementedError 389 390 def is_(self, other: ExpOrStr) -> Is: 391 raise NotImplementedError 392 393 def like(self, other: ExpOrStr) -> Like: 394 raise NotImplementedError 395 396 def ilike(self, other: ExpOrStr) -> ILike: 397 raise NotImplementedError 398 399 def eq(self, other: t.Any) -> EQ: 400 raise NotImplementedError 401 402 def neq(self, other: t.Any) -> NEQ: 403 raise NotImplementedError 404 405 def rlike(self, other: ExpOrStr) -> RegexpLike: 406 raise NotImplementedError 407 408 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 409 raise NotImplementedError 410 411 def asc(self, nulls_first: bool = True) -> Ordered: 412 raise NotImplementedError 413 414 def desc(self, nulls_first: bool = False) -> Ordered: 415 raise NotImplementedError 416 417 def __lt__(self, other: t.Any) -> LT: 418 raise NotImplementedError 419 420 def __le__(self, other: t.Any) -> LTE: 421 raise NotImplementedError 422 423 def __gt__(self, other: t.Any) -> GT: 424 raise NotImplementedError 425 426 def __ge__(self, other: t.Any) -> GTE: 427 raise NotImplementedError 428 429 def __add__(self, other: t.Any) -> Add: 430 raise NotImplementedError 431 432 def __radd__(self, other: t.Any) -> Add: 433 raise NotImplementedError 434 435 def __sub__(self, other: t.Any) -> Sub: 436 raise NotImplementedError 437 438 def __rsub__(self, other: t.Any) -> Sub: 439 raise NotImplementedError 440 441 def __mul__(self, other: t.Any) -> Mul: 442 raise NotImplementedError 443 444 def __rmul__(self, other: t.Any) -> Mul: 445 raise NotImplementedError 446 447 def __truediv__(self, other: t.Any) -> Div: 448 raise NotImplementedError 449 450 def __rtruediv__(self, other: t.Any) -> Div: 451 raise NotImplementedError 452 453 def __floordiv__(self, other: t.Any) -> IntDiv: 454 raise NotImplementedError 455 456 def __rfloordiv__(self, other: t.Any) -> IntDiv: 457 raise NotImplementedError 458 459 def __mod__(self, other: t.Any) -> Mod: 460 raise NotImplementedError 461 462 def __rmod__(self, other: t.Any) -> Mod: 463 raise NotImplementedError 464 465 def __pow__(self, other: t.Any) -> Pow: 466 raise NotImplementedError 467 468 def __rpow__(self, other: t.Any) -> Pow: 469 raise NotImplementedError 470 471 def __and__(self, other: t.Any) -> And: 472 raise NotImplementedError 473 474 def __rand__(self, other: t.Any) -> And: 475 raise NotImplementedError 476 477 def __or__(self, other: t.Any) -> Or: 478 raise NotImplementedError 479 480 def __ror__(self, other: t.Any) -> Or: 481 raise NotImplementedError 482 483 def __neg__(self) -> Neg: 484 raise NotImplementedError 485 486 def __invert__(self) -> Not: 487 raise NotImplementedError 488 489 def pipe( 490 self, func: t.Callable[Concatenate[Self, P], R], *args: P.args, **kwargs: P.kwargs 491 ) -> R: 492 """Apply a function to `Self` (the current instance) and return the result. 493 494 Doing `expr.pipe(func, *args, **kwargs)` is equivalent to `func(expr, *args, **kwargs)`. 495 496 It allows you to chain operations in a fluent way on any given function that takes `Self` as its first argument. 497 498 Tip: 499 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 500 501 Args: 502 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 503 *args: Additional positional arguments to pass to `func` after `Self`. 504 **kwargs: Additional keyword arguments to pass to `func`. 505 506 Returns: 507 The result of applying `func` to `Self` with the given arguments. 508 """ 509 return func(self, *args, **kwargs) 510 511 def apply( 512 self, func: t.Callable[Concatenate[Self, P], t.Any], *args: P.args, **kwargs: P.kwargs 513 ) -> Self: 514 """Apply a function to `Self` (the current instance) for side effects, and return `Self`. 515 516 Useful for inspecting intermediate expressions in a method chain by simply adding/removing `apply` calls, especially when combined with `pipe`. 517 518 Tip: 519 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 520 521 Args: 522 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 523 *args: Additional positional arguments to pass to `func` after `Self`. 524 **kwargs: Additional keyword arguments to pass to `func`. 525 526 Returns: 527 The same instance. 528 """ 529 func(self, *args, **kwargs) 530 return self
The base class for all expressions in a syntax tree. Each Expr encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.
Attributes:
- key: a unique key for each class in the Expr hierarchy. This is useful for hashing and representing expressions as strings.
- arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
- parent: a reference to the parent expression (or None, in case of root expressions).
- arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
- index: the index of an expression if it is inside of a list argument in its parent.
- comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
- type: the
sqlglot.expressions.DataTypetype of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information. - meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expr): ... arg_types = {"this": True, "expression": False}The above definition informs us that Foo is an Expr that requires an argument called "this" and may also optionally receive an argument called "expression".
Arguments:
- args: a mapping used for retrieving the arguments of an expression, given their arg keys.
114 def __init__(self, **args: object) -> None: 115 self.args: dict[str, t.Any] = args 116 self.parent: Expr | None = None 117 self.arg_key: str | None = None 118 self.index: int | None = None 119 self.comments: list[str] | None = None 120 self._type: DataType | None = None 121 self._meta: dict[str, t.Any] | None = None 122 self._hash: int | None = None 123 124 if not self.is_primitive: 125 for arg_key, value in self.args.items(): 126 self._set_parent(arg_key, value)
302 def dump(self) -> list[dict[str, t.Any]]: 303 """ 304 Dump this Expr to a JSON-serializable dict. 305 """ 306 from sqlglot.serde import dump 307 308 return dump(self)
Dump this Expr to a JSON-serializable dict.
310 @classmethod 311 def load(cls, obj: list[dict[str, Any]] | None) -> Expr: 312 """ 313 Load a dict (as returned by `Expr.dump`) into an Expr instance. 314 """ 315 from sqlglot.serde import load 316 317 result = load(obj) 318 assert isinstance(result, Expr) 319 return result
Load a dict (as returned by Expr.dump) into an Expr instance.
489 def pipe( 490 self, func: t.Callable[Concatenate[Self, P], R], *args: P.args, **kwargs: P.kwargs 491 ) -> R: 492 """Apply a function to `Self` (the current instance) and return the result. 493 494 Doing `expr.pipe(func, *args, **kwargs)` is equivalent to `func(expr, *args, **kwargs)`. 495 496 It allows you to chain operations in a fluent way on any given function that takes `Self` as its first argument. 497 498 Tip: 499 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 500 501 Args: 502 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 503 *args: Additional positional arguments to pass to `func` after `Self`. 504 **kwargs: Additional keyword arguments to pass to `func`. 505 506 Returns: 507 The result of applying `func` to `Self` with the given arguments. 508 """ 509 return func(self, *args, **kwargs)
Apply a function to Self (the current instance) and return the result.
Doing expr.pipe(func, *args, **kwargs) is equivalent to func(expr, *args, **kwargs).
It allows you to chain operations in a fluent way on any given function that takes Self as its first argument.
Tip:
If
funcdoesn't takeSelfas it's first argument, you can use a lambda to work around it.
Arguments:
- func: The function to apply. It should take
Selfas its first argument, followed by any additional arguments specified in*argsand**kwargs. - *args: Additional positional arguments to pass to
funcafterSelf. - **kwargs: Additional keyword arguments to pass to
func.
Returns:
The result of applying
functoSelfwith the given arguments.
511 def apply( 512 self, func: t.Callable[Concatenate[Self, P], t.Any], *args: P.args, **kwargs: P.kwargs 513 ) -> Self: 514 """Apply a function to `Self` (the current instance) for side effects, and return `Self`. 515 516 Useful for inspecting intermediate expressions in a method chain by simply adding/removing `apply` calls, especially when combined with `pipe`. 517 518 Tip: 519 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 520 521 Args: 522 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 523 *args: Additional positional arguments to pass to `func` after `Self`. 524 **kwargs: Additional keyword arguments to pass to `func`. 525 526 Returns: 527 The same instance. 528 """ 529 func(self, *args, **kwargs) 530 return self
Apply a function to Self (the current instance) for side effects, and return Self.
Useful for inspecting intermediate expressions in a method chain by simply adding/removing apply calls, especially when combined with pipe.
Tip:
If
funcdoesn't takeSelfas it's first argument, you can use a lambda to work around it.
Arguments:
- func: The function to apply. It should take
Selfas its first argument, followed by any additional arguments specified in*argsand**kwargs. - *args: Additional positional arguments to pass to
funcafterSelf. - **kwargs: Additional keyword arguments to pass to
func.
Returns:
The same instance.
533class Expression(Expr): 534 __slots__ = ( 535 "args", 536 "parent", 537 "arg_key", 538 "index", 539 "comments", 540 "_type", 541 "_meta", 542 "_hash", 543 ) 544 545 def __eq__(self, other: object) -> bool: 546 return self is other or (type(self) is type(other) and hash(self) == hash(other)) 547 548 def __ne__(self, other: object) -> bool: 549 return not self.__eq__(other) 550 551 def __hash__(self) -> int: 552 if self._hash is None: 553 nodes: list[Expr] = [] 554 queue: deque[Expr] = deque() 555 queue.append(self) 556 557 while queue: 558 node = queue.popleft() 559 nodes.append(node) 560 561 for child in node.iter_expressions(): 562 if child._hash is None: 563 queue.append(child) 564 565 for node in reversed(nodes): 566 hash_ = hash(node.key) 567 568 if node._hash_raw_args: 569 for k, v in sorted(node.args.items()): 570 if v: 571 hash_ = hash((hash_, k, v)) 572 else: 573 for k, v in sorted(node.args.items()): 574 vt = type(v) 575 576 if vt is list: 577 for x in v: 578 if x is not None and x is not False: 579 hash_ = hash((hash_, k, x.lower() if type(x) is str else x)) 580 else: 581 hash_ = hash((hash_, k)) 582 elif v is not None and v is not False: 583 hash_ = hash((hash_, k, v.lower() if vt is str else v)) 584 585 node._hash = hash_ 586 assert self._hash 587 return self._hash 588 589 def __reduce__( 590 self, 591 ) -> tuple[ 592 t.Callable[[list[dict[str, t.Any]] | None], Expr | DType | None], 593 tuple[list[dict[str, t.Any]]], 594 ]: 595 from sqlglot.serde import dump, load 596 597 return (load, (dump(self),)) 598 599 @property 600 def this(self) -> t.Any: 601 """ 602 Retrieves the argument with key "this". 603 """ 604 return self.args.get("this") 605 606 @property 607 def expression(self) -> t.Any: 608 """ 609 Retrieves the argument with key "expression". 610 """ 611 return self.args.get("expression") 612 613 @property 614 def expressions(self) -> list[t.Any]: 615 """ 616 Retrieves the argument with key "expressions". 617 """ 618 return self.args.get("expressions") or [] 619 620 def text(self, key: str) -> str: 621 """ 622 Returns a textual representation of the argument corresponding to "key". This can only be used 623 for args that are strings or leaf Expr instances, such as identifiers and literals. 624 """ 625 field = self.args.get(key) 626 if isinstance(field, str): 627 return field 628 if isinstance(field, (Identifier, Literal, Var)): 629 return field.this 630 if isinstance(field, (Star, Null)): 631 return field.name 632 return "" 633 634 @property 635 def is_string(self) -> bool: 636 """ 637 Checks whether a Literal expression is a string. 638 """ 639 return isinstance(self, Literal) and self.args["is_string"] 640 641 @property 642 def is_number(self) -> bool: 643 """ 644 Checks whether a Literal expression is a number. 645 """ 646 return (isinstance(self, Literal) and not self.args["is_string"]) or ( 647 isinstance(self, Neg) and self.this.is_number 648 ) 649 650 def to_py(self) -> t.Any: 651 """ 652 Returns a Python object equivalent of the SQL node. 653 """ 654 raise ValueError(f"{self} cannot be converted to a Python object.") 655 656 @property 657 def is_int(self) -> bool: 658 """ 659 Checks whether an expression is an integer. 660 """ 661 return self.is_number and isinstance(self.to_py(), int) 662 663 @property 664 def is_star(self) -> bool: 665 """Checks whether an expression is a star.""" 666 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star)) 667 668 @property 669 def alias(self) -> str: 670 """ 671 Returns the alias of the expression, or an empty string if it's not aliased. 672 """ 673 alias = self.args.get("alias") 674 if isinstance(alias, Expression): 675 return alias.name 676 return self.text("alias") 677 678 @property 679 def alias_column_names(self) -> list[str]: 680 table_alias = self.args.get("alias") 681 if not table_alias: 682 return [] 683 return [c.name for c in table_alias.args.get("columns") or []] 684 685 @property 686 def name(self) -> str: 687 return self.text("this") 688 689 @property 690 def alias_or_name(self) -> str: 691 return self.alias or self.name 692 693 @property 694 def output_name(self) -> str: 695 """ 696 Name of the output column if this expression is a selection. 697 698 If the Expr has no output name, an empty string is returned. 699 700 Example: 701 >>> from sqlglot import parse_one 702 >>> parse_one("SELECT a").expressions[0].output_name 703 'a' 704 >>> parse_one("SELECT b AS c").expressions[0].output_name 705 'c' 706 >>> parse_one("SELECT 1 + 2").expressions[0].output_name 707 '' 708 """ 709 return "" 710 711 @property 712 def type(self) -> DataType | None: 713 if self.is_cast: 714 return self._type or self.to # type: ignore[attr-defined] 715 return self._type 716 717 @type.setter 718 def type(self, dtype: DataType | DType | str | None) -> None: 719 if dtype and type(dtype).__name__ != "DataType": 720 from sqlglot.expressions.datatypes import DataType as _DataType 721 722 dtype = _DataType.build(dtype) 723 self._type = dtype # type: ignore[assignment] 724 725 def is_type(self, *dtypes: DATA_TYPE) -> bool: 726 t = self._type 727 return t is not None and t.is_type(*dtypes) 728 729 def is_leaf(self) -> bool: 730 return not any((isinstance(v, Expr) or type(v) is list) and v for v in self.args.values()) 731 732 @property 733 def meta(self) -> dict[str, t.Any]: 734 if self._meta is None: 735 self._meta = {} 736 return self._meta 737 738 def __deepcopy__(self, memo: t.Any) -> Expr: 739 root = self.__class__() 740 stack: list[tuple[Expr, Expr]] = [(self, root)] 741 742 while stack: 743 node, copy = stack.pop() 744 745 if node.comments is not None: 746 copy.comments = deepcopy(node.comments) 747 if node._type is not None: 748 copy._type = deepcopy(node._type) 749 if node._meta is not None: 750 copy._meta = deepcopy(node._meta) 751 if node._hash is not None: 752 copy._hash = node._hash 753 754 for k, vs in node.args.items(): 755 if isinstance(vs, Expr): 756 stack.append((vs, vs.__class__())) 757 copy.set(k, stack[-1][-1]) 758 elif type(vs) is list: 759 copy.args[k] = [] 760 761 for v in vs: 762 if isinstance(v, Expr): 763 stack.append((v, v.__class__())) 764 copy.append(k, stack[-1][-1]) 765 else: 766 copy.append(k, v) 767 else: 768 copy.args[k] = vs 769 770 return root 771 772 def copy(self: E) -> E: 773 """ 774 Returns a deep copy of the expression. 775 """ 776 return deepcopy(self) 777 778 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 779 if self.comments is None: 780 self.comments = [] 781 782 if comments: 783 for comment in comments: 784 _, *meta = comment.split(SQLGLOT_META) 785 if meta: 786 for kv in "".join(meta).split(","): 787 k, *v = kv.split("=") 788 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 789 790 if not prepend: 791 self.comments.append(comment) 792 793 if prepend: 794 self.comments = comments + self.comments 795 796 def pop_comments(self) -> list[str]: 797 comments = self.comments or [] 798 self.comments = None 799 return comments 800 801 def append(self, arg_key: str, value: t.Any) -> None: 802 """ 803 Appends value to arg_key if it's a list or sets it as a new list. 804 805 Args: 806 arg_key (str): name of the list expression arg 807 value (Any): value to append to the list 808 """ 809 if type(self.args.get(arg_key)) is not list: 810 self.args[arg_key] = [] 811 self._set_parent(arg_key, value) 812 values = self.args[arg_key] 813 if isinstance(value, Expr): 814 value.index = len(values) 815 values.append(value) 816 817 def set( 818 self, 819 arg_key: str, 820 value: object, 821 index: int | None = None, 822 overwrite: bool = True, 823 ) -> None: 824 """ 825 Sets arg_key to value. 826 827 Args: 828 arg_key: name of the expression arg. 829 value: value to set the arg to. 830 index: if the arg is a list, this specifies what position to add the value in it. 831 overwrite: assuming an index is given, this determines whether to overwrite the 832 list entry instead of only inserting a new value (i.e., like list.insert). 833 """ 834 node: Expr | None = self 835 836 while node and node._hash is not None: 837 node._hash = None 838 node = node.parent 839 840 if index is not None: 841 expressions = self.args.get(arg_key) or [] 842 843 if seq_get(expressions, index) is None: 844 return 845 846 if value is None: 847 expressions.pop(index) 848 for v in expressions[index:]: 849 v.index = v.index - 1 850 return 851 852 if isinstance(value, list): 853 expressions.pop(index) 854 expressions[index:index] = value 855 elif overwrite: 856 expressions[index] = value 857 else: 858 expressions.insert(index, value) 859 860 value = expressions 861 elif value is None: 862 self.args.pop(arg_key, None) 863 return 864 865 self.args[arg_key] = value 866 self._set_parent(arg_key, value, index) 867 868 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 869 if isinstance(value, Expr): 870 value.parent = self 871 value.arg_key = arg_key 872 value.index = index 873 elif isinstance(value, list): 874 for i, v in enumerate(value): 875 if isinstance(v, Expr): 876 v.parent = self 877 v.arg_key = arg_key 878 v.index = i 879 880 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 881 """Set multiples keyword arguments at once, using `.set()` method. 882 883 Args: 884 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 885 Returns: 886 Self: The same `Expression` with the updated arguments. 887 """ 888 if kwargs: 889 for k, v in kwargs.items(): 890 self.set(k, v) 891 return self 892 893 @property 894 def depth(self) -> int: 895 """ 896 Returns the depth of this tree. 897 """ 898 if self.parent: 899 return self.parent.depth + 1 900 return 0 901 902 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 903 """Yields the key and expression for all arguments, exploding list args.""" 904 for vs in reversed(self.args.values()) if reverse else self.args.values(): 905 if isinstance(vs, list): 906 for v in reversed(vs) if reverse else vs: 907 if isinstance(v, Expr): 908 yield t.cast(E, v) 909 elif isinstance(vs, Expr): 910 yield t.cast(E, vs) 911 912 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 913 """ 914 Returns the first node in this tree which matches at least one of 915 the specified types. 916 917 Args: 918 expression_types: the expression type(s) to match. 919 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 920 921 Returns: 922 The node which matches the criteria or None if no such node was found. 923 """ 924 return next(self.find_all(*expression_types, bfs=bfs), None) 925 926 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 927 """ 928 Returns a generator object which visits all nodes in this tree and only 929 yields those that match at least one of the specified expression types. 930 931 Args: 932 expression_types: the expression type(s) to match. 933 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 934 935 Returns: 936 The generator object. 937 """ 938 for expression in self.walk(bfs=bfs): 939 if isinstance(expression, expression_types): 940 yield expression 941 942 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 943 """ 944 Returns a nearest parent matching expression_types. 945 946 Args: 947 expression_types: the expression type(s) to match. 948 949 Returns: 950 The parent node. 951 """ 952 ancestor = self.parent 953 while ancestor and not isinstance(ancestor, expression_types): 954 ancestor = ancestor.parent 955 return ancestor # type: ignore[return-value] 956 957 @property 958 def parent_select(self) -> Select | None: 959 """ 960 Returns the parent select statement. 961 """ 962 from sqlglot.expressions.query import Select as _Select 963 964 return self.find_ancestor(_Select) 965 966 @property 967 def same_parent(self) -> bool: 968 """Returns if the parent is the same class as itself.""" 969 return type(self.parent) is self.__class__ 970 971 def root(self) -> Expr: 972 """ 973 Returns the root expression of this tree. 974 """ 975 expression: Expr = self 976 while expression.parent: 977 expression = expression.parent 978 return expression 979 980 def walk( 981 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 982 ) -> Iterator[Expr]: 983 """ 984 Returns a generator object which visits all nodes in this tree. 985 986 Args: 987 bfs: if set to True the BFS traversal order will be applied, 988 otherwise the DFS traversal will be used instead. 989 prune: callable that returns True if the generator should stop traversing 990 this branch of the tree. 991 992 Returns: 993 the generator object. 994 """ 995 if bfs: 996 yield from self.bfs(prune=prune) 997 else: 998 yield from self.dfs(prune=prune) 999 1000 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1001 """ 1002 Returns a generator object which visits all nodes in this tree in 1003 the DFS (Depth-first) order. 1004 1005 Returns: 1006 The generator object. 1007 """ 1008 stack = [self] 1009 1010 while stack: 1011 node = stack.pop() 1012 yield node 1013 if prune and prune(node): 1014 continue 1015 for v in node.iter_expressions(reverse=True): 1016 stack.append(v) 1017 1018 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1019 """ 1020 Returns a generator object which visits all nodes in this tree in 1021 the BFS (Breadth-first) order. 1022 1023 Returns: 1024 The generator object. 1025 """ 1026 queue: deque[Expr] = deque() 1027 queue.append(self) 1028 1029 while queue: 1030 node = queue.popleft() 1031 yield node 1032 if prune and prune(node): 1033 continue 1034 for v in node.iter_expressions(): 1035 queue.append(v) 1036 1037 def unnest(self) -> Expr: 1038 """ 1039 Returns the first non parenthesis child or self. 1040 """ 1041 expression = self 1042 while type(expression) is Paren: 1043 expression = expression.this 1044 return expression 1045 1046 def unalias(self) -> Expr: 1047 """ 1048 Returns the inner expression if this is an Alias. 1049 """ 1050 if isinstance(self, Alias): 1051 return self.this 1052 return self 1053 1054 def unnest_operands(self) -> tuple[Expr, ...]: 1055 """ 1056 Returns unnested operands as a tuple. 1057 """ 1058 return tuple(arg.unnest() for arg in self.iter_expressions()) 1059 1060 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1061 """ 1062 Returns a generator which yields child nodes whose parents are the same class. 1063 1064 A AND B AND C -> [A, B, C] 1065 """ 1066 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1067 if type(node) is not self.__class__: 1068 yield node.unnest() if unnest and not node.is_subquery else node 1069 1070 def __str__(self) -> str: 1071 return self.sql() 1072 1073 def __repr__(self) -> str: 1074 return _to_s(self) 1075 1076 def to_s(self) -> str: 1077 """ 1078 Same as __repr__, but includes additional information which can be useful 1079 for debugging, like empty or missing args and the AST nodes' object IDs. 1080 """ 1081 return _to_s(self, verbose=True) 1082 1083 def sql( 1084 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1085 ) -> str: 1086 """ 1087 Returns SQL string representation of this tree. 1088 1089 Args: 1090 dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql"). 1091 opts: other `sqlglot.generator.Generator` options. 1092 1093 Returns: 1094 The SQL string. 1095 """ 1096 from sqlglot.dialects.dialect import Dialect 1097 1098 return Dialect.get_or_raise(dialect).generate(self, copy=copy, **opts) 1099 1100 def transform( 1101 self, fun: t.Callable, *args: object, copy: bool = True, **kwargs: object 1102 ) -> t.Any: 1103 """ 1104 Visits all tree nodes (excluding already transformed ones) 1105 and applies the given transformation function to each node. 1106 1107 Args: 1108 fun: a function which takes a node as an argument and returns a 1109 new transformed node or the same node without modifications. If the function 1110 returns None, then the corresponding node will be removed from the syntax tree. 1111 copy: if set to True a new tree instance is constructed, otherwise the tree is 1112 modified in place. 1113 1114 Returns: 1115 The transformed tree. 1116 """ 1117 root: t.Any = None 1118 new_node: t.Any = None 1119 1120 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1121 parent, arg_key, index = node.parent, node.arg_key, node.index 1122 new_node = fun(node, *args, **kwargs) 1123 1124 if not root: 1125 root = new_node 1126 elif parent and arg_key and new_node is not node: 1127 parent.set(arg_key, new_node, index) 1128 1129 assert root 1130 return root 1131 1132 def replace(self, expression: T) -> T: 1133 """ 1134 Swap out this expression with a new expression. 1135 1136 For example:: 1137 1138 >>> import sqlglot 1139 >>> tree = sqlglot.parse_one("SELECT x FROM tbl") 1140 >>> tree.find(sqlglot.exp.Column).replace(sqlglot.exp.column("y")) 1141 Column( 1142 this=Identifier(this=y, quoted=False)) 1143 >>> tree.sql() 1144 'SELECT y FROM tbl' 1145 1146 Args: 1147 expression (T): new node 1148 1149 Returns: 1150 T: The new expression or expressions. 1151 """ 1152 parent = self.parent 1153 1154 if not parent or parent is expression: 1155 return expression 1156 1157 key = self.arg_key 1158 1159 if key: 1160 value = parent.args.get(key) 1161 1162 if type(expression) is list and isinstance(value, Expr): 1163 # We are trying to replace an Expr with a list, so it's assumed that 1164 # the intention was to really replace the parent of this expression. 1165 if value.parent: 1166 value.parent.replace(expression) 1167 else: 1168 parent.set(key, expression, self.index) 1169 1170 if expression is not self: 1171 self.parent = None 1172 self.arg_key = None 1173 self.index = None 1174 1175 return expression 1176 1177 def pop(self: E) -> E: 1178 """ 1179 Remove this expression from its AST. 1180 1181 Returns: 1182 The popped expression. 1183 """ 1184 self.replace(None) 1185 return self 1186 1187 def assert_is(self, type_: Type[E]) -> E: 1188 """ 1189 Assert that this `Expr` is an instance of `type_`. 1190 1191 If it is NOT an instance of `type_`, this raises an assertion error. 1192 Otherwise, this returns this expression. 1193 1194 Examples: 1195 This is useful for type security in chained expressions: 1196 1197 >>> import sqlglot 1198 >>> sqlglot.parse_one("SELECT x from y").assert_is(sqlglot.exp.Select).select("z").sql() 1199 'SELECT x, z FROM y' 1200 """ 1201 if not isinstance(self, type_): 1202 raise AssertionError(f"{self} is not {type_}.") 1203 return self 1204 1205 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1206 """ 1207 Checks if this expression is valid (e.g. all mandatory args are set). 1208 1209 Args: 1210 args: a sequence of values that were used to instantiate a Func expression. This is used 1211 to check that the provided arguments don't exceed the function argument limit. 1212 1213 Returns: 1214 A list of error messages for all possible errors that were found. 1215 """ 1216 if UNITTEST: 1217 for k in self.args: 1218 if k not in self.arg_types: 1219 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1220 1221 errors: list[str] | None = None 1222 1223 for k in self.required_args: 1224 v = self.args.get(k) 1225 if v is None or (isinstance(v, list) and not v): 1226 if errors is None: 1227 errors = [] 1228 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1229 1230 if ( 1231 args 1232 and isinstance(self, Func) 1233 and len(args) > len(self.arg_types) 1234 and not self.is_var_len_args 1235 ): 1236 if errors is None: 1237 errors = [] 1238 errors.append( 1239 f"The number of provided arguments ({len(args)}) is greater than " 1240 f"the maximum number of supported arguments ({len(self.arg_types)})" 1241 ) 1242 1243 return errors or [] 1244 1245 def and_( 1246 self, 1247 *expressions: ExpOrStr | None, 1248 dialect: DialectType = None, 1249 copy: bool = True, 1250 wrap: bool = True, 1251 **opts: Unpack[ParserNoDialectArgs], 1252 ) -> Condition: 1253 """ 1254 AND this condition with one or multiple expressions. 1255 1256 Example: 1257 >>> condition("x=1").and_("y=1").sql() 1258 'x = 1 AND y = 1' 1259 1260 Args: 1261 *expressions: the SQL code strings to parse. 1262 If an `Expr` instance is passed, it will be used as-is. 1263 dialect: the dialect used to parse the input expression. 1264 copy: whether to copy the involved expressions (only applies to Exprs). 1265 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 1266 precedence issues, but can be turned off when the produced AST is too deep and 1267 causes recursion-related issues. 1268 opts: other options to use to parse the input expressions. 1269 1270 Returns: 1271 The new And condition. 1272 """ 1273 return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1274 1275 def or_( 1276 self, 1277 *expressions: ExpOrStr | None, 1278 dialect: DialectType = None, 1279 copy: bool = True, 1280 wrap: bool = True, 1281 **opts: Unpack[ParserNoDialectArgs], 1282 ) -> Condition: 1283 """ 1284 OR this condition with one or multiple expressions. 1285 1286 Example: 1287 >>> condition("x=1").or_("y=1").sql() 1288 'x = 1 OR y = 1' 1289 1290 Args: 1291 *expressions: the SQL code strings to parse. 1292 If an `Expr` instance is passed, it will be used as-is. 1293 dialect: the dialect used to parse the input expression. 1294 copy: whether to copy the involved expressions (only applies to Exprs). 1295 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 1296 precedence issues, but can be turned off when the produced AST is too deep and 1297 causes recursion-related issues. 1298 opts: other options to use to parse the input expressions. 1299 1300 Returns: 1301 The new Or condition. 1302 """ 1303 return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1304 1305 def not_(self, copy: bool = True) -> Not: 1306 """ 1307 Wrap this condition with NOT. 1308 1309 Example: 1310 >>> condition("x=1").not_().sql() 1311 'NOT x = 1' 1312 1313 Args: 1314 copy: whether to copy this object. 1315 1316 Returns: 1317 The new Not instance. 1318 """ 1319 return not_(self, copy=copy) 1320 1321 def update_positions( 1322 self: E, 1323 other: Token | Expr | None = None, 1324 line: int | None = None, 1325 col: int | None = None, 1326 start: int | None = None, 1327 end: int | None = None, 1328 ) -> E: 1329 """ 1330 Update this expression with positions from a token or other expression. 1331 1332 Args: 1333 other: a token or expression to update this expression with. 1334 line: the line number to use if other is None 1335 col: column number 1336 start: start char index 1337 end: end char index 1338 1339 Returns: 1340 The updated expression. 1341 """ 1342 if isinstance(other, Token): 1343 meta = self.meta 1344 meta["line"] = other.line 1345 meta["col"] = other.col 1346 meta["start"] = other.start 1347 meta["end"] = other.end 1348 elif other is not None: 1349 other_meta = other._meta 1350 if other_meta: 1351 meta = self.meta 1352 for k in POSITION_META_KEYS: 1353 if k in other_meta: 1354 meta[k] = other_meta[k] 1355 else: 1356 meta = self.meta 1357 meta["line"] = line 1358 meta["col"] = col 1359 meta["start"] = start 1360 meta["end"] = end 1361 return self 1362 1363 def as_( 1364 self, 1365 alias: str | Identifier, 1366 quoted: bool | None = None, 1367 dialect: DialectType = None, 1368 copy: bool = True, 1369 table: bool | Sequence[str | Identifier] = False, 1370 **opts: Unpack[ParserNoDialectArgs], 1371 ) -> Expr: 1372 return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, table=table, **opts) 1373 1374 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 1375 this = self.copy() 1376 other = convert(other, copy=True) 1377 if not isinstance(this, klass) and not isinstance(other, klass): 1378 this = _wrap(this, Binary) 1379 other = _wrap(other, Binary) 1380 if reverse: 1381 return klass(this=other, expression=this) 1382 return klass(this=this, expression=other) 1383 1384 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 1385 return Bracket( 1386 this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)] 1387 ) 1388 1389 def __iter__(self) -> Iterator: 1390 if "expressions" in self.arg_types: 1391 return iter(self.args.get("expressions") or []) 1392 # We define this because __getitem__ converts Expr into an iterable, which is 1393 # problematic because one can hit infinite loops if they do "for x in some_expr: ..." 1394 # See: https://peps.python.org/pep-0234/ 1395 raise TypeError(f"'{self.__class__.__name__}' object is not iterable") 1396 1397 def isin( 1398 self, 1399 *expressions: t.Any, 1400 query: ExpOrStr | None = None, 1401 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 1402 dialect: DialectType = None, 1403 copy: bool = True, 1404 **opts: Unpack[ParserNoDialectArgs], 1405 ) -> In: 1406 from sqlglot.expressions.query import Query 1407 1408 subquery: Expr | None = None 1409 if query: 1410 subquery = maybe_parse(query, dialect=dialect, copy=copy, **opts) 1411 if isinstance(subquery, Query): 1412 subquery = subquery.subquery(copy=False) 1413 unnest_list: list[ExpOrStr] = ensure_list(unnest) 1414 return In( 1415 this=maybe_copy(self, copy), 1416 expressions=[convert(e, copy=copy) for e in expressions], 1417 query=subquery, 1418 unnest=( 1419 _lazy_unnest( 1420 expressions=[ 1421 maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in unnest_list 1422 ] 1423 ) 1424 if unnest 1425 else None 1426 ), 1427 ) 1428 1429 def between( 1430 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 1431 ) -> Between: 1432 between = Between( 1433 this=maybe_copy(self, copy), 1434 low=convert(low, copy=copy), 1435 high=convert(high, copy=copy), 1436 ) 1437 if symmetric is not None: 1438 between.set("symmetric", symmetric) 1439 1440 return between 1441 1442 def is_(self, other: ExpOrStr) -> Is: 1443 return self._binop(Is, other) 1444 1445 def like(self, other: ExpOrStr) -> Like: 1446 return self._binop(Like, other) 1447 1448 def ilike(self, other: ExpOrStr) -> ILike: 1449 return self._binop(ILike, other) 1450 1451 def eq(self, other: t.Any) -> EQ: 1452 return self._binop(EQ, other) 1453 1454 def neq(self, other: t.Any) -> NEQ: 1455 return self._binop(NEQ, other) 1456 1457 def rlike(self, other: ExpOrStr) -> RegexpLike: 1458 return self._binop(RegexpLike, other) 1459 1460 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 1461 div = self._binop(Div, other) 1462 div.set("typed", typed) 1463 div.set("safe", safe) 1464 return div 1465 1466 def asc(self, nulls_first: bool = True) -> Ordered: 1467 return Ordered(this=self.copy(), nulls_first=nulls_first) 1468 1469 def desc(self, nulls_first: bool = False) -> Ordered: 1470 return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first) 1471 1472 def __lt__(self, other: t.Any) -> LT: 1473 return self._binop(LT, other) 1474 1475 def __le__(self, other: t.Any) -> LTE: 1476 return self._binop(LTE, other) 1477 1478 def __gt__(self, other: t.Any) -> GT: 1479 return self._binop(GT, other) 1480 1481 def __ge__(self, other: t.Any) -> GTE: 1482 return self._binop(GTE, other) 1483 1484 def __add__(self, other: t.Any) -> Add: 1485 return self._binop(Add, other) 1486 1487 def __radd__(self, other: t.Any) -> Add: 1488 return self._binop(Add, other, reverse=True) 1489 1490 def __sub__(self, other: t.Any) -> Sub: 1491 return self._binop(Sub, other) 1492 1493 def __rsub__(self, other: t.Any) -> Sub: 1494 return self._binop(Sub, other, reverse=True) 1495 1496 def __mul__(self, other: t.Any) -> Mul: 1497 return self._binop(Mul, other) 1498 1499 def __rmul__(self, other: t.Any) -> Mul: 1500 return self._binop(Mul, other, reverse=True) 1501 1502 def __truediv__(self, other: t.Any) -> Div: 1503 return self._binop(Div, other) 1504 1505 def __rtruediv__(self, other: t.Any) -> Div: 1506 return self._binop(Div, other, reverse=True) 1507 1508 def __floordiv__(self, other: t.Any) -> IntDiv: 1509 return self._binop(IntDiv, other) 1510 1511 def __rfloordiv__(self, other: t.Any) -> IntDiv: 1512 return self._binop(IntDiv, other, reverse=True) 1513 1514 def __mod__(self, other: t.Any) -> Mod: 1515 return self._binop(Mod, other) 1516 1517 def __rmod__(self, other: t.Any) -> Mod: 1518 return self._binop(Mod, other, reverse=True) 1519 1520 def __pow__(self, other: t.Any) -> Pow: 1521 return self._binop(Pow, other) 1522 1523 def __rpow__(self, other: t.Any) -> Pow: 1524 return self._binop(Pow, other, reverse=True) 1525 1526 def __and__(self, other: t.Any) -> And: 1527 return self._binop(And, other) 1528 1529 def __rand__(self, other: t.Any) -> And: 1530 return self._binop(And, other, reverse=True) 1531 1532 def __or__(self, other: t.Any) -> Or: 1533 return self._binop(Or, other) 1534 1535 def __ror__(self, other: t.Any) -> Or: 1536 return self._binop(Or, other, reverse=True) 1537 1538 def __neg__(self) -> Neg: 1539 return Neg(this=_wrap(self.copy(), Binary)) 1540 1541 def __invert__(self) -> Not: 1542 return not_(self.copy())
599 @property 600 def this(self) -> t.Any: 601 """ 602 Retrieves the argument with key "this". 603 """ 604 return self.args.get("this")
Retrieves the argument with key "this".
606 @property 607 def expression(self) -> t.Any: 608 """ 609 Retrieves the argument with key "expression". 610 """ 611 return self.args.get("expression")
Retrieves the argument with key "expression".
613 @property 614 def expressions(self) -> list[t.Any]: 615 """ 616 Retrieves the argument with key "expressions". 617 """ 618 return self.args.get("expressions") or []
Retrieves the argument with key "expressions".
620 def text(self, key: str) -> str: 621 """ 622 Returns a textual representation of the argument corresponding to "key". This can only be used 623 for args that are strings or leaf Expr instances, such as identifiers and literals. 624 """ 625 field = self.args.get(key) 626 if isinstance(field, str): 627 return field 628 if isinstance(field, (Identifier, Literal, Var)): 629 return field.this 630 if isinstance(field, (Star, Null)): 631 return field.name 632 return ""
Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expr instances, such as identifiers and literals.
634 @property 635 def is_string(self) -> bool: 636 """ 637 Checks whether a Literal expression is a string. 638 """ 639 return isinstance(self, Literal) and self.args["is_string"]
Checks whether a Literal expression is a string.
641 @property 642 def is_number(self) -> bool: 643 """ 644 Checks whether a Literal expression is a number. 645 """ 646 return (isinstance(self, Literal) and not self.args["is_string"]) or ( 647 isinstance(self, Neg) and self.this.is_number 648 )
Checks whether a Literal expression is a number.
650 def to_py(self) -> t.Any: 651 """ 652 Returns a Python object equivalent of the SQL node. 653 """ 654 raise ValueError(f"{self} cannot be converted to a Python object.")
Returns a Python object equivalent of the SQL node.
656 @property 657 def is_int(self) -> bool: 658 """ 659 Checks whether an expression is an integer. 660 """ 661 return self.is_number and isinstance(self.to_py(), int)
Checks whether an expression is an integer.
663 @property 664 def is_star(self) -> bool: 665 """Checks whether an expression is a star.""" 666 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
Checks whether an expression is a star.
668 @property 669 def alias(self) -> str: 670 """ 671 Returns the alias of the expression, or an empty string if it's not aliased. 672 """ 673 alias = self.args.get("alias") 674 if isinstance(alias, Expression): 675 return alias.name 676 return self.text("alias")
Returns the alias of the expression, or an empty string if it's not aliased.
693 @property 694 def output_name(self) -> str: 695 """ 696 Name of the output column if this expression is a selection. 697 698 If the Expr has no output name, an empty string is returned. 699 700 Example: 701 >>> from sqlglot import parse_one 702 >>> parse_one("SELECT a").expressions[0].output_name 703 'a' 704 >>> parse_one("SELECT b AS c").expressions[0].output_name 705 'c' 706 >>> parse_one("SELECT 1 + 2").expressions[0].output_name 707 '' 708 """ 709 return ""
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
772 def copy(self: E) -> E: 773 """ 774 Returns a deep copy of the expression. 775 """ 776 return deepcopy(self)
Returns a deep copy of the expression.
778 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 779 if self.comments is None: 780 self.comments = [] 781 782 if comments: 783 for comment in comments: 784 _, *meta = comment.split(SQLGLOT_META) 785 if meta: 786 for kv in "".join(meta).split(","): 787 k, *v = kv.split("=") 788 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 789 790 if not prepend: 791 self.comments.append(comment) 792 793 if prepend: 794 self.comments = comments + self.comments
801 def append(self, arg_key: str, value: t.Any) -> None: 802 """ 803 Appends value to arg_key if it's a list or sets it as a new list. 804 805 Args: 806 arg_key (str): name of the list expression arg 807 value (Any): value to append to the list 808 """ 809 if type(self.args.get(arg_key)) is not list: 810 self.args[arg_key] = [] 811 self._set_parent(arg_key, value) 812 values = self.args[arg_key] 813 if isinstance(value, Expr): 814 value.index = len(values) 815 values.append(value)
Appends value to arg_key if it's a list or sets it as a new list.
Arguments:
- arg_key (str): name of the list expression arg
- value (Any): value to append to the list
817 def set( 818 self, 819 arg_key: str, 820 value: object, 821 index: int | None = None, 822 overwrite: bool = True, 823 ) -> None: 824 """ 825 Sets arg_key to value. 826 827 Args: 828 arg_key: name of the expression arg. 829 value: value to set the arg to. 830 index: if the arg is a list, this specifies what position to add the value in it. 831 overwrite: assuming an index is given, this determines whether to overwrite the 832 list entry instead of only inserting a new value (i.e., like list.insert). 833 """ 834 node: Expr | None = self 835 836 while node and node._hash is not None: 837 node._hash = None 838 node = node.parent 839 840 if index is not None: 841 expressions = self.args.get(arg_key) or [] 842 843 if seq_get(expressions, index) is None: 844 return 845 846 if value is None: 847 expressions.pop(index) 848 for v in expressions[index:]: 849 v.index = v.index - 1 850 return 851 852 if isinstance(value, list): 853 expressions.pop(index) 854 expressions[index:index] = value 855 elif overwrite: 856 expressions[index] = value 857 else: 858 expressions.insert(index, value) 859 860 value = expressions 861 elif value is None: 862 self.args.pop(arg_key, None) 863 return 864 865 self.args[arg_key] = value 866 self._set_parent(arg_key, value, index)
Sets arg_key to value.
Arguments:
- arg_key: name of the expression arg.
- value: value to set the arg to.
- index: if the arg is a list, this specifies what position to add the value in it.
- overwrite: assuming an index is given, this determines whether to overwrite the list entry instead of only inserting a new value (i.e., like list.insert).
880 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 881 """Set multiples keyword arguments at once, using `.set()` method. 882 883 Args: 884 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 885 Returns: 886 Self: The same `Expression` with the updated arguments. 887 """ 888 if kwargs: 889 for k, v in kwargs.items(): 890 self.set(k, v) 891 return self
Set multiples keyword arguments at once, using .set() method.
Arguments:
- kwargs (Mapping[str, object]): a
Mappingof arg keys to values to set.
Returns:
Self: The same
Expressionwith the updated arguments.
893 @property 894 def depth(self) -> int: 895 """ 896 Returns the depth of this tree. 897 """ 898 if self.parent: 899 return self.parent.depth + 1 900 return 0
Returns the depth of this tree.
902 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 903 """Yields the key and expression for all arguments, exploding list args.""" 904 for vs in reversed(self.args.values()) if reverse else self.args.values(): 905 if isinstance(vs, list): 906 for v in reversed(vs) if reverse else vs: 907 if isinstance(v, Expr): 908 yield t.cast(E, v) 909 elif isinstance(vs, Expr): 910 yield t.cast(E, vs)
Yields the key and expression for all arguments, exploding list args.
912 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 913 """ 914 Returns the first node in this tree which matches at least one of 915 the specified types. 916 917 Args: 918 expression_types: the expression type(s) to match. 919 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 920 921 Returns: 922 The node which matches the criteria or None if no such node was found. 923 """ 924 return next(self.find_all(*expression_types, bfs=bfs), None)
Returns the first node in this tree which matches at least one of the specified types.
Arguments:
- expression_types: the expression type(s) to match.
- bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:
The node which matches the criteria or None if no such node was found.
926 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 927 """ 928 Returns a generator object which visits all nodes in this tree and only 929 yields those that match at least one of the specified expression types. 930 931 Args: 932 expression_types: the expression type(s) to match. 933 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 934 935 Returns: 936 The generator object. 937 """ 938 for expression in self.walk(bfs=bfs): 939 if isinstance(expression, expression_types): 940 yield expression
Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.
Arguments:
- expression_types: the expression type(s) to match.
- bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:
The generator object.
942 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 943 """ 944 Returns a nearest parent matching expression_types. 945 946 Args: 947 expression_types: the expression type(s) to match. 948 949 Returns: 950 The parent node. 951 """ 952 ancestor = self.parent 953 while ancestor and not isinstance(ancestor, expression_types): 954 ancestor = ancestor.parent 955 return ancestor # type: ignore[return-value]
Returns a nearest parent matching expression_types.
Arguments:
- expression_types: the expression type(s) to match.
Returns:
The parent node.
957 @property 958 def parent_select(self) -> Select | None: 959 """ 960 Returns the parent select statement. 961 """ 962 from sqlglot.expressions.query import Select as _Select 963 964 return self.find_ancestor(_Select)
Returns the parent select statement.
966 @property 967 def same_parent(self) -> bool: 968 """Returns if the parent is the same class as itself.""" 969 return type(self.parent) is self.__class__
Returns if the parent is the same class as itself.
971 def root(self) -> Expr: 972 """ 973 Returns the root expression of this tree. 974 """ 975 expression: Expr = self 976 while expression.parent: 977 expression = expression.parent 978 return expression
Returns the root expression of this tree.
980 def walk( 981 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 982 ) -> Iterator[Expr]: 983 """ 984 Returns a generator object which visits all nodes in this tree. 985 986 Args: 987 bfs: if set to True the BFS traversal order will be applied, 988 otherwise the DFS traversal will be used instead. 989 prune: callable that returns True if the generator should stop traversing 990 this branch of the tree. 991 992 Returns: 993 the generator object. 994 """ 995 if bfs: 996 yield from self.bfs(prune=prune) 997 else: 998 yield from self.dfs(prune=prune)
Returns a generator object which visits all nodes in this tree.
Arguments:
- bfs: if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
- prune: callable that returns True if the generator should stop traversing this branch of the tree.
Returns:
the generator object.
1000 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1001 """ 1002 Returns a generator object which visits all nodes in this tree in 1003 the DFS (Depth-first) order. 1004 1005 Returns: 1006 The generator object. 1007 """ 1008 stack = [self] 1009 1010 while stack: 1011 node = stack.pop() 1012 yield node 1013 if prune and prune(node): 1014 continue 1015 for v in node.iter_expressions(reverse=True): 1016 stack.append(v)
Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.
Returns:
The generator object.
1018 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1019 """ 1020 Returns a generator object which visits all nodes in this tree in 1021 the BFS (Breadth-first) order. 1022 1023 Returns: 1024 The generator object. 1025 """ 1026 queue: deque[Expr] = deque() 1027 queue.append(self) 1028 1029 while queue: 1030 node = queue.popleft() 1031 yield node 1032 if prune and prune(node): 1033 continue 1034 for v in node.iter_expressions(): 1035 queue.append(v)
Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.
Returns:
The generator object.
1037 def unnest(self) -> Expr: 1038 """ 1039 Returns the first non parenthesis child or self. 1040 """ 1041 expression = self 1042 while type(expression) is Paren: 1043 expression = expression.this 1044 return expression
Returns the first non parenthesis child or self.
1046 def unalias(self) -> Expr: 1047 """ 1048 Returns the inner expression if this is an Alias. 1049 """ 1050 if isinstance(self, Alias): 1051 return self.this 1052 return self
Returns the inner expression if this is an Alias.
1054 def unnest_operands(self) -> tuple[Expr, ...]: 1055 """ 1056 Returns unnested operands as a tuple. 1057 """ 1058 return tuple(arg.unnest() for arg in self.iter_expressions())
Returns unnested operands as a tuple.
1060 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1061 """ 1062 Returns a generator which yields child nodes whose parents are the same class. 1063 1064 A AND B AND C -> [A, B, C] 1065 """ 1066 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1067 if type(node) is not self.__class__: 1068 yield node.unnest() if unnest and not node.is_subquery else node
Returns a generator which yields child nodes whose parents are the same class.
A AND B AND C -> [A, B, C]
1076 def to_s(self) -> str: 1077 """ 1078 Same as __repr__, but includes additional information which can be useful 1079 for debugging, like empty or missing args and the AST nodes' object IDs. 1080 """ 1081 return _to_s(self, verbose=True)
Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.
1083 def sql( 1084 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1085 ) -> str: 1086 """ 1087 Returns SQL string representation of this tree. 1088 1089 Args: 1090 dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql"). 1091 opts: other `sqlglot.generator.Generator` options. 1092 1093 Returns: 1094 The SQL string. 1095 """ 1096 from sqlglot.dialects.dialect import Dialect 1097 1098 return Dialect.get_or_raise(dialect).generate(self, copy=copy, **opts)
Returns SQL string representation of this tree.
Arguments:
- dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
- opts: other
sqlglot.generator.Generatoroptions.
Returns:
The SQL string.
1100 def transform( 1101 self, fun: t.Callable, *args: object, copy: bool = True, **kwargs: object 1102 ) -> t.Any: 1103 """ 1104 Visits all tree nodes (excluding already transformed ones) 1105 and applies the given transformation function to each node. 1106 1107 Args: 1108 fun: a function which takes a node as an argument and returns a 1109 new transformed node or the same node without modifications. If the function 1110 returns None, then the corresponding node will be removed from the syntax tree. 1111 copy: if set to True a new tree instance is constructed, otherwise the tree is 1112 modified in place. 1113 1114 Returns: 1115 The transformed tree. 1116 """ 1117 root: t.Any = None 1118 new_node: t.Any = None 1119 1120 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1121 parent, arg_key, index = node.parent, node.arg_key, node.index 1122 new_node = fun(node, *args, **kwargs) 1123 1124 if not root: 1125 root = new_node 1126 elif parent and arg_key and new_node is not node: 1127 parent.set(arg_key, new_node, index) 1128 1129 assert root 1130 return root
Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.
Arguments:
- fun: a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
- copy: if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:
The transformed tree.
1132 def replace(self, expression: T) -> T: 1133 """ 1134 Swap out this expression with a new expression. 1135 1136 For example:: 1137 1138 >>> import sqlglot 1139 >>> tree = sqlglot.parse_one("SELECT x FROM tbl") 1140 >>> tree.find(sqlglot.exp.Column).replace(sqlglot.exp.column("y")) 1141 Column( 1142 this=Identifier(this=y, quoted=False)) 1143 >>> tree.sql() 1144 'SELECT y FROM tbl' 1145 1146 Args: 1147 expression (T): new node 1148 1149 Returns: 1150 T: The new expression or expressions. 1151 """ 1152 parent = self.parent 1153 1154 if not parent or parent is expression: 1155 return expression 1156 1157 key = self.arg_key 1158 1159 if key: 1160 value = parent.args.get(key) 1161 1162 if type(expression) is list and isinstance(value, Expr): 1163 # We are trying to replace an Expr with a list, so it's assumed that 1164 # the intention was to really replace the parent of this expression. 1165 if value.parent: 1166 value.parent.replace(expression) 1167 else: 1168 parent.set(key, expression, self.index) 1169 1170 if expression is not self: 1171 self.parent = None 1172 self.arg_key = None 1173 self.index = None 1174 1175 return expression
Swap out this expression with a new expression.
For example::
>>> import sqlglot
>>> tree = sqlglot.parse_one("SELECT x FROM tbl")
>>> tree.find(sqlglot.exp.Column).replace(sqlglot.exp.column("y"))
Column(
this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
- expression (T): new node
Returns:
T: The new expression or expressions.
1177 def pop(self: E) -> E: 1178 """ 1179 Remove this expression from its AST. 1180 1181 Returns: 1182 The popped expression. 1183 """ 1184 self.replace(None) 1185 return self
Remove this expression from its AST.
Returns:
The popped expression.
1187 def assert_is(self, type_: Type[E]) -> E: 1188 """ 1189 Assert that this `Expr` is an instance of `type_`. 1190 1191 If it is NOT an instance of `type_`, this raises an assertion error. 1192 Otherwise, this returns this expression. 1193 1194 Examples: 1195 This is useful for type security in chained expressions: 1196 1197 >>> import sqlglot 1198 >>> sqlglot.parse_one("SELECT x from y").assert_is(sqlglot.exp.Select).select("z").sql() 1199 'SELECT x, z FROM y' 1200 """ 1201 if not isinstance(self, type_): 1202 raise AssertionError(f"{self} is not {type_}.") 1203 return self
Assert that this Expr is an instance of type_.
If it is NOT an instance of type_, this raises an assertion error.
Otherwise, this returns this expression.
Examples:
This is useful for type security in chained expressions:
>>> import sqlglot >>> sqlglot.parse_one("SELECT x from y").assert_is(sqlglot.exp.Select).select("z").sql() 'SELECT x, z FROM y'
1205 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1206 """ 1207 Checks if this expression is valid (e.g. all mandatory args are set). 1208 1209 Args: 1210 args: a sequence of values that were used to instantiate a Func expression. This is used 1211 to check that the provided arguments don't exceed the function argument limit. 1212 1213 Returns: 1214 A list of error messages for all possible errors that were found. 1215 """ 1216 if UNITTEST: 1217 for k in self.args: 1218 if k not in self.arg_types: 1219 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1220 1221 errors: list[str] | None = None 1222 1223 for k in self.required_args: 1224 v = self.args.get(k) 1225 if v is None or (isinstance(v, list) and not v): 1226 if errors is None: 1227 errors = [] 1228 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1229 1230 if ( 1231 args 1232 and isinstance(self, Func) 1233 and len(args) > len(self.arg_types) 1234 and not self.is_var_len_args 1235 ): 1236 if errors is None: 1237 errors = [] 1238 errors.append( 1239 f"The number of provided arguments ({len(args)}) is greater than " 1240 f"the maximum number of supported arguments ({len(self.arg_types)})" 1241 ) 1242 1243 return errors or []
Checks if this expression is valid (e.g. all mandatory args are set).
Arguments:
- args: a sequence of values that were used to instantiate a Func expression. This is used to check that the provided arguments don't exceed the function argument limit.
Returns:
A list of error messages for all possible errors that were found.
1245 def and_( 1246 self, 1247 *expressions: ExpOrStr | None, 1248 dialect: DialectType = None, 1249 copy: bool = True, 1250 wrap: bool = True, 1251 **opts: Unpack[ParserNoDialectArgs], 1252 ) -> Condition: 1253 """ 1254 AND this condition with one or multiple expressions. 1255 1256 Example: 1257 >>> condition("x=1").and_("y=1").sql() 1258 'x = 1 AND y = 1' 1259 1260 Args: 1261 *expressions: the SQL code strings to parse. 1262 If an `Expr` instance is passed, it will be used as-is. 1263 dialect: the dialect used to parse the input expression. 1264 copy: whether to copy the involved expressions (only applies to Exprs). 1265 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 1266 precedence issues, but can be turned off when the produced AST is too deep and 1267 causes recursion-related issues. 1268 opts: other options to use to parse the input expressions. 1269 1270 Returns: 1271 The new And condition. 1272 """ 1273 return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
AND this condition with one or multiple expressions.
Example:
>>> condition("x=1").and_("y=1").sql() 'x = 1 AND y = 1'
Arguments:
- *expressions: the SQL code strings to parse.
If an
Exprinstance is passed, it will be used as-is. - dialect: the dialect used to parse the input expression.
- copy: whether to copy the involved expressions (only applies to Exprs).
- wrap: whether to wrap the operands in
Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues. - opts: other options to use to parse the input expressions.
Returns:
The new And condition.
1275 def or_( 1276 self, 1277 *expressions: ExpOrStr | None, 1278 dialect: DialectType = None, 1279 copy: bool = True, 1280 wrap: bool = True, 1281 **opts: Unpack[ParserNoDialectArgs], 1282 ) -> Condition: 1283 """ 1284 OR this condition with one or multiple expressions. 1285 1286 Example: 1287 >>> condition("x=1").or_("y=1").sql() 1288 'x = 1 OR y = 1' 1289 1290 Args: 1291 *expressions: the SQL code strings to parse. 1292 If an `Expr` instance is passed, it will be used as-is. 1293 dialect: the dialect used to parse the input expression. 1294 copy: whether to copy the involved expressions (only applies to Exprs). 1295 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 1296 precedence issues, but can be turned off when the produced AST is too deep and 1297 causes recursion-related issues. 1298 opts: other options to use to parse the input expressions. 1299 1300 Returns: 1301 The new Or condition. 1302 """ 1303 return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
OR this condition with one or multiple expressions.
Example:
>>> condition("x=1").or_("y=1").sql() 'x = 1 OR y = 1'
Arguments:
- *expressions: the SQL code strings to parse.
If an
Exprinstance is passed, it will be used as-is. - dialect: the dialect used to parse the input expression.
- copy: whether to copy the involved expressions (only applies to Exprs).
- wrap: whether to wrap the operands in
Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues. - opts: other options to use to parse the input expressions.
Returns:
The new Or condition.
1305 def not_(self, copy: bool = True) -> Not: 1306 """ 1307 Wrap this condition with NOT. 1308 1309 Example: 1310 >>> condition("x=1").not_().sql() 1311 'NOT x = 1' 1312 1313 Args: 1314 copy: whether to copy this object. 1315 1316 Returns: 1317 The new Not instance. 1318 """ 1319 return not_(self, copy=copy)
Wrap this condition with NOT.
Example:
>>> condition("x=1").not_().sql() 'NOT x = 1'
Arguments:
- copy: whether to copy this object.
Returns:
The new Not instance.
1321 def update_positions( 1322 self: E, 1323 other: Token | Expr | None = None, 1324 line: int | None = None, 1325 col: int | None = None, 1326 start: int | None = None, 1327 end: int | None = None, 1328 ) -> E: 1329 """ 1330 Update this expression with positions from a token or other expression. 1331 1332 Args: 1333 other: a token or expression to update this expression with. 1334 line: the line number to use if other is None 1335 col: column number 1336 start: start char index 1337 end: end char index 1338 1339 Returns: 1340 The updated expression. 1341 """ 1342 if isinstance(other, Token): 1343 meta = self.meta 1344 meta["line"] = other.line 1345 meta["col"] = other.col 1346 meta["start"] = other.start 1347 meta["end"] = other.end 1348 elif other is not None: 1349 other_meta = other._meta 1350 if other_meta: 1351 meta = self.meta 1352 for k in POSITION_META_KEYS: 1353 if k in other_meta: 1354 meta[k] = other_meta[k] 1355 else: 1356 meta = self.meta 1357 meta["line"] = line 1358 meta["col"] = col 1359 meta["start"] = start 1360 meta["end"] = end 1361 return self
Update this expression with positions from a token or other expression.
Arguments:
- other: a token or expression to update this expression with.
- line: the line number to use if other is None
- col: column number
- start: start char index
- end: end char index
Returns:
The updated expression.
1363 def as_( 1364 self, 1365 alias: str | Identifier, 1366 quoted: bool | None = None, 1367 dialect: DialectType = None, 1368 copy: bool = True, 1369 table: bool | Sequence[str | Identifier] = False, 1370 **opts: Unpack[ParserNoDialectArgs], 1371 ) -> Expr: 1372 return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, table=table, **opts)
1397 def isin( 1398 self, 1399 *expressions: t.Any, 1400 query: ExpOrStr | None = None, 1401 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 1402 dialect: DialectType = None, 1403 copy: bool = True, 1404 **opts: Unpack[ParserNoDialectArgs], 1405 ) -> In: 1406 from sqlglot.expressions.query import Query 1407 1408 subquery: Expr | None = None 1409 if query: 1410 subquery = maybe_parse(query, dialect=dialect, copy=copy, **opts) 1411 if isinstance(subquery, Query): 1412 subquery = subquery.subquery(copy=False) 1413 unnest_list: list[ExpOrStr] = ensure_list(unnest) 1414 return In( 1415 this=maybe_copy(self, copy), 1416 expressions=[convert(e, copy=copy) for e in expressions], 1417 query=subquery, 1418 unnest=( 1419 _lazy_unnest( 1420 expressions=[ 1421 maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in unnest_list 1422 ] 1423 ) 1424 if unnest 1425 else None 1426 ), 1427 )
1429 def between( 1430 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 1431 ) -> Between: 1432 between = Between( 1433 this=maybe_copy(self, copy), 1434 low=convert(low, copy=copy), 1435 high=convert(high, copy=copy), 1436 ) 1437 if symmetric is not None: 1438 between.set("symmetric", symmetric) 1439 1440 return between
Inherited Members
Logical conditions like x AND y, or simply x
Inherited Members
- Expr
- Expr
- arg_types
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
Relationships like x = y, x > 1, x >= y.
Inherited Members
- Expr
- Expr
- arg_types
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
1559class Cache(Expression): 1560 arg_types = { 1561 "this": True, 1562 "lazy": False, 1563 "options": False, 1564 "expression": False, 1565 }
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expr
- Expr
- arg_types
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
Inherited Members
- Expr
- Expr
- arg_types
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1598@trait 1599class Binary(Condition): 1600 arg_types: t.ClassVar[dict[str, bool]] = {"this": True, "expression": True} 1601 1602 @property 1603 def left(self) -> Expr: 1604 return self.args["this"] 1605 1606 @property 1607 def right(self) -> Expr: 1608 return self.args["expression"]
Inherited Members
- Expr
- Expr
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
Inherited Members
- Expr
- Expr
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
1616@trait 1617class Func(Condition): 1618 """ 1619 The base class for all function expressions. 1620 1621 Attributes: 1622 is_var_len_args (bool): if set to True the last argument defined in arg_types will be 1623 treated as a variable length argument and the argument's value will be stored as a list. 1624 _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this 1625 function expression. These values are used to map this node to a name during parsing as 1626 well as to provide the function's name during SQL string generation. By default the SQL 1627 name is set to the expression's class name transformed to snake case. 1628 """ 1629 1630 is_var_len_args: t.ClassVar[bool] = False 1631 _sql_names: t.ClassVar[list[str]] = [] 1632 1633 @classmethod 1634 def from_arg_list(cls, args: Sequence[object]) -> Self: 1635 if cls.is_var_len_args: 1636 all_arg_keys = tuple(cls.arg_types) 1637 # If this function supports variable length argument treat the last argument as such. 1638 non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys 1639 num_non_var = len(non_var_len_arg_keys) 1640 1641 args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)} 1642 args_dict[all_arg_keys[-1]] = args[num_non_var:] 1643 else: 1644 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} 1645 1646 return cls(**args_dict) 1647 1648 @classmethod 1649 def sql_names(cls) -> list[str]: 1650 if cls is Func: 1651 raise NotImplementedError( 1652 "SQL name is only supported by concrete function implementations" 1653 ) 1654 if not cls._sql_names: 1655 return [camel_to_snake_case(cls.__name__)] 1656 return cls._sql_names 1657 1658 @classmethod 1659 def sql_name(cls) -> str: 1660 sql_names = cls.sql_names() 1661 assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}." 1662 return sql_names[0] 1663 1664 @classmethod 1665 def default_parser_mappings(cls) -> dict[str, t.Callable[[Sequence[object]], Self]]: 1666 return {name: cls.from_arg_list for name in cls.sql_names()}
The base class for all function expressions.
Attributes:
- is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
- _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
1633 @classmethod 1634 def from_arg_list(cls, args: Sequence[object]) -> Self: 1635 if cls.is_var_len_args: 1636 all_arg_keys = tuple(cls.arg_types) 1637 # If this function supports variable length argument treat the last argument as such. 1638 non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys 1639 num_non_var = len(non_var_len_arg_keys) 1640 1641 args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)} 1642 args_dict[all_arg_keys[-1]] = args[num_non_var:] 1643 else: 1644 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} 1645 1646 return cls(**args_dict)
Inherited Members
- Expr
- Expr
- arg_types
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
Inherited Members
- Expr
- Expr
- arg_types
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
1674class Column(Expression, Condition): 1675 arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False} 1676 1677 @property 1678 def table(self) -> str: 1679 return self.text("table") 1680 1681 @property 1682 def db(self) -> str: 1683 return self.text("db") 1684 1685 @property 1686 def catalog(self) -> str: 1687 return self.text("catalog") 1688 1689 @property 1690 def output_name(self) -> str: 1691 return self.name 1692 1693 @property 1694 def parts(self) -> list[Identifier | Star]: 1695 """Return the parts of a column in order catalog, db, table, name.""" 1696 return [ 1697 self.args[part] for part in ("catalog", "db", "table", "this") if self.args.get(part) 1698 ] 1699 1700 def to_dot(self, include_dots: bool = True) -> Dot | Identifier | Star: 1701 """Converts the column into a dot expression.""" 1702 parts = self.parts 1703 parent = self.parent 1704 1705 if include_dots: 1706 while isinstance(parent, Dot): 1707 parts.append(parent.expression) 1708 parent = parent.parent 1709 1710 return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
1693 @property 1694 def parts(self) -> list[Identifier | Star]: 1695 """Return the parts of a column in order catalog, db, table, name.""" 1696 return [ 1697 self.args[part] for part in ("catalog", "db", "table", "this") if self.args.get(part) 1698 ]
Return the parts of a column in order catalog, db, table, name.
1700 def to_dot(self, include_dots: bool = True) -> Dot | Identifier | Star: 1701 """Converts the column into a dot expression.""" 1702 parts = self.parts 1703 parent = self.parent 1704 1705 if include_dots: 1706 while isinstance(parent, Dot): 1707 parts.append(parent.expression) 1708 parent = parent.parent 1709 1710 return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
Converts the column into a dot expression.
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1713class Literal(Expression, Condition): 1714 arg_types = {"this": True, "is_string": True} 1715 _hash_raw_args = True 1716 is_primitive = True 1717 1718 @classmethod 1719 def number(cls, number: object) -> Literal | Neg: 1720 lit = cls(this=str(number), is_string=False) 1721 try: 1722 to_py = lit.to_py() 1723 if not isinstance(to_py, str) and to_py < 0: 1724 lit.set("this", str(abs(to_py))) 1725 return Neg(this=lit) 1726 except Exception: 1727 pass 1728 return lit 1729 1730 @classmethod 1731 def string(cls, string: object) -> Literal: 1732 return cls(this=str(string), is_string=True) 1733 1734 @property 1735 def output_name(self) -> str: 1736 return self.name 1737 1738 def to_py(self) -> int | str | Decimal: 1739 if self.is_number: 1740 try: 1741 return int(self.this) 1742 except ValueError: 1743 return Decimal(self.this) 1744 return self.this
1718 @classmethod 1719 def number(cls, number: object) -> Literal | Neg: 1720 lit = cls(this=str(number), is_string=False) 1721 try: 1722 to_py = lit.to_py() 1723 if not isinstance(to_py, str) and to_py < 0: 1724 lit.set("this", str(abs(to_py))) 1725 return Neg(this=lit) 1726 except Exception: 1727 pass 1728 return lit
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
1738 def to_py(self) -> int | str | Decimal: 1739 if self.is_number: 1740 try: 1741 return int(self.this) 1742 except ValueError: 1743 return Decimal(self.this) 1744 return self.this
Returns a Python object equivalent of the SQL node.
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1767class Identifier(Expression): 1768 arg_types = {"this": True, "quoted": False, "global_": False, "temporary": False} 1769 is_primitive = True 1770 _hash_raw_args = True 1771 1772 @property 1773 def quoted(self) -> bool: 1774 return bool(self.args.get("quoted")) 1775 1776 @property 1777 def output_name(self) -> str: 1778 return self.name
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1785class Star(Expression): 1786 arg_types = {"except_": False, "replace": False, "rename": False} 1787 1788 @property 1789 def name(self) -> str: 1790 return "*" 1791 1792 @property 1793 def output_name(self) -> str: 1794 return self.name
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1805class Placeholder(Expression, Condition): 1806 arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False} 1807 1808 @property 1809 def name(self) -> str: 1810 return self.text("this") or "?"
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1813class Null(Expression, Condition): 1814 arg_types = {} 1815 1816 @property 1817 def name(self) -> str: 1818 return "NULL" 1819 1820 def to_py(self) -> t.Literal[None]: 1821 return None
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- is_int
- is_star
- alias
- alias_column_names
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1824class Boolean(Expression, Condition): 1825 is_primitive = True 1826 1827 def to_py(self) -> bool: 1828 return self.this
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1831class Dot(Expression, Binary): 1832 @property 1833 def is_star(self) -> bool: 1834 return self.expression.is_star 1835 1836 @property 1837 def name(self) -> str: 1838 return self.expression.name 1839 1840 @property 1841 def output_name(self) -> str: 1842 return self.name 1843 1844 @classmethod 1845 def build(cls, expressions: Sequence[Expr]) -> Dot: 1846 """Build a Dot object with a sequence of expressions.""" 1847 if len(expressions) < 2: 1848 raise ValueError("Dot requires >= 2 expressions.") 1849 1850 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) 1851 1852 @property 1853 def parts(self) -> list[Expr]: 1854 """Return the parts of a table / column in order catalog, db, table.""" 1855 this, *parts = self.flatten() 1856 1857 parts.reverse() 1858 1859 for arg in COLUMN_PARTS: 1860 part = this.args.get(arg) 1861 1862 if isinstance(part, Expr): 1863 parts.append(part) 1864 1865 parts.reverse() 1866 return parts
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
1844 @classmethod 1845 def build(cls, expressions: Sequence[Expr]) -> Dot: 1846 """Build a Dot object with a sequence of expressions.""" 1847 if len(expressions) < 2: 1848 raise ValueError("Dot requires >= 2 expressions.") 1849 1850 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
Build a Dot object with a sequence of expressions.
1852 @property 1853 def parts(self) -> list[Expr]: 1854 """Return the parts of a table / column in order catalog, db, table.""" 1855 this, *parts = self.flatten() 1856 1857 parts.reverse() 1858 1859 for arg in COLUMN_PARTS: 1860 part = this.args.get(arg) 1861 1862 if isinstance(part, Expr): 1863 parts.append(part) 1864 1865 parts.reverse() 1866 return parts
Return the parts of a table / column in order catalog, db, table.
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- alias
- alias_column_names
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Kwarg in special functions like func(kwarg => y).
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1873class Alias(Expression): 1874 arg_types = {"this": True, "alias": False} 1875 1876 @property 1877 def output_name(self) -> str: 1878 return self.alias
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1889class Aliases(Expression): 1890 arg_types = {"this": True, "expressions": True} 1891 1892 @property 1893 def aliases(self) -> list[Expr]: 1894 return self.expressions
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1897class Bracket(Expression, Condition): 1898 # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator 1899 arg_types = { 1900 "this": True, 1901 "expressions": True, 1902 "offset": False, 1903 "safe": False, 1904 "returns_list_for_maps": False, 1905 "json_access": False, 1906 } 1907 1908 @property 1909 def output_name(self) -> str: 1910 if len(self.expressions) == 1: 1911 return self.expressions[0].output_name 1912 1913 return super().output_name
1908 @property 1909 def output_name(self) -> str: 1910 if len(self.expressions) == 1: 1911 return self.expressions[0].output_name 1912 1913 return super().output_name
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1940class ParameterizedAgg(Expression, AggFunc): 1941 arg_types = {"this": True, "expressions": True, "params": True}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1944class Anonymous(Expression, Func): 1945 arg_types = {"this": True, "expressions": False} 1946 is_var_len_args = True 1947 1948 @property 1949 def name(self) -> str: 1950 return self.this if isinstance(self.this, str) else self.this.name
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1953class AnonymousAggFunc(Expression, AggFunc): 1954 arg_types = {"this": True, "expressions": False} 1955 is_var_len_args = True
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1962class CombinedParameterizedAgg(ParameterizedAgg): 1963 arg_types = {"this": True, "expressions": True, "params": True}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1966class HashAgg(Expression, AggFunc): 1967 arg_types = {"this": True, "expressions": False} 1968 is_var_len_args = True
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1971class Hll(Expression, AggFunc): 1972 arg_types = {"this": True, "expressions": False} 1973 is_var_len_args = True
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1976class ApproxDistinct(Expression, AggFunc): 1977 arg_types = {"this": True, "accuracy": False} 1978 _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
1985@trait 1986class TimeUnit(Expr): 1987 """Automatically converts unit arg into a var.""" 1988 1989 UNABBREVIATED_UNIT_NAME: t.ClassVar[dict[str, str]] = { 1990 "D": "DAY", 1991 "H": "HOUR", 1992 "M": "MINUTE", 1993 "MS": "MILLISECOND", 1994 "NS": "NANOSECOND", 1995 "Q": "QUARTER", 1996 "S": "SECOND", 1997 "US": "MICROSECOND", 1998 "W": "WEEK", 1999 "Y": "YEAR", 2000 } 2001 2002 VAR_LIKE: t.ClassVar[tuple[Type[Expr], ...]] = (Column, Literal, Var) 2003 2004 def __init__(self, **args: object) -> None: 2005 super().__init__(**args) 2006 2007 unit = self.args.get("unit") 2008 if ( 2009 unit 2010 and type(unit) in TimeUnit.VAR_LIKE 2011 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2012 ): 2013 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2014 self.args["unit"] = unit 2015 self._set_parent("unit", unit) 2016 elif type(unit).__name__ == "Week": 2017 unit.set("this", Var(this=unit.this.name.upper())) # type: ignore[union-attr] 2018 2019 @property 2020 def unit(self) -> Expr | None: 2021 return self.args.get("unit")
Automatically converts unit arg into a var.
2004 def __init__(self, **args: object) -> None: 2005 super().__init__(**args) 2006 2007 unit = self.args.get("unit") 2008 if ( 2009 unit 2010 and type(unit) in TimeUnit.VAR_LIKE 2011 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2012 ): 2013 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2014 self.args["unit"] = unit 2015 self._set_parent("unit", unit) 2016 elif type(unit).__name__ == "Week": 2017 unit.set("this", Var(this=unit.this.name.upper())) # type: ignore[union-attr]
Inherited Members
- Expr
- arg_types
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
2030@trait 2031class IntervalOp(TimeUnit): 2032 def interval(self) -> Interval: 2033 from sqlglot.expressions.datatypes import Interval 2034 2035 expr = self.expression 2036 return Interval( 2037 this=expr.copy() if expr is not None else None, 2038 unit=self.unit.copy() if self.unit else None, 2039 )
Inherited Members
- Expr
- arg_types
- is_var_len_args
- is_subquery
- is_cast
- args
- parent
- arg_key
- index
- comments
- is_primitive
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- dump
- load
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- pipe
- apply
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2050class Ordered(Expression): 2051 arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False} 2052 2053 @property 2054 def name(self) -> str: 2055 return self.this.name
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2062class BitwiseAnd(Expression, Binary): 2063 arg_types = {"this": True, "expression": True, "padside": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2066class BitwiseLeftShift(Expression, Binary): 2067 arg_types = {"this": True, "expression": True, "requires_int128": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2070class BitwiseOr(Expression, Binary): 2071 arg_types = {"this": True, "expression": True, "padside": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2074class BitwiseRightShift(Expression, Binary): 2075 arg_types = {"this": True, "expression": True, "requires_int128": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2078class BitwiseXor(Expression, Binary): 2079 arg_types = {"this": True, "expression": True, "padside": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2082class Div(Expression, Binary): 2083 arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2098class DPipe(Expression, Binary): 2099 arg_types = {"this": True, "expression": True, "safe": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2182class Operator(Expression, Binary): 2183 arg_types = {"this": True, "operator": True, "expression": True}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2210class Paren(Unary): 2211 @property 2212 def output_name(self) -> str: 2213 return self.this.name
Name of the output column if this expression is a selection.
If the Expr has no output name, an empty string is returned.
Example:
>>> from sqlglot import parse_one >>> parse_one("SELECT a").expressions[0].output_name 'a' >>> parse_one("SELECT b AS c").expressions[0].output_name 'c' >>> parse_one("SELECT 1 + 2").expressions[0].output_name ''
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2216class Neg(Unary): 2217 def to_py(self) -> int | Decimal: 2218 if self.is_number: 2219 return self.this.to_py() * -1 2220 return super().to_py()
2217 def to_py(self) -> int | Decimal: 2218 if self.is_number: 2219 return self.this.to_py() * -1 2220 return super().to_py()
Returns a Python object equivalent of the SQL node.
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2235class FormatPhrase(Expression): 2236 """Format override for a column in Teradata. 2237 Can be expanded to additional dialects as needed 2238 2239 https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT 2240 """ 2241 2242 arg_types = {"this": True, "format": True}
Format override for a column in Teradata. Can be expanded to additional dialects as needed
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2245class Between(Expression, Predicate): 2246 arg_types = {"this": True, "low": True, "high": True, "symmetric": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2253class In(Expression, Predicate): 2254 arg_types = { 2255 "this": True, 2256 "expressions": False, 2257 "query": False, 2258 "unnest": False, 2259 "field": False, 2260 "is_global": False, 2261 }
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2272class Xor(Expression, Connector, Func): 2273 arg_types = {"this": False, "expression": False, "expressions": False, "round_input": False} 2274 is_var_len_args = True
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2281class RegexpLike(Expression, Binary, Func): 2282 arg_types = {"this": True, "expression": True, "flag": False, "full_match": False}
Inherited Members
- Expression
- this
- expression
- expressions
- text
- is_string
- is_number
- to_py
- is_int
- is_star
- alias
- alias_column_names
- name
- alias_or_name
- output_name
- type
- is_type
- is_leaf
- meta
- copy
- add_comments
- pop_comments
- append
- set
- set_kwargs
- depth
- iter_expressions
- find
- find_all
- find_ancestor
- parent_select
- same_parent
- root
- walk
- dfs
- bfs
- unnest
- unalias
- unnest_operands
- flatten
- to_s
- sql
- transform
- replace
- pop
- assert_is
- error_messages
- and_
- or_
- not_
- update_positions
- as_
- isin
- between
- is_
- like
- ilike
- eq
- neq
- rlike
- div
- asc
- desc
- args
- parent
- arg_key
- index
- comments
2285def not_( 2286 expression: ExpOrStr, 2287 dialect: DialectType = None, 2288 copy: bool = True, 2289 **opts: Unpack[ParserNoDialectArgs], 2290) -> Not: 2291 """ 2292 Wrap a condition with a NOT operator. 2293 2294 Example: 2295 >>> not_("this_suit='black'").sql() 2296 "NOT this_suit = 'black'" 2297 2298 Args: 2299 expression: the SQL code string to parse. 2300 If an Expr instance is passed, this is used as-is. 2301 dialect: the dialect used to parse the input expression. 2302 copy: whether to copy the expression or not. 2303 **opts: other options to use to parse the input expressions. 2304 2305 Returns: 2306 The new condition. 2307 """ 2308 this = condition( 2309 expression, 2310 dialect=dialect, 2311 copy=copy, 2312 **opts, 2313 ) 2314 return Not(this=_wrap(this, Connector))
Wrap a condition with a NOT operator.
Example:
>>> not_("this_suit='black'").sql() "NOT this_suit = 'black'"
Arguments:
- expression: the SQL code string to parse. If an Expr instance is passed, this is used as-is.
- dialect: the dialect used to parse the input expression.
- copy: whether to copy the expression or not.
- **opts: other options to use to parse the input expressions.
Returns:
The new condition.
2323def convert(value: t.Any, copy: bool = False) -> Expr: 2324 """Convert a python value into an expression object. 2325 2326 Raises an error if a conversion is not possible. 2327 2328 Args: 2329 value: A python object. 2330 copy: Whether to copy `value` (only applies to Exprs and collections). 2331 2332 Returns: 2333 The equivalent expression object. 2334 """ 2335 if isinstance(value, Expr): 2336 return maybe_copy(value, copy) 2337 if isinstance(value, str): 2338 return Literal.string(value) 2339 if isinstance(value, bool): 2340 return Boolean(this=value) 2341 if value is None or (isinstance(value, float) and math.isnan(value)): 2342 return Null() 2343 if isinstance(value, numbers.Number): 2344 return Literal.number(value) 2345 if isinstance(value, bytes): 2346 from sqlglot.expressions.query import HexString as _HexString 2347 2348 return _HexString(this=value.hex()) 2349 if isinstance(value, datetime.datetime): 2350 datetime_literal = Literal.string(value.isoformat(sep=" ")) 2351 2352 tz = None 2353 if value.tzinfo: 2354 # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles" 2355 # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot 2356 tz = Literal.string(str(value.tzinfo)) 2357 2358 from sqlglot.expressions.temporal import TimeStrToTime as _TimeStrToTime 2359 2360 return _TimeStrToTime(this=datetime_literal, zone=tz) 2361 if isinstance(value, datetime.date): 2362 date_literal = Literal.string(value.strftime("%Y-%m-%d")) 2363 from sqlglot.expressions.temporal import DateStrToDate as _DateStrToDate 2364 2365 return _DateStrToDate(this=date_literal) 2366 if isinstance(value, datetime.time): 2367 time_literal = Literal.string(value.isoformat()) 2368 from sqlglot.expressions.temporal import TsOrDsToTime as _TsOrDsToTime 2369 2370 return _TsOrDsToTime(this=time_literal) 2371 if isinstance(value, tuple): 2372 if hasattr(value, "_fields"): 2373 from sqlglot.expressions.array import Struct as _Struct 2374 2375 return _Struct( 2376 expressions=[ 2377 PropertyEQ( 2378 this=to_identifier(k), expression=convert(getattr(value, k), copy=copy) 2379 ) 2380 for k in value._fields 2381 ] 2382 ) 2383 from sqlglot.expressions.query import Tuple as _Tuple 2384 2385 return _Tuple(expressions=[convert(v, copy=copy) for v in value]) 2386 if isinstance(value, list): 2387 from sqlglot.expressions.array import Array as _Array 2388 2389 return _Array(expressions=[convert(v, copy=copy) for v in value]) 2390 if isinstance(value, dict): 2391 from sqlglot.expressions.array import Array as _Array, Map as _Map 2392 2393 return _Map( 2394 keys=_Array(expressions=[convert(k, copy=copy) for k in value]), 2395 values=_Array(expressions=[convert(v, copy=copy) for v in value.values()]), 2396 ) 2397 if hasattr(value, "__dict__"): 2398 from sqlglot.expressions.array import Struct as _Struct 2399 2400 return _Struct( 2401 expressions=[ 2402 PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy)) 2403 for k, v in value.__dict__.items() 2404 ] 2405 ) 2406 raise ValueError(f"Cannot convert {value}")
Convert a python value into an expression object.
Raises an error if a conversion is not possible.
Arguments:
- value: A python object.
- copy: Whether to copy
value(only applies to Exprs and collections).
Returns:
The equivalent expression object.
2470def maybe_parse( 2471 sql_or_expression: ExpOrStr, 2472 *, 2473 into: IntoType | None = None, 2474 dialect: DialectType = None, 2475 prefix: str | None = None, 2476 copy: bool = False, 2477 **opts: Unpack[ParserNoDialectArgs], 2478) -> Expr: 2479 """Gracefully handle a possible string or expression. 2480 2481 Example: 2482 >>> maybe_parse("1") 2483 Literal(this=1, is_string=False) 2484 >>> maybe_parse(to_identifier("x")) 2485 Identifier(this=x, quoted=False) 2486 2487 Args: 2488 sql_or_expression: the SQL code string or an expression 2489 into: the SQLGlot Expr to parse into 2490 dialect: the dialect used to parse the input expressions (in the case that an 2491 input expression is a SQL string). 2492 prefix: a string to prefix the sql with before it gets parsed 2493 (automatically includes a space) 2494 copy: whether to copy the expression. 2495 **opts: other options to use to parse the input expressions (again, in the case 2496 that an input expression is a SQL string). 2497 2498 Returns: 2499 Expr: the parsed or given expression. 2500 """ 2501 if isinstance(sql_or_expression, Expr): 2502 if copy: 2503 return sql_or_expression.copy() 2504 return sql_or_expression 2505 2506 if sql_or_expression is None: 2507 raise ParseError("SQL cannot be None") 2508 2509 import sqlglot 2510 2511 sql = str(sql_or_expression) 2512 if prefix: 2513 sql = f"{prefix} {sql}" 2514 2515 return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
Gracefully handle a possible string or expression.
Example:
>>> maybe_parse("1") Literal(this=1, is_string=False) >>> maybe_parse(to_identifier("x")) Identifier(this=x, quoted=False)
Arguments:
- sql_or_expression: the SQL code string or an expression
- into: the SQLGlot Expr to parse into
- dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
- prefix: a string to prefix the sql with before it gets parsed (automatically includes a space)
- copy: whether to copy the expression.
- **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:
Expr: the parsed or given expression.
2767def to_identifier(name, quoted=None, copy=True): 2768 """Builds an identifier. 2769 2770 Args: 2771 name: The name to turn into an identifier. 2772 quoted: Whether to force quote the identifier. 2773 copy: Whether to copy name if it's an Identifier. 2774 2775 Returns: 2776 The identifier ast node. 2777 """ 2778 2779 if name is None: 2780 return None 2781 2782 if isinstance(name, Identifier): 2783 identifier = maybe_copy(name, copy) 2784 elif isinstance(name, str): 2785 identifier = Identifier( 2786 this=name, 2787 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, 2788 ) 2789 else: 2790 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") 2791 return identifier
Builds an identifier.
Arguments:
- name: The name to turn into an identifier.
- quoted: Whether to force quote the identifier.
- copy: Whether to copy name if it's an Identifier.
Returns:
The identifier ast node.
2794def condition( 2795 expression: ExpOrStr, 2796 dialect: DialectType = None, 2797 copy: bool = True, 2798 **opts: Unpack[ParserNoDialectArgs], 2799) -> Expr: 2800 """ 2801 Initialize a logical condition expression. 2802 2803 Example: 2804 >>> condition("x=1").sql() 2805 'x = 1' 2806 2807 This is helpful for composing larger logical syntax trees: 2808 >>> where = condition("x=1") 2809 >>> where = where.and_("y=1") 2810 >>> where.sql() 2811 'x = 1 AND y = 1' 2812 2813 Args: 2814 *expression: the SQL code string to parse. 2815 If an Expr instance is passed, this is used as-is. 2816 dialect: the dialect used to parse the input expression (in the case that the 2817 input expression is a SQL string). 2818 copy: Whether to copy `expression` (only applies to expressions). 2819 **opts: other options to use to parse the input expressions (again, in the case 2820 that the input expression is a SQL string). 2821 2822 Returns: 2823 The new Condition instance 2824 """ 2825 return maybe_parse( 2826 expression, 2827 into=Condition, 2828 dialect=dialect, 2829 copy=copy, 2830 **opts, 2831 )
Initialize a logical condition expression.
Example:
>>> condition("x=1").sql() 'x = 1'This is helpful for composing larger logical syntax trees:
>>> where = condition("x=1") >>> where = where.and_("y=1") >>> where.sql() 'x = 1 AND y = 1'
Arguments:
- *expression: the SQL code string to parse. If an Expr instance is passed, this is used as-is.
- dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
- copy: Whether to copy
expression(only applies to expressions). - **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:
The new Condition instance
2834def and_( 2835 *expressions: ExpOrStr | None, 2836 dialect: DialectType = None, 2837 copy: bool = True, 2838 wrap: bool = True, 2839 **opts: Unpack[ParserNoDialectArgs], 2840) -> Condition: 2841 """ 2842 Combine multiple conditions with an AND logical operator. 2843 2844 Example: 2845 >>> and_("x=1", and_("y=1", "z=1")).sql() 2846 'x = 1 AND (y = 1 AND z = 1)' 2847 2848 Args: 2849 *expressions: the SQL code strings to parse. 2850 If an Expr instance is passed, this is used as-is. 2851 dialect: the dialect used to parse the input expression. 2852 copy: whether to copy `expressions` (only applies to Exprs). 2853 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2854 precedence issues, but can be turned off when the produced AST is too deep and 2855 causes recursion-related issues. 2856 **opts: other options to use to parse the input expressions. 2857 2858 Returns: 2859 The new condition 2860 """ 2861 return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
Combine multiple conditions with an AND logical operator.
Example:
>>> and_("x=1", and_("y=1", "z=1")).sql() 'x = 1 AND (y = 1 AND z = 1)'
Arguments:
- *expressions: the SQL code strings to parse. If an Expr instance is passed, this is used as-is.
- dialect: the dialect used to parse the input expression.
- copy: whether to copy
expressions(only applies to Exprs). - wrap: whether to wrap the operands in
Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues. - **opts: other options to use to parse the input expressions.
Returns:
The new condition
2864def or_( 2865 *expressions: ExpOrStr | None, 2866 dialect: DialectType = None, 2867 copy: bool = True, 2868 wrap: bool = True, 2869 **opts: Unpack[ParserNoDialectArgs], 2870) -> Condition: 2871 """ 2872 Combine multiple conditions with an OR logical operator. 2873 2874 Example: 2875 >>> or_("x=1", or_("y=1", "z=1")).sql() 2876 'x = 1 OR (y = 1 OR z = 1)' 2877 2878 Args: 2879 *expressions: the SQL code strings to parse. 2880 If an Expr instance is passed, this is used as-is. 2881 dialect: the dialect used to parse the input expression. 2882 copy: whether to copy `expressions` (only applies to Exprs). 2883 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2884 precedence issues, but can be turned off when the produced AST is too deep and 2885 causes recursion-related issues. 2886 **opts: other options to use to parse the input expressions. 2887 2888 Returns: 2889 The new condition 2890 """ 2891 return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
Combine multiple conditions with an OR logical operator.
Example:
>>> or_("x=1", or_("y=1", "z=1")).sql() 'x = 1 OR (y = 1 OR z = 1)'
Arguments:
- *expressions: the SQL code strings to parse. If an Expr instance is passed, this is used as-is.
- dialect: the dialect used to parse the input expression.
- copy: whether to copy
expressions(only applies to Exprs). - wrap: whether to wrap the operands in
Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues. - **opts: other options to use to parse the input expressions.
Returns:
The new condition
2894def xor( 2895 *expressions: ExpOrStr | None, 2896 dialect: DialectType = None, 2897 copy: bool = True, 2898 wrap: bool = True, 2899 **opts: Unpack[ParserNoDialectArgs], 2900) -> Condition: 2901 """ 2902 Combine multiple conditions with an XOR logical operator. 2903 2904 Example: 2905 >>> xor("x=1", xor("y=1", "z=1")).sql() 2906 'x = 1 XOR (y = 1 XOR z = 1)' 2907 2908 Args: 2909 *expressions: the SQL code strings to parse. 2910 If an Expr instance is passed, this is used as-is. 2911 dialect: the dialect used to parse the input expression. 2912 copy: whether to copy `expressions` (only applies to Exprs). 2913 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2914 precedence issues, but can be turned off when the produced AST is too deep and 2915 causes recursion-related issues. 2916 **opts: other options to use to parse the input expressions. 2917 2918 Returns: 2919 The new condition 2920 """ 2921 return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
Combine multiple conditions with an XOR logical operator.
Example:
>>> xor("x=1", xor("y=1", "z=1")).sql() 'x = 1 XOR (y = 1 XOR z = 1)'
Arguments:
- *expressions: the SQL code strings to parse. If an Expr instance is passed, this is used as-is.
- dialect: the dialect used to parse the input expression.
- copy: whether to copy
expressions(only applies to Exprs). - wrap: whether to wrap the operands in
Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues. - **opts: other options to use to parse the input expressions.
Returns:
The new condition
2924def paren(expression: ExpOrStr, copy: bool = True) -> Paren: 2925 """ 2926 Wrap an expression in parentheses. 2927 2928 Example: 2929 >>> paren("5 + 3").sql() 2930 '(5 + 3)' 2931 2932 Args: 2933 expression: the SQL code string to parse. 2934 If an Expr instance is passed, this is used as-is. 2935 copy: whether to copy the expression or not. 2936 2937 Returns: 2938 The wrapped expression. 2939 """ 2940 return Paren(this=maybe_parse(expression, copy=copy))
Wrap an expression in parentheses.
Example:
>>> paren("5 + 3").sql() '(5 + 3)'
Arguments:
- expression: the SQL code string to parse. If an Expr instance is passed, this is used as-is.
- copy: whether to copy the expression or not.
Returns:
The wrapped expression.
2943def alias_( 2944 expression: ExpOrStr, 2945 alias: str | Identifier | None, 2946 table: bool | Sequence[str | Identifier] = False, 2947 quoted: bool | None = None, 2948 dialect: DialectType = None, 2949 copy: bool = True, 2950 **opts: Unpack[ParserNoDialectArgs], 2951) -> Expr: 2952 """Create an Alias expression. 2953 2954 Example: 2955 >>> alias_('foo', 'bar').sql() 2956 'foo AS bar' 2957 2958 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() 2959 '(SELECT 1, 2) AS bar(a, b)' 2960 2961 Args: 2962 expression: the SQL code strings to parse. 2963 If an Expr instance is passed, this is used as-is. 2964 alias: the alias name to use. If the name has 2965 special characters it is quoted. 2966 table: Whether to create a table alias, can also be a list of columns. 2967 quoted: whether to quote the alias 2968 dialect: the dialect used to parse the input expression. 2969 copy: Whether to copy the expression. 2970 **opts: other options to use to parse the input expressions. 2971 2972 Returns: 2973 Alias: the aliased expression 2974 """ 2975 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) 2976 alias = to_identifier(alias, quoted=quoted) 2977 2978 if table: 2979 from sqlglot.expressions.query import TableAlias as _TableAlias 2980 2981 table_alias = _TableAlias(this=alias) 2982 exp.set("alias", table_alias) 2983 2984 if not isinstance(table, bool): 2985 for column in table: 2986 table_alias.append("columns", to_identifier(column, quoted=quoted)) 2987 2988 return exp 2989 2990 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in 2991 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node 2992 # for the complete Window expression. 2993 # 2994 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls 2995 2996 if "alias" in exp.arg_types and type(exp).__name__ != "Window": 2997 exp.set("alias", alias) 2998 return exp 2999 return Alias(this=exp, alias=alias)
Create an Alias expression.
Example:
>>> alias_('foo', 'bar').sql() 'foo AS bar'>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() '(SELECT 1, 2) AS bar(a, b)'
Arguments:
- expression: the SQL code strings to parse. If an Expr instance is passed, this is used as-is.
- alias: the alias name to use. If the name has special characters it is quoted.
- table: Whether to create a table alias, can also be a list of columns.
- quoted: whether to quote the alias
- dialect: the dialect used to parse the input expression.
- copy: Whether to copy the expression.
- **opts: other options to use to parse the input expressions.
Returns:
Alias: the aliased expression
3030def column( 3031 col, 3032 table=None, 3033 db=None, 3034 catalog=None, 3035 *, 3036 fields=None, 3037 quoted=None, 3038 copy: bool = True, 3039): 3040 """ 3041 Build a Column. 3042 3043 Args: 3044 col: Column name. 3045 table: Table name. 3046 db: Database name. 3047 catalog: Catalog name. 3048 fields: Additional fields using dots. 3049 quoted: Whether to force quotes on the column's identifiers. 3050 copy: Whether to copy identifiers if passed in. 3051 3052 Returns: 3053 The new Column instance. 3054 """ 3055 if not isinstance(col, Star): 3056 col = to_identifier(col, quoted=quoted, copy=copy) 3057 3058 this: Column | Dot = Column( 3059 this=col, 3060 table=to_identifier(table, quoted=quoted, copy=copy), 3061 db=to_identifier(db, quoted=quoted, copy=copy), 3062 catalog=to_identifier(catalog, quoted=quoted, copy=copy), 3063 ) 3064 3065 if fields: 3066 this = Dot.build( 3067 (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields)) 3068 ) 3069 return this
Build a Column.
Arguments:
- col: Column name.
- table: Table name.
- db: Database name.
- catalog: Catalog name.
- fields: Additional fields using dots.
- quoted: Whether to force quotes on the column's identifiers.
- copy: Whether to copy identifiers if passed in.
Returns:
The new Column instance.