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