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