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 builtins import type as Type 14from collections import deque 15from collections.abc import Collection, Iterator, Mapping, MutableMapping, Sequence 16from copy import deepcopy 17from decimal import Decimal 18from functools import reduce 19 20from sqlglot._typing import E, GeneratorNoDialectArgs, ParserNoDialectArgs, T 21from sqlglot.errors import ParseError 22from sqlglot.helper import ( 23 camel_to_snake_case, 24 ensure_list, 25 seq_get, 26 to_bool, 27 trait, 28) 29from sqlglot.tokenizer_core import Token 30 31if t.TYPE_CHECKING: 32 from typing_extensions import Concatenate, Self, Unpack 33 34 from sqlglot._typing import P 35 from sqlglot.dialects.dialect import DialectType 36 from sqlglot.expressions.datatypes import DATA_TYPE, DataType, DType, Interval 37 from sqlglot.expressions.query import Select 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 = { 1793 "this": True, 1794 "quoted": False, 1795 "global_": False, 1796 "temporary": False, 1797 } 1798 is_primitive = True 1799 _hash_raw_args = True 1800 1801 @property 1802 def quoted(self) -> bool: 1803 return bool(self.args.get("quoted")) 1804 1805 @property 1806 def output_name(self) -> str: 1807 return self.name 1808 1809 1810# https://docs.snowflake.com/en/sql-reference/identifier-literal 1811# "expressions" holds the arguments when the resolved identifier is invoked as a 1812# function, e.g. `IDENTIFIER('my_func')(1, 2)` 1813class DynamicIdentifier(Expression, Func): 1814 arg_types = {"this": True, "expressions": False} 1815 1816 1817class Opclass(Expression): 1818 arg_types = {"this": True, "expression": True} 1819 1820 1821class Star(Expression): 1822 arg_types = {"except_": False, "replace": False, "rename": False, "ilike": False} 1823 1824 @property 1825 def name(self) -> str: 1826 return "*" 1827 1828 @property 1829 def output_name(self) -> str: 1830 return self.name 1831 1832 1833class Parameter(Expression, Condition): 1834 arg_types = {"this": True, "expression": False} 1835 1836 1837class SessionParameter(Expression, Condition): 1838 arg_types = {"this": True, "kind": False} 1839 1840 1841class Placeholder(Expression, Condition): 1842 arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False} 1843 1844 @property 1845 def name(self) -> str: 1846 return self.text("this") or "?" 1847 1848 1849class Null(Expression, Condition): 1850 arg_types = {} 1851 1852 @property 1853 def name(self) -> str: 1854 return "NULL" 1855 1856 def to_py(self) -> t.Literal[None]: 1857 return None 1858 1859 1860class Boolean(Expression, Condition): 1861 is_primitive = True 1862 1863 def to_py(self) -> bool: 1864 return self.this 1865 1866 1867class Dot(Expression, Binary): 1868 @property 1869 def is_star(self) -> bool: 1870 return self.expression.is_star 1871 1872 @property 1873 def name(self) -> str: 1874 return self.expression.name 1875 1876 @property 1877 def output_name(self) -> str: 1878 return self.name 1879 1880 @classmethod 1881 def build(cls, expressions: Sequence[Expr]) -> Dot: 1882 """Build a Dot object with a sequence of expressions.""" 1883 if len(expressions) < 2: 1884 raise ValueError("Dot requires >= 2 expressions.") 1885 1886 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) 1887 1888 @property 1889 def parts(self) -> list[Expr]: 1890 """Return the parts of a table / column in order catalog, db, table.""" 1891 this, *parts = self.flatten() 1892 1893 parts.reverse() 1894 1895 for arg in COLUMN_PARTS: 1896 part = this.args.get(arg) 1897 1898 if isinstance(part, Expr): 1899 parts.append(part) 1900 1901 parts.reverse() 1902 return parts 1903 1904 1905class Kwarg(Expression, Binary): 1906 """Kwarg in special functions like func(kwarg => y).""" 1907 1908 1909class Alias(Expression): 1910 arg_types = {"this": True, "alias": False} 1911 1912 @property 1913 def output_name(self) -> str: 1914 return self.alias 1915 1916 1917class PivotAlias(Alias): 1918 pass 1919 1920 1921class PivotAny(Expression): 1922 arg_types = {"this": False} 1923 1924 1925class Aliases(Expression): 1926 arg_types = {"this": True, "expressions": True} 1927 1928 @property 1929 def aliases(self) -> list[Expr]: 1930 return self.expressions 1931 1932 1933class Bracket(Expression, Condition): 1934 # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator 1935 arg_types = { 1936 "this": True, 1937 "expressions": True, 1938 "offset": False, 1939 "safe": False, 1940 "returns_list_for_maps": False, 1941 "json_access": False, 1942 } 1943 1944 @property 1945 def output_name(self) -> str: 1946 if len(self.expressions) == 1: 1947 return self.expressions[0].output_name 1948 1949 return super().output_name 1950 1951 1952class ForIn(Expression): 1953 arg_types = {"this": True, "expression": True} 1954 1955 1956class IgnoreNulls(Expression): 1957 pass 1958 1959 1960class RespectNulls(Expression): 1961 pass 1962 1963 1964class HavingMax(Expression): 1965 arg_types = {"this": True, "expression": True, "max": True} 1966 1967 1968class SafeFunc(Expression, Func): 1969 pass 1970 1971 1972class Typeof(Expression, Func): 1973 pass 1974 1975 1976class ParameterizedAgg(Expression, AggFunc): 1977 arg_types = {"this": True, "expressions": True, "params": True} 1978 1979 1980class Anonymous(Expression, Func): 1981 arg_types = {"this": True, "expressions": False} 1982 is_var_len_args = True 1983 1984 @property 1985 def name(self) -> str: 1986 return self.this if isinstance(self.this, str) else self.this.name 1987 1988 1989class AnonymousAggFunc(Expression, AggFunc): 1990 arg_types = {"this": True, "expressions": False} 1991 is_var_len_args = True 1992 1993 1994class CombinedAggFunc(AnonymousAggFunc): 1995 arg_types = {"this": True, "expressions": False} 1996 1997 1998class CombinedParameterizedAgg(ParameterizedAgg): 1999 arg_types = {"this": True, "expressions": True, "params": True} 2000 2001 2002class HashAgg(Expression, AggFunc): 2003 arg_types = {"this": True, "expressions": False} 2004 is_var_len_args = True 2005 2006 2007class Hll(Expression, AggFunc): 2008 arg_types = {"this": True, "expressions": False} 2009 is_var_len_args = True 2010 2011 2012class ApproxDistinct(Expression, AggFunc): 2013 arg_types = {"this": True, "accuracy": False} 2014 _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"] 2015 2016 2017class Slice(Expression): 2018 arg_types = {"this": False, "expression": False, "step": False} 2019 2020 2021@trait 2022class TimeUnit(Expr): 2023 """Automatically converts unit arg into a var.""" 2024 2025 UNABBREVIATED_UNIT_NAME: t.ClassVar[dict[str, str]] = { 2026 "D": "DAY", 2027 "H": "HOUR", 2028 "M": "MINUTE", 2029 "MS": "MILLISECOND", 2030 "NS": "NANOSECOND", 2031 "Q": "QUARTER", 2032 "S": "SECOND", 2033 "US": "MICROSECOND", 2034 "W": "WEEK", 2035 "Y": "YEAR", 2036 } 2037 2038 VAR_LIKE: t.ClassVar[tuple[Type[Expr], ...]] = (Column, Literal, Var) 2039 2040 def __init__(self, **args: object) -> None: 2041 super().__init__(**args) 2042 2043 unit = self.args.get("unit") 2044 if ( 2045 unit 2046 and type(unit) in TimeUnit.VAR_LIKE 2047 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2048 ): 2049 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2050 self.args["unit"] = unit 2051 self._set_parent("unit", unit) 2052 elif type(unit).__name__ == "Week": 2053 unit.set("this", Var(this=unit.this.name.upper())) # type: ignore[union-attr] 2054 2055 @property 2056 def unit(self) -> Expr | None: 2057 return self.args.get("unit") 2058 2059 2060class _TimeUnit(Expression, TimeUnit): 2061 """Automatically converts unit arg into a var.""" 2062 2063 arg_types = {"unit": False} 2064 2065 2066@trait 2067class IntervalOp(TimeUnit): 2068 def interval(self) -> Interval: 2069 from sqlglot.expressions.datatypes import Interval 2070 2071 expr = self.expression 2072 return Interval( 2073 this=expr.copy() if expr is not None else None, 2074 unit=self.unit.copy() if self.unit else None, 2075 ) 2076 2077 2078class Filter(Expression): 2079 arg_types = {"this": True, "expression": True} 2080 2081 2082class Check(Expression): 2083 pass 2084 2085 2086class Ordered(Expression): 2087 arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False} 2088 2089 @property 2090 def name(self) -> str: 2091 return self.this.name 2092 2093 2094class Add(Expression, Binary): 2095 pass 2096 2097 2098class BitwiseAnd(Expression, Binary): 2099 arg_types = {"this": True, "expression": True, "padside": False} 2100 2101 2102class BitwiseLeftShift(Expression, Binary): 2103 arg_types = {"this": True, "expression": True, "requires_int128": False} 2104 2105 2106class BitwiseOr(Expression, Binary): 2107 arg_types = {"this": True, "expression": True, "padside": False} 2108 2109 2110class BitwiseRightShift(Expression, Binary): 2111 arg_types = {"this": True, "expression": True, "requires_int128": False} 2112 2113 2114class BitwiseXor(Expression, Binary): 2115 arg_types = {"this": True, "expression": True, "padside": False} 2116 2117 2118class Div(Expression, Binary): 2119 arg_types = {"this": True, "expression": True, "typed": False, "safe": False} 2120 2121 2122class Overlaps(Expression, Binary): 2123 pass 2124 2125 2126class ExtendsLeft(Expression, Binary): 2127 pass 2128 2129 2130class ExtendsRight(Expression, Binary): 2131 pass 2132 2133 2134class DPipe(Expression, Binary): 2135 arg_types = {"this": True, "expression": True, "safe": False} 2136 2137 2138class EQ(Expression, Binary, Predicate): 2139 pass 2140 2141 2142class NullSafeEQ(Expression, Binary, Predicate): 2143 pass 2144 2145 2146class NullSafeNEQ(Expression, Binary, Predicate): 2147 pass 2148 2149 2150class PropertyEQ(Expression, Binary): 2151 pass 2152 2153 2154class Distance(Expression, Binary): 2155 pass 2156 2157 2158class DistanceNd(Expression, Binary): 2159 pass 2160 2161 2162class Escape(Expression, Binary): 2163 pass 2164 2165 2166class Glob(Expression, Binary, Predicate): 2167 pass 2168 2169 2170class GT(Expression, Binary, Predicate): 2171 pass 2172 2173 2174class GTE(Expression, Binary, Predicate): 2175 pass 2176 2177 2178class ILike(Expression, Binary, Predicate): 2179 arg_types = {"this": True, "expression": True, "negate": False} 2180 2181 2182class IntDiv(Expression, Binary): 2183 pass 2184 2185 2186class Is(Expression, Binary, Predicate): 2187 pass 2188 2189 2190class Like(Expression, Binary, Predicate): 2191 arg_types = {"this": True, "expression": True, "negate": False} 2192 2193 2194class Match(Expression, Binary, Predicate): 2195 pass 2196 2197 2198class LT(Expression, Binary, Predicate): 2199 pass 2200 2201 2202class LTE(Expression, Binary, Predicate): 2203 pass 2204 2205 2206class Mod(Expression, Binary): 2207 pass 2208 2209 2210class Mul(Expression, Binary): 2211 pass 2212 2213 2214class NEQ(Expression, Binary, Predicate): 2215 pass 2216 2217 2218class NestedJSONSelect(Expression, Binary): 2219 pass 2220 2221 2222class Operator(Expression, Binary): 2223 arg_types = {"this": True, "operator": True, "expression": True} 2224 2225 2226class SimilarTo(Expression, Binary, Predicate): 2227 pass 2228 2229 2230class Sub(Expression, Binary): 2231 pass 2232 2233 2234class Adjacent(Expression, Binary): 2235 pass 2236 2237 2238class Unary(Expression, Condition): 2239 pass 2240 2241 2242class BitwiseNot(Unary): 2243 pass 2244 2245 2246class Not(Unary): 2247 pass 2248 2249 2250class Paren(Unary): 2251 @property 2252 def output_name(self) -> str: 2253 return self.this.name 2254 2255 2256class Neg(Unary): 2257 def to_py(self) -> int | Decimal: 2258 if self.is_number: 2259 return self.this.to_py() * -1 2260 return super().to_py() 2261 2262 2263class AtIndex(Expression): 2264 arg_types = {"this": True, "expression": True} 2265 2266 2267class AtTimeZone(Expression): 2268 arg_types = {"this": True, "zone": True} 2269 2270 2271class FromTimeZone(Expression): 2272 arg_types = {"this": True, "zone": True} 2273 2274 2275class FormatPhrase(Expression): 2276 """Format override for a column in Teradata. 2277 Can be expanded to additional dialects as needed 2278 2279 https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT 2280 """ 2281 2282 arg_types = {"this": True, "format": True} 2283 2284 2285class Between(Expression, Predicate): 2286 arg_types = {"this": True, "low": True, "high": True, "symmetric": False} 2287 2288 2289class Distinct(Expression): 2290 arg_types = {"expressions": False, "on": False} 2291 2292 2293class In(Expression, Predicate): 2294 arg_types = { 2295 "this": True, 2296 "expressions": False, 2297 "query": False, 2298 "unnest": False, 2299 "field": False, 2300 "is_global": False, 2301 } 2302 2303 2304class And(Expression, Connector, Func): 2305 pass 2306 2307 2308class Or(Expression, Connector, Func): 2309 pass 2310 2311 2312class Xor(Expression, Connector, Func): 2313 arg_types = {"this": True, "expression": True, "round_input": False} 2314 2315 2316class Pow(Expression, Binary, Func): 2317 _sql_names = ["POWER", "POW"] 2318 2319 2320class RegexpLike(Expression, Binary, Func): 2321 arg_types = {"this": True, "expression": True, "flag": False, "full_match": False} 2322 2323 2324def not_( 2325 expression: ExpOrStr, 2326 dialect: DialectType = None, 2327 copy: bool = True, 2328 **opts: Unpack[ParserNoDialectArgs], 2329) -> Not: 2330 """ 2331 Wrap a condition with a NOT operator. 2332 2333 Example: 2334 >>> not_("this_suit='black'").sql() 2335 "NOT this_suit = 'black'" 2336 2337 Args: 2338 expression: the SQL code string to parse. 2339 If an Expr instance is passed, this is used as-is. 2340 dialect: the dialect used to parse the input expression. 2341 copy: whether to copy the expression or not. 2342 **opts: other options to use to parse the input expressions. 2343 2344 Returns: 2345 The new condition. 2346 """ 2347 this = condition( 2348 expression, 2349 dialect=dialect, 2350 copy=copy, 2351 **opts, 2352 ) 2353 return Not(this=_wrap(this, Connector)) 2354 2355 2356def _lazy_unnest(**kwargs: object) -> Expr: 2357 from sqlglot.expressions.array import Unnest 2358 2359 return Unnest(**kwargs) 2360 2361 2362def convert(value: t.Any, copy: bool = False) -> Expr: 2363 """Convert a python value into an expression object. 2364 2365 Raises an error if a conversion is not possible. 2366 2367 Args: 2368 value: A python object. 2369 copy: Whether to copy `value` (only applies to Exprs and collections). 2370 2371 Returns: 2372 The equivalent expression object. 2373 """ 2374 if isinstance(value, Expr): 2375 return maybe_copy(value, copy) 2376 if isinstance(value, str): 2377 return Literal.string(value) 2378 if isinstance(value, bool): 2379 return Boolean(this=value) 2380 if value is None or (isinstance(value, float) and math.isnan(value)): 2381 return Null() 2382 if isinstance(value, numbers.Number): 2383 return Literal.number(value) 2384 if isinstance(value, bytes): 2385 from sqlglot.expressions.query import HexString as _HexString 2386 2387 return _HexString(this=value.hex()) 2388 if isinstance(value, datetime.datetime): 2389 datetime_literal = Literal.string(value.isoformat(sep=" ")) 2390 2391 tz = None 2392 if value.tzinfo: 2393 # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles" 2394 # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot 2395 tz = Literal.string(str(value.tzinfo)) 2396 2397 from sqlglot.expressions.temporal import TimeStrToTime as _TimeStrToTime 2398 2399 return _TimeStrToTime(this=datetime_literal, zone=tz) 2400 if isinstance(value, datetime.date): 2401 date_literal = Literal.string(value.strftime("%Y-%m-%d")) 2402 from sqlglot.expressions.temporal import DateStrToDate as _DateStrToDate 2403 2404 return _DateStrToDate(this=date_literal) 2405 if isinstance(value, datetime.time): 2406 time_literal = Literal.string(value.isoformat()) 2407 from sqlglot.expressions.temporal import TsOrDsToTime as _TsOrDsToTime 2408 2409 return _TsOrDsToTime(this=time_literal) 2410 if isinstance(value, tuple): 2411 if hasattr(value, "_fields"): 2412 from sqlglot.expressions.array import Struct as _Struct 2413 2414 return _Struct( 2415 expressions=[ 2416 PropertyEQ( 2417 this=to_identifier(k), expression=convert(getattr(value, k), copy=copy) 2418 ) 2419 for k in value._fields 2420 ] 2421 ) 2422 from sqlglot.expressions.query import Tuple as _Tuple 2423 2424 return _Tuple(expressions=[convert(v, copy=copy) for v in value]) 2425 if isinstance(value, list): 2426 from sqlglot.expressions.array import Array as _Array 2427 2428 return _Array(expressions=[convert(v, copy=copy) for v in value]) 2429 if isinstance(value, dict): 2430 from sqlglot.expressions.array import Array as _Array 2431 from sqlglot.expressions.array import Map as _Map 2432 2433 return _Map( 2434 keys=_Array(expressions=[convert(k, copy=copy) for k in value]), 2435 values=_Array(expressions=[convert(v, copy=copy) for v in value.values()]), 2436 ) 2437 if hasattr(value, "__dict__"): 2438 from sqlglot.expressions.array import Struct as _Struct 2439 2440 return _Struct( 2441 expressions=[ 2442 PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy)) 2443 for k, v in value.__dict__.items() 2444 ] 2445 ) 2446 raise ValueError(f"Cannot convert {value}") 2447 2448 2449QUERY_MODIFIERS = { 2450 "match": False, 2451 "laterals": False, 2452 "joins": False, 2453 "connect": False, 2454 "pivots": False, 2455 "prewhere": False, 2456 "where": False, 2457 "group": False, 2458 "having": False, 2459 "qualify": False, 2460 "windows": False, 2461 "distribute": False, 2462 "sort": False, 2463 "cluster": False, 2464 "order": False, 2465 "limit": False, 2466 "offset": False, 2467 "locks": False, 2468 "sample": False, 2469 "settings": False, 2470 "format": False, 2471 "options": False, 2472 "for_": False, 2473} 2474 2475 2476TIMESTAMP_PARTS = { 2477 "year": False, 2478 "month": False, 2479 "day": False, 2480 "hour": False, 2481 "min": False, 2482 "sec": False, 2483 "nano": False, 2484} 2485 2486 2487@t.overload 2488def maybe_parse( 2489 sql_or_expression: int | str, 2490 *, 2491 into: Type[E], 2492 dialect: DialectType = None, 2493 prefix: str | None = None, 2494 copy: bool = False, 2495 **opts: Unpack[ParserNoDialectArgs], 2496) -> E: ... 2497 2498 2499@t.overload 2500def maybe_parse( 2501 sql_or_expression: int | str | E, 2502 *, 2503 into: IntoType | None = None, 2504 dialect: DialectType = None, 2505 prefix: str | None = None, 2506 copy: bool = False, 2507 **opts: Unpack[ParserNoDialectArgs], 2508) -> E: ... 2509 2510 2511def maybe_parse( 2512 sql_or_expression: ExpOrStr, 2513 *, 2514 into: IntoType | None = None, 2515 dialect: DialectType = None, 2516 prefix: str | None = None, 2517 copy: bool = False, 2518 **opts: Unpack[ParserNoDialectArgs], 2519) -> Expr: 2520 """Gracefully handle a possible string or expression. 2521 2522 Example: 2523 >>> maybe_parse("1") 2524 Literal(this=1, is_string=False) 2525 >>> maybe_parse(to_identifier("x")) 2526 Identifier(this=x, quoted=False) 2527 2528 Args: 2529 sql_or_expression: the SQL code string or an expression 2530 into: the SQLGlot Expr to parse into 2531 dialect: the dialect used to parse the input expressions (in the case that an 2532 input expression is a SQL string). 2533 prefix: a string to prefix the sql with before it gets parsed 2534 (automatically includes a space) 2535 copy: whether to copy the expression. 2536 **opts: other options to use to parse the input expressions (again, in the case 2537 that an input expression is a SQL string). 2538 2539 Returns: 2540 Expr: the parsed or given expression. 2541 """ 2542 if isinstance(sql_or_expression, Expr): 2543 if copy: 2544 return sql_or_expression.copy() 2545 return sql_or_expression 2546 2547 if sql_or_expression is None: 2548 raise ParseError("SQL cannot be None") 2549 2550 import sqlglot 2551 2552 sql = str(sql_or_expression) 2553 if prefix: 2554 sql = f"{prefix} {sql}" 2555 2556 return sqlglot.parse_one(sql, read=dialect, into=into, **opts) 2557 2558 2559@t.overload 2560def maybe_copy(instance: None, copy: bool = True) -> None: ... 2561 2562 2563@t.overload 2564def maybe_copy(instance: E, copy: bool = True) -> E: ... 2565 2566 2567def maybe_copy(instance, copy=True): 2568 return instance.copy() if copy and instance else instance 2569 2570 2571def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str: 2572 """Generate a textual representation of an Expr tree""" 2573 indent = "\n" + (" " * (level + 1)) 2574 delim = f",{indent}" 2575 2576 if isinstance(node, Expr): 2577 args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose} 2578 2579 if (node.type or verbose) and not node.is_data_type: 2580 args["_type"] = node.type 2581 if node.comments or verbose: 2582 args["_comments"] = node.comments 2583 2584 if verbose: 2585 args["_id"] = id(node) 2586 2587 # Inline leaves for a more compact representation 2588 if node.is_leaf(): 2589 indent = "" 2590 delim = ", " 2591 2592 repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted) 2593 items = delim.join( 2594 [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()] 2595 ) 2596 return f"{node.__class__.__name__}({indent}{items})" 2597 2598 if isinstance(node, list): 2599 items = delim.join(_to_s(i, verbose, level + 1) for i in node) 2600 items = f"{indent}{items}" if items else "" 2601 return f"[{items}]" 2602 2603 # We use the representation of the string to avoid stripping out important whitespace 2604 if repr_str and isinstance(node, str): 2605 node = repr(node) 2606 2607 # Indent multiline strings to match the current level 2608 return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines()) 2609 2610 2611def _is_wrong_expression(expression, into): 2612 return isinstance(expression, Expr) and not isinstance(expression, into) 2613 2614 2615def _apply_builder( 2616 expression: ExpOrStr, 2617 instance: E, 2618 arg: str, 2619 copy: bool = True, 2620 prefix: str | None = None, 2621 into: Type[Expr] | None = None, 2622 dialect: DialectType = None, 2623 into_arg="this", 2624 **opts: Unpack[ParserNoDialectArgs], 2625) -> E: 2626 if _is_wrong_expression(expression, into) and into is not None: 2627 expression = into(**{into_arg: expression}) 2628 instance = maybe_copy(instance, copy) 2629 expression = maybe_parse( 2630 sql_or_expression=expression, 2631 prefix=prefix, 2632 into=into, 2633 dialect=dialect, 2634 **opts, 2635 ) 2636 instance.set(arg, expression) 2637 return instance 2638 2639 2640def _apply_child_list_builder( 2641 *expressions: ExpOrStr | None, 2642 instance: E, 2643 arg: str, 2644 append: bool = True, 2645 copy: bool = True, 2646 prefix: str | None = None, 2647 into: Type[Expr] | None = None, 2648 dialect: DialectType = None, 2649 properties: MutableMapping[str, object] | None = None, 2650 **opts: Unpack[ParserNoDialectArgs], 2651) -> E: 2652 instance = maybe_copy(instance, copy) 2653 parsed = [] 2654 properties = {} if properties is None else properties 2655 2656 for expression in expressions: 2657 if expression is not None: 2658 if _is_wrong_expression(expression, into) and into is not None: 2659 expression = into(expressions=[expression]) 2660 2661 expression = maybe_parse( 2662 expression, 2663 into=into, 2664 dialect=dialect, 2665 prefix=prefix, 2666 **opts, 2667 ) 2668 for k, v in expression.args.items(): 2669 if k == "expressions": 2670 parsed.extend(v) 2671 else: 2672 properties[k] = v 2673 2674 existing = instance.args.get(arg) 2675 if append and existing: 2676 parsed = existing.expressions + parsed 2677 if into is None: 2678 raise ValueError("`into` is required to use `_apply_child_list_builder`") 2679 child = into(expressions=parsed) 2680 for k, v in properties.items(): 2681 child.set(k, v) 2682 instance.set(arg, child) 2683 2684 return instance 2685 2686 2687def _apply_list_builder( 2688 *expressions: ExpOrStr | None, 2689 instance: E, 2690 arg: str, 2691 append: bool = True, 2692 copy: bool = True, 2693 prefix: str | None = None, 2694 into: Type[Expr] | None = None, 2695 dialect: DialectType = None, 2696 **opts: Unpack[ParserNoDialectArgs], 2697) -> E: 2698 inst = maybe_copy(instance, copy) 2699 2700 parsed = [ 2701 maybe_parse( 2702 sql_or_expression=expression, 2703 into=into, 2704 prefix=prefix, 2705 dialect=dialect, 2706 **opts, 2707 ) 2708 for expression in expressions 2709 if expression is not None 2710 ] 2711 2712 existing_expressions = inst.args.get(arg) 2713 if append and existing_expressions: 2714 parsed = existing_expressions + parsed 2715 2716 inst.set(arg, parsed) 2717 return inst 2718 2719 2720def _apply_conjunction_builder( 2721 *expressions: ExpOrStr | None, 2722 instance: E, 2723 arg: str, 2724 into: Type[Expr] | None = None, 2725 append: bool = True, 2726 copy: bool = True, 2727 dialect: DialectType = None, 2728 **opts: Unpack[ParserNoDialectArgs], 2729) -> E: 2730 filtered = [exp for exp in expressions if exp is not None and exp != ""] 2731 if not filtered: 2732 return instance 2733 2734 inst = maybe_copy(instance, copy) 2735 2736 existing = inst.args.get(arg) 2737 if append and existing is not None: 2738 filtered = [existing.this if into else existing] + filtered 2739 2740 node = and_(*filtered, dialect=dialect, copy=copy, **opts) 2741 2742 inst.set(arg, into(this=node) if into else node) 2743 return inst 2744 2745 2746def _combine( 2747 expressions: Sequence[ExpOrStr | None], 2748 operator: Type[Expr], 2749 dialect: DialectType = None, 2750 copy: bool = True, 2751 wrap: bool = True, 2752 **opts: Unpack[ParserNoDialectArgs], 2753) -> Expr: 2754 conditions = [ 2755 condition(expression, dialect=dialect, copy=copy, **opts) 2756 for expression in expressions 2757 if expression is not None 2758 ] 2759 2760 this, *rest = conditions 2761 if rest and wrap: 2762 this = _wrap(this, Connector) 2763 for expression in rest: 2764 this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression) 2765 2766 return this 2767 2768 2769@t.overload 2770def _wrap(expression: None, kind: Type[Expr]) -> None: ... 2771 2772 2773@t.overload 2774def _wrap(expression: E, kind: Type[Expr]) -> E | Paren: ... 2775 2776 2777def _wrap(expression: E | None, kind: Type[Expr]) -> E | None | Paren: 2778 return Paren(this=expression) if isinstance(expression, kind) else expression 2779 2780 2781def _apply_set_operation( 2782 *expressions: ExpOrStr, 2783 set_operation: Type, 2784 distinct: bool = True, 2785 dialect: DialectType = None, 2786 copy: bool = True, 2787 **opts: Unpack[ParserNoDialectArgs], 2788) -> t.Any: 2789 return reduce( 2790 lambda x, y: set_operation(this=x, expression=y, distinct=distinct, **opts), 2791 (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions), 2792 ) 2793 2794 2795SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$") 2796 2797 2798@t.overload 2799def to_identifier(name: None, quoted: bool | None = None, copy: bool = True) -> None: ... 2800 2801 2802@t.overload 2803def to_identifier( 2804 name: int | str | Identifier, quoted: bool | None = None, copy: bool = True 2805) -> Identifier: ... 2806 2807 2808def to_identifier(name, quoted=None, copy=True): 2809 """Builds an identifier. 2810 2811 Args: 2812 name: The name to turn into an identifier. 2813 quoted: Whether to force quote the identifier. 2814 copy: Whether to copy name if it's an Identifier. 2815 2816 Returns: 2817 The identifier ast node. 2818 """ 2819 2820 if name is None: 2821 return None 2822 2823 if isinstance(name, Identifier): 2824 identifier = maybe_copy(name, copy) 2825 elif isinstance(name, str): 2826 identifier = Identifier( 2827 this=name, 2828 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, 2829 ) 2830 else: 2831 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") 2832 return identifier 2833 2834 2835def condition( 2836 expression: ExpOrStr, 2837 dialect: DialectType = None, 2838 copy: bool = True, 2839 **opts: Unpack[ParserNoDialectArgs], 2840) -> Expr: 2841 """ 2842 Initialize a logical condition expression. 2843 2844 Example: 2845 >>> condition("x=1").sql() 2846 'x = 1' 2847 2848 This is helpful for composing larger logical syntax trees: 2849 >>> where = condition("x=1") 2850 >>> where = where.and_("y=1") 2851 >>> where.sql() 2852 'x = 1 AND y = 1' 2853 2854 Args: 2855 *expression: the SQL code string to parse. 2856 If an Expr instance is passed, this is used as-is. 2857 dialect: the dialect used to parse the input expression (in the case that the 2858 input expression is a SQL string). 2859 copy: Whether to copy `expression` (only applies to expressions). 2860 **opts: other options to use to parse the input expressions (again, in the case 2861 that the input expression is a SQL string). 2862 2863 Returns: 2864 The new Condition instance 2865 """ 2866 return maybe_parse( 2867 expression, 2868 into=Condition, 2869 dialect=dialect, 2870 copy=copy, 2871 **opts, 2872 ) 2873 2874 2875def and_( 2876 *expressions: ExpOrStr | None, 2877 dialect: DialectType = None, 2878 copy: bool = True, 2879 wrap: bool = True, 2880 **opts: Unpack[ParserNoDialectArgs], 2881) -> Condition: 2882 """ 2883 Combine multiple conditions with an AND logical operator. 2884 2885 Example: 2886 >>> and_("x=1", and_("y=1", "z=1")).sql() 2887 'x = 1 AND (y = 1 AND z = 1)' 2888 2889 Args: 2890 *expressions: the SQL code strings to parse. 2891 If an Expr instance is passed, this is used as-is. 2892 dialect: the dialect used to parse the input expression. 2893 copy: whether to copy `expressions` (only applies to Exprs). 2894 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2895 precedence issues, but can be turned off when the produced AST is too deep and 2896 causes recursion-related issues. 2897 **opts: other options to use to parse the input expressions. 2898 2899 Returns: 2900 The new condition 2901 """ 2902 return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts)) 2903 2904 2905def or_( 2906 *expressions: ExpOrStr | None, 2907 dialect: DialectType = None, 2908 copy: bool = True, 2909 wrap: bool = True, 2910 **opts: Unpack[ParserNoDialectArgs], 2911) -> Condition: 2912 """ 2913 Combine multiple conditions with an OR logical operator. 2914 2915 Example: 2916 >>> or_("x=1", or_("y=1", "z=1")).sql() 2917 'x = 1 OR (y = 1 OR z = 1)' 2918 2919 Args: 2920 *expressions: the SQL code strings to parse. 2921 If an Expr instance is passed, this is used as-is. 2922 dialect: the dialect used to parse the input expression. 2923 copy: whether to copy `expressions` (only applies to Exprs). 2924 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2925 precedence issues, but can be turned off when the produced AST is too deep and 2926 causes recursion-related issues. 2927 **opts: other options to use to parse the input expressions. 2928 2929 Returns: 2930 The new condition 2931 """ 2932 return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts)) 2933 2934 2935def xor( 2936 *expressions: ExpOrStr | None, 2937 dialect: DialectType = None, 2938 copy: bool = True, 2939 wrap: bool = True, 2940 **opts: Unpack[ParserNoDialectArgs], 2941) -> Condition: 2942 """ 2943 Combine multiple conditions with an XOR logical operator. 2944 2945 Example: 2946 >>> xor("x=1", xor("y=1", "z=1")).sql() 2947 'x = 1 XOR (y = 1 XOR z = 1)' 2948 2949 Args: 2950 *expressions: the SQL code strings to parse. 2951 If an Expr instance is passed, this is used as-is. 2952 dialect: the dialect used to parse the input expression. 2953 copy: whether to copy `expressions` (only applies to Exprs). 2954 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2955 precedence issues, but can be turned off when the produced AST is too deep and 2956 causes recursion-related issues. 2957 **opts: other options to use to parse the input expressions. 2958 2959 Returns: 2960 The new condition 2961 """ 2962 return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts)) 2963 2964 2965def paren(expression: ExpOrStr, copy: bool = True) -> Paren: 2966 """ 2967 Wrap an expression in parentheses. 2968 2969 Example: 2970 >>> paren("5 + 3").sql() 2971 '(5 + 3)' 2972 2973 Args: 2974 expression: the SQL code string to parse. 2975 If an Expr instance is passed, this is used as-is. 2976 copy: whether to copy the expression or not. 2977 2978 Returns: 2979 The wrapped expression. 2980 """ 2981 return Paren(this=maybe_parse(expression, copy=copy)) 2982 2983 2984def alias_( 2985 expression: ExpOrStr, 2986 alias: str | Identifier | None, 2987 table: bool | Sequence[str | Identifier] = False, 2988 quoted: bool | None = None, 2989 dialect: DialectType = None, 2990 copy: bool = True, 2991 **opts: Unpack[ParserNoDialectArgs], 2992) -> Expr: 2993 """Create an Alias expression. 2994 2995 Example: 2996 >>> alias_('foo', 'bar').sql() 2997 'foo AS bar' 2998 2999 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() 3000 '(SELECT 1, 2) AS bar(a, b)' 3001 3002 Args: 3003 expression: the SQL code strings to parse. 3004 If an Expr instance is passed, this is used as-is. 3005 alias: the alias name to use. If the name has 3006 special characters it is quoted. 3007 table: Whether to create a table alias, can also be a list of columns. 3008 quoted: whether to quote the alias 3009 dialect: the dialect used to parse the input expression. 3010 copy: Whether to copy the expression. 3011 **opts: other options to use to parse the input expressions. 3012 3013 Returns: 3014 Alias: the aliased expression 3015 """ 3016 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) 3017 alias = to_identifier(alias, quoted=quoted) 3018 3019 if table: 3020 from sqlglot.expressions.query import TableAlias as _TableAlias 3021 3022 table_alias = _TableAlias(this=alias) 3023 exp.set("alias", table_alias) 3024 3025 if not isinstance(table, bool): 3026 for column in table: 3027 table_alias.append("columns", to_identifier(column, quoted=quoted)) 3028 3029 return exp 3030 3031 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in 3032 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node 3033 # for the complete Window expression. 3034 # 3035 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls 3036 3037 if "alias" in exp.arg_types and type(exp).__name__ != "Window": 3038 exp.set("alias", alias) 3039 return exp 3040 return Alias(this=exp, alias=alias) 3041 3042 3043@t.overload 3044def column( 3045 col: str | Identifier, 3046 table: str | Identifier | None = None, 3047 db: str | Identifier | None = None, 3048 catalog: str | Identifier | None = None, 3049 *, 3050 fields: Collection[str | Identifier], 3051 quoted: bool | None = None, 3052 copy: bool = True, 3053) -> Dot: 3054 pass 3055 3056 3057@t.overload 3058def column( 3059 col: str | Identifier | Star, 3060 table: str | Identifier | None = None, 3061 db: str | Identifier | None = None, 3062 catalog: str | Identifier | None = None, 3063 *, 3064 fields: t.Literal[None] = None, 3065 quoted: bool | None = None, 3066 copy: bool = True, 3067) -> Column: 3068 pass 3069 3070 3071def column( 3072 col, 3073 table=None, 3074 db=None, 3075 catalog=None, 3076 *, 3077 fields=None, 3078 quoted=None, 3079 copy: bool = True, 3080): 3081 """ 3082 Build a Column. 3083 3084 Args: 3085 col: Column name. 3086 table: Table name. 3087 db: Database name. 3088 catalog: Catalog name. 3089 fields: Additional fields using dots. 3090 quoted: Whether to force quotes on the column's identifiers. 3091 copy: Whether to copy identifiers if passed in. 3092 3093 Returns: 3094 The new Column instance. 3095 """ 3096 if not isinstance(col, Star): 3097 col = to_identifier(col, quoted=quoted, copy=copy) 3098 3099 this: Column | Dot = Column( 3100 this=col, 3101 table=to_identifier(table, quoted=quoted, copy=copy), 3102 db=to_identifier(db, quoted=quoted, copy=copy), 3103 catalog=to_identifier(catalog, quoted=quoted, copy=copy), 3104 ) 3105 3106 if fields: 3107 this = Dot.build( 3108 (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields)) 3109 ) 3110 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 = { 1794 "this": True, 1795 "quoted": False, 1796 "global_": False, 1797 "temporary": False, 1798 } 1799 is_primitive = True 1800 _hash_raw_args = True 1801 1802 @property 1803 def quoted(self) -> bool: 1804 return bool(self.args.get("quoted")) 1805 1806 @property 1807 def output_name(self) -> str: 1808 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
1814class DynamicIdentifier(Expression, Func): 1815 arg_types = {"this": True, "expressions": 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
1822class Star(Expression): 1823 arg_types = {"except_": False, "replace": False, "rename": False, "ilike": False} 1824 1825 @property 1826 def name(self) -> str: 1827 return "*" 1828 1829 @property 1830 def output_name(self) -> str: 1831 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
1842class Placeholder(Expression, Condition): 1843 arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False} 1844 1845 @property 1846 def name(self) -> str: 1847 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
1850class Null(Expression, Condition): 1851 arg_types = {} 1852 1853 @property 1854 def name(self) -> str: 1855 return "NULL" 1856 1857 def to_py(self) -> t.Literal[None]: 1858 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
1861class Boolean(Expression, Condition): 1862 is_primitive = True 1863 1864 def to_py(self) -> bool: 1865 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
1868class Dot(Expression, Binary): 1869 @property 1870 def is_star(self) -> bool: 1871 return self.expression.is_star 1872 1873 @property 1874 def name(self) -> str: 1875 return self.expression.name 1876 1877 @property 1878 def output_name(self) -> str: 1879 return self.name 1880 1881 @classmethod 1882 def build(cls, expressions: Sequence[Expr]) -> Dot: 1883 """Build a Dot object with a sequence of expressions.""" 1884 if len(expressions) < 2: 1885 raise ValueError("Dot requires >= 2 expressions.") 1886 1887 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) 1888 1889 @property 1890 def parts(self) -> list[Expr]: 1891 """Return the parts of a table / column in order catalog, db, table.""" 1892 this, *parts = self.flatten() 1893 1894 parts.reverse() 1895 1896 for arg in COLUMN_PARTS: 1897 part = this.args.get(arg) 1898 1899 if isinstance(part, Expr): 1900 parts.append(part) 1901 1902 parts.reverse() 1903 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 ''
1881 @classmethod 1882 def build(cls, expressions: Sequence[Expr]) -> Dot: 1883 """Build a Dot object with a sequence of expressions.""" 1884 if len(expressions) < 2: 1885 raise ValueError("Dot requires >= 2 expressions.") 1886 1887 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
Build a Dot object with a sequence of expressions.
1889 @property 1890 def parts(self) -> list[Expr]: 1891 """Return the parts of a table / column in order catalog, db, table.""" 1892 this, *parts = self.flatten() 1893 1894 parts.reverse() 1895 1896 for arg in COLUMN_PARTS: 1897 part = this.args.get(arg) 1898 1899 if isinstance(part, Expr): 1900 parts.append(part) 1901 1902 parts.reverse() 1903 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
1910class Alias(Expression): 1911 arg_types = {"this": True, "alias": False} 1912 1913 @property 1914 def output_name(self) -> str: 1915 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
1926class Aliases(Expression): 1927 arg_types = {"this": True, "expressions": True} 1928 1929 @property 1930 def aliases(self) -> list[Expr]: 1931 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
1934class Bracket(Expression, Condition): 1935 # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator 1936 arg_types = { 1937 "this": True, 1938 "expressions": True, 1939 "offset": False, 1940 "safe": False, 1941 "returns_list_for_maps": False, 1942 "json_access": False, 1943 } 1944 1945 @property 1946 def output_name(self) -> str: 1947 if len(self.expressions) == 1: 1948 return self.expressions[0].output_name 1949 1950 return super().output_name
1945 @property 1946 def output_name(self) -> str: 1947 if len(self.expressions) == 1: 1948 return self.expressions[0].output_name 1949 1950 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
1977class ParameterizedAgg(Expression, AggFunc): 1978 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
1981class Anonymous(Expression, Func): 1982 arg_types = {"this": True, "expressions": False} 1983 is_var_len_args = True 1984 1985 @property 1986 def name(self) -> str: 1987 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
1990class AnonymousAggFunc(Expression, AggFunc): 1991 arg_types = {"this": True, "expressions": False} 1992 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
1999class CombinedParameterizedAgg(ParameterizedAgg): 2000 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
2003class HashAgg(Expression, AggFunc): 2004 arg_types = {"this": True, "expressions": False} 2005 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
2008class Hll(Expression, AggFunc): 2009 arg_types = {"this": True, "expressions": False} 2010 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
2013class ApproxDistinct(Expression, AggFunc): 2014 arg_types = {"this": True, "accuracy": False} 2015 _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
2022@trait 2023class TimeUnit(Expr): 2024 """Automatically converts unit arg into a var.""" 2025 2026 UNABBREVIATED_UNIT_NAME: t.ClassVar[dict[str, str]] = { 2027 "D": "DAY", 2028 "H": "HOUR", 2029 "M": "MINUTE", 2030 "MS": "MILLISECOND", 2031 "NS": "NANOSECOND", 2032 "Q": "QUARTER", 2033 "S": "SECOND", 2034 "US": "MICROSECOND", 2035 "W": "WEEK", 2036 "Y": "YEAR", 2037 } 2038 2039 VAR_LIKE: t.ClassVar[tuple[Type[Expr], ...]] = (Column, Literal, Var) 2040 2041 def __init__(self, **args: object) -> None: 2042 super().__init__(**args) 2043 2044 unit = self.args.get("unit") 2045 if ( 2046 unit 2047 and type(unit) in TimeUnit.VAR_LIKE 2048 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2049 ): 2050 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2051 self.args["unit"] = unit 2052 self._set_parent("unit", unit) 2053 elif type(unit).__name__ == "Week": 2054 unit.set("this", Var(this=unit.this.name.upper())) # type: ignore[union-attr] 2055 2056 @property 2057 def unit(self) -> Expr | None: 2058 return self.args.get("unit")
Automatically converts unit arg into a var.
2041 def __init__(self, **args: object) -> None: 2042 super().__init__(**args) 2043 2044 unit = self.args.get("unit") 2045 if ( 2046 unit 2047 and type(unit) in TimeUnit.VAR_LIKE 2048 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2049 ): 2050 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2051 self.args["unit"] = unit 2052 self._set_parent("unit", unit) 2053 elif type(unit).__name__ == "Week": 2054 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
2067@trait 2068class IntervalOp(TimeUnit): 2069 def interval(self) -> Interval: 2070 from sqlglot.expressions.datatypes import Interval 2071 2072 expr = self.expression 2073 return Interval( 2074 this=expr.copy() if expr is not None else None, 2075 unit=self.unit.copy() if self.unit else None, 2076 )
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
2087class Ordered(Expression): 2088 arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False} 2089 2090 @property 2091 def name(self) -> str: 2092 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
2099class BitwiseAnd(Expression, Binary): 2100 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
2103class BitwiseLeftShift(Expression, Binary): 2104 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
2107class BitwiseOr(Expression, Binary): 2108 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
2111class BitwiseRightShift(Expression, Binary): 2112 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
2115class BitwiseXor(Expression, Binary): 2116 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
2119class Div(Expression, Binary): 2120 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
2135class DPipe(Expression, Binary): 2136 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
2179class ILike(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
2191class Like(Expression, Binary, Predicate): 2192 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
2223class Operator(Expression, Binary): 2224 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
2251class Paren(Unary): 2252 @property 2253 def output_name(self) -> str: 2254 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
2257class Neg(Unary): 2258 def to_py(self) -> int | Decimal: 2259 if self.is_number: 2260 return self.this.to_py() * -1 2261 return super().to_py()
2258 def to_py(self) -> int | Decimal: 2259 if self.is_number: 2260 return self.this.to_py() * -1 2261 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
2276class FormatPhrase(Expression): 2277 """Format override for a column in Teradata. 2278 Can be expanded to additional dialects as needed 2279 2280 https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT 2281 """ 2282 2283 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
2286class Between(Expression, Predicate): 2287 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
2294class In(Expression, Predicate): 2295 arg_types = { 2296 "this": True, 2297 "expressions": False, 2298 "query": False, 2299 "unnest": False, 2300 "field": False, 2301 "is_global": False, 2302 }
Inherited 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
2313class Xor(Expression, Connector, Func): 2314 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
2321class RegexpLike(Expression, Binary, Func): 2322 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
2325def not_( 2326 expression: ExpOrStr, 2327 dialect: DialectType = None, 2328 copy: bool = True, 2329 **opts: Unpack[ParserNoDialectArgs], 2330) -> Not: 2331 """ 2332 Wrap a condition with a NOT operator. 2333 2334 Example: 2335 >>> not_("this_suit='black'").sql() 2336 "NOT this_suit = 'black'" 2337 2338 Args: 2339 expression: the SQL code string to parse. 2340 If an Expr instance is passed, this is used as-is. 2341 dialect: the dialect used to parse the input expression. 2342 copy: whether to copy the expression or not. 2343 **opts: other options to use to parse the input expressions. 2344 2345 Returns: 2346 The new condition. 2347 """ 2348 this = condition( 2349 expression, 2350 dialect=dialect, 2351 copy=copy, 2352 **opts, 2353 ) 2354 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.
2363def convert(value: t.Any, copy: bool = False) -> Expr: 2364 """Convert a python value into an expression object. 2365 2366 Raises an error if a conversion is not possible. 2367 2368 Args: 2369 value: A python object. 2370 copy: Whether to copy `value` (only applies to Exprs and collections). 2371 2372 Returns: 2373 The equivalent expression object. 2374 """ 2375 if isinstance(value, Expr): 2376 return maybe_copy(value, copy) 2377 if isinstance(value, str): 2378 return Literal.string(value) 2379 if isinstance(value, bool): 2380 return Boolean(this=value) 2381 if value is None or (isinstance(value, float) and math.isnan(value)): 2382 return Null() 2383 if isinstance(value, numbers.Number): 2384 return Literal.number(value) 2385 if isinstance(value, bytes): 2386 from sqlglot.expressions.query import HexString as _HexString 2387 2388 return _HexString(this=value.hex()) 2389 if isinstance(value, datetime.datetime): 2390 datetime_literal = Literal.string(value.isoformat(sep=" ")) 2391 2392 tz = None 2393 if value.tzinfo: 2394 # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles" 2395 # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot 2396 tz = Literal.string(str(value.tzinfo)) 2397 2398 from sqlglot.expressions.temporal import TimeStrToTime as _TimeStrToTime 2399 2400 return _TimeStrToTime(this=datetime_literal, zone=tz) 2401 if isinstance(value, datetime.date): 2402 date_literal = Literal.string(value.strftime("%Y-%m-%d")) 2403 from sqlglot.expressions.temporal import DateStrToDate as _DateStrToDate 2404 2405 return _DateStrToDate(this=date_literal) 2406 if isinstance(value, datetime.time): 2407 time_literal = Literal.string(value.isoformat()) 2408 from sqlglot.expressions.temporal import TsOrDsToTime as _TsOrDsToTime 2409 2410 return _TsOrDsToTime(this=time_literal) 2411 if isinstance(value, tuple): 2412 if hasattr(value, "_fields"): 2413 from sqlglot.expressions.array import Struct as _Struct 2414 2415 return _Struct( 2416 expressions=[ 2417 PropertyEQ( 2418 this=to_identifier(k), expression=convert(getattr(value, k), copy=copy) 2419 ) 2420 for k in value._fields 2421 ] 2422 ) 2423 from sqlglot.expressions.query import Tuple as _Tuple 2424 2425 return _Tuple(expressions=[convert(v, copy=copy) for v in value]) 2426 if isinstance(value, list): 2427 from sqlglot.expressions.array import Array as _Array 2428 2429 return _Array(expressions=[convert(v, copy=copy) for v in value]) 2430 if isinstance(value, dict): 2431 from sqlglot.expressions.array import Array as _Array 2432 from sqlglot.expressions.array import Map as _Map 2433 2434 return _Map( 2435 keys=_Array(expressions=[convert(k, copy=copy) for k in value]), 2436 values=_Array(expressions=[convert(v, copy=copy) for v in value.values()]), 2437 ) 2438 if hasattr(value, "__dict__"): 2439 from sqlglot.expressions.array import Struct as _Struct 2440 2441 return _Struct( 2442 expressions=[ 2443 PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy)) 2444 for k, v in value.__dict__.items() 2445 ] 2446 ) 2447 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.
2512def maybe_parse( 2513 sql_or_expression: ExpOrStr, 2514 *, 2515 into: IntoType | None = None, 2516 dialect: DialectType = None, 2517 prefix: str | None = None, 2518 copy: bool = False, 2519 **opts: Unpack[ParserNoDialectArgs], 2520) -> Expr: 2521 """Gracefully handle a possible string or expression. 2522 2523 Example: 2524 >>> maybe_parse("1") 2525 Literal(this=1, is_string=False) 2526 >>> maybe_parse(to_identifier("x")) 2527 Identifier(this=x, quoted=False) 2528 2529 Args: 2530 sql_or_expression: the SQL code string or an expression 2531 into: the SQLGlot Expr to parse into 2532 dialect: the dialect used to parse the input expressions (in the case that an 2533 input expression is a SQL string). 2534 prefix: a string to prefix the sql with before it gets parsed 2535 (automatically includes a space) 2536 copy: whether to copy the expression. 2537 **opts: other options to use to parse the input expressions (again, in the case 2538 that an input expression is a SQL string). 2539 2540 Returns: 2541 Expr: the parsed or given expression. 2542 """ 2543 if isinstance(sql_or_expression, Expr): 2544 if copy: 2545 return sql_or_expression.copy() 2546 return sql_or_expression 2547 2548 if sql_or_expression is None: 2549 raise ParseError("SQL cannot be None") 2550 2551 import sqlglot 2552 2553 sql = str(sql_or_expression) 2554 if prefix: 2555 sql = f"{prefix} {sql}" 2556 2557 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.
2809def to_identifier(name, quoted=None, copy=True): 2810 """Builds an identifier. 2811 2812 Args: 2813 name: The name to turn into an identifier. 2814 quoted: Whether to force quote the identifier. 2815 copy: Whether to copy name if it's an Identifier. 2816 2817 Returns: 2818 The identifier ast node. 2819 """ 2820 2821 if name is None: 2822 return None 2823 2824 if isinstance(name, Identifier): 2825 identifier = maybe_copy(name, copy) 2826 elif isinstance(name, str): 2827 identifier = Identifier( 2828 this=name, 2829 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, 2830 ) 2831 else: 2832 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") 2833 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.
2836def condition( 2837 expression: ExpOrStr, 2838 dialect: DialectType = None, 2839 copy: bool = True, 2840 **opts: Unpack[ParserNoDialectArgs], 2841) -> Expr: 2842 """ 2843 Initialize a logical condition expression. 2844 2845 Example: 2846 >>> condition("x=1").sql() 2847 'x = 1' 2848 2849 This is helpful for composing larger logical syntax trees: 2850 >>> where = condition("x=1") 2851 >>> where = where.and_("y=1") 2852 >>> where.sql() 2853 'x = 1 AND y = 1' 2854 2855 Args: 2856 *expression: the SQL code string to parse. 2857 If an Expr instance is passed, this is used as-is. 2858 dialect: the dialect used to parse the input expression (in the case that the 2859 input expression is a SQL string). 2860 copy: Whether to copy `expression` (only applies to expressions). 2861 **opts: other options to use to parse the input expressions (again, in the case 2862 that the input expression is a SQL string). 2863 2864 Returns: 2865 The new Condition instance 2866 """ 2867 return maybe_parse( 2868 expression, 2869 into=Condition, 2870 dialect=dialect, 2871 copy=copy, 2872 **opts, 2873 )
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
2876def and_( 2877 *expressions: ExpOrStr | None, 2878 dialect: DialectType = None, 2879 copy: bool = True, 2880 wrap: bool = True, 2881 **opts: Unpack[ParserNoDialectArgs], 2882) -> Condition: 2883 """ 2884 Combine multiple conditions with an AND logical operator. 2885 2886 Example: 2887 >>> and_("x=1", and_("y=1", "z=1")).sql() 2888 'x = 1 AND (y = 1 AND z = 1)' 2889 2890 Args: 2891 *expressions: the SQL code strings to parse. 2892 If an Expr instance is passed, this is used as-is. 2893 dialect: the dialect used to parse the input expression. 2894 copy: whether to copy `expressions` (only applies to Exprs). 2895 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2896 precedence issues, but can be turned off when the produced AST is too deep and 2897 causes recursion-related issues. 2898 **opts: other options to use to parse the input expressions. 2899 2900 Returns: 2901 The new condition 2902 """ 2903 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
2906def or_( 2907 *expressions: ExpOrStr | None, 2908 dialect: DialectType = None, 2909 copy: bool = True, 2910 wrap: bool = True, 2911 **opts: Unpack[ParserNoDialectArgs], 2912) -> Condition: 2913 """ 2914 Combine multiple conditions with an OR logical operator. 2915 2916 Example: 2917 >>> or_("x=1", or_("y=1", "z=1")).sql() 2918 'x = 1 OR (y = 1 OR z = 1)' 2919 2920 Args: 2921 *expressions: the SQL code strings to parse. 2922 If an Expr instance is passed, this is used as-is. 2923 dialect: the dialect used to parse the input expression. 2924 copy: whether to copy `expressions` (only applies to Exprs). 2925 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2926 precedence issues, but can be turned off when the produced AST is too deep and 2927 causes recursion-related issues. 2928 **opts: other options to use to parse the input expressions. 2929 2930 Returns: 2931 The new condition 2932 """ 2933 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
2936def xor( 2937 *expressions: ExpOrStr | None, 2938 dialect: DialectType = None, 2939 copy: bool = True, 2940 wrap: bool = True, 2941 **opts: Unpack[ParserNoDialectArgs], 2942) -> Condition: 2943 """ 2944 Combine multiple conditions with an XOR logical operator. 2945 2946 Example: 2947 >>> xor("x=1", xor("y=1", "z=1")).sql() 2948 'x = 1 XOR (y = 1 XOR z = 1)' 2949 2950 Args: 2951 *expressions: the SQL code strings to parse. 2952 If an Expr instance is passed, this is used as-is. 2953 dialect: the dialect used to parse the input expression. 2954 copy: whether to copy `expressions` (only applies to Exprs). 2955 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2956 precedence issues, but can be turned off when the produced AST is too deep and 2957 causes recursion-related issues. 2958 **opts: other options to use to parse the input expressions. 2959 2960 Returns: 2961 The new condition 2962 """ 2963 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
2966def paren(expression: ExpOrStr, copy: bool = True) -> Paren: 2967 """ 2968 Wrap an expression in parentheses. 2969 2970 Example: 2971 >>> paren("5 + 3").sql() 2972 '(5 + 3)' 2973 2974 Args: 2975 expression: the SQL code string to parse. 2976 If an Expr instance is passed, this is used as-is. 2977 copy: whether to copy the expression or not. 2978 2979 Returns: 2980 The wrapped expression. 2981 """ 2982 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.
2985def alias_( 2986 expression: ExpOrStr, 2987 alias: str | Identifier | None, 2988 table: bool | Sequence[str | Identifier] = False, 2989 quoted: bool | None = None, 2990 dialect: DialectType = None, 2991 copy: bool = True, 2992 **opts: Unpack[ParserNoDialectArgs], 2993) -> Expr: 2994 """Create an Alias expression. 2995 2996 Example: 2997 >>> alias_('foo', 'bar').sql() 2998 'foo AS bar' 2999 3000 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() 3001 '(SELECT 1, 2) AS bar(a, b)' 3002 3003 Args: 3004 expression: the SQL code strings to parse. 3005 If an Expr instance is passed, this is used as-is. 3006 alias: the alias name to use. If the name has 3007 special characters it is quoted. 3008 table: Whether to create a table alias, can also be a list of columns. 3009 quoted: whether to quote the alias 3010 dialect: the dialect used to parse the input expression. 3011 copy: Whether to copy the expression. 3012 **opts: other options to use to parse the input expressions. 3013 3014 Returns: 3015 Alias: the aliased expression 3016 """ 3017 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) 3018 alias = to_identifier(alias, quoted=quoted) 3019 3020 if table: 3021 from sqlglot.expressions.query import TableAlias as _TableAlias 3022 3023 table_alias = _TableAlias(this=alias) 3024 exp.set("alias", table_alias) 3025 3026 if not isinstance(table, bool): 3027 for column in table: 3028 table_alias.append("columns", to_identifier(column, quoted=quoted)) 3029 3030 return exp 3031 3032 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in 3033 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node 3034 # for the complete Window expression. 3035 # 3036 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls 3037 3038 if "alias" in exp.arg_types and type(exp).__name__ != "Window": 3039 exp.set("alias", alias) 3040 return exp 3041 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
3072def column( 3073 col, 3074 table=None, 3075 db=None, 3076 catalog=None, 3077 *, 3078 fields=None, 3079 quoted=None, 3080 copy: bool = True, 3081): 3082 """ 3083 Build a Column. 3084 3085 Args: 3086 col: Column name. 3087 table: Table name. 3088 db: Database name. 3089 catalog: Catalog name. 3090 fields: Additional fields using dots. 3091 quoted: Whether to force quotes on the column's identifiers. 3092 copy: Whether to copy identifiers if passed in. 3093 3094 Returns: 3095 The new Column instance. 3096 """ 3097 if not isinstance(col, Star): 3098 col = to_identifier(col, quoted=quoted, copy=copy) 3099 3100 this: Column | Dot = Column( 3101 this=col, 3102 table=to_identifier(table, quoted=quoted, copy=copy), 3103 db=to_identifier(db, quoted=quoted, copy=copy), 3104 catalog=to_identifier(catalog, quoted=quoted, copy=copy), 3105 ) 3106 3107 if fields: 3108 this = Dot.build( 3109 (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields)) 3110 ) 3111 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.