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 """ 130 Retrieves the argument with key "this". 131 """ 132 raise NotImplementedError 133 134 @property 135 def expression(self) -> t.Any: 136 """ 137 Retrieves the argument with key "expression". 138 """ 139 raise NotImplementedError 140 141 @property 142 def expressions(self) -> list[t.Any]: 143 """ 144 Retrieves the argument with key "expressions". 145 """ 146 raise NotImplementedError 147 148 def text(self, key: str) -> str: 149 """ 150 Returns a textual representation of the argument corresponding to "key". This can only be used 151 for args that are strings or leaf Expr instances, such as identifiers and literals. 152 """ 153 raise NotImplementedError 154 155 @property 156 def is_string(self) -> bool: 157 """ 158 Checks whether a Literal expression is a string. 159 """ 160 raise NotImplementedError 161 162 @property 163 def is_number(self) -> bool: 164 """ 165 Checks whether a Literal expression is a number. 166 """ 167 raise NotImplementedError 168 169 def to_py(self) -> t.Any: 170 """ 171 Returns a Python object equivalent of the SQL node. 172 """ 173 raise NotImplementedError 174 175 @property 176 def is_int(self) -> bool: 177 """ 178 Checks whether an expression is an integer. 179 """ 180 raise NotImplementedError 181 182 @property 183 def is_star(self) -> bool: 184 """Checks whether an expression is a star.""" 185 raise NotImplementedError 186 187 @property 188 def alias(self) -> str: 189 """ 190 Returns the alias of the expression, or an empty string if it's not aliased. 191 """ 192 raise NotImplementedError 193 194 @property 195 def alias_column_names(self) -> list[str]: 196 raise NotImplementedError 197 198 @property 199 def name(self) -> str: 200 raise NotImplementedError 201 202 @property 203 def alias_or_name(self) -> str: 204 raise NotImplementedError 205 206 @property 207 def output_name(self) -> str: 208 """ 209 Name of the output column if this expression is a selection. 210 211 If the Expr has no output name, an empty string is returned. 212 213 Example: 214 >>> from sqlglot import parse_one 215 >>> parse_one("SELECT a").expressions[0].output_name 216 'a' 217 >>> parse_one("SELECT b AS c").expressions[0].output_name 218 'c' 219 >>> parse_one("SELECT 1 + 2").expressions[0].output_name 220 '' 221 """ 222 raise NotImplementedError 223 224 @property 225 def type(self) -> DataType | None: 226 raise NotImplementedError 227 228 @type.setter 229 def type(self, dtype: DataType | DType | str | None) -> None: 230 raise NotImplementedError 231 232 def is_type(self, *dtypes: DATA_TYPE) -> bool: 233 raise NotImplementedError 234 235 def is_leaf(self) -> bool: 236 raise NotImplementedError 237 238 @property 239 def meta(self) -> dict[str, t.Any]: 240 raise NotImplementedError 241 242 def __deepcopy__(self, memo: t.Any) -> Expr: 243 raise NotImplementedError 244 245 def copy(self: E) -> E: 246 """ 247 Returns a deep copy of the expression. 248 """ 249 raise NotImplementedError 250 251 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 252 raise NotImplementedError 253 254 def pop_comments(self) -> list[str]: 255 raise NotImplementedError 256 257 def append(self, arg_key: str, value: t.Any) -> None: 258 """ 259 Appends value to arg_key if it's a list or sets it as a new list. 260 261 Args: 262 arg_key (str): name of the list expression arg 263 value (Any): value to append to the list 264 """ 265 raise NotImplementedError 266 267 def set( 268 self, 269 arg_key: str, 270 value: object, 271 index: int | None = None, 272 overwrite: bool = True, 273 ) -> None: 274 """ 275 Sets arg_key to value. 276 277 Args: 278 arg_key: name of the expression arg. 279 value: value to set the arg to. 280 index: if the arg is a list, this specifies what position to add the value in it. 281 overwrite: assuming an index is given, this determines whether to overwrite the 282 list entry instead of only inserting a new value (i.e., like list.insert). 283 """ 284 raise NotImplementedError 285 286 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 287 raise NotImplementedError 288 289 @property 290 def depth(self) -> int: 291 """ 292 Returns the depth of this tree. 293 """ 294 raise NotImplementedError 295 296 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 297 """Yields the key and expression for all arguments, exploding list args.""" 298 raise NotImplementedError 299 300 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 301 """ 302 Returns the first node in this tree which matches at least one of 303 the specified types. 304 305 Args: 306 expression_types: the expression type(s) to match. 307 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 308 309 Returns: 310 The node which matches the criteria or None if no such node was found. 311 """ 312 raise NotImplementedError 313 314 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 315 """ 316 Returns a generator object which visits all nodes in this tree and only 317 yields those that match at least one of the specified expression types. 318 319 Args: 320 expression_types: the expression type(s) to match. 321 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 322 323 Returns: 324 The generator object. 325 """ 326 raise NotImplementedError 327 328 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 329 """ 330 Returns a nearest parent matching expression_types. 331 332 Args: 333 expression_types: the expression type(s) to match. 334 335 Returns: 336 The parent node. 337 """ 338 raise NotImplementedError 339 340 @property 341 def parent_select(self) -> Select | None: 342 """ 343 Returns the parent select statement. 344 """ 345 raise NotImplementedError 346 347 @property 348 def same_parent(self) -> bool: 349 """Returns if the parent is the same class as itself.""" 350 raise NotImplementedError 351 352 def root(self) -> Expr: 353 """ 354 Returns the root expression of this tree. 355 """ 356 raise NotImplementedError 357 358 def walk( 359 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 360 ) -> Iterator[Expr]: 361 """ 362 Returns a generator object which visits all nodes in this tree. 363 364 Args: 365 bfs: if set to True the BFS traversal order will be applied, 366 otherwise the DFS traversal will be used instead. 367 prune: callable that returns True if the generator should stop traversing 368 this branch of the tree. 369 370 Returns: 371 the generator object. 372 """ 373 raise NotImplementedError 374 375 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 376 """ 377 Returns a generator object which visits all nodes in this tree in 378 the DFS (Depth-first) order. 379 380 Returns: 381 The generator object. 382 """ 383 raise NotImplementedError 384 385 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 386 """ 387 Returns a generator object which visits all nodes in this tree in 388 the BFS (Breadth-first) order. 389 390 Returns: 391 The generator object. 392 """ 393 raise NotImplementedError 394 395 def unnest(self) -> Expr: 396 """ 397 Returns the first non parenthesis child or self. 398 """ 399 raise NotImplementedError 400 401 def unalias(self) -> Expr: 402 """ 403 Returns the inner expression if this is an Alias. 404 """ 405 raise NotImplementedError 406 407 def unnest_operands(self) -> tuple[Expr, ...]: 408 """ 409 Returns unnested operands as a tuple. 410 """ 411 raise NotImplementedError 412 413 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 414 """ 415 Returns a generator which yields child nodes whose parents are the same class. 416 417 A AND B AND C -> [A, B, C] 418 """ 419 raise NotImplementedError 420 421 def to_s(self) -> str: 422 """ 423 Same as __repr__, but includes additional information which can be useful 424 for debugging, like empty or missing args and the AST nodes' object IDs. 425 """ 426 raise NotImplementedError 427 428 def sql( 429 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 430 ) -> str: 431 """ 432 Returns SQL string representation of this tree. 433 434 Args: 435 dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql"). 436 opts: other `sqlglot.generator.Generator` options. 437 438 Returns: 439 The SQL string. 440 """ 441 raise NotImplementedError 442 443 def transform( 444 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 445 ) -> T: 446 """ 447 Visits all tree nodes (excluding already transformed ones) 448 and applies the given transformation function to each node. 449 450 Args: 451 fun: a function which takes a node as an argument and returns a 452 new transformed node or the same node without modifications. If the function 453 returns None, then the corresponding node will be removed from the syntax tree. 454 copy: if set to True a new tree instance is constructed, otherwise the tree is 455 modified in place. 456 457 Returns: 458 The transformed tree. 459 """ 460 raise NotImplementedError 461 462 def replace(self, expression: T) -> T: 463 """ 464 Swap out this expression with a new expression. 465 466 For example:: 467 468 >>> import sqlglot 469 >>> tree = sqlglot.parse_one("SELECT x FROM tbl") 470 >>> tree.find(sqlglot.exp.Column).replace(sqlglot.exp.column("y")) 471 Column( 472 this=Identifier(this=y, quoted=False)) 473 >>> tree.sql() 474 'SELECT y FROM tbl' 475 476 Args: 477 expression (T): new node 478 479 Returns: 480 T: The new expression or expressions. 481 """ 482 raise NotImplementedError 483 484 def pop(self: E) -> E: 485 """ 486 Remove this expression from its AST. 487 488 Returns: 489 The popped expression. 490 """ 491 raise NotImplementedError 492 493 def assert_is(self, type_: Type[E]) -> E: 494 """ 495 Assert that this `Expr` is an instance of `type_`. 496 497 If it is NOT an instance of `type_`, this raises an assertion error. 498 Otherwise, this returns this expression. 499 500 Examples: 501 This is useful for type security in chained expressions: 502 503 >>> import sqlglot 504 >>> sqlglot.parse_one("SELECT x from y").assert_is(sqlglot.exp.Select).select("z").sql() 505 'SELECT x, z FROM y' 506 """ 507 raise NotImplementedError 508 509 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 510 """ 511 Checks if this expression is valid (e.g. all mandatory args are set). 512 513 Args: 514 args: a sequence of values that were used to instantiate a Func expression. This is used 515 to check that the provided arguments don't exceed the function argument limit. 516 517 Returns: 518 A list of error messages for all possible errors that were found. 519 """ 520 raise NotImplementedError 521 522 def dump(self) -> list[dict[str, t.Any]]: 523 """ 524 Dump this Expr to a JSON-serializable dict. 525 """ 526 from sqlglot.serde import dump 527 528 return dump(self) 529 530 @classmethod 531 def load(cls, obj: list[dict[str, Any]] | None) -> Expr: 532 """ 533 Load a dict (as returned by `Expr.dump`) into an Expr instance. 534 """ 535 from sqlglot.serde import load 536 537 result = load(obj) 538 assert isinstance(result, Expr) 539 return result 540 541 def and_( 542 self, 543 *expressions: ExpOrStr | None, 544 dialect: DialectType = None, 545 copy: bool = True, 546 wrap: bool = True, 547 **opts: Unpack[ParserNoDialectArgs], 548 ) -> Condition: 549 """ 550 AND this condition with one or multiple expressions. 551 552 Example: 553 >>> condition("x=1").and_("y=1").sql() 554 'x = 1 AND y = 1' 555 556 Args: 557 *expressions: the SQL code strings to parse. 558 If an `Expr` instance is passed, it will be used as-is. 559 dialect: the dialect used to parse the input expression. 560 copy: whether to copy the involved expressions (only applies to Exprs). 561 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 562 precedence issues, but can be turned off when the produced AST is too deep and 563 causes recursion-related issues. 564 opts: other options to use to parse the input expressions. 565 566 Returns: 567 The new And condition. 568 """ 569 raise NotImplementedError 570 571 def or_( 572 self, 573 *expressions: ExpOrStr | None, 574 dialect: DialectType = None, 575 copy: bool = True, 576 wrap: bool = True, 577 **opts: Unpack[ParserNoDialectArgs], 578 ) -> Condition: 579 """ 580 OR this condition with one or multiple expressions. 581 582 Example: 583 >>> condition("x=1").or_("y=1").sql() 584 'x = 1 OR y = 1' 585 586 Args: 587 *expressions: the SQL code strings to parse. 588 If an `Expr` instance is passed, it will be used as-is. 589 dialect: the dialect used to parse the input expression. 590 copy: whether to copy the involved expressions (only applies to Exprs). 591 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 592 precedence issues, but can be turned off when the produced AST is too deep and 593 causes recursion-related issues. 594 opts: other options to use to parse the input expressions. 595 596 Returns: 597 The new Or condition. 598 """ 599 raise NotImplementedError 600 601 def not_(self, copy: bool = True) -> Not: 602 """ 603 Wrap this condition with NOT. 604 605 Example: 606 >>> condition("x=1").not_().sql() 607 'NOT x = 1' 608 609 Args: 610 copy: whether to copy this object. 611 612 Returns: 613 The new Not instance. 614 """ 615 raise NotImplementedError 616 617 def update_positions( 618 self: E, 619 other: Token | Expr | None = None, 620 line: int | None = None, 621 col: int | None = None, 622 start: int | None = None, 623 end: int | None = None, 624 ) -> E: 625 """ 626 Update this expression with positions from a token or other expression. 627 628 Args: 629 other: a token or expression to update this expression with. 630 line: the line number to use if other is None 631 col: column number 632 start: start char index 633 end: end char index 634 635 Returns: 636 The updated expression. 637 """ 638 raise NotImplementedError 639 640 def as_( 641 self, 642 alias: str | Identifier, 643 quoted: bool | None = None, 644 dialect: DialectType = None, 645 copy: bool = True, 646 table: bool | Sequence[str | Identifier] = False, 647 **opts: Unpack[ParserNoDialectArgs], 648 ) -> Expr: 649 raise NotImplementedError 650 651 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 652 raise NotImplementedError 653 654 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 655 raise NotImplementedError 656 657 def __iter__(self) -> Iterator: 658 raise NotImplementedError 659 660 def isin( 661 self, 662 *expressions: t.Any, 663 query: ExpOrStr | None = None, 664 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 665 dialect: DialectType = None, 666 copy: bool = True, 667 **opts: Unpack[ParserNoDialectArgs], 668 ) -> In: 669 raise NotImplementedError 670 671 def between( 672 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 673 ) -> Between: 674 raise NotImplementedError 675 676 def is_(self, other: ExpOrStr) -> Is: 677 raise NotImplementedError 678 679 def like(self, other: ExpOrStr) -> Like: 680 raise NotImplementedError 681 682 def ilike(self, other: ExpOrStr) -> ILike: 683 raise NotImplementedError 684 685 def eq(self, other: t.Any) -> EQ: 686 raise NotImplementedError 687 688 def neq(self, other: t.Any) -> NEQ: 689 raise NotImplementedError 690 691 def rlike(self, other: ExpOrStr) -> RegexpLike: 692 raise NotImplementedError 693 694 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 695 raise NotImplementedError 696 697 def asc(self, nulls_first: bool = True) -> Ordered: 698 raise NotImplementedError 699 700 def desc(self, nulls_first: bool = False) -> Ordered: 701 raise NotImplementedError 702 703 def __lt__(self, other: t.Any) -> LT: 704 raise NotImplementedError 705 706 def __le__(self, other: t.Any) -> LTE: 707 raise NotImplementedError 708 709 def __gt__(self, other: t.Any) -> GT: 710 raise NotImplementedError 711 712 def __ge__(self, other: t.Any) -> GTE: 713 raise NotImplementedError 714 715 def __add__(self, other: t.Any) -> Add: 716 raise NotImplementedError 717 718 def __radd__(self, other: t.Any) -> Add: 719 raise NotImplementedError 720 721 def __sub__(self, other: t.Any) -> Sub: 722 raise NotImplementedError 723 724 def __rsub__(self, other: t.Any) -> Sub: 725 raise NotImplementedError 726 727 def __mul__(self, other: t.Any) -> Mul: 728 raise NotImplementedError 729 730 def __rmul__(self, other: t.Any) -> Mul: 731 raise NotImplementedError 732 733 def __truediv__(self, other: t.Any) -> Div: 734 raise NotImplementedError 735 736 def __rtruediv__(self, other: t.Any) -> Div: 737 raise NotImplementedError 738 739 def __floordiv__(self, other: t.Any) -> IntDiv: 740 raise NotImplementedError 741 742 def __rfloordiv__(self, other: t.Any) -> IntDiv: 743 raise NotImplementedError 744 745 def __mod__(self, other: t.Any) -> Mod: 746 raise NotImplementedError 747 748 def __rmod__(self, other: t.Any) -> Mod: 749 raise NotImplementedError 750 751 def __pow__(self, other: t.Any) -> Pow: 752 raise NotImplementedError 753 754 def __rpow__(self, other: t.Any) -> Pow: 755 raise NotImplementedError 756 757 def __and__(self, other: t.Any) -> And: 758 raise NotImplementedError 759 760 def __rand__(self, other: t.Any) -> And: 761 raise NotImplementedError 762 763 def __or__(self, other: t.Any) -> Or: 764 raise NotImplementedError 765 766 def __ror__(self, other: t.Any) -> Or: 767 raise NotImplementedError 768 769 def __neg__(self) -> Neg: 770 raise NotImplementedError 771 772 def __invert__(self) -> Not: 773 raise NotImplementedError 774 775 def pipe( 776 self, func: t.Callable[Concatenate[Self, P], R], *args: P.args, **kwargs: P.kwargs 777 ) -> R: 778 """Apply a function to `Self` (the current instance) and return the result. 779 780 Doing `expr.pipe(func, *args, **kwargs)` is equivalent to `func(expr, *args, **kwargs)`. 781 782 It allows you to chain operations in a fluent way on any given function that takes `Self` as its first argument. 783 784 Tip: 785 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 786 787 Args: 788 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 789 *args: Additional positional arguments to pass to `func` after `Self`. 790 **kwargs: Additional keyword arguments to pass to `func`. 791 792 Returns: 793 The result of applying `func` to `Self` with the given arguments. 794 """ 795 return func(self, *args, **kwargs) 796 797 def apply( 798 self, func: t.Callable[Concatenate[Self, P], t.Any], *args: P.args, **kwargs: P.kwargs 799 ) -> Self: 800 """Apply a function to `Self` (the current instance) for side effects, and return `Self`. 801 802 Useful for inspecting intermediate expressions in a method chain by simply adding/removing `apply` calls, especially when combined with `pipe`. 803 804 Tip: 805 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 806 807 Args: 808 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 809 *args: Additional positional arguments to pass to `func` after `Self`. 810 **kwargs: Additional keyword arguments to pass to `func`. 811 812 Returns: 813 The same instance. 814 """ 815 func(self, *args, **kwargs) 816 return self 817 818 819class Expression(Expr): 820 __slots__ = ( 821 "args", 822 "parent", 823 "arg_key", 824 "index", 825 "comments", 826 "_type", 827 "_meta", 828 "_hash", 829 ) 830 831 def __eq__(self, other: object) -> bool: 832 return self is other or (type(self) is type(other) and hash(self) == hash(other)) 833 834 def __ne__(self, other: object) -> bool: 835 return not self.__eq__(other) 836 837 def __hash__(self) -> int: 838 if self._hash is None: 839 nodes: list[Expr] = [] 840 queue: deque[Expr] = deque() 841 queue.append(self) 842 843 while queue: 844 node = queue.popleft() 845 nodes.append(node) 846 847 for child in node.iter_expressions(): 848 if child._hash is None: 849 queue.append(child) 850 851 for node in reversed(nodes): 852 hash_ = hash(node.key) 853 854 if node._hash_raw_args: 855 for k, v in sorted(node.args.items()): 856 if v: 857 hash_ = hash((hash_, k, v)) 858 else: 859 for k, v in sorted(node.args.items()): 860 vt = type(v) 861 862 if vt is list: 863 for x in v: 864 if x is not None and x is not False: 865 hash_ = hash((hash_, k, x.lower() if type(x) is str else x)) 866 else: 867 hash_ = hash((hash_, k)) 868 elif v is not None and v is not False: 869 hash_ = hash((hash_, k, v.lower() if vt is str else v)) 870 871 node._hash = hash_ 872 assert self._hash 873 return self._hash 874 875 def __reduce__( 876 self, 877 ) -> tuple[ 878 t.Callable[[list[dict[str, t.Any]] | None], Expr | DType | None], 879 tuple[list[dict[str, t.Any]]], 880 ]: 881 from sqlglot.serde import dump, load 882 883 return (load, (dump(self),)) 884 885 @property 886 def this(self) -> t.Any: 887 return self.args.get("this") 888 889 @property 890 def expression(self) -> t.Any: 891 return self.args.get("expression") 892 893 @property 894 def expressions(self) -> list[t.Any]: 895 return self.args.get("expressions") or [] 896 897 def text(self, key: str) -> str: 898 field = self.args.get(key) 899 if isinstance(field, str): 900 return field 901 if isinstance(field, (Identifier, Literal, Var)): 902 return field.this 903 if isinstance(field, (Star, Null)): 904 return field.name 905 return "" 906 907 @property 908 def is_string(self) -> bool: 909 return isinstance(self, Literal) and self.args["is_string"] 910 911 @property 912 def is_number(self) -> bool: 913 return (isinstance(self, Literal) and not self.args["is_string"]) or ( 914 isinstance(self, Neg) and self.this.is_number 915 ) 916 917 def to_py(self) -> t.Any: 918 raise ValueError(f"{self} cannot be converted to a Python object.") 919 920 @property 921 def is_int(self) -> bool: 922 return self.is_number and isinstance(self.to_py(), int) 923 924 @property 925 def is_star(self) -> bool: 926 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star)) 927 928 @property 929 def alias(self) -> str: 930 alias = self.args.get("alias") 931 if isinstance(alias, Expression): 932 return alias.name 933 return self.text("alias") 934 935 @property 936 def alias_column_names(self) -> list[str]: 937 table_alias = self.args.get("alias") 938 if not table_alias: 939 return [] 940 return [c.name for c in table_alias.args.get("columns") or []] 941 942 @property 943 def name(self) -> str: 944 return self.text("this") 945 946 @property 947 def alias_or_name(self) -> str: 948 return self.alias or self.name 949 950 @property 951 def output_name(self) -> str: 952 return "" 953 954 @property 955 def type(self) -> DataType | None: 956 if self.is_cast: 957 return self._type or self.to # type: ignore[attr-defined] 958 return self._type 959 960 @type.setter 961 def type(self, dtype: DataType | DType | str | None) -> None: 962 if dtype and type(dtype).__name__ != "DataType": 963 from sqlglot.expressions.datatypes import DataType as _DataType 964 965 dtype = _DataType.build(dtype) 966 self._type = dtype # type: ignore[assignment] 967 968 def is_type(self, *dtypes: DATA_TYPE) -> bool: 969 t = self._type 970 return t is not None and t.is_type(*dtypes) 971 972 def is_leaf(self) -> bool: 973 return not any((isinstance(v, Expr) or type(v) is list) and v for v in self.args.values()) 974 975 @property 976 def meta(self) -> dict[str, t.Any]: 977 if self._meta is None: 978 self._meta = {} 979 return self._meta 980 981 def __deepcopy__(self, memo: t.Any) -> Expr: 982 root = self.__class__() 983 stack: list[tuple[Expr, Expr]] = [(self, root)] 984 985 while stack: 986 node, copy = stack.pop() 987 988 if node.comments is not None: 989 copy.comments = deepcopy(node.comments) 990 if node._type is not None: 991 copy._type = deepcopy(node._type) 992 if node._meta is not None: 993 copy._meta = deepcopy(node._meta) 994 if node._hash is not None: 995 copy._hash = node._hash 996 997 for k, vs in node.args.items(): 998 if isinstance(vs, Expr): 999 stack.append((vs, vs.__class__())) 1000 copy.set(k, stack[-1][-1]) 1001 elif type(vs) is list: 1002 copy.args[k] = [] 1003 1004 for v in vs: 1005 if isinstance(v, Expr): 1006 stack.append((v, v.__class__())) 1007 copy.append(k, stack[-1][-1]) 1008 else: 1009 copy.append(k, v) 1010 else: 1011 copy.args[k] = vs 1012 1013 return root 1014 1015 def copy(self: E) -> E: 1016 return deepcopy(self) 1017 1018 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 1019 if self.comments is None: 1020 self.comments = [] 1021 1022 if comments: 1023 for comment in comments: 1024 _, *meta = comment.split(SQLGLOT_META) 1025 if meta: 1026 for kv in "".join(meta).split(","): 1027 k, *v = kv.split("=") 1028 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 1029 1030 if not prepend: 1031 self.comments.append(comment) 1032 1033 if prepend: 1034 self.comments = comments + self.comments 1035 1036 def pop_comments(self) -> list[str]: 1037 comments = self.comments or [] 1038 self.comments = None 1039 return comments 1040 1041 def append(self, arg_key: str, value: t.Any) -> None: 1042 if type(self.args.get(arg_key)) is not list: 1043 self.args[arg_key] = [] 1044 self._set_parent(arg_key, value) 1045 values = self.args[arg_key] 1046 if isinstance(value, Expr): 1047 value.index = len(values) 1048 values.append(value) 1049 1050 def set( 1051 self, 1052 arg_key: str, 1053 value: object, 1054 index: int | None = None, 1055 overwrite: bool = True, 1056 ) -> None: 1057 node: Expr | None = self 1058 1059 while node and node._hash is not None: 1060 node._hash = None 1061 node = node.parent 1062 1063 if index is not None: 1064 expressions = self.args.get(arg_key) or [] 1065 1066 if seq_get(expressions, index) is None: 1067 return 1068 1069 if value is None: 1070 expressions.pop(index) 1071 for v in expressions[index:]: 1072 v.index = v.index - 1 1073 return 1074 1075 if isinstance(value, list): 1076 expressions.pop(index) 1077 expressions[index:index] = value 1078 elif overwrite: 1079 expressions[index] = value 1080 else: 1081 expressions.insert(index, value) 1082 1083 value = expressions 1084 elif value is None: 1085 self.args.pop(arg_key, None) 1086 return 1087 1088 self.args[arg_key] = value 1089 self._set_parent(arg_key, value, index) 1090 1091 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 1092 if isinstance(value, Expr): 1093 value.parent = self 1094 value.arg_key = arg_key 1095 value.index = index 1096 elif isinstance(value, list): 1097 for i, v in enumerate(value): 1098 if isinstance(v, Expr): 1099 v.parent = self 1100 v.arg_key = arg_key 1101 v.index = i 1102 1103 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 1104 """Set multiples keyword arguments at once, using `.set()` method. 1105 1106 Args: 1107 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 1108 Returns: 1109 Self: The same `Expression` with the updated arguments. 1110 """ 1111 if kwargs: 1112 for k, v in kwargs.items(): 1113 self.set(k, v) 1114 return self 1115 1116 @property 1117 def depth(self) -> int: 1118 if self.parent: 1119 return self.parent.depth + 1 1120 return 0 1121 1122 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 1123 for vs in reversed(self.args.values()) if reverse else self.args.values(): 1124 if isinstance(vs, list): 1125 for v in reversed(vs) if reverse else vs: 1126 if isinstance(v, Expr): 1127 yield t.cast(E, v) 1128 elif isinstance(vs, Expr): 1129 yield t.cast(E, vs) 1130 1131 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 1132 return next(self.find_all(*expression_types, bfs=bfs), None) 1133 1134 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 1135 for expression in self.walk(bfs=bfs): 1136 if isinstance(expression, expression_types): 1137 yield expression 1138 1139 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 1140 ancestor = self.parent 1141 while ancestor and not isinstance(ancestor, expression_types): 1142 ancestor = ancestor.parent 1143 return ancestor # type: ignore[return-value] 1144 1145 @property 1146 def parent_select(self) -> Select | None: 1147 from sqlglot.expressions.query import Select as _Select 1148 1149 return self.find_ancestor(_Select) 1150 1151 @property 1152 def same_parent(self) -> bool: 1153 return type(self.parent) is self.__class__ 1154 1155 def root(self) -> Expr: 1156 expression: Expr = self 1157 while expression.parent: 1158 expression = expression.parent 1159 return expression 1160 1161 def walk( 1162 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 1163 ) -> Iterator[Expr]: 1164 if bfs: 1165 yield from self.bfs(prune=prune) 1166 else: 1167 yield from self.dfs(prune=prune) 1168 1169 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1170 stack = [self] 1171 1172 while stack: 1173 node = stack.pop() 1174 yield node 1175 if prune and prune(node): 1176 continue 1177 for v in node.iter_expressions(reverse=True): 1178 stack.append(v) 1179 1180 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1181 queue: deque[Expr] = deque() 1182 queue.append(self) 1183 1184 while queue: 1185 node = queue.popleft() 1186 yield node 1187 if prune and prune(node): 1188 continue 1189 for v in node.iter_expressions(): 1190 queue.append(v) 1191 1192 def unnest(self) -> Expr: 1193 expression = self 1194 while type(expression) is Paren: 1195 expression = expression.this 1196 return expression 1197 1198 def unalias(self) -> Expr: 1199 if isinstance(self, Alias): 1200 return self.this 1201 return self 1202 1203 def unnest_operands(self) -> tuple[Expr, ...]: 1204 return tuple(arg.unnest() for arg in self.iter_expressions()) 1205 1206 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1207 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1208 if type(node) is not self.__class__: 1209 yield node.unnest() if unnest and not node.is_subquery else node 1210 1211 def __str__(self) -> str: 1212 return self.sql() 1213 1214 def __repr__(self) -> str: 1215 return _to_s(self) 1216 1217 def to_s(self) -> str: 1218 return _to_s(self, verbose=True) 1219 1220 def sql( 1221 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1222 ) -> str: 1223 from sqlglot.dialects.dialect import Dialect 1224 1225 return Dialect.get_or_raise(dialect).generate(self, copy=copy, **opts) 1226 1227 def transform( 1228 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 1229 ) -> T: 1230 root: t.Any = None 1231 new_node: t.Any = None 1232 1233 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1234 parent, arg_key, index = node.parent, node.arg_key, node.index 1235 new_node = fun(node, *args, **kwargs) 1236 1237 if not root: 1238 root = new_node 1239 elif parent and arg_key and new_node is not node: 1240 parent.set(arg_key, new_node, index) 1241 1242 assert root 1243 return root 1244 1245 def replace(self, expression: T) -> T: 1246 parent = self.parent 1247 1248 if not parent or parent is expression: 1249 return expression 1250 1251 key = self.arg_key 1252 1253 if key: 1254 value = parent.args.get(key) 1255 1256 if type(expression) is list and isinstance(value, Expr): 1257 # We are trying to replace an Expr with a list, so it's assumed that 1258 # the intention was to really replace the parent of this expression. 1259 if value.parent: 1260 value.parent.replace(expression) 1261 else: 1262 parent.set(key, expression, self.index) 1263 1264 if expression is not self: 1265 self.parent = None 1266 self.arg_key = None 1267 self.index = None 1268 1269 return expression 1270 1271 def pop(self: E) -> E: 1272 self.replace(None) 1273 return self 1274 1275 def assert_is(self, type_: Type[E]) -> E: 1276 if not isinstance(self, type_): 1277 raise AssertionError(f"{self} is not {type_}.") 1278 return self 1279 1280 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1281 if UNITTEST: 1282 for k in self.args: 1283 if k not in self.arg_types: 1284 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1285 1286 errors: list[str] | None = None 1287 1288 for k in self.required_args: 1289 v = self.args.get(k) 1290 if v is None or (isinstance(v, list) and not v): 1291 if errors is None: 1292 errors = [] 1293 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1294 1295 if ( 1296 args 1297 and isinstance(self, Func) 1298 and len(args) > len(self.arg_types) 1299 and not self.is_var_len_args 1300 ): 1301 if errors is None: 1302 errors = [] 1303 errors.append( 1304 f"The number of provided arguments ({len(args)}) is greater than " 1305 f"the maximum number of supported arguments ({len(self.arg_types)})" 1306 ) 1307 1308 return errors or [] 1309 1310 def and_( 1311 self, 1312 *expressions: ExpOrStr | None, 1313 dialect: DialectType = None, 1314 copy: bool = True, 1315 wrap: bool = True, 1316 **opts: Unpack[ParserNoDialectArgs], 1317 ) -> Condition: 1318 return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1319 1320 def or_( 1321 self, 1322 *expressions: ExpOrStr | None, 1323 dialect: DialectType = None, 1324 copy: bool = True, 1325 wrap: bool = True, 1326 **opts: Unpack[ParserNoDialectArgs], 1327 ) -> Condition: 1328 return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1329 1330 def not_(self, copy: bool = True) -> Not: 1331 return not_(self, copy=copy) 1332 1333 def update_positions( 1334 self: E, 1335 other: Token | Expr | None = None, 1336 line: int | None = None, 1337 col: int | None = None, 1338 start: int | None = None, 1339 end: int | None = None, 1340 ) -> E: 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 arg_types = {"this": True, "expression": True, "negate": False} 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 arg_types = {"this": True, "expression": True, "negate": False} 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 """ 131 Retrieves the argument with key "this". 132 """ 133 raise NotImplementedError 134 135 @property 136 def expression(self) -> t.Any: 137 """ 138 Retrieves the argument with key "expression". 139 """ 140 raise NotImplementedError 141 142 @property 143 def expressions(self) -> list[t.Any]: 144 """ 145 Retrieves the argument with key "expressions". 146 """ 147 raise NotImplementedError 148 149 def text(self, key: str) -> str: 150 """ 151 Returns a textual representation of the argument corresponding to "key". This can only be used 152 for args that are strings or leaf Expr instances, such as identifiers and literals. 153 """ 154 raise NotImplementedError 155 156 @property 157 def is_string(self) -> bool: 158 """ 159 Checks whether a Literal expression is a string. 160 """ 161 raise NotImplementedError 162 163 @property 164 def is_number(self) -> bool: 165 """ 166 Checks whether a Literal expression is a number. 167 """ 168 raise NotImplementedError 169 170 def to_py(self) -> t.Any: 171 """ 172 Returns a Python object equivalent of the SQL node. 173 """ 174 raise NotImplementedError 175 176 @property 177 def is_int(self) -> bool: 178 """ 179 Checks whether an expression is an integer. 180 """ 181 raise NotImplementedError 182 183 @property 184 def is_star(self) -> bool: 185 """Checks whether an expression is a star.""" 186 raise NotImplementedError 187 188 @property 189 def alias(self) -> str: 190 """ 191 Returns the alias of the expression, or an empty string if it's not aliased. 192 """ 193 raise NotImplementedError 194 195 @property 196 def alias_column_names(self) -> list[str]: 197 raise NotImplementedError 198 199 @property 200 def name(self) -> str: 201 raise NotImplementedError 202 203 @property 204 def alias_or_name(self) -> str: 205 raise NotImplementedError 206 207 @property 208 def output_name(self) -> str: 209 """ 210 Name of the output column if this expression is a selection. 211 212 If the Expr has no output name, an empty string is returned. 213 214 Example: 215 >>> from sqlglot import parse_one 216 >>> parse_one("SELECT a").expressions[0].output_name 217 'a' 218 >>> parse_one("SELECT b AS c").expressions[0].output_name 219 'c' 220 >>> parse_one("SELECT 1 + 2").expressions[0].output_name 221 '' 222 """ 223 raise NotImplementedError 224 225 @property 226 def type(self) -> DataType | None: 227 raise NotImplementedError 228 229 @type.setter 230 def type(self, dtype: DataType | DType | str | None) -> None: 231 raise NotImplementedError 232 233 def is_type(self, *dtypes: DATA_TYPE) -> bool: 234 raise NotImplementedError 235 236 def is_leaf(self) -> bool: 237 raise NotImplementedError 238 239 @property 240 def meta(self) -> dict[str, t.Any]: 241 raise NotImplementedError 242 243 def __deepcopy__(self, memo: t.Any) -> Expr: 244 raise NotImplementedError 245 246 def copy(self: E) -> E: 247 """ 248 Returns a deep copy of the expression. 249 """ 250 raise NotImplementedError 251 252 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 253 raise NotImplementedError 254 255 def pop_comments(self) -> list[str]: 256 raise NotImplementedError 257 258 def append(self, arg_key: str, value: t.Any) -> None: 259 """ 260 Appends value to arg_key if it's a list or sets it as a new list. 261 262 Args: 263 arg_key (str): name of the list expression arg 264 value (Any): value to append to the list 265 """ 266 raise NotImplementedError 267 268 def set( 269 self, 270 arg_key: str, 271 value: object, 272 index: int | None = None, 273 overwrite: bool = True, 274 ) -> None: 275 """ 276 Sets arg_key to value. 277 278 Args: 279 arg_key: name of the expression arg. 280 value: value to set the arg to. 281 index: if the arg is a list, this specifies what position to add the value in it. 282 overwrite: assuming an index is given, this determines whether to overwrite the 283 list entry instead of only inserting a new value (i.e., like list.insert). 284 """ 285 raise NotImplementedError 286 287 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 288 raise NotImplementedError 289 290 @property 291 def depth(self) -> int: 292 """ 293 Returns the depth of this tree. 294 """ 295 raise NotImplementedError 296 297 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 298 """Yields the key and expression for all arguments, exploding list args.""" 299 raise NotImplementedError 300 301 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 302 """ 303 Returns the first node in this tree which matches at least one of 304 the specified types. 305 306 Args: 307 expression_types: the expression type(s) to match. 308 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 309 310 Returns: 311 The node which matches the criteria or None if no such node was found. 312 """ 313 raise NotImplementedError 314 315 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 316 """ 317 Returns a generator object which visits all nodes in this tree and only 318 yields those that match at least one of the specified expression types. 319 320 Args: 321 expression_types: the expression type(s) to match. 322 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 323 324 Returns: 325 The generator object. 326 """ 327 raise NotImplementedError 328 329 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 330 """ 331 Returns a nearest parent matching expression_types. 332 333 Args: 334 expression_types: the expression type(s) to match. 335 336 Returns: 337 The parent node. 338 """ 339 raise NotImplementedError 340 341 @property 342 def parent_select(self) -> Select | None: 343 """ 344 Returns the parent select statement. 345 """ 346 raise NotImplementedError 347 348 @property 349 def same_parent(self) -> bool: 350 """Returns if the parent is the same class as itself.""" 351 raise NotImplementedError 352 353 def root(self) -> Expr: 354 """ 355 Returns the root expression of this tree. 356 """ 357 raise NotImplementedError 358 359 def walk( 360 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 361 ) -> Iterator[Expr]: 362 """ 363 Returns a generator object which visits all nodes in this tree. 364 365 Args: 366 bfs: if set to True the BFS traversal order will be applied, 367 otherwise the DFS traversal will be used instead. 368 prune: callable that returns True if the generator should stop traversing 369 this branch of the tree. 370 371 Returns: 372 the generator object. 373 """ 374 raise NotImplementedError 375 376 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 377 """ 378 Returns a generator object which visits all nodes in this tree in 379 the DFS (Depth-first) order. 380 381 Returns: 382 The generator object. 383 """ 384 raise NotImplementedError 385 386 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 387 """ 388 Returns a generator object which visits all nodes in this tree in 389 the BFS (Breadth-first) order. 390 391 Returns: 392 The generator object. 393 """ 394 raise NotImplementedError 395 396 def unnest(self) -> Expr: 397 """ 398 Returns the first non parenthesis child or self. 399 """ 400 raise NotImplementedError 401 402 def unalias(self) -> Expr: 403 """ 404 Returns the inner expression if this is an Alias. 405 """ 406 raise NotImplementedError 407 408 def unnest_operands(self) -> tuple[Expr, ...]: 409 """ 410 Returns unnested operands as a tuple. 411 """ 412 raise NotImplementedError 413 414 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 415 """ 416 Returns a generator which yields child nodes whose parents are the same class. 417 418 A AND B AND C -> [A, B, C] 419 """ 420 raise NotImplementedError 421 422 def to_s(self) -> str: 423 """ 424 Same as __repr__, but includes additional information which can be useful 425 for debugging, like empty or missing args and the AST nodes' object IDs. 426 """ 427 raise NotImplementedError 428 429 def sql( 430 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 431 ) -> str: 432 """ 433 Returns SQL string representation of this tree. 434 435 Args: 436 dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql"). 437 opts: other `sqlglot.generator.Generator` options. 438 439 Returns: 440 The SQL string. 441 """ 442 raise NotImplementedError 443 444 def transform( 445 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 446 ) -> T: 447 """ 448 Visits all tree nodes (excluding already transformed ones) 449 and applies the given transformation function to each node. 450 451 Args: 452 fun: a function which takes a node as an argument and returns a 453 new transformed node or the same node without modifications. If the function 454 returns None, then the corresponding node will be removed from the syntax tree. 455 copy: if set to True a new tree instance is constructed, otherwise the tree is 456 modified in place. 457 458 Returns: 459 The transformed tree. 460 """ 461 raise NotImplementedError 462 463 def replace(self, expression: T) -> T: 464 """ 465 Swap out this expression with a new expression. 466 467 For example:: 468 469 >>> import sqlglot 470 >>> tree = sqlglot.parse_one("SELECT x FROM tbl") 471 >>> tree.find(sqlglot.exp.Column).replace(sqlglot.exp.column("y")) 472 Column( 473 this=Identifier(this=y, quoted=False)) 474 >>> tree.sql() 475 'SELECT y FROM tbl' 476 477 Args: 478 expression (T): new node 479 480 Returns: 481 T: The new expression or expressions. 482 """ 483 raise NotImplementedError 484 485 def pop(self: E) -> E: 486 """ 487 Remove this expression from its AST. 488 489 Returns: 490 The popped expression. 491 """ 492 raise NotImplementedError 493 494 def assert_is(self, type_: Type[E]) -> E: 495 """ 496 Assert that this `Expr` is an instance of `type_`. 497 498 If it is NOT an instance of `type_`, this raises an assertion error. 499 Otherwise, this returns this expression. 500 501 Examples: 502 This is useful for type security in chained expressions: 503 504 >>> import sqlglot 505 >>> sqlglot.parse_one("SELECT x from y").assert_is(sqlglot.exp.Select).select("z").sql() 506 'SELECT x, z FROM y' 507 """ 508 raise NotImplementedError 509 510 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 511 """ 512 Checks if this expression is valid (e.g. all mandatory args are set). 513 514 Args: 515 args: a sequence of values that were used to instantiate a Func expression. This is used 516 to check that the provided arguments don't exceed the function argument limit. 517 518 Returns: 519 A list of error messages for all possible errors that were found. 520 """ 521 raise NotImplementedError 522 523 def dump(self) -> list[dict[str, t.Any]]: 524 """ 525 Dump this Expr to a JSON-serializable dict. 526 """ 527 from sqlglot.serde import dump 528 529 return dump(self) 530 531 @classmethod 532 def load(cls, obj: list[dict[str, Any]] | None) -> Expr: 533 """ 534 Load a dict (as returned by `Expr.dump`) into an Expr instance. 535 """ 536 from sqlglot.serde import load 537 538 result = load(obj) 539 assert isinstance(result, Expr) 540 return result 541 542 def and_( 543 self, 544 *expressions: ExpOrStr | None, 545 dialect: DialectType = None, 546 copy: bool = True, 547 wrap: bool = True, 548 **opts: Unpack[ParserNoDialectArgs], 549 ) -> Condition: 550 """ 551 AND this condition with one or multiple expressions. 552 553 Example: 554 >>> condition("x=1").and_("y=1").sql() 555 'x = 1 AND y = 1' 556 557 Args: 558 *expressions: the SQL code strings to parse. 559 If an `Expr` instance is passed, it will be used as-is. 560 dialect: the dialect used to parse the input expression. 561 copy: whether to copy the involved expressions (only applies to Exprs). 562 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 563 precedence issues, but can be turned off when the produced AST is too deep and 564 causes recursion-related issues. 565 opts: other options to use to parse the input expressions. 566 567 Returns: 568 The new And condition. 569 """ 570 raise NotImplementedError 571 572 def or_( 573 self, 574 *expressions: ExpOrStr | None, 575 dialect: DialectType = None, 576 copy: bool = True, 577 wrap: bool = True, 578 **opts: Unpack[ParserNoDialectArgs], 579 ) -> Condition: 580 """ 581 OR this condition with one or multiple expressions. 582 583 Example: 584 >>> condition("x=1").or_("y=1").sql() 585 'x = 1 OR y = 1' 586 587 Args: 588 *expressions: the SQL code strings to parse. 589 If an `Expr` instance is passed, it will be used as-is. 590 dialect: the dialect used to parse the input expression. 591 copy: whether to copy the involved expressions (only applies to Exprs). 592 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 593 precedence issues, but can be turned off when the produced AST is too deep and 594 causes recursion-related issues. 595 opts: other options to use to parse the input expressions. 596 597 Returns: 598 The new Or condition. 599 """ 600 raise NotImplementedError 601 602 def not_(self, copy: bool = True) -> Not: 603 """ 604 Wrap this condition with NOT. 605 606 Example: 607 >>> condition("x=1").not_().sql() 608 'NOT x = 1' 609 610 Args: 611 copy: whether to copy this object. 612 613 Returns: 614 The new Not instance. 615 """ 616 raise NotImplementedError 617 618 def update_positions( 619 self: E, 620 other: Token | Expr | None = None, 621 line: int | None = None, 622 col: int | None = None, 623 start: int | None = None, 624 end: int | None = None, 625 ) -> E: 626 """ 627 Update this expression with positions from a token or other expression. 628 629 Args: 630 other: a token or expression to update this expression with. 631 line: the line number to use if other is None 632 col: column number 633 start: start char index 634 end: end char index 635 636 Returns: 637 The updated expression. 638 """ 639 raise NotImplementedError 640 641 def as_( 642 self, 643 alias: str | Identifier, 644 quoted: bool | None = None, 645 dialect: DialectType = None, 646 copy: bool = True, 647 table: bool | Sequence[str | Identifier] = False, 648 **opts: Unpack[ParserNoDialectArgs], 649 ) -> Expr: 650 raise NotImplementedError 651 652 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 653 raise NotImplementedError 654 655 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 656 raise NotImplementedError 657 658 def __iter__(self) -> Iterator: 659 raise NotImplementedError 660 661 def isin( 662 self, 663 *expressions: t.Any, 664 query: ExpOrStr | None = None, 665 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 666 dialect: DialectType = None, 667 copy: bool = True, 668 **opts: Unpack[ParserNoDialectArgs], 669 ) -> In: 670 raise NotImplementedError 671 672 def between( 673 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 674 ) -> Between: 675 raise NotImplementedError 676 677 def is_(self, other: ExpOrStr) -> Is: 678 raise NotImplementedError 679 680 def like(self, other: ExpOrStr) -> Like: 681 raise NotImplementedError 682 683 def ilike(self, other: ExpOrStr) -> ILike: 684 raise NotImplementedError 685 686 def eq(self, other: t.Any) -> EQ: 687 raise NotImplementedError 688 689 def neq(self, other: t.Any) -> NEQ: 690 raise NotImplementedError 691 692 def rlike(self, other: ExpOrStr) -> RegexpLike: 693 raise NotImplementedError 694 695 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 696 raise NotImplementedError 697 698 def asc(self, nulls_first: bool = True) -> Ordered: 699 raise NotImplementedError 700 701 def desc(self, nulls_first: bool = False) -> Ordered: 702 raise NotImplementedError 703 704 def __lt__(self, other: t.Any) -> LT: 705 raise NotImplementedError 706 707 def __le__(self, other: t.Any) -> LTE: 708 raise NotImplementedError 709 710 def __gt__(self, other: t.Any) -> GT: 711 raise NotImplementedError 712 713 def __ge__(self, other: t.Any) -> GTE: 714 raise NotImplementedError 715 716 def __add__(self, other: t.Any) -> Add: 717 raise NotImplementedError 718 719 def __radd__(self, other: t.Any) -> Add: 720 raise NotImplementedError 721 722 def __sub__(self, other: t.Any) -> Sub: 723 raise NotImplementedError 724 725 def __rsub__(self, other: t.Any) -> Sub: 726 raise NotImplementedError 727 728 def __mul__(self, other: t.Any) -> Mul: 729 raise NotImplementedError 730 731 def __rmul__(self, other: t.Any) -> Mul: 732 raise NotImplementedError 733 734 def __truediv__(self, other: t.Any) -> Div: 735 raise NotImplementedError 736 737 def __rtruediv__(self, other: t.Any) -> Div: 738 raise NotImplementedError 739 740 def __floordiv__(self, other: t.Any) -> IntDiv: 741 raise NotImplementedError 742 743 def __rfloordiv__(self, other: t.Any) -> IntDiv: 744 raise NotImplementedError 745 746 def __mod__(self, other: t.Any) -> Mod: 747 raise NotImplementedError 748 749 def __rmod__(self, other: t.Any) -> Mod: 750 raise NotImplementedError 751 752 def __pow__(self, other: t.Any) -> Pow: 753 raise NotImplementedError 754 755 def __rpow__(self, other: t.Any) -> Pow: 756 raise NotImplementedError 757 758 def __and__(self, other: t.Any) -> And: 759 raise NotImplementedError 760 761 def __rand__(self, other: t.Any) -> And: 762 raise NotImplementedError 763 764 def __or__(self, other: t.Any) -> Or: 765 raise NotImplementedError 766 767 def __ror__(self, other: t.Any) -> Or: 768 raise NotImplementedError 769 770 def __neg__(self) -> Neg: 771 raise NotImplementedError 772 773 def __invert__(self) -> Not: 774 raise NotImplementedError 775 776 def pipe( 777 self, func: t.Callable[Concatenate[Self, P], R], *args: P.args, **kwargs: P.kwargs 778 ) -> R: 779 """Apply a function to `Self` (the current instance) and return the result. 780 781 Doing `expr.pipe(func, *args, **kwargs)` is equivalent to `func(expr, *args, **kwargs)`. 782 783 It allows you to chain operations in a fluent way on any given function that takes `Self` as its first argument. 784 785 Tip: 786 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 787 788 Args: 789 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 790 *args: Additional positional arguments to pass to `func` after `Self`. 791 **kwargs: Additional keyword arguments to pass to `func`. 792 793 Returns: 794 The result of applying `func` to `Self` with the given arguments. 795 """ 796 return func(self, *args, **kwargs) 797 798 def apply( 799 self, func: t.Callable[Concatenate[Self, P], t.Any], *args: P.args, **kwargs: P.kwargs 800 ) -> Self: 801 """Apply a function to `Self` (the current instance) for side effects, and return `Self`. 802 803 Useful for inspecting intermediate expressions in a method chain by simply adding/removing `apply` calls, especially when combined with `pipe`. 804 805 Tip: 806 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 807 808 Args: 809 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 810 *args: Additional positional arguments to pass to `func` after `Self`. 811 **kwargs: Additional keyword arguments to pass to `func`. 812 813 Returns: 814 The same instance. 815 """ 816 func(self, *args, **kwargs) 817 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)
128 @property 129 def this(self) -> t.Any: 130 """ 131 Retrieves the argument with key "this". 132 """ 133 raise NotImplementedError
Retrieves the argument with key "this".
135 @property 136 def expression(self) -> t.Any: 137 """ 138 Retrieves the argument with key "expression". 139 """ 140 raise NotImplementedError
Retrieves the argument with key "expression".
142 @property 143 def expressions(self) -> list[t.Any]: 144 """ 145 Retrieves the argument with key "expressions". 146 """ 147 raise NotImplementedError
Retrieves the argument with key "expressions".
149 def text(self, key: str) -> str: 150 """ 151 Returns a textual representation of the argument corresponding to "key". This can only be used 152 for args that are strings or leaf Expr instances, such as identifiers and literals. 153 """ 154 raise NotImplementedError
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.
156 @property 157 def is_string(self) -> bool: 158 """ 159 Checks whether a Literal expression is a string. 160 """ 161 raise NotImplementedError
Checks whether a Literal expression is a string.
163 @property 164 def is_number(self) -> bool: 165 """ 166 Checks whether a Literal expression is a number. 167 """ 168 raise NotImplementedError
Checks whether a Literal expression is a number.
170 def to_py(self) -> t.Any: 171 """ 172 Returns a Python object equivalent of the SQL node. 173 """ 174 raise NotImplementedError
Returns a Python object equivalent of the SQL node.
176 @property 177 def is_int(self) -> bool: 178 """ 179 Checks whether an expression is an integer. 180 """ 181 raise NotImplementedError
Checks whether an expression is an integer.
183 @property 184 def is_star(self) -> bool: 185 """Checks whether an expression is a star.""" 186 raise NotImplementedError
Checks whether an expression is a star.
188 @property 189 def alias(self) -> str: 190 """ 191 Returns the alias of the expression, or an empty string if it's not aliased. 192 """ 193 raise NotImplementedError
Returns the alias of the expression, or an empty string if it's not aliased.
207 @property 208 def output_name(self) -> str: 209 """ 210 Name of the output column if this expression is a selection. 211 212 If the Expr has no output name, an empty string is returned. 213 214 Example: 215 >>> from sqlglot import parse_one 216 >>> parse_one("SELECT a").expressions[0].output_name 217 'a' 218 >>> parse_one("SELECT b AS c").expressions[0].output_name 219 'c' 220 >>> parse_one("SELECT 1 + 2").expressions[0].output_name 221 '' 222 """ 223 raise NotImplementedError
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 ''
246 def copy(self: E) -> E: 247 """ 248 Returns a deep copy of the expression. 249 """ 250 raise NotImplementedError
Returns a deep copy of the expression.
258 def append(self, arg_key: str, value: t.Any) -> None: 259 """ 260 Appends value to arg_key if it's a list or sets it as a new list. 261 262 Args: 263 arg_key (str): name of the list expression arg 264 value (Any): value to append to the list 265 """ 266 raise NotImplementedError
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
268 def set( 269 self, 270 arg_key: str, 271 value: object, 272 index: int | None = None, 273 overwrite: bool = True, 274 ) -> None: 275 """ 276 Sets arg_key to value. 277 278 Args: 279 arg_key: name of the expression arg. 280 value: value to set the arg to. 281 index: if the arg is a list, this specifies what position to add the value in it. 282 overwrite: assuming an index is given, this determines whether to overwrite the 283 list entry instead of only inserting a new value (i.e., like list.insert). 284 """ 285 raise NotImplementedError
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).
290 @property 291 def depth(self) -> int: 292 """ 293 Returns the depth of this tree. 294 """ 295 raise NotImplementedError
Returns the depth of this tree.
297 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 298 """Yields the key and expression for all arguments, exploding list args.""" 299 raise NotImplementedError
Yields the key and expression for all arguments, exploding list args.
301 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 302 """ 303 Returns the first node in this tree which matches at least one of 304 the specified types. 305 306 Args: 307 expression_types: the expression type(s) to match. 308 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 309 310 Returns: 311 The node which matches the criteria or None if no such node was found. 312 """ 313 raise NotImplementedError
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.
315 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 316 """ 317 Returns a generator object which visits all nodes in this tree and only 318 yields those that match at least one of the specified expression types. 319 320 Args: 321 expression_types: the expression type(s) to match. 322 bfs: whether to search the AST using the BFS algorithm (DFS is used if false). 323 324 Returns: 325 The generator object. 326 """ 327 raise NotImplementedError
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.
329 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 330 """ 331 Returns a nearest parent matching expression_types. 332 333 Args: 334 expression_types: the expression type(s) to match. 335 336 Returns: 337 The parent node. 338 """ 339 raise NotImplementedError
Returns a nearest parent matching expression_types.
Arguments:
- expression_types: the expression type(s) to match.
Returns:
The parent node.
341 @property 342 def parent_select(self) -> Select | None: 343 """ 344 Returns the parent select statement. 345 """ 346 raise NotImplementedError
Returns the parent select statement.
348 @property 349 def same_parent(self) -> bool: 350 """Returns if the parent is the same class as itself.""" 351 raise NotImplementedError
Returns if the parent is the same class as itself.
353 def root(self) -> Expr: 354 """ 355 Returns the root expression of this tree. 356 """ 357 raise NotImplementedError
Returns the root expression of this tree.
359 def walk( 360 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 361 ) -> Iterator[Expr]: 362 """ 363 Returns a generator object which visits all nodes in this tree. 364 365 Args: 366 bfs: if set to True the BFS traversal order will be applied, 367 otherwise the DFS traversal will be used instead. 368 prune: callable that returns True if the generator should stop traversing 369 this branch of the tree. 370 371 Returns: 372 the generator object. 373 """ 374 raise NotImplementedError
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.
376 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 377 """ 378 Returns a generator object which visits all nodes in this tree in 379 the DFS (Depth-first) order. 380 381 Returns: 382 The generator object. 383 """ 384 raise NotImplementedError
Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.
Returns:
The generator object.
386 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 387 """ 388 Returns a generator object which visits all nodes in this tree in 389 the BFS (Breadth-first) order. 390 391 Returns: 392 The generator object. 393 """ 394 raise NotImplementedError
Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.
Returns:
The generator object.
396 def unnest(self) -> Expr: 397 """ 398 Returns the first non parenthesis child or self. 399 """ 400 raise NotImplementedError
Returns the first non parenthesis child or self.
402 def unalias(self) -> Expr: 403 """ 404 Returns the inner expression if this is an Alias. 405 """ 406 raise NotImplementedError
Returns the inner expression if this is an Alias.
408 def unnest_operands(self) -> tuple[Expr, ...]: 409 """ 410 Returns unnested operands as a tuple. 411 """ 412 raise NotImplementedError
Returns unnested operands as a tuple.
414 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 415 """ 416 Returns a generator which yields child nodes whose parents are the same class. 417 418 A AND B AND C -> [A, B, C] 419 """ 420 raise NotImplementedError
Returns a generator which yields child nodes whose parents are the same class.
A AND B AND C -> [A, B, C]
422 def to_s(self) -> str: 423 """ 424 Same as __repr__, but includes additional information which can be useful 425 for debugging, like empty or missing args and the AST nodes' object IDs. 426 """ 427 raise NotImplementedError
Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.
429 def sql( 430 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 431 ) -> str: 432 """ 433 Returns SQL string representation of this tree. 434 435 Args: 436 dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql"). 437 opts: other `sqlglot.generator.Generator` options. 438 439 Returns: 440 The SQL string. 441 """ 442 raise NotImplementedError
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.
444 def transform( 445 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 446 ) -> T: 447 """ 448 Visits all tree nodes (excluding already transformed ones) 449 and applies the given transformation function to each node. 450 451 Args: 452 fun: a function which takes a node as an argument and returns a 453 new transformed node or the same node without modifications. If the function 454 returns None, then the corresponding node will be removed from the syntax tree. 455 copy: if set to True a new tree instance is constructed, otherwise the tree is 456 modified in place. 457 458 Returns: 459 The transformed tree. 460 """ 461 raise NotImplementedError
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.
463 def replace(self, expression: T) -> T: 464 """ 465 Swap out this expression with a new expression. 466 467 For example:: 468 469 >>> import sqlglot 470 >>> tree = sqlglot.parse_one("SELECT x FROM tbl") 471 >>> tree.find(sqlglot.exp.Column).replace(sqlglot.exp.column("y")) 472 Column( 473 this=Identifier(this=y, quoted=False)) 474 >>> tree.sql() 475 'SELECT y FROM tbl' 476 477 Args: 478 expression (T): new node 479 480 Returns: 481 T: The new expression or expressions. 482 """ 483 raise NotImplementedError
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.
485 def pop(self: E) -> E: 486 """ 487 Remove this expression from its AST. 488 489 Returns: 490 The popped expression. 491 """ 492 raise NotImplementedError
Remove this expression from its AST.
Returns:
The popped expression.
494 def assert_is(self, type_: Type[E]) -> E: 495 """ 496 Assert that this `Expr` is an instance of `type_`. 497 498 If it is NOT an instance of `type_`, this raises an assertion error. 499 Otherwise, this returns this expression. 500 501 Examples: 502 This is useful for type security in chained expressions: 503 504 >>> import sqlglot 505 >>> sqlglot.parse_one("SELECT x from y").assert_is(sqlglot.exp.Select).select("z").sql() 506 'SELECT x, z FROM y' 507 """ 508 raise NotImplementedError
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'
510 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 511 """ 512 Checks if this expression is valid (e.g. all mandatory args are set). 513 514 Args: 515 args: a sequence of values that were used to instantiate a Func expression. This is used 516 to check that the provided arguments don't exceed the function argument limit. 517 518 Returns: 519 A list of error messages for all possible errors that were found. 520 """ 521 raise NotImplementedError
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.
523 def dump(self) -> list[dict[str, t.Any]]: 524 """ 525 Dump this Expr to a JSON-serializable dict. 526 """ 527 from sqlglot.serde import dump 528 529 return dump(self)
Dump this Expr to a JSON-serializable dict.
531 @classmethod 532 def load(cls, obj: list[dict[str, Any]] | None) -> Expr: 533 """ 534 Load a dict (as returned by `Expr.dump`) into an Expr instance. 535 """ 536 from sqlglot.serde import load 537 538 result = load(obj) 539 assert isinstance(result, Expr) 540 return result
Load a dict (as returned by Expr.dump) into an Expr instance.
542 def and_( 543 self, 544 *expressions: ExpOrStr | None, 545 dialect: DialectType = None, 546 copy: bool = True, 547 wrap: bool = True, 548 **opts: Unpack[ParserNoDialectArgs], 549 ) -> Condition: 550 """ 551 AND this condition with one or multiple expressions. 552 553 Example: 554 >>> condition("x=1").and_("y=1").sql() 555 'x = 1 AND y = 1' 556 557 Args: 558 *expressions: the SQL code strings to parse. 559 If an `Expr` instance is passed, it will be used as-is. 560 dialect: the dialect used to parse the input expression. 561 copy: whether to copy the involved expressions (only applies to Exprs). 562 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 563 precedence issues, but can be turned off when the produced AST is too deep and 564 causes recursion-related issues. 565 opts: other options to use to parse the input expressions. 566 567 Returns: 568 The new And condition. 569 """ 570 raise NotImplementedError
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.
572 def or_( 573 self, 574 *expressions: ExpOrStr | None, 575 dialect: DialectType = None, 576 copy: bool = True, 577 wrap: bool = True, 578 **opts: Unpack[ParserNoDialectArgs], 579 ) -> Condition: 580 """ 581 OR this condition with one or multiple expressions. 582 583 Example: 584 >>> condition("x=1").or_("y=1").sql() 585 'x = 1 OR y = 1' 586 587 Args: 588 *expressions: the SQL code strings to parse. 589 If an `Expr` instance is passed, it will be used as-is. 590 dialect: the dialect used to parse the input expression. 591 copy: whether to copy the involved expressions (only applies to Exprs). 592 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 593 precedence issues, but can be turned off when the produced AST is too deep and 594 causes recursion-related issues. 595 opts: other options to use to parse the input expressions. 596 597 Returns: 598 The new Or condition. 599 """ 600 raise NotImplementedError
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.
602 def not_(self, copy: bool = True) -> Not: 603 """ 604 Wrap this condition with NOT. 605 606 Example: 607 >>> condition("x=1").not_().sql() 608 'NOT x = 1' 609 610 Args: 611 copy: whether to copy this object. 612 613 Returns: 614 The new Not instance. 615 """ 616 raise NotImplementedError
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.
618 def update_positions( 619 self: E, 620 other: Token | Expr | None = None, 621 line: int | None = None, 622 col: int | None = None, 623 start: int | None = None, 624 end: int | None = None, 625 ) -> E: 626 """ 627 Update this expression with positions from a token or other expression. 628 629 Args: 630 other: a token or expression to update this expression with. 631 line: the line number to use if other is None 632 col: column number 633 start: start char index 634 end: end char index 635 636 Returns: 637 The updated expression. 638 """ 639 raise NotImplementedError
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.
776 def pipe( 777 self, func: t.Callable[Concatenate[Self, P], R], *args: P.args, **kwargs: P.kwargs 778 ) -> R: 779 """Apply a function to `Self` (the current instance) and return the result. 780 781 Doing `expr.pipe(func, *args, **kwargs)` is equivalent to `func(expr, *args, **kwargs)`. 782 783 It allows you to chain operations in a fluent way on any given function that takes `Self` as its first argument. 784 785 Tip: 786 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 787 788 Args: 789 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 790 *args: Additional positional arguments to pass to `func` after `Self`. 791 **kwargs: Additional keyword arguments to pass to `func`. 792 793 Returns: 794 The result of applying `func` to `Self` with the given arguments. 795 """ 796 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.
798 def apply( 799 self, func: t.Callable[Concatenate[Self, P], t.Any], *args: P.args, **kwargs: P.kwargs 800 ) -> Self: 801 """Apply a function to `Self` (the current instance) for side effects, and return `Self`. 802 803 Useful for inspecting intermediate expressions in a method chain by simply adding/removing `apply` calls, especially when combined with `pipe`. 804 805 Tip: 806 If `func` doesn't take `Self` as it's first argument, you can use a lambda to work around it. 807 808 Args: 809 func: The function to apply. It should take `Self` as its first argument, followed by any additional arguments specified in `*args` and `**kwargs`. 810 *args: Additional positional arguments to pass to `func` after `Self`. 811 **kwargs: Additional keyword arguments to pass to `func`. 812 813 Returns: 814 The same instance. 815 """ 816 func(self, *args, **kwargs) 817 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.
820class Expression(Expr): 821 __slots__ = ( 822 "args", 823 "parent", 824 "arg_key", 825 "index", 826 "comments", 827 "_type", 828 "_meta", 829 "_hash", 830 ) 831 832 def __eq__(self, other: object) -> bool: 833 return self is other or (type(self) is type(other) and hash(self) == hash(other)) 834 835 def __ne__(self, other: object) -> bool: 836 return not self.__eq__(other) 837 838 def __hash__(self) -> int: 839 if self._hash is None: 840 nodes: list[Expr] = [] 841 queue: deque[Expr] = deque() 842 queue.append(self) 843 844 while queue: 845 node = queue.popleft() 846 nodes.append(node) 847 848 for child in node.iter_expressions(): 849 if child._hash is None: 850 queue.append(child) 851 852 for node in reversed(nodes): 853 hash_ = hash(node.key) 854 855 if node._hash_raw_args: 856 for k, v in sorted(node.args.items()): 857 if v: 858 hash_ = hash((hash_, k, v)) 859 else: 860 for k, v in sorted(node.args.items()): 861 vt = type(v) 862 863 if vt is list: 864 for x in v: 865 if x is not None and x is not False: 866 hash_ = hash((hash_, k, x.lower() if type(x) is str else x)) 867 else: 868 hash_ = hash((hash_, k)) 869 elif v is not None and v is not False: 870 hash_ = hash((hash_, k, v.lower() if vt is str else v)) 871 872 node._hash = hash_ 873 assert self._hash 874 return self._hash 875 876 def __reduce__( 877 self, 878 ) -> tuple[ 879 t.Callable[[list[dict[str, t.Any]] | None], Expr | DType | None], 880 tuple[list[dict[str, t.Any]]], 881 ]: 882 from sqlglot.serde import dump, load 883 884 return (load, (dump(self),)) 885 886 @property 887 def this(self) -> t.Any: 888 return self.args.get("this") 889 890 @property 891 def expression(self) -> t.Any: 892 return self.args.get("expression") 893 894 @property 895 def expressions(self) -> list[t.Any]: 896 return self.args.get("expressions") or [] 897 898 def text(self, key: str) -> str: 899 field = self.args.get(key) 900 if isinstance(field, str): 901 return field 902 if isinstance(field, (Identifier, Literal, Var)): 903 return field.this 904 if isinstance(field, (Star, Null)): 905 return field.name 906 return "" 907 908 @property 909 def is_string(self) -> bool: 910 return isinstance(self, Literal) and self.args["is_string"] 911 912 @property 913 def is_number(self) -> bool: 914 return (isinstance(self, Literal) and not self.args["is_string"]) or ( 915 isinstance(self, Neg) and self.this.is_number 916 ) 917 918 def to_py(self) -> t.Any: 919 raise ValueError(f"{self} cannot be converted to a Python object.") 920 921 @property 922 def is_int(self) -> bool: 923 return self.is_number and isinstance(self.to_py(), int) 924 925 @property 926 def is_star(self) -> bool: 927 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star)) 928 929 @property 930 def alias(self) -> str: 931 alias = self.args.get("alias") 932 if isinstance(alias, Expression): 933 return alias.name 934 return self.text("alias") 935 936 @property 937 def alias_column_names(self) -> list[str]: 938 table_alias = self.args.get("alias") 939 if not table_alias: 940 return [] 941 return [c.name for c in table_alias.args.get("columns") or []] 942 943 @property 944 def name(self) -> str: 945 return self.text("this") 946 947 @property 948 def alias_or_name(self) -> str: 949 return self.alias or self.name 950 951 @property 952 def output_name(self) -> str: 953 return "" 954 955 @property 956 def type(self) -> DataType | None: 957 if self.is_cast: 958 return self._type or self.to # type: ignore[attr-defined] 959 return self._type 960 961 @type.setter 962 def type(self, dtype: DataType | DType | str | None) -> None: 963 if dtype and type(dtype).__name__ != "DataType": 964 from sqlglot.expressions.datatypes import DataType as _DataType 965 966 dtype = _DataType.build(dtype) 967 self._type = dtype # type: ignore[assignment] 968 969 def is_type(self, *dtypes: DATA_TYPE) -> bool: 970 t = self._type 971 return t is not None and t.is_type(*dtypes) 972 973 def is_leaf(self) -> bool: 974 return not any((isinstance(v, Expr) or type(v) is list) and v for v in self.args.values()) 975 976 @property 977 def meta(self) -> dict[str, t.Any]: 978 if self._meta is None: 979 self._meta = {} 980 return self._meta 981 982 def __deepcopy__(self, memo: t.Any) -> Expr: 983 root = self.__class__() 984 stack: list[tuple[Expr, Expr]] = [(self, root)] 985 986 while stack: 987 node, copy = stack.pop() 988 989 if node.comments is not None: 990 copy.comments = deepcopy(node.comments) 991 if node._type is not None: 992 copy._type = deepcopy(node._type) 993 if node._meta is not None: 994 copy._meta = deepcopy(node._meta) 995 if node._hash is not None: 996 copy._hash = node._hash 997 998 for k, vs in node.args.items(): 999 if isinstance(vs, Expr): 1000 stack.append((vs, vs.__class__())) 1001 copy.set(k, stack[-1][-1]) 1002 elif type(vs) is list: 1003 copy.args[k] = [] 1004 1005 for v in vs: 1006 if isinstance(v, Expr): 1007 stack.append((v, v.__class__())) 1008 copy.append(k, stack[-1][-1]) 1009 else: 1010 copy.append(k, v) 1011 else: 1012 copy.args[k] = vs 1013 1014 return root 1015 1016 def copy(self: E) -> E: 1017 return deepcopy(self) 1018 1019 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 1020 if self.comments is None: 1021 self.comments = [] 1022 1023 if comments: 1024 for comment in comments: 1025 _, *meta = comment.split(SQLGLOT_META) 1026 if meta: 1027 for kv in "".join(meta).split(","): 1028 k, *v = kv.split("=") 1029 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 1030 1031 if not prepend: 1032 self.comments.append(comment) 1033 1034 if prepend: 1035 self.comments = comments + self.comments 1036 1037 def pop_comments(self) -> list[str]: 1038 comments = self.comments or [] 1039 self.comments = None 1040 return comments 1041 1042 def append(self, arg_key: str, value: t.Any) -> None: 1043 if type(self.args.get(arg_key)) is not list: 1044 self.args[arg_key] = [] 1045 self._set_parent(arg_key, value) 1046 values = self.args[arg_key] 1047 if isinstance(value, Expr): 1048 value.index = len(values) 1049 values.append(value) 1050 1051 def set( 1052 self, 1053 arg_key: str, 1054 value: object, 1055 index: int | None = None, 1056 overwrite: bool = True, 1057 ) -> None: 1058 node: Expr | None = self 1059 1060 while node and node._hash is not None: 1061 node._hash = None 1062 node = node.parent 1063 1064 if index is not None: 1065 expressions = self.args.get(arg_key) or [] 1066 1067 if seq_get(expressions, index) is None: 1068 return 1069 1070 if value is None: 1071 expressions.pop(index) 1072 for v in expressions[index:]: 1073 v.index = v.index - 1 1074 return 1075 1076 if isinstance(value, list): 1077 expressions.pop(index) 1078 expressions[index:index] = value 1079 elif overwrite: 1080 expressions[index] = value 1081 else: 1082 expressions.insert(index, value) 1083 1084 value = expressions 1085 elif value is None: 1086 self.args.pop(arg_key, None) 1087 return 1088 1089 self.args[arg_key] = value 1090 self._set_parent(arg_key, value, index) 1091 1092 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 1093 if isinstance(value, Expr): 1094 value.parent = self 1095 value.arg_key = arg_key 1096 value.index = index 1097 elif isinstance(value, list): 1098 for i, v in enumerate(value): 1099 if isinstance(v, Expr): 1100 v.parent = self 1101 v.arg_key = arg_key 1102 v.index = i 1103 1104 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 1105 """Set multiples keyword arguments at once, using `.set()` method. 1106 1107 Args: 1108 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 1109 Returns: 1110 Self: The same `Expression` with the updated arguments. 1111 """ 1112 if kwargs: 1113 for k, v in kwargs.items(): 1114 self.set(k, v) 1115 return self 1116 1117 @property 1118 def depth(self) -> int: 1119 if self.parent: 1120 return self.parent.depth + 1 1121 return 0 1122 1123 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 1124 for vs in reversed(self.args.values()) if reverse else self.args.values(): 1125 if isinstance(vs, list): 1126 for v in reversed(vs) if reverse else vs: 1127 if isinstance(v, Expr): 1128 yield t.cast(E, v) 1129 elif isinstance(vs, Expr): 1130 yield t.cast(E, vs) 1131 1132 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 1133 return next(self.find_all(*expression_types, bfs=bfs), None) 1134 1135 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 1136 for expression in self.walk(bfs=bfs): 1137 if isinstance(expression, expression_types): 1138 yield expression 1139 1140 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 1141 ancestor = self.parent 1142 while ancestor and not isinstance(ancestor, expression_types): 1143 ancestor = ancestor.parent 1144 return ancestor # type: ignore[return-value] 1145 1146 @property 1147 def parent_select(self) -> Select | None: 1148 from sqlglot.expressions.query import Select as _Select 1149 1150 return self.find_ancestor(_Select) 1151 1152 @property 1153 def same_parent(self) -> bool: 1154 return type(self.parent) is self.__class__ 1155 1156 def root(self) -> Expr: 1157 expression: Expr = self 1158 while expression.parent: 1159 expression = expression.parent 1160 return expression 1161 1162 def walk( 1163 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 1164 ) -> Iterator[Expr]: 1165 if bfs: 1166 yield from self.bfs(prune=prune) 1167 else: 1168 yield from self.dfs(prune=prune) 1169 1170 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1171 stack = [self] 1172 1173 while stack: 1174 node = stack.pop() 1175 yield node 1176 if prune and prune(node): 1177 continue 1178 for v in node.iter_expressions(reverse=True): 1179 stack.append(v) 1180 1181 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1182 queue: deque[Expr] = deque() 1183 queue.append(self) 1184 1185 while queue: 1186 node = queue.popleft() 1187 yield node 1188 if prune and prune(node): 1189 continue 1190 for v in node.iter_expressions(): 1191 queue.append(v) 1192 1193 def unnest(self) -> Expr: 1194 expression = self 1195 while type(expression) is Paren: 1196 expression = expression.this 1197 return expression 1198 1199 def unalias(self) -> Expr: 1200 if isinstance(self, Alias): 1201 return self.this 1202 return self 1203 1204 def unnest_operands(self) -> tuple[Expr, ...]: 1205 return tuple(arg.unnest() for arg in self.iter_expressions()) 1206 1207 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1208 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1209 if type(node) is not self.__class__: 1210 yield node.unnest() if unnest and not node.is_subquery else node 1211 1212 def __str__(self) -> str: 1213 return self.sql() 1214 1215 def __repr__(self) -> str: 1216 return _to_s(self) 1217 1218 def to_s(self) -> str: 1219 return _to_s(self, verbose=True) 1220 1221 def sql( 1222 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1223 ) -> str: 1224 from sqlglot.dialects.dialect import Dialect 1225 1226 return Dialect.get_or_raise(dialect).generate(self, copy=copy, **opts) 1227 1228 def transform( 1229 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 1230 ) -> T: 1231 root: t.Any = None 1232 new_node: t.Any = None 1233 1234 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1235 parent, arg_key, index = node.parent, node.arg_key, node.index 1236 new_node = fun(node, *args, **kwargs) 1237 1238 if not root: 1239 root = new_node 1240 elif parent and arg_key and new_node is not node: 1241 parent.set(arg_key, new_node, index) 1242 1243 assert root 1244 return root 1245 1246 def replace(self, expression: T) -> T: 1247 parent = self.parent 1248 1249 if not parent or parent is expression: 1250 return expression 1251 1252 key = self.arg_key 1253 1254 if key: 1255 value = parent.args.get(key) 1256 1257 if type(expression) is list and isinstance(value, Expr): 1258 # We are trying to replace an Expr with a list, so it's assumed that 1259 # the intention was to really replace the parent of this expression. 1260 if value.parent: 1261 value.parent.replace(expression) 1262 else: 1263 parent.set(key, expression, self.index) 1264 1265 if expression is not self: 1266 self.parent = None 1267 self.arg_key = None 1268 self.index = None 1269 1270 return expression 1271 1272 def pop(self: E) -> E: 1273 self.replace(None) 1274 return self 1275 1276 def assert_is(self, type_: Type[E]) -> E: 1277 if not isinstance(self, type_): 1278 raise AssertionError(f"{self} is not {type_}.") 1279 return self 1280 1281 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1282 if UNITTEST: 1283 for k in self.args: 1284 if k not in self.arg_types: 1285 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1286 1287 errors: list[str] | None = None 1288 1289 for k in self.required_args: 1290 v = self.args.get(k) 1291 if v is None or (isinstance(v, list) and not v): 1292 if errors is None: 1293 errors = [] 1294 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1295 1296 if ( 1297 args 1298 and isinstance(self, Func) 1299 and len(args) > len(self.arg_types) 1300 and not self.is_var_len_args 1301 ): 1302 if errors is None: 1303 errors = [] 1304 errors.append( 1305 f"The number of provided arguments ({len(args)}) is greater than " 1306 f"the maximum number of supported arguments ({len(self.arg_types)})" 1307 ) 1308 1309 return errors or [] 1310 1311 def and_( 1312 self, 1313 *expressions: ExpOrStr | None, 1314 dialect: DialectType = None, 1315 copy: bool = True, 1316 wrap: bool = True, 1317 **opts: Unpack[ParserNoDialectArgs], 1318 ) -> Condition: 1319 return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1320 1321 def or_( 1322 self, 1323 *expressions: ExpOrStr | None, 1324 dialect: DialectType = None, 1325 copy: bool = True, 1326 wrap: bool = True, 1327 **opts: Unpack[ParserNoDialectArgs], 1328 ) -> Condition: 1329 return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1330 1331 def not_(self, copy: bool = True) -> Not: 1332 return not_(self, copy=copy) 1333 1334 def update_positions( 1335 self: E, 1336 other: Token | Expr | None = None, 1337 line: int | None = None, 1338 col: int | None = None, 1339 start: int | None = None, 1340 end: int | None = None, 1341 ) -> E: 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())
894 @property 895 def expressions(self) -> list[t.Any]: 896 return self.args.get("expressions") or []
Retrieves the argument with key "expressions".
898 def text(self, key: str) -> str: 899 field = self.args.get(key) 900 if isinstance(field, str): 901 return field 902 if isinstance(field, (Identifier, Literal, Var)): 903 return field.this 904 if isinstance(field, (Star, Null)): 905 return field.name 906 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.
908 @property 909 def is_string(self) -> bool: 910 return isinstance(self, Literal) and self.args["is_string"]
Checks whether a Literal expression is a string.
912 @property 913 def is_number(self) -> bool: 914 return (isinstance(self, Literal) and not self.args["is_string"]) or ( 915 isinstance(self, Neg) and self.this.is_number 916 )
Checks whether a Literal expression is a number.
918 def to_py(self) -> t.Any: 919 raise ValueError(f"{self} cannot be converted to a Python object.")
Returns a Python object equivalent of the SQL node.
921 @property 922 def is_int(self) -> bool: 923 return self.is_number and isinstance(self.to_py(), int)
Checks whether an expression is an integer.
925 @property 926 def is_star(self) -> bool: 927 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
Checks whether an expression is a star.
929 @property 930 def alias(self) -> str: 931 alias = self.args.get("alias") 932 if isinstance(alias, Expression): 933 return alias.name 934 return self.text("alias")
Returns the alias of the expression, or an empty string if it's not aliased.
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 ''
1019 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 1020 if self.comments is None: 1021 self.comments = [] 1022 1023 if comments: 1024 for comment in comments: 1025 _, *meta = comment.split(SQLGLOT_META) 1026 if meta: 1027 for kv in "".join(meta).split(","): 1028 k, *v = kv.split("=") 1029 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 1030 1031 if not prepend: 1032 self.comments.append(comment) 1033 1034 if prepend: 1035 self.comments = comments + self.comments
1042 def append(self, arg_key: str, value: t.Any) -> None: 1043 if type(self.args.get(arg_key)) is not list: 1044 self.args[arg_key] = [] 1045 self._set_parent(arg_key, value) 1046 values = self.args[arg_key] 1047 if isinstance(value, Expr): 1048 value.index = len(values) 1049 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
1051 def set( 1052 self, 1053 arg_key: str, 1054 value: object, 1055 index: int | None = None, 1056 overwrite: bool = True, 1057 ) -> None: 1058 node: Expr | None = self 1059 1060 while node and node._hash is not None: 1061 node._hash = None 1062 node = node.parent 1063 1064 if index is not None: 1065 expressions = self.args.get(arg_key) or [] 1066 1067 if seq_get(expressions, index) is None: 1068 return 1069 1070 if value is None: 1071 expressions.pop(index) 1072 for v in expressions[index:]: 1073 v.index = v.index - 1 1074 return 1075 1076 if isinstance(value, list): 1077 expressions.pop(index) 1078 expressions[index:index] = value 1079 elif overwrite: 1080 expressions[index] = value 1081 else: 1082 expressions.insert(index, value) 1083 1084 value = expressions 1085 elif value is None: 1086 self.args.pop(arg_key, None) 1087 return 1088 1089 self.args[arg_key] = value 1090 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).
1104 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 1105 """Set multiples keyword arguments at once, using `.set()` method. 1106 1107 Args: 1108 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 1109 Returns: 1110 Self: The same `Expression` with the updated arguments. 1111 """ 1112 if kwargs: 1113 for k, v in kwargs.items(): 1114 self.set(k, v) 1115 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.
1117 @property 1118 def depth(self) -> int: 1119 if self.parent: 1120 return self.parent.depth + 1 1121 return 0
Returns the depth of this tree.
1123 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 1124 for vs in reversed(self.args.values()) if reverse else self.args.values(): 1125 if isinstance(vs, list): 1126 for v in reversed(vs) if reverse else vs: 1127 if isinstance(v, Expr): 1128 yield t.cast(E, v) 1129 elif isinstance(vs, Expr): 1130 yield t.cast(E, vs)
Yields the key and expression for all arguments, exploding list args.
1132 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 1133 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.
1135 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 1136 for expression in self.walk(bfs=bfs): 1137 if isinstance(expression, expression_types): 1138 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.
1140 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 1141 ancestor = self.parent 1142 while ancestor and not isinstance(ancestor, expression_types): 1143 ancestor = ancestor.parent 1144 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.
1146 @property 1147 def parent_select(self) -> Select | None: 1148 from sqlglot.expressions.query import Select as _Select 1149 1150 return self.find_ancestor(_Select)
Returns the parent select statement.
1156 def root(self) -> Expr: 1157 expression: Expr = self 1158 while expression.parent: 1159 expression = expression.parent 1160 return expression
Returns the root expression of this tree.
1162 def walk( 1163 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 1164 ) -> Iterator[Expr]: 1165 if bfs: 1166 yield from self.bfs(prune=prune) 1167 else: 1168 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.
1170 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1171 stack = [self] 1172 1173 while stack: 1174 node = stack.pop() 1175 yield node 1176 if prune and prune(node): 1177 continue 1178 for v in node.iter_expressions(reverse=True): 1179 stack.append(v)
Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.
Returns:
The generator object.
1181 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1182 queue: deque[Expr] = deque() 1183 queue.append(self) 1184 1185 while queue: 1186 node = queue.popleft() 1187 yield node 1188 if prune and prune(node): 1189 continue 1190 for v in node.iter_expressions(): 1191 queue.append(v)
Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.
Returns:
The generator object.
1193 def unnest(self) -> Expr: 1194 expression = self 1195 while type(expression) is Paren: 1196 expression = expression.this 1197 return expression
Returns the first non parenthesis child or self.
1199 def unalias(self) -> Expr: 1200 if isinstance(self, Alias): 1201 return self.this 1202 return self
Returns the inner expression if this is an Alias.
1204 def unnest_operands(self) -> tuple[Expr, ...]: 1205 return tuple(arg.unnest() for arg in self.iter_expressions())
Returns unnested operands as a tuple.
1207 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1208 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1209 if type(node) is not self.__class__: 1210 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]
Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.
1221 def sql( 1222 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1223 ) -> str: 1224 from sqlglot.dialects.dialect import Dialect 1225 1226 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.
1228 def transform( 1229 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 1230 ) -> T: 1231 root: t.Any = None 1232 new_node: t.Any = None 1233 1234 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1235 parent, arg_key, index = node.parent, node.arg_key, node.index 1236 new_node = fun(node, *args, **kwargs) 1237 1238 if not root: 1239 root = new_node 1240 elif parent and arg_key and new_node is not node: 1241 parent.set(arg_key, new_node, index) 1242 1243 assert root 1244 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.
1246 def replace(self, expression: T) -> T: 1247 parent = self.parent 1248 1249 if not parent or parent is expression: 1250 return expression 1251 1252 key = self.arg_key 1253 1254 if key: 1255 value = parent.args.get(key) 1256 1257 if type(expression) is list and isinstance(value, Expr): 1258 # We are trying to replace an Expr with a list, so it's assumed that 1259 # the intention was to really replace the parent of this expression. 1260 if value.parent: 1261 value.parent.replace(expression) 1262 else: 1263 parent.set(key, expression, self.index) 1264 1265 if expression is not self: 1266 self.parent = None 1267 self.arg_key = None 1268 self.index = None 1269 1270 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.
1276 def assert_is(self, type_: Type[E]) -> E: 1277 if not isinstance(self, type_): 1278 raise AssertionError(f"{self} is not {type_}.") 1279 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'
1281 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1282 if UNITTEST: 1283 for k in self.args: 1284 if k not in self.arg_types: 1285 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1286 1287 errors: list[str] | None = None 1288 1289 for k in self.required_args: 1290 v = self.args.get(k) 1291 if v is None or (isinstance(v, list) and not v): 1292 if errors is None: 1293 errors = [] 1294 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1295 1296 if ( 1297 args 1298 and isinstance(self, Func) 1299 and len(args) > len(self.arg_types) 1300 and not self.is_var_len_args 1301 ): 1302 if errors is None: 1303 errors = [] 1304 errors.append( 1305 f"The number of provided arguments ({len(args)}) is greater than " 1306 f"the maximum number of supported arguments ({len(self.arg_types)})" 1307 ) 1308 1309 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.
1311 def and_( 1312 self, 1313 *expressions: ExpOrStr | None, 1314 dialect: DialectType = None, 1315 copy: bool = True, 1316 wrap: bool = True, 1317 **opts: Unpack[ParserNoDialectArgs], 1318 ) -> Condition: 1319 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.
1321 def or_( 1322 self, 1323 *expressions: ExpOrStr | None, 1324 dialect: DialectType = None, 1325 copy: bool = True, 1326 wrap: bool = True, 1327 **opts: Unpack[ParserNoDialectArgs], 1328 ) -> Condition: 1329 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.
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.
1334 def update_positions( 1335 self: E, 1336 other: Token | Expr | None = None, 1337 line: int | None = None, 1338 col: int | None = None, 1339 start: int | None = None, 1340 end: int | None = None, 1341 ) -> E: 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
2138class ILike(Expression, Binary, Predicate): 2139 arg_types = {"this": True, "expression": True, "negate": 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
2150class Like(Expression, Binary, Predicate): 2151 arg_types = {"this": True, "expression": True, "negate": 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
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.