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, tuple(v) if type(v) is list else 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 try: 937 return self.is_number and isinstance(self.to_py(), int) 938 except ValueError: 939 return False 940 941 @property 942 def is_star(self) -> bool: 943 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star)) 944 945 @property 946 def alias(self) -> str: 947 alias = self.args.get("alias") 948 if isinstance(alias, Expression): 949 return alias.name 950 return self.text("alias") 951 952 @property 953 def alias_column_names(self) -> list[str]: 954 table_alias = self.args.get("alias") 955 if not table_alias: 956 return [] 957 return [c.name for c in table_alias.args.get("columns") or []] 958 959 @property 960 def name(self) -> str: 961 return self.text("this") 962 963 @property 964 def alias_or_name(self) -> str: 965 return self.alias or self.name 966 967 @property 968 def output_name(self) -> str: 969 return "" 970 971 @property 972 def type(self) -> DataType | None: 973 if self.is_data_type: 974 return self # type: ignore[return-value] 975 if self.is_cast: 976 return self._type or self.to # type: ignore[attr-defined] 977 return self._type 978 979 @type.setter 980 def type(self, dtype: DataType | DType | str | None) -> None: 981 if dtype and type(dtype).__name__ != "DataType": 982 from sqlglot.expressions.datatypes import DataType as _DataType 983 984 dtype = _DataType.build(dtype) 985 self._type = dtype # type: ignore[assignment] 986 987 def is_type(self, *dtypes: DATA_TYPE) -> bool: 988 t = self._type 989 return t is not None and t.is_type(*dtypes) 990 991 def is_leaf(self) -> bool: 992 return not any((isinstance(v, Expr) or type(v) is list) and v for v in self.args.values()) 993 994 @property 995 def meta(self) -> dict[str, t.Any]: 996 if self._meta is None: 997 self._meta = {} 998 return self._meta 999 1000 def meta_get(self, key: str, default: t.Any = None) -> t.Any: 1001 """Reads a meta value without allocating the meta dict (unlike the `meta` property).""" 1002 meta = self._meta 1003 return meta.get(key, default) if meta is not None else default 1004 1005 def __deepcopy__(self, memo: t.Any) -> Expr: 1006 root = self.__class__() 1007 stack: list[tuple[Expr, Expr]] = [(self, root)] 1008 1009 while stack: 1010 node, copy = stack.pop() 1011 1012 if node.comments is not None: 1013 copy.comments = deepcopy(node.comments) 1014 if node._type is not None: 1015 copy._type = deepcopy(node._type) 1016 if node._meta is not None: 1017 copy._meta = deepcopy(node._meta) 1018 if node._hash is not None: 1019 copy._hash = node._hash 1020 1021 for k, vs in node.args.items(): 1022 if isinstance(vs, Expr): 1023 stack.append((vs, vs.__class__())) 1024 copy.set(k, stack[-1][-1]) 1025 elif type(vs) is list: 1026 copy.args[k] = [] 1027 1028 for v in vs: 1029 if isinstance(v, Expr): 1030 stack.append((v, v.__class__())) 1031 copy.append(k, stack[-1][-1]) 1032 else: 1033 copy.append(k, v) 1034 else: 1035 copy.args[k] = vs 1036 1037 return root 1038 1039 def copy(self: E) -> E: 1040 return deepcopy(self) 1041 1042 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 1043 if self.comments is None: 1044 self.comments = [] 1045 1046 if comments: 1047 for comment in comments: 1048 _, *meta = comment.split(SQLGLOT_META) 1049 if meta: 1050 for kv in "".join(meta).split(","): 1051 k, *v = kv.split("=") 1052 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 1053 1054 if not prepend: 1055 self.comments.append(comment) 1056 1057 if prepend: 1058 self.comments = comments + self.comments 1059 1060 def pop_comments(self) -> list[str]: 1061 comments = self.comments or [] 1062 self.comments = None 1063 return comments 1064 1065 def append(self, arg_key: str, value: t.Any) -> None: 1066 node: Expr | None = self 1067 while node and node._hash is not None: 1068 node._hash = None 1069 node = node.parent 1070 1071 if type(self.args.get(arg_key)) is not list: 1072 self.args[arg_key] = [] 1073 self._set_parent(arg_key, value) 1074 values = self.args[arg_key] 1075 if isinstance(value, Expr): 1076 value.index = len(values) 1077 values.append(value) 1078 1079 def set( 1080 self, 1081 arg_key: str, 1082 value: object, 1083 index: int | None = None, 1084 overwrite: bool = True, 1085 ) -> None: 1086 node: Expr | None = self 1087 1088 while node and node._hash is not None: 1089 node._hash = None 1090 node = node.parent 1091 1092 if index is not None: 1093 expressions = self.args.get(arg_key) or [] 1094 1095 if seq_get(expressions, index) is None: 1096 return 1097 1098 if value is None: 1099 expressions.pop(index) 1100 for v in expressions[index:]: 1101 v.index = v.index - 1 1102 return 1103 1104 if isinstance(value, list): 1105 expressions.pop(index) 1106 expressions[index:index] = value 1107 elif overwrite: 1108 expressions[index] = value 1109 else: 1110 expressions.insert(index, value) 1111 1112 value = expressions 1113 elif value is None: 1114 self.args.pop(arg_key, None) 1115 return 1116 1117 self.args[arg_key] = value 1118 self._set_parent(arg_key, value, index) 1119 1120 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 1121 if isinstance(value, Expr): 1122 value.parent = self 1123 value.arg_key = arg_key 1124 value.index = index 1125 elif isinstance(value, list): 1126 for i, v in enumerate(value): 1127 if isinstance(v, Expr): 1128 v.parent = self 1129 v.arg_key = arg_key 1130 v.index = i 1131 1132 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 1133 """Set multiples keyword arguments at once, using `.set()` method. 1134 1135 Args: 1136 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 1137 Returns: 1138 Self: The same `Expression` with the updated arguments. 1139 """ 1140 if kwargs: 1141 for k, v in kwargs.items(): 1142 self.set(k, v) 1143 return self 1144 1145 @property 1146 def depth(self) -> int: 1147 if self.parent: 1148 return self.parent.depth + 1 1149 return 0 1150 1151 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 1152 for vs in reversed(self.args.values()) if reverse else self.args.values(): 1153 if isinstance(vs, list): 1154 for v in reversed(vs) if reverse else vs: 1155 if isinstance(v, Expr): 1156 yield t.cast(E, v) 1157 elif isinstance(vs, Expr): 1158 yield t.cast(E, vs) 1159 1160 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 1161 return next(self.find_all(*expression_types, bfs=bfs), None) 1162 1163 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 1164 for expression in self.walk(bfs=bfs): 1165 if isinstance(expression, expression_types): 1166 yield expression 1167 1168 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 1169 ancestor = self.parent 1170 while ancestor and not isinstance(ancestor, expression_types): 1171 ancestor = ancestor.parent 1172 return ancestor # type: ignore[return-value] 1173 1174 @property 1175 def parent_select(self) -> Select | None: 1176 from sqlglot.expressions.query import Select as _Select 1177 1178 return self.find_ancestor(_Select) 1179 1180 @property 1181 def same_parent(self) -> bool: 1182 return type(self.parent) is self.__class__ 1183 1184 def root(self) -> Expr: 1185 expression: Expr = self 1186 while expression.parent: 1187 expression = expression.parent 1188 return expression 1189 1190 def walk( 1191 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 1192 ) -> Iterator[Expr]: 1193 if bfs: 1194 yield from self.bfs(prune=prune) 1195 else: 1196 yield from self.dfs(prune=prune) 1197 1198 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1199 stack = [self] 1200 1201 while stack: 1202 node = stack.pop() 1203 yield node 1204 if prune and prune(node): 1205 continue 1206 for v in node.iter_expressions(reverse=True): 1207 stack.append(v) 1208 1209 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1210 queue: deque[Expr] = deque() 1211 queue.append(self) 1212 1213 while queue: 1214 node = queue.popleft() 1215 yield node 1216 if prune and prune(node): 1217 continue 1218 for v in node.iter_expressions(): 1219 queue.append(v) 1220 1221 def unnest(self) -> Expr: 1222 expression = self 1223 while type(expression) is Paren: 1224 expression = expression.this 1225 return expression 1226 1227 def unalias(self) -> Expr: 1228 if isinstance(self, Alias): 1229 return self.this 1230 return self 1231 1232 def unnest_operands(self) -> tuple[Expr, ...]: 1233 return tuple(arg.unnest() for arg in self.iter_expressions()) 1234 1235 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1236 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1237 if type(node) is not self.__class__: 1238 yield node.unnest() if unnest and not node.is_subquery else node 1239 1240 def __str__(self) -> str: 1241 return self.sql() 1242 1243 def __repr__(self) -> str: 1244 return _to_s(self) 1245 1246 def to_s(self) -> str: 1247 return _to_s(self, verbose=True) 1248 1249 def sql( 1250 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1251 ) -> str: 1252 from sqlglot.dialects.dialect import Dialect 1253 1254 return Dialect.get_or_raise(dialect).generate(self, copy=copy, **opts) 1255 1256 def transform( 1257 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 1258 ) -> T: 1259 root: t.Any = None 1260 new_node: t.Any = None 1261 1262 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1263 parent, arg_key, index = node.parent, node.arg_key, node.index 1264 new_node = fun(node, *args, **kwargs) 1265 1266 if not root: 1267 root = new_node 1268 elif parent and arg_key and new_node is not node: 1269 parent.set(arg_key, new_node, index) 1270 1271 assert root 1272 return root 1273 1274 def replace(self, expression: T) -> T: 1275 parent = self.parent 1276 1277 if not parent or parent is expression: 1278 return expression 1279 1280 key = self.arg_key 1281 1282 if key: 1283 value = parent.args.get(key) 1284 1285 if type(expression) is list and isinstance(value, Expr): 1286 # We are trying to replace an Expr with a list, so it's assumed that 1287 # the intention was to really replace the parent of this expression. 1288 if value.parent: 1289 value.parent.replace(expression) 1290 else: 1291 parent.set(key, expression, self.index) 1292 1293 if expression is not self: 1294 self.parent = None 1295 self.arg_key = None 1296 self.index = None 1297 1298 return expression 1299 1300 def pop(self: E) -> E: 1301 self.replace(None) 1302 return self 1303 1304 def assert_is(self, type_: Type[E]) -> E: 1305 if not isinstance(self, type_): 1306 raise AssertionError(f"{self} is not {type_}.") 1307 return self 1308 1309 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1310 if UNITTEST: 1311 for k in self.args: 1312 if k not in self.arg_types: 1313 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1314 1315 errors: list[str] | None = None 1316 1317 for k in self.required_args: 1318 v = self.args.get(k) 1319 if v is None or (isinstance(v, list) and not v): 1320 if errors is None: 1321 errors = [] 1322 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1323 1324 if ( 1325 args 1326 and isinstance(self, Func) 1327 and len(args) > len(self.arg_types) 1328 and not self.is_var_len_args 1329 ): 1330 if errors is None: 1331 errors = [] 1332 errors.append( 1333 f"The number of provided arguments ({len(args)}) is greater than " 1334 f"the maximum number of supported arguments ({len(self.arg_types)})" 1335 ) 1336 1337 return errors or [] 1338 1339 def and_( 1340 self, 1341 *expressions: ExpOrStr | None, 1342 dialect: DialectType = None, 1343 copy: bool = True, 1344 wrap: bool = True, 1345 **opts: Unpack[ParserNoDialectArgs], 1346 ) -> Condition: 1347 return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1348 1349 def or_( 1350 self, 1351 *expressions: ExpOrStr | None, 1352 dialect: DialectType = None, 1353 copy: bool = True, 1354 wrap: bool = True, 1355 **opts: Unpack[ParserNoDialectArgs], 1356 ) -> Condition: 1357 return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1358 1359 def not_(self, copy: bool = True) -> Not: 1360 return not_(self, copy=copy) 1361 1362 def update_positions( 1363 self: E, 1364 other: Token | Expr | None = None, 1365 line: int | None = None, 1366 col: int | None = None, 1367 start: int | None = None, 1368 end: int | None = None, 1369 ) -> E: 1370 if isinstance(other, Token): 1371 meta = self.meta 1372 meta["line"] = other.line 1373 meta["col"] = other.col 1374 meta["start"] = other.start 1375 meta["end"] = other.end 1376 elif other is not None: 1377 other_meta = other._meta 1378 if other_meta: 1379 meta = self.meta 1380 for k in POSITION_META_KEYS: 1381 if k in other_meta: 1382 meta[k] = other_meta[k] 1383 else: 1384 meta = self.meta 1385 meta["line"] = line 1386 meta["col"] = col 1387 meta["start"] = start 1388 meta["end"] = end 1389 return self 1390 1391 def as_( 1392 self, 1393 alias: str | Identifier, 1394 quoted: bool | None = None, 1395 dialect: DialectType = None, 1396 copy: bool = True, 1397 table: bool | Sequence[str | Identifier] = False, 1398 **opts: Unpack[ParserNoDialectArgs], 1399 ) -> Expr: 1400 return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, table=table, **opts) 1401 1402 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 1403 this = self.copy() 1404 other = convert(other, copy=True) 1405 if not isinstance(this, klass) and not isinstance(other, klass): 1406 this = _wrap(this, Binary) 1407 other = _wrap(other, Binary) 1408 if reverse: 1409 return klass(this=other, expression=this) 1410 return klass(this=this, expression=other) 1411 1412 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 1413 return Bracket( 1414 this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)] 1415 ) 1416 1417 def __iter__(self) -> Iterator: 1418 if "expressions" in self.arg_types: 1419 return iter(self.args.get("expressions") or []) 1420 # We define this because __getitem__ converts Expr into an iterable, which is 1421 # problematic because one can hit infinite loops if they do "for x in some_expr: ..." 1422 # See: https://peps.python.org/pep-0234/ 1423 raise TypeError(f"'{self.__class__.__name__}' object is not iterable") 1424 1425 def isin( 1426 self, 1427 *expressions: t.Any, 1428 query: ExpOrStr | None = None, 1429 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 1430 dialect: DialectType = None, 1431 copy: bool = True, 1432 **opts: Unpack[ParserNoDialectArgs], 1433 ) -> In: 1434 from sqlglot.expressions.query import Query 1435 1436 subquery: Expr | None = None 1437 if query: 1438 subquery = maybe_parse(query, dialect=dialect, copy=copy, **opts) 1439 if isinstance(subquery, Query): 1440 subquery = subquery.subquery(copy=False) 1441 unnest_list: list[ExpOrStr] = ensure_list(unnest) 1442 return In( 1443 this=maybe_copy(self, copy), 1444 expressions=[convert(e, copy=copy) for e in expressions], 1445 query=subquery, 1446 unnest=( 1447 _lazy_unnest( 1448 expressions=[ 1449 maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in unnest_list 1450 ] 1451 ) 1452 if unnest 1453 else None 1454 ), 1455 ) 1456 1457 def between( 1458 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 1459 ) -> Between: 1460 between = Between( 1461 this=maybe_copy(self, copy), 1462 low=convert(low, copy=copy), 1463 high=convert(high, copy=copy), 1464 ) 1465 if symmetric is not None: 1466 between.set("symmetric", symmetric) 1467 1468 return between 1469 1470 def is_(self, other: ExpOrStr) -> Is: 1471 return self._binop(Is, other) 1472 1473 def like(self, other: ExpOrStr) -> Like: 1474 return self._binop(Like, other) 1475 1476 def ilike(self, other: ExpOrStr) -> ILike: 1477 return self._binop(ILike, other) 1478 1479 def eq(self, other: t.Any) -> EQ: 1480 return self._binop(EQ, other) 1481 1482 def neq(self, other: t.Any) -> NEQ: 1483 return self._binop(NEQ, other) 1484 1485 def rlike(self, other: ExpOrStr) -> RegexpLike: 1486 return self._binop(RegexpLike, other) 1487 1488 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 1489 div = self._binop(Div, other) 1490 div.set("typed", typed) 1491 div.set("safe", safe) 1492 return div 1493 1494 def asc(self, nulls_first: bool = True) -> Ordered: 1495 return Ordered(this=self.copy(), nulls_first=nulls_first) 1496 1497 def desc(self, nulls_first: bool = False) -> Ordered: 1498 return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first) 1499 1500 def __lt__(self, other: t.Any) -> LT: 1501 return self._binop(LT, other) 1502 1503 def __le__(self, other: t.Any) -> LTE: 1504 return self._binop(LTE, other) 1505 1506 def __gt__(self, other: t.Any) -> GT: 1507 return self._binop(GT, other) 1508 1509 def __ge__(self, other: t.Any) -> GTE: 1510 return self._binop(GTE, other) 1511 1512 def __add__(self, other: t.Any) -> Add: 1513 return self._binop(Add, other) 1514 1515 def __radd__(self, other: t.Any) -> Add: 1516 return self._binop(Add, other, reverse=True) 1517 1518 def __sub__(self, other: t.Any) -> Sub: 1519 return self._binop(Sub, other) 1520 1521 def __rsub__(self, other: t.Any) -> Sub: 1522 return self._binop(Sub, other, reverse=True) 1523 1524 def __mul__(self, other: t.Any) -> Mul: 1525 return self._binop(Mul, other) 1526 1527 def __rmul__(self, other: t.Any) -> Mul: 1528 return self._binop(Mul, other, reverse=True) 1529 1530 def __truediv__(self, other: t.Any) -> Div: 1531 return self._binop(Div, other) 1532 1533 def __rtruediv__(self, other: t.Any) -> Div: 1534 return self._binop(Div, other, reverse=True) 1535 1536 def __floordiv__(self, other: t.Any) -> IntDiv: 1537 return self._binop(IntDiv, other) 1538 1539 def __rfloordiv__(self, other: t.Any) -> IntDiv: 1540 return self._binop(IntDiv, other, reverse=True) 1541 1542 def __mod__(self, other: t.Any) -> Mod: 1543 return self._binop(Mod, other) 1544 1545 def __rmod__(self, other: t.Any) -> Mod: 1546 return self._binop(Mod, other, reverse=True) 1547 1548 def __pow__(self, other: t.Any) -> Pow: 1549 return self._binop(Pow, other) 1550 1551 def __rpow__(self, other: t.Any) -> Pow: 1552 return self._binop(Pow, other, reverse=True) 1553 1554 def __and__(self, other: t.Any) -> And: 1555 return self._binop(And, other) 1556 1557 def __rand__(self, other: t.Any) -> And: 1558 return self._binop(And, other, reverse=True) 1559 1560 def __or__(self, other: t.Any) -> Or: 1561 return self._binop(Or, other) 1562 1563 def __ror__(self, other: t.Any) -> Or: 1564 return self._binop(Or, other, reverse=True) 1565 1566 def __neg__(self) -> Neg: 1567 return Neg(this=_wrap(self.copy(), Binary)) 1568 1569 def __invert__(self) -> Not: 1570 return not_(self.copy()) 1571 1572 1573IntoType = t.Union[Type[Expr], Collection[Type[Expr]]] 1574ExpOrStr = t.Union[int, str, Expr] 1575 1576 1577@trait 1578class Condition(Expr): 1579 """Logical conditions like x AND y, or simply x""" 1580 1581 1582@trait 1583class Predicate(Condition): 1584 """Any condition that evaluates to a boolean, e.g. x = y, x LIKE 'a%', a @> b.""" 1585 1586 1587class Cache(Expression): 1588 arg_types = { 1589 "this": True, 1590 "lazy": False, 1591 "options": False, 1592 "expression": False, 1593 } 1594 1595 1596class Uncache(Expression): 1597 arg_types = {"this": True, "exists": False} 1598 1599 1600class Refresh(Expression): 1601 arg_types = { 1602 "this": True, 1603 "kind": True, 1604 "partition_start": False, 1605 "partition_end": False, 1606 "force": False, 1607 "mode": False, 1608 } 1609 1610 1611class LockingStatement(Expression): 1612 arg_types = {"this": True, "expression": True} 1613 1614 1615@trait 1616class ColumnConstraintKind(Expr): 1617 pass 1618 1619 1620@trait 1621class SubqueryPredicate(Predicate): 1622 pass 1623 1624 1625class All(Expression, SubqueryPredicate): 1626 pass 1627 1628 1629class Any(Expression, SubqueryPredicate): 1630 pass 1631 1632 1633@trait 1634class Binary(Condition): 1635 arg_types: t.ClassVar[dict[str, bool]] = {"this": True, "expression": True} 1636 1637 @property 1638 def left(self) -> Expr: 1639 return self.args["this"] 1640 1641 @property 1642 def right(self) -> Expr: 1643 return self.args["expression"] 1644 1645 1646@trait 1647class Connector(Binary): 1648 pass 1649 1650 1651@trait 1652class Func(Condition): 1653 """ 1654 The base class for all function expressions. 1655 1656 Attributes: 1657 is_var_len_args (bool): if set to True the argument identified by var_len_arg_key will be 1658 treated as a variable length argument and the argument's value will be stored as a list. 1659 var_len_arg_key (str): the arg_types key that collects the variable length arguments. 1660 Arguments preceding it in arg_types are filled positionally; those following it (e.g. 1661 dialect flags) are never populated by from_arg_list. 1662 _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this 1663 function expression. These values are used to map this node to a name during parsing as 1664 well as to provide the function's name during SQL string generation. By default the SQL 1665 name is set to the expression's class name transformed to snake case. 1666 """ 1667 1668 is_var_len_args: t.ClassVar[bool] = False 1669 var_len_arg_key: t.ClassVar[str] = "expressions" 1670 _sql_names: t.ClassVar[list[str]] = [] 1671 1672 @classmethod 1673 def from_arg_list(cls, args: Sequence[object]) -> Self: 1674 if cls.is_var_len_args: 1675 all_arg_keys = tuple(cls.arg_types) 1676 var_len_index = all_arg_keys.index(cls.var_len_arg_key) 1677 1678 args_dict = {arg_key: arg for arg, arg_key in zip(args, all_arg_keys[:var_len_index])} 1679 args_dict[cls.var_len_arg_key] = args[var_len_index:] 1680 else: 1681 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} 1682 1683 return cls(**args_dict) 1684 1685 @classmethod 1686 def sql_names(cls) -> list[str]: 1687 if cls is Func: 1688 raise NotImplementedError( 1689 "SQL name is only supported by concrete function implementations" 1690 ) 1691 if not cls._sql_names: 1692 return [camel_to_snake_case(cls.__name__)] 1693 return cls._sql_names 1694 1695 @classmethod 1696 def sql_name(cls) -> str: 1697 sql_names = cls.sql_names() 1698 assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}." 1699 return sql_names[0] 1700 1701 @classmethod 1702 def default_parser_mappings(cls) -> dict[str, t.Callable[[Sequence[object]], Self]]: 1703 return {name: cls.from_arg_list for name in cls.sql_names()} 1704 1705 1706@trait 1707class AggFunc(Func): 1708 pass 1709 1710 1711class Column(Expression, Condition): 1712 # "shadow" marks a column whose qualifier is shadowed by a projection alias, so it must be 1713 # rendered unqualified in dialects where PROJECTION_ALIASES_SHADOW_SOURCE_NAMES is set 1714 arg_types = { 1715 "this": True, 1716 "table": False, 1717 "db": False, 1718 "catalog": False, 1719 "join_mark": False, 1720 "shadow": False, 1721 } 1722 1723 @property 1724 def table(self) -> str: 1725 return self.text("table") 1726 1727 @property 1728 def db(self) -> str: 1729 return self.text("db") 1730 1731 @property 1732 def catalog(self) -> str: 1733 return self.text("catalog") 1734 1735 @property 1736 def output_name(self) -> str: 1737 return self.name 1738 1739 @property 1740 def parts(self) -> list[Expr]: 1741 """Return the parts of a column in order catalog, db, table, name.""" 1742 return [ 1743 self.args[part] for part in ("catalog", "db", "table", "this") if self.args.get(part) 1744 ] 1745 1746 def to_dot(self, include_dots: bool = True) -> Expr: 1747 """Converts the column into a dot expression.""" 1748 parts = self.parts 1749 parent = self.parent 1750 1751 if include_dots: 1752 while isinstance(parent, Dot): 1753 parts.append(parent.expression) 1754 parent = parent.parent 1755 1756 return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0] 1757 1758 1759class Literal(Expression, Condition): 1760 arg_types = {"this": True, "is_string": True} 1761 _hash_raw_args = True 1762 is_primitive = True 1763 1764 @classmethod 1765 def number(cls, number: object) -> Literal | Neg: 1766 lit = cls(this=str(number), is_string=False) 1767 try: 1768 to_py = lit.to_py() 1769 if not isinstance(to_py, str) and to_py < 0: 1770 lit.set("this", str(abs(to_py))) 1771 return Neg(this=lit) 1772 except Exception: 1773 pass 1774 return lit 1775 1776 @classmethod 1777 def string(cls, string: object) -> Literal: 1778 return cls(this=str(string), is_string=True) 1779 1780 @property 1781 def output_name(self) -> str: 1782 return self.name 1783 1784 def to_py(self) -> int | str | Decimal: 1785 if self.is_number: 1786 try: 1787 return int(self.this) 1788 except ValueError: 1789 try: 1790 return Decimal(self.this) 1791 except InvalidOperation as e: 1792 raise ValueError(f"Invalid numeric literal: {self.this!r}") from e 1793 return self.this 1794 1795 1796class Var(Expression): 1797 is_primitive = True 1798 1799 1800class WithinGroup(Expression): 1801 arg_types = {"this": True, "expression": False} 1802 1803 1804class Pseudocolumn(Column): 1805 pass 1806 1807 1808class Hint(Expression): 1809 arg_types = {"expressions": True} 1810 1811 1812class JoinHint(Expression): 1813 arg_types = {"this": True, "expressions": True} 1814 1815 1816class Identifier(Expression): 1817 arg_types = { 1818 "this": True, 1819 "quoted": False, 1820 "global_": False, 1821 "temporary": False, 1822 } 1823 is_primitive = True 1824 _hash_raw_args = True 1825 1826 @property 1827 def quoted(self) -> bool: 1828 return bool(self.args.get("quoted")) 1829 1830 @property 1831 def output_name(self) -> str: 1832 return self.name 1833 1834 1835# https://docs.snowflake.com/en/sql-reference/identifier-literal 1836# "expressions" holds the arguments when the resolved identifier is invoked as a 1837# function, e.g. `IDENTIFIER('my_func')(1, 2)` 1838class DynamicIdentifier(Expression, Func): 1839 arg_types = {"this": True, "expressions": False} 1840 1841 @property 1842 def name(self) -> str: 1843 return self.this.name if self.this else "" 1844 1845 1846class Opclass(Expression): 1847 arg_types = {"this": True, "expression": True} 1848 1849 1850class Star(Expression): 1851 arg_types = {"except_": False, "replace": False, "rename": False, "ilike": False} 1852 1853 @property 1854 def name(self) -> str: 1855 return "*" 1856 1857 @property 1858 def output_name(self) -> str: 1859 return self.name 1860 1861 1862class Parameter(Expression, Condition): 1863 arg_types = {"this": True, "expression": False} 1864 1865 1866class SessionParameter(Expression, Condition): 1867 arg_types = {"this": True, "kind": False} 1868 1869 1870class Placeholder(Expression, Condition): 1871 arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False} 1872 _hash_raw_args = True 1873 1874 @property 1875 def name(self) -> str: 1876 return self.text("this") or "?" 1877 1878 1879class Null(Expression, Condition): 1880 arg_types = {} 1881 1882 @property 1883 def name(self) -> str: 1884 return "NULL" 1885 1886 def to_py(self) -> t.Literal[None]: 1887 return None 1888 1889 1890class Boolean(Expression, Condition): 1891 is_primitive = True 1892 1893 def to_py(self) -> bool: 1894 return self.this 1895 1896 1897class Dot(Expression, Binary): 1898 @property 1899 def is_star(self) -> bool: 1900 return self.expression.is_star 1901 1902 @property 1903 def name(self) -> str: 1904 return self.expression.name 1905 1906 @property 1907 def output_name(self) -> str: 1908 return self.name 1909 1910 @classmethod 1911 def build(cls, expressions: Sequence[Expr]) -> Dot: 1912 """Build a Dot object with a sequence of expressions.""" 1913 if len(expressions) < 2: 1914 raise ValueError("Dot requires >= 2 expressions.") 1915 1916 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) 1917 1918 @property 1919 def parts(self) -> list[Expr]: 1920 """Return the parts of a table / column in order catalog, db, table.""" 1921 this, *parts = self.flatten() 1922 1923 parts.reverse() 1924 1925 for arg in COLUMN_PARTS: 1926 part = this.args.get(arg) 1927 1928 if isinstance(part, Expr): 1929 parts.append(part) 1930 1931 parts.reverse() 1932 return parts 1933 1934 1935class Kwarg(Expression, Binary): 1936 """Kwarg in special functions like func(kwarg => y).""" 1937 1938 1939class Alias(Expression): 1940 arg_types = {"this": True, "alias": False} 1941 1942 @property 1943 def output_name(self) -> str: 1944 return self.alias 1945 1946 1947class PivotAlias(Alias): 1948 pass 1949 1950 1951class PivotAny(Expression): 1952 arg_types = {"this": False} 1953 1954 1955class Aliases(Expression): 1956 arg_types = {"this": True, "expressions": True} 1957 1958 @property 1959 def aliases(self) -> list[Expr]: 1960 return self.expressions 1961 1962 1963class Bracket(Expression, Condition): 1964 # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator 1965 arg_types = { 1966 "this": True, 1967 "expressions": True, 1968 "offset": False, 1969 "safe": False, 1970 "returns_list_for_maps": False, 1971 "json_access": False, 1972 } 1973 1974 @property 1975 def output_name(self) -> str: 1976 if len(self.expressions) == 1: 1977 return self.expressions[0].output_name 1978 1979 return super().output_name 1980 1981 1982class ForIn(Expression): 1983 arg_types = {"this": True, "expression": True} 1984 1985 1986class IgnoreNulls(Expression): 1987 pass 1988 1989 1990class RespectNulls(Expression): 1991 pass 1992 1993 1994class HavingMax(Expression): 1995 arg_types = {"this": True, "expression": True, "max": True} 1996 1997 1998class SafeFunc(Expression, Func): 1999 pass 2000 2001 2002class Typeof(Expression, Func): 2003 pass 2004 2005 2006class ParameterizedAgg(Expression, AggFunc): 2007 arg_types = {"this": True, "expressions": True, "params": True} 2008 _hash_raw_args = True 2009 2010 2011class Anonymous(Expression, Func): 2012 arg_types = {"this": True, "expressions": False} 2013 is_var_len_args = True 2014 2015 @property 2016 def name(self) -> str: 2017 return self.this if isinstance(self.this, str) else self.this.name 2018 2019 2020class AnonymousAggFunc(Expression, AggFunc): 2021 arg_types = {"this": True, "expressions": False} 2022 is_var_len_args = True 2023 _hash_raw_args = True 2024 2025 2026class CombinedAggFunc(AnonymousAggFunc): 2027 arg_types = {"this": True, "expressions": False} 2028 2029 2030class CombinedParameterizedAgg(ParameterizedAgg): 2031 arg_types = {"this": True, "expressions": True, "params": True} 2032 2033 2034class HashAgg(Expression, AggFunc): 2035 arg_types = {"this": True, "expressions": False} 2036 is_var_len_args = True 2037 2038 2039class Hll(Expression, AggFunc): 2040 arg_types = {"this": True, "expressions": False} 2041 is_var_len_args = True 2042 2043 2044class ApproxDistinct(Expression, AggFunc): 2045 arg_types = {"this": True, "accuracy": False} 2046 _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"] 2047 2048 2049class Slice(Expression): 2050 arg_types = {"this": False, "expression": False, "step": False} 2051 2052 2053@trait 2054class TimeUnit(Expr): 2055 """Automatically converts unit arg into a var.""" 2056 2057 UNABBREVIATED_UNIT_NAME: t.ClassVar[dict[str, str]] = { 2058 "D": "DAY", 2059 "H": "HOUR", 2060 "M": "MINUTE", 2061 "MS": "MILLISECOND", 2062 "NS": "NANOSECOND", 2063 "Q": "QUARTER", 2064 "S": "SECOND", 2065 "US": "MICROSECOND", 2066 "W": "WEEK", 2067 "Y": "YEAR", 2068 } 2069 2070 VAR_LIKE: t.ClassVar[tuple[Type[Expr], ...]] = (Column, Literal, Var) 2071 2072 def __init__(self, **args: object) -> None: 2073 super().__init__(**args) 2074 2075 unit = self.args.get("unit") 2076 if ( 2077 unit 2078 and type(unit) in TimeUnit.VAR_LIKE 2079 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2080 ): 2081 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2082 self.args["unit"] = unit 2083 self._set_parent("unit", unit) 2084 elif type(unit).__name__ == "Week": 2085 unit.set("this", Var(this=unit.this.name.upper())) # type: ignore[union-attr] 2086 2087 @property 2088 def unit(self) -> Expr | None: 2089 return self.args.get("unit") 2090 2091 2092class _TimeUnit(Expression, TimeUnit): 2093 """Automatically converts unit arg into a var.""" 2094 2095 arg_types = {"unit": False} 2096 2097 2098@trait 2099class IntervalOp(TimeUnit): 2100 def interval(self) -> Interval: 2101 from sqlglot.expressions.datatypes import Interval 2102 2103 expr = self.expression 2104 return Interval( 2105 this=expr.copy() if expr is not None else None, 2106 unit=self.unit.copy() if self.unit else None, 2107 ) 2108 2109 2110class Filter(Expression): 2111 arg_types = {"this": True, "expression": True} 2112 2113 2114class Per(Expression): 2115 arg_types = {"this": True, "expressions": True} 2116 2117 2118class Check(Expression): 2119 pass 2120 2121 2122class Ordered(Expression): 2123 arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False} 2124 2125 @property 2126 def name(self) -> str: 2127 return self.this.name 2128 2129 2130class Add(Expression, Binary): 2131 pass 2132 2133 2134class BitwiseAnd(Expression, Binary): 2135 arg_types = {"this": True, "expression": True, "padside": False} 2136 2137 2138class BitwiseLeftShift(Expression, Binary): 2139 arg_types = {"this": True, "expression": True, "requires_int128": False} 2140 2141 2142class BitwiseOr(Expression, Binary): 2143 arg_types = {"this": True, "expression": True, "padside": False} 2144 2145 2146class BitwiseRightShift(Expression, Binary): 2147 arg_types = {"this": True, "expression": True, "requires_int128": False} 2148 2149 2150class BitwiseXor(Expression, Binary): 2151 arg_types = {"this": True, "expression": True, "padside": False} 2152 2153 2154class Div(Expression, Binary): 2155 arg_types = {"this": True, "expression": True, "typed": False, "safe": False} 2156 2157 2158class Overlaps(Expression, Binary, Predicate): 2159 pass 2160 2161 2162class ExtendsLeft(Expression, Binary, Predicate): 2163 pass 2164 2165 2166class ExtendsRight(Expression, Binary, Predicate): 2167 pass 2168 2169 2170class DPipe(Expression, Binary): 2171 arg_types = {"this": True, "expression": True, "safe": False} 2172 2173 2174class EQ(Expression, Binary, Predicate): 2175 pass 2176 2177 2178class NullSafeEQ(Expression, Binary, Predicate): 2179 pass 2180 2181 2182class NullSafeNEQ(Expression, Binary, Predicate): 2183 pass 2184 2185 2186class PropertyEQ(Expression, Binary): 2187 pass 2188 2189 2190class Distance(Expression, Binary): 2191 pass 2192 2193 2194class DistanceNd(Expression, Binary): 2195 pass 2196 2197 2198class Escape(Expression, Binary): 2199 pass 2200 2201 2202class Glob(Expression, Binary, Predicate): 2203 pass 2204 2205 2206class GT(Expression, Binary, Predicate): 2207 pass 2208 2209 2210class GTE(Expression, Binary, Predicate): 2211 pass 2212 2213 2214class ILike(Expression, Binary, Predicate): 2215 arg_types = {"this": True, "expression": True, "negate": False} 2216 2217 2218class IntDiv(Expression, Binary): 2219 pass 2220 2221 2222class Is(Expression, Binary, Predicate): 2223 arg_types = {"this": True, "expression": True, "negate": False} 2224 2225 2226class Like(Expression, Binary, Predicate): 2227 arg_types = {"this": True, "expression": True, "negate": False} 2228 2229 2230class Match(Expression, Binary, Predicate): 2231 arg_types = {"this": True, "expression": True, "kind": False, "analyzer": False} 2232 2233 2234class LT(Expression, Binary, Predicate): 2235 pass 2236 2237 2238class LTE(Expression, Binary, Predicate): 2239 pass 2240 2241 2242class Mod(Expression, Binary): 2243 arg_types = {"this": True, "expression": True, "safe": False} 2244 2245 2246class Mul(Expression, Binary): 2247 pass 2248 2249 2250class NEQ(Expression, Binary, Predicate): 2251 pass 2252 2253 2254class NestedJSONSelect(Expression, Binary): 2255 pass 2256 2257 2258class Operator(Expression, Binary): 2259 arg_types = {"this": True, "operator": True, "expression": True} 2260 2261 2262class SimilarTo(Expression, Binary, Predicate): 2263 pass 2264 2265 2266class Sub(Expression, Binary): 2267 pass 2268 2269 2270class Adjacent(Expression, Binary, Predicate): 2271 pass 2272 2273 2274class Unary(Expression, Condition): 2275 pass 2276 2277 2278class BitwiseNot(Unary): 2279 pass 2280 2281 2282class Not(Unary): 2283 pass 2284 2285 2286class Paren(Unary): 2287 @property 2288 def output_name(self) -> str: 2289 return self.this.name 2290 2291 2292class Neg(Unary): 2293 def to_py(self) -> int | Decimal: 2294 if self.is_number: 2295 return self.this.to_py() * -1 2296 return super().to_py() 2297 2298 2299class AtIndex(Expression): 2300 arg_types = {"this": True, "expression": True} 2301 2302 2303class AtTimeZone(Expression): 2304 arg_types = {"this": True, "zone": True} 2305 2306 2307class FromTimeZone(Expression): 2308 arg_types = {"this": True, "zone": True} 2309 2310 2311class FormatPhrase(Expression): 2312 """Format override for a column in Teradata. 2313 Can be expanded to additional dialects as needed 2314 2315 https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT 2316 """ 2317 2318 arg_types = {"this": True, "format": True} 2319 2320 @property 2321 def name(self) -> str: 2322 return self.this.name 2323 2324 @property 2325 def output_name(self) -> str: 2326 return self.this.output_name 2327 2328 2329class TeradataTitle(Expression): 2330 """A Teradata TITLE display heading, which does not rename the expression.""" 2331 2332 arg_types = {"this": True, "title": True} 2333 2334 @property 2335 def name(self) -> str: 2336 return self.this.name 2337 2338 @property 2339 def output_name(self) -> str: 2340 return self.this.output_name 2341 2342 2343class Between(Expression, Predicate): 2344 arg_types = {"this": True, "low": True, "high": True, "symmetric": False} 2345 2346 2347class Distinct(Expression): 2348 arg_types = {"expressions": False, "on": False} 2349 2350 2351class In(Expression, Predicate): 2352 arg_types = { 2353 "this": True, 2354 "expressions": False, 2355 "query": False, 2356 "unnest": False, 2357 "field": False, 2358 "is_global": False, 2359 } 2360 2361 2362class And(Expression, Connector, Func): 2363 pass 2364 2365 2366class Or(Expression, Connector, Func): 2367 pass 2368 2369 2370class Xor(Expression, Connector, Func): 2371 arg_types = {"this": True, "expression": True, "round_input": False} 2372 2373 2374class Pow(Expression, Binary, Func): 2375 _sql_names = ["POWER", "POW"] 2376 2377 2378class RegexpLike(Expression, Binary, Predicate, Func): 2379 arg_types = {"this": True, "expression": True, "flag": False, "full_match": False} 2380 2381 2382def not_( 2383 expression: ExpOrStr, 2384 dialect: DialectType = None, 2385 copy: bool = True, 2386 **opts: Unpack[ParserNoDialectArgs], 2387) -> Not: 2388 """ 2389 Wrap a condition with a NOT operator. 2390 2391 Example: 2392 >>> not_("this_suit='black'").sql() 2393 "NOT this_suit = 'black'" 2394 2395 Args: 2396 expression: the SQL code string to parse. 2397 If an Expr instance is passed, this is used as-is. 2398 dialect: the dialect used to parse the input expression. 2399 copy: whether to copy the expression or not. 2400 **opts: other options to use to parse the input expressions. 2401 2402 Returns: 2403 The new condition. 2404 """ 2405 this = condition( 2406 expression, 2407 dialect=dialect, 2408 copy=copy, 2409 **opts, 2410 ) 2411 return Not(this=_wrap(this, Connector)) 2412 2413 2414def _lazy_unnest(**kwargs: object) -> Expr: 2415 from sqlglot.expressions.array import Unnest 2416 2417 return Unnest(**kwargs) 2418 2419 2420def convert(value: t.Any, copy: bool = False) -> Expr: 2421 """Convert a python value into an expression object. 2422 2423 Raises an error if a conversion is not possible. 2424 2425 Args: 2426 value: A python object. 2427 copy: Whether to copy `value` (only applies to Exprs and collections). 2428 2429 Returns: 2430 The equivalent expression object. 2431 """ 2432 if isinstance(value, Expr): 2433 return maybe_copy(value, copy) 2434 if isinstance(value, str): 2435 return Literal.string(value) 2436 if isinstance(value, bool): 2437 return Boolean(this=value) 2438 if value is None or (isinstance(value, float) and math.isnan(value)): 2439 return Null() 2440 if isinstance(value, numbers.Number): 2441 return Literal.number(value) 2442 if isinstance(value, bytes): 2443 from sqlglot.expressions.query import HexString as _HexString 2444 2445 return _HexString(this=value.hex()) 2446 if isinstance(value, datetime.datetime): 2447 datetime_literal = Literal.string(value.isoformat(sep=" ")) 2448 2449 tz = None 2450 if value.tzinfo: 2451 # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles" 2452 # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot 2453 tz = Literal.string(str(value.tzinfo)) 2454 2455 from sqlglot.expressions.temporal import TimeStrToTime as _TimeStrToTime 2456 2457 return _TimeStrToTime(this=datetime_literal, zone=tz) 2458 if isinstance(value, datetime.date): 2459 date_literal = Literal.string(value.strftime("%Y-%m-%d")) 2460 from sqlglot.expressions.temporal import DateStrToDate as _DateStrToDate 2461 2462 return _DateStrToDate(this=date_literal) 2463 if isinstance(value, datetime.time): 2464 time_literal = Literal.string(value.isoformat()) 2465 from sqlglot.expressions.temporal import TsOrDsToTime as _TsOrDsToTime 2466 2467 return _TsOrDsToTime(this=time_literal) 2468 if isinstance(value, tuple): 2469 if hasattr(value, "_fields"): 2470 from sqlglot.expressions.array import Struct as _Struct 2471 2472 return _Struct( 2473 expressions=[ 2474 PropertyEQ( 2475 this=to_identifier(k), expression=convert(getattr(value, k), copy=copy) 2476 ) 2477 for k in value._fields 2478 ] 2479 ) 2480 from sqlglot.expressions.query import Tuple as _Tuple 2481 2482 return _Tuple(expressions=[convert(v, copy=copy) for v in value]) 2483 if isinstance(value, list): 2484 from sqlglot.expressions.array import Array as _Array 2485 2486 return _Array(expressions=[convert(v, copy=copy) for v in value]) 2487 if isinstance(value, dict): 2488 from sqlglot.expressions.array import Array as _Array 2489 from sqlglot.expressions.array import Map as _Map 2490 2491 return _Map( 2492 keys=_Array(expressions=[convert(k, copy=copy) for k in value]), 2493 values=_Array(expressions=[convert(v, copy=copy) for v in value.values()]), 2494 ) 2495 if hasattr(value, "__dict__"): 2496 from sqlglot.expressions.array import Struct as _Struct 2497 2498 return _Struct( 2499 expressions=[ 2500 PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy)) 2501 for k, v in value.__dict__.items() 2502 ] 2503 ) 2504 raise ValueError(f"Cannot convert {value}") 2505 2506 2507QUERY_MODIFIERS = { 2508 "match": False, 2509 "laterals": False, 2510 "joins": False, 2511 "connect": False, 2512 "pivots": False, 2513 "prewhere": False, 2514 "where": False, 2515 "group": False, 2516 "having": False, 2517 "qualify": False, 2518 "windows": False, 2519 "distribute": False, 2520 "sort": False, 2521 "cluster": False, 2522 "order": False, 2523 "limit": False, 2524 "offset": False, 2525 "locks": False, 2526 "sample": False, 2527 "settings": False, 2528 "format": False, 2529 "options": False, 2530 "for_": False, 2531} 2532 2533 2534TIMESTAMP_PARTS = { 2535 "year": False, 2536 "month": False, 2537 "day": False, 2538 "hour": False, 2539 "min": False, 2540 "sec": False, 2541 "nano": False, 2542} 2543 2544 2545@t.overload 2546def maybe_parse( 2547 sql_or_expression: int | str, 2548 *, 2549 into: Type[E], 2550 dialect: DialectType = None, 2551 prefix: str | None = None, 2552 copy: bool = False, 2553 **opts: Unpack[ParserNoDialectArgs], 2554) -> E: ... 2555 2556 2557@t.overload 2558def maybe_parse( 2559 sql_or_expression: int | str | E, 2560 *, 2561 into: IntoType | None = None, 2562 dialect: DialectType = None, 2563 prefix: str | None = None, 2564 copy: bool = False, 2565 **opts: Unpack[ParserNoDialectArgs], 2566) -> E: ... 2567 2568 2569def maybe_parse( 2570 sql_or_expression: ExpOrStr, 2571 *, 2572 into: IntoType | None = None, 2573 dialect: DialectType = None, 2574 prefix: str | None = None, 2575 copy: bool = False, 2576 **opts: Unpack[ParserNoDialectArgs], 2577) -> Expr: 2578 """Gracefully handle a possible string or expression. 2579 2580 Example: 2581 >>> maybe_parse("1") 2582 Literal(this=1, is_string=False) 2583 >>> maybe_parse(to_identifier("x")) 2584 Identifier(this=x, quoted=False) 2585 2586 Args: 2587 sql_or_expression: the SQL code string or an expression 2588 into: the SQLGlot Expr to parse into 2589 dialect: the dialect used to parse the input expressions (in the case that an 2590 input expression is a SQL string). 2591 prefix: a string to prefix the sql with before it gets parsed 2592 (automatically includes a space) 2593 copy: whether to copy the expression. 2594 **opts: other options to use to parse the input expressions (again, in the case 2595 that an input expression is a SQL string). 2596 2597 Returns: 2598 Expr: the parsed or given expression. 2599 """ 2600 if isinstance(sql_or_expression, Expr): 2601 if copy: 2602 return sql_or_expression.copy() 2603 return sql_or_expression 2604 2605 if sql_or_expression is None: 2606 raise ParseError("SQL cannot be None") 2607 2608 import sqlglot 2609 2610 sql = str(sql_or_expression) 2611 if prefix: 2612 sql = f"{prefix} {sql}" 2613 2614 return sqlglot.parse_one(sql, read=dialect, into=into, **opts) 2615 2616 2617@t.overload 2618def maybe_copy(instance: None, copy: bool = True) -> None: ... 2619 2620 2621@t.overload 2622def maybe_copy(instance: E, copy: bool = True) -> E: ... 2623 2624 2625def maybe_copy(instance, copy=True): 2626 return instance.copy() if copy and instance else instance 2627 2628 2629def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str: 2630 """Generate a textual representation of an Expr tree""" 2631 indent = "\n" + (" " * (level + 1)) 2632 delim = f",{indent}" 2633 2634 if isinstance(node, Expr): 2635 args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose} 2636 2637 if (node.type or verbose) and not node.is_data_type: 2638 args["_type"] = node.type 2639 if node.comments or verbose: 2640 args["_comments"] = node.comments 2641 2642 if verbose: 2643 args["_id"] = id(node) 2644 2645 # Inline leaves for a more compact representation 2646 if node.is_leaf(): 2647 indent = "" 2648 delim = ", " 2649 2650 repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted) 2651 items = delim.join( 2652 [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()] 2653 ) 2654 return f"{node.__class__.__name__}({indent}{items})" 2655 2656 if isinstance(node, list): 2657 items = delim.join(_to_s(i, verbose, level + 1) for i in node) 2658 items = f"{indent}{items}" if items else "" 2659 return f"[{items}]" 2660 2661 # We use the representation of the string to avoid stripping out important whitespace 2662 if repr_str and isinstance(node, str): 2663 node = repr(node) 2664 2665 # Indent multiline strings to match the current level 2666 return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines()) 2667 2668 2669def _is_wrong_expression(expression, into): 2670 return isinstance(expression, Expr) and not isinstance(expression, into) 2671 2672 2673def _apply_builder( 2674 expression: ExpOrStr, 2675 instance: E, 2676 arg: str, 2677 copy: bool = True, 2678 prefix: str | None = None, 2679 into: Type[Expr] | None = None, 2680 dialect: DialectType = None, 2681 into_arg="this", 2682 **opts: Unpack[ParserNoDialectArgs], 2683) -> E: 2684 if _is_wrong_expression(expression, into) and into is not None: 2685 expression = into(**{into_arg: expression}) 2686 instance = maybe_copy(instance, copy) 2687 expression = maybe_parse( 2688 sql_or_expression=expression, 2689 prefix=prefix, 2690 into=into, 2691 dialect=dialect, 2692 **opts, 2693 ) 2694 instance.set(arg, expression) 2695 return instance 2696 2697 2698def _apply_child_list_builder( 2699 *expressions: ExpOrStr | None, 2700 instance: E, 2701 arg: str, 2702 append: bool = True, 2703 copy: bool = True, 2704 prefix: str | None = None, 2705 into: Type[Expr] | None = None, 2706 dialect: DialectType = None, 2707 properties: MutableMapping[str, object] | None = None, 2708 **opts: Unpack[ParserNoDialectArgs], 2709) -> E: 2710 instance = maybe_copy(instance, copy) 2711 parsed = [] 2712 properties = {} if properties is None else properties 2713 2714 for expression in expressions: 2715 if expression is not None: 2716 if _is_wrong_expression(expression, into) and into is not None: 2717 expression = into(expressions=[expression]) 2718 2719 expression = maybe_parse( 2720 expression, 2721 into=into, 2722 dialect=dialect, 2723 prefix=prefix, 2724 **opts, 2725 ) 2726 for k, v in expression.args.items(): 2727 if k == "expressions": 2728 parsed.extend(v) 2729 else: 2730 properties[k] = v 2731 2732 existing = instance.args.get(arg) 2733 if append and existing: 2734 parsed = existing.expressions + parsed 2735 if into is None: 2736 raise ValueError("`into` is required to use `_apply_child_list_builder`") 2737 child = into(expressions=parsed) 2738 for k, v in properties.items(): 2739 child.set(k, v) 2740 instance.set(arg, child) 2741 2742 return instance 2743 2744 2745def _apply_list_builder( 2746 *expressions: ExpOrStr | None, 2747 instance: E, 2748 arg: str, 2749 append: bool = True, 2750 copy: bool = True, 2751 prefix: str | None = None, 2752 into: Type[Expr] | None = None, 2753 dialect: DialectType = None, 2754 **opts: Unpack[ParserNoDialectArgs], 2755) -> E: 2756 inst = maybe_copy(instance, copy) 2757 2758 parsed = [ 2759 maybe_parse( 2760 sql_or_expression=expression, 2761 into=into, 2762 prefix=prefix, 2763 dialect=dialect, 2764 **opts, 2765 ) 2766 for expression in expressions 2767 if expression is not None 2768 ] 2769 2770 existing_expressions = inst.args.get(arg) 2771 if append and existing_expressions: 2772 parsed = existing_expressions + parsed 2773 2774 inst.set(arg, parsed) 2775 return inst 2776 2777 2778def _apply_conjunction_builder( 2779 *expressions: ExpOrStr | None, 2780 instance: E, 2781 arg: str, 2782 into: Type[Expr] | None = None, 2783 append: bool = True, 2784 copy: bool = True, 2785 dialect: DialectType = None, 2786 **opts: Unpack[ParserNoDialectArgs], 2787) -> E: 2788 filtered = [exp for exp in expressions if exp is not None and exp != ""] 2789 if not filtered: 2790 return instance 2791 2792 inst = maybe_copy(instance, copy) 2793 2794 existing = inst.args.get(arg) 2795 if append and existing is not None: 2796 filtered = [existing.this if into else existing] + filtered 2797 2798 node = and_(*filtered, dialect=dialect, copy=copy, **opts) 2799 2800 inst.set(arg, into(this=node) if into else node) 2801 return inst 2802 2803 2804def _combine( 2805 expressions: Sequence[ExpOrStr | None], 2806 operator: Type[Expr], 2807 dialect: DialectType = None, 2808 copy: bool = True, 2809 wrap: bool = True, 2810 **opts: Unpack[ParserNoDialectArgs], 2811) -> Expr: 2812 conditions = [ 2813 condition(expression, dialect=dialect, copy=copy, **opts) 2814 for expression in expressions 2815 if expression is not None 2816 ] 2817 2818 this, *rest = conditions 2819 if rest and wrap: 2820 this = _wrap(this, Connector) 2821 for expression in rest: 2822 this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression) 2823 2824 return this 2825 2826 2827@t.overload 2828def _wrap(expression: None, kind: Type[Expr]) -> None: ... 2829 2830 2831@t.overload 2832def _wrap(expression: E, kind: Type[Expr]) -> E | Paren: ... 2833 2834 2835def _wrap(expression: E | None, kind: Type[Expr]) -> E | None | Paren: 2836 return Paren(this=expression) if isinstance(expression, kind) else expression 2837 2838 2839def _apply_set_operation( 2840 *expressions: ExpOrStr, 2841 set_operation: Type, 2842 distinct: bool = True, 2843 dialect: DialectType = None, 2844 copy: bool = True, 2845 **opts: Unpack[ParserNoDialectArgs], 2846) -> t.Any: 2847 return reduce( 2848 lambda x, y: set_operation(this=x, expression=y, distinct=distinct, **opts), 2849 (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions), 2850 ) 2851 2852 2853SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$") 2854 2855 2856@t.overload 2857def to_identifier(name: None, quoted: bool | None = None, copy: bool = True) -> None: ... 2858 2859 2860@t.overload 2861def to_identifier( 2862 name: int | str | Identifier, quoted: bool | None = None, copy: bool = True 2863) -> Identifier: ... 2864 2865 2866def to_identifier(name, quoted=None, copy=True): 2867 """Builds an identifier. 2868 2869 Args: 2870 name: The name to turn into an identifier. 2871 quoted: Whether to force quote the identifier. 2872 copy: Whether to copy name if it's an Identifier. 2873 2874 Returns: 2875 The identifier ast node. 2876 """ 2877 2878 if name is None: 2879 return None 2880 2881 if isinstance(name, Identifier): 2882 identifier = maybe_copy(name, copy) 2883 elif isinstance(name, str): 2884 identifier = Identifier( 2885 this=name, 2886 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, 2887 ) 2888 else: 2889 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") 2890 return identifier 2891 2892 2893def condition( 2894 expression: ExpOrStr, 2895 dialect: DialectType = None, 2896 copy: bool = True, 2897 **opts: Unpack[ParserNoDialectArgs], 2898) -> Expr: 2899 """ 2900 Initialize a logical condition expression. 2901 2902 Example: 2903 >>> condition("x=1").sql() 2904 'x = 1' 2905 2906 This is helpful for composing larger logical syntax trees: 2907 >>> where = condition("x=1") 2908 >>> where = where.and_("y=1") 2909 >>> where.sql() 2910 'x = 1 AND y = 1' 2911 2912 Args: 2913 *expression: the SQL code string to parse. 2914 If an Expr instance is passed, this is used as-is. 2915 dialect: the dialect used to parse the input expression (in the case that the 2916 input expression is a SQL string). 2917 copy: Whether to copy `expression` (only applies to expressions). 2918 **opts: other options to use to parse the input expressions (again, in the case 2919 that the input expression is a SQL string). 2920 2921 Returns: 2922 The new Condition instance 2923 """ 2924 return maybe_parse( 2925 expression, 2926 into=Condition, 2927 dialect=dialect, 2928 copy=copy, 2929 **opts, 2930 ) 2931 2932 2933def and_( 2934 *expressions: ExpOrStr | None, 2935 dialect: DialectType = None, 2936 copy: bool = True, 2937 wrap: bool = True, 2938 **opts: Unpack[ParserNoDialectArgs], 2939) -> Condition: 2940 """ 2941 Combine multiple conditions with an AND logical operator. 2942 2943 Example: 2944 >>> and_("x=1", and_("y=1", "z=1")).sql() 2945 'x = 1 AND (y = 1 AND z = 1)' 2946 2947 Args: 2948 *expressions: the SQL code strings to parse. 2949 If an Expr instance is passed, this is used as-is. 2950 dialect: the dialect used to parse the input expression. 2951 copy: whether to copy `expressions` (only applies to Exprs). 2952 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2953 precedence issues, but can be turned off when the produced AST is too deep and 2954 causes recursion-related issues. 2955 **opts: other options to use to parse the input expressions. 2956 2957 Returns: 2958 The new condition 2959 """ 2960 return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts)) 2961 2962 2963def or_( 2964 *expressions: ExpOrStr | None, 2965 dialect: DialectType = None, 2966 copy: bool = True, 2967 wrap: bool = True, 2968 **opts: Unpack[ParserNoDialectArgs], 2969) -> Condition: 2970 """ 2971 Combine multiple conditions with an OR logical operator. 2972 2973 Example: 2974 >>> or_("x=1", or_("y=1", "z=1")).sql() 2975 'x = 1 OR (y = 1 OR z = 1)' 2976 2977 Args: 2978 *expressions: the SQL code strings to parse. 2979 If an Expr instance is passed, this is used as-is. 2980 dialect: the dialect used to parse the input expression. 2981 copy: whether to copy `expressions` (only applies to Exprs). 2982 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2983 precedence issues, but can be turned off when the produced AST is too deep and 2984 causes recursion-related issues. 2985 **opts: other options to use to parse the input expressions. 2986 2987 Returns: 2988 The new condition 2989 """ 2990 return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts)) 2991 2992 2993def xor( 2994 *expressions: ExpOrStr | None, 2995 dialect: DialectType = None, 2996 copy: bool = True, 2997 wrap: bool = True, 2998 **opts: Unpack[ParserNoDialectArgs], 2999) -> Condition: 3000 """ 3001 Combine multiple conditions with an XOR logical operator. 3002 3003 Example: 3004 >>> xor("x=1", xor("y=1", "z=1")).sql() 3005 'x = 1 XOR (y = 1 XOR z = 1)' 3006 3007 Args: 3008 *expressions: the SQL code strings to parse. 3009 If an Expr instance is passed, this is used as-is. 3010 dialect: the dialect used to parse the input expression. 3011 copy: whether to copy `expressions` (only applies to Exprs). 3012 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 3013 precedence issues, but can be turned off when the produced AST is too deep and 3014 causes recursion-related issues. 3015 **opts: other options to use to parse the input expressions. 3016 3017 Returns: 3018 The new condition 3019 """ 3020 return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts)) 3021 3022 3023def paren(expression: ExpOrStr, copy: bool = True) -> Paren: 3024 """ 3025 Wrap an expression in parentheses. 3026 3027 Example: 3028 >>> paren("5 + 3").sql() 3029 '(5 + 3)' 3030 3031 Args: 3032 expression: the SQL code string to parse. 3033 If an Expr instance is passed, this is used as-is. 3034 copy: whether to copy the expression or not. 3035 3036 Returns: 3037 The wrapped expression. 3038 """ 3039 return Paren(this=maybe_parse(expression, copy=copy)) 3040 3041 3042def alias_( 3043 expression: ExpOrStr, 3044 alias: str | Identifier | None, 3045 table: bool | Sequence[str | Identifier] = False, 3046 quoted: bool | None = None, 3047 dialect: DialectType = None, 3048 copy: bool = True, 3049 **opts: Unpack[ParserNoDialectArgs], 3050) -> Expr: 3051 """Create an Alias expression. 3052 3053 Example: 3054 >>> alias_('foo', 'bar').sql() 3055 'foo AS bar' 3056 3057 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() 3058 '(SELECT 1, 2) AS bar(a, b)' 3059 3060 Args: 3061 expression: the SQL code strings to parse. 3062 If an Expr instance is passed, this is used as-is. 3063 alias: the alias name to use. If the name has 3064 special characters it is quoted. 3065 table: Whether to create a table alias, can also be a list of columns. 3066 quoted: whether to quote the alias 3067 dialect: the dialect used to parse the input expression. 3068 copy: Whether to copy the expression. 3069 **opts: other options to use to parse the input expressions. 3070 3071 Returns: 3072 Alias: the aliased expression 3073 """ 3074 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) 3075 alias = to_identifier(alias, quoted=quoted) 3076 3077 if table: 3078 from sqlglot.expressions.query import TableAlias as _TableAlias 3079 3080 table_alias = _TableAlias(this=alias) 3081 exp.set("alias", table_alias) 3082 3083 if not isinstance(table, bool): 3084 for column in table: 3085 table_alias.append("columns", to_identifier(column, quoted=quoted)) 3086 3087 return exp 3088 3089 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in 3090 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node 3091 # for the complete Window expression. 3092 # 3093 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls 3094 3095 if "alias" in exp.arg_types and type(exp).__name__ != "Window": 3096 exp.set("alias", alias) 3097 return exp 3098 return Alias(this=exp, alias=alias) 3099 3100 3101@t.overload 3102def column( 3103 col: str | Expr, 3104 table: str | Identifier | None = None, 3105 db: str | Identifier | None = None, 3106 catalog: str | Identifier | None = None, 3107 *, 3108 fields: Collection[str | Identifier], 3109 quoted: bool | None = None, 3110 copy: bool = True, 3111) -> Dot: 3112 pass 3113 3114 3115@t.overload 3116def column( 3117 col: str | Expr, 3118 table: str | Identifier | None = None, 3119 db: str | Identifier | None = None, 3120 catalog: str | Identifier | None = None, 3121 *, 3122 fields: t.Literal[None] = None, 3123 quoted: bool | None = None, 3124 copy: bool = True, 3125) -> Column: 3126 pass 3127 3128 3129def column( 3130 col, 3131 table=None, 3132 db=None, 3133 catalog=None, 3134 *, 3135 fields=None, 3136 quoted=None, 3137 copy: bool = True, 3138): 3139 """ 3140 Build a Column. 3141 3142 Args: 3143 col: Column name or expression. 3144 table: Table name. 3145 db: Database name. 3146 catalog: Catalog name. 3147 fields: Additional fields using dots. 3148 quoted: Whether to force quotes on the column's identifiers. 3149 copy: Whether to copy expressions if passed in. 3150 3151 Returns: 3152 The new Column instance. 3153 """ 3154 col = maybe_copy(col, copy) if isinstance(col, Expr) else to_identifier(col, quoted=quoted) 3155 3156 this: Column | Dot = Column( 3157 this=col, 3158 table=to_identifier(table, quoted=quoted, copy=copy), 3159 db=to_identifier(db, quoted=quoted, copy=copy), 3160 catalog=to_identifier(catalog, quoted=quoted, copy=copy), 3161 ) 3162 3163 if fields: 3164 this = Dot.build( 3165 (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields)) 3166 ) 3167 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, tuple(v) if type(v) is list else 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 try: 938 return self.is_number and isinstance(self.to_py(), int) 939 except ValueError: 940 return False 941 942 @property 943 def is_star(self) -> bool: 944 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star)) 945 946 @property 947 def alias(self) -> str: 948 alias = self.args.get("alias") 949 if isinstance(alias, Expression): 950 return alias.name 951 return self.text("alias") 952 953 @property 954 def alias_column_names(self) -> list[str]: 955 table_alias = self.args.get("alias") 956 if not table_alias: 957 return [] 958 return [c.name for c in table_alias.args.get("columns") or []] 959 960 @property 961 def name(self) -> str: 962 return self.text("this") 963 964 @property 965 def alias_or_name(self) -> str: 966 return self.alias or self.name 967 968 @property 969 def output_name(self) -> str: 970 return "" 971 972 @property 973 def type(self) -> DataType | None: 974 if self.is_data_type: 975 return self # type: ignore[return-value] 976 if self.is_cast: 977 return self._type or self.to # type: ignore[attr-defined] 978 return self._type 979 980 @type.setter 981 def type(self, dtype: DataType | DType | str | None) -> None: 982 if dtype and type(dtype).__name__ != "DataType": 983 from sqlglot.expressions.datatypes import DataType as _DataType 984 985 dtype = _DataType.build(dtype) 986 self._type = dtype # type: ignore[assignment] 987 988 def is_type(self, *dtypes: DATA_TYPE) -> bool: 989 t = self._type 990 return t is not None and t.is_type(*dtypes) 991 992 def is_leaf(self) -> bool: 993 return not any((isinstance(v, Expr) or type(v) is list) and v for v in self.args.values()) 994 995 @property 996 def meta(self) -> dict[str, t.Any]: 997 if self._meta is None: 998 self._meta = {} 999 return self._meta 1000 1001 def meta_get(self, key: str, default: t.Any = None) -> t.Any: 1002 """Reads a meta value without allocating the meta dict (unlike the `meta` property).""" 1003 meta = self._meta 1004 return meta.get(key, default) if meta is not None else default 1005 1006 def __deepcopy__(self, memo: t.Any) -> Expr: 1007 root = self.__class__() 1008 stack: list[tuple[Expr, Expr]] = [(self, root)] 1009 1010 while stack: 1011 node, copy = stack.pop() 1012 1013 if node.comments is not None: 1014 copy.comments = deepcopy(node.comments) 1015 if node._type is not None: 1016 copy._type = deepcopy(node._type) 1017 if node._meta is not None: 1018 copy._meta = deepcopy(node._meta) 1019 if node._hash is not None: 1020 copy._hash = node._hash 1021 1022 for k, vs in node.args.items(): 1023 if isinstance(vs, Expr): 1024 stack.append((vs, vs.__class__())) 1025 copy.set(k, stack[-1][-1]) 1026 elif type(vs) is list: 1027 copy.args[k] = [] 1028 1029 for v in vs: 1030 if isinstance(v, Expr): 1031 stack.append((v, v.__class__())) 1032 copy.append(k, stack[-1][-1]) 1033 else: 1034 copy.append(k, v) 1035 else: 1036 copy.args[k] = vs 1037 1038 return root 1039 1040 def copy(self: E) -> E: 1041 return deepcopy(self) 1042 1043 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 1044 if self.comments is None: 1045 self.comments = [] 1046 1047 if comments: 1048 for comment in comments: 1049 _, *meta = comment.split(SQLGLOT_META) 1050 if meta: 1051 for kv in "".join(meta).split(","): 1052 k, *v = kv.split("=") 1053 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 1054 1055 if not prepend: 1056 self.comments.append(comment) 1057 1058 if prepend: 1059 self.comments = comments + self.comments 1060 1061 def pop_comments(self) -> list[str]: 1062 comments = self.comments or [] 1063 self.comments = None 1064 return comments 1065 1066 def append(self, arg_key: str, value: t.Any) -> None: 1067 node: Expr | None = self 1068 while node and node._hash is not None: 1069 node._hash = None 1070 node = node.parent 1071 1072 if type(self.args.get(arg_key)) is not list: 1073 self.args[arg_key] = [] 1074 self._set_parent(arg_key, value) 1075 values = self.args[arg_key] 1076 if isinstance(value, Expr): 1077 value.index = len(values) 1078 values.append(value) 1079 1080 def set( 1081 self, 1082 arg_key: str, 1083 value: object, 1084 index: int | None = None, 1085 overwrite: bool = True, 1086 ) -> None: 1087 node: Expr | None = self 1088 1089 while node and node._hash is not None: 1090 node._hash = None 1091 node = node.parent 1092 1093 if index is not None: 1094 expressions = self.args.get(arg_key) or [] 1095 1096 if seq_get(expressions, index) is None: 1097 return 1098 1099 if value is None: 1100 expressions.pop(index) 1101 for v in expressions[index:]: 1102 v.index = v.index - 1 1103 return 1104 1105 if isinstance(value, list): 1106 expressions.pop(index) 1107 expressions[index:index] = value 1108 elif overwrite: 1109 expressions[index] = value 1110 else: 1111 expressions.insert(index, value) 1112 1113 value = expressions 1114 elif value is None: 1115 self.args.pop(arg_key, None) 1116 return 1117 1118 self.args[arg_key] = value 1119 self._set_parent(arg_key, value, index) 1120 1121 def _set_parent(self, arg_key: str, value: object, index: int | None = None) -> None: 1122 if isinstance(value, Expr): 1123 value.parent = self 1124 value.arg_key = arg_key 1125 value.index = index 1126 elif isinstance(value, list): 1127 for i, v in enumerate(value): 1128 if isinstance(v, Expr): 1129 v.parent = self 1130 v.arg_key = arg_key 1131 v.index = i 1132 1133 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 1134 """Set multiples keyword arguments at once, using `.set()` method. 1135 1136 Args: 1137 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 1138 Returns: 1139 Self: The same `Expression` with the updated arguments. 1140 """ 1141 if kwargs: 1142 for k, v in kwargs.items(): 1143 self.set(k, v) 1144 return self 1145 1146 @property 1147 def depth(self) -> int: 1148 if self.parent: 1149 return self.parent.depth + 1 1150 return 0 1151 1152 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 1153 for vs in reversed(self.args.values()) if reverse else self.args.values(): 1154 if isinstance(vs, list): 1155 for v in reversed(vs) if reverse else vs: 1156 if isinstance(v, Expr): 1157 yield t.cast(E, v) 1158 elif isinstance(vs, Expr): 1159 yield t.cast(E, vs) 1160 1161 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 1162 return next(self.find_all(*expression_types, bfs=bfs), None) 1163 1164 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 1165 for expression in self.walk(bfs=bfs): 1166 if isinstance(expression, expression_types): 1167 yield expression 1168 1169 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 1170 ancestor = self.parent 1171 while ancestor and not isinstance(ancestor, expression_types): 1172 ancestor = ancestor.parent 1173 return ancestor # type: ignore[return-value] 1174 1175 @property 1176 def parent_select(self) -> Select | None: 1177 from sqlglot.expressions.query import Select as _Select 1178 1179 return self.find_ancestor(_Select) 1180 1181 @property 1182 def same_parent(self) -> bool: 1183 return type(self.parent) is self.__class__ 1184 1185 def root(self) -> Expr: 1186 expression: Expr = self 1187 while expression.parent: 1188 expression = expression.parent 1189 return expression 1190 1191 def walk( 1192 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 1193 ) -> Iterator[Expr]: 1194 if bfs: 1195 yield from self.bfs(prune=prune) 1196 else: 1197 yield from self.dfs(prune=prune) 1198 1199 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1200 stack = [self] 1201 1202 while stack: 1203 node = stack.pop() 1204 yield node 1205 if prune and prune(node): 1206 continue 1207 for v in node.iter_expressions(reverse=True): 1208 stack.append(v) 1209 1210 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1211 queue: deque[Expr] = deque() 1212 queue.append(self) 1213 1214 while queue: 1215 node = queue.popleft() 1216 yield node 1217 if prune and prune(node): 1218 continue 1219 for v in node.iter_expressions(): 1220 queue.append(v) 1221 1222 def unnest(self) -> Expr: 1223 expression = self 1224 while type(expression) is Paren: 1225 expression = expression.this 1226 return expression 1227 1228 def unalias(self) -> Expr: 1229 if isinstance(self, Alias): 1230 return self.this 1231 return self 1232 1233 def unnest_operands(self) -> tuple[Expr, ...]: 1234 return tuple(arg.unnest() for arg in self.iter_expressions()) 1235 1236 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1237 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1238 if type(node) is not self.__class__: 1239 yield node.unnest() if unnest and not node.is_subquery else node 1240 1241 def __str__(self) -> str: 1242 return self.sql() 1243 1244 def __repr__(self) -> str: 1245 return _to_s(self) 1246 1247 def to_s(self) -> str: 1248 return _to_s(self, verbose=True) 1249 1250 def sql( 1251 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1252 ) -> str: 1253 from sqlglot.dialects.dialect import Dialect 1254 1255 return Dialect.get_or_raise(dialect).generate(self, copy=copy, **opts) 1256 1257 def transform( 1258 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 1259 ) -> T: 1260 root: t.Any = None 1261 new_node: t.Any = None 1262 1263 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1264 parent, arg_key, index = node.parent, node.arg_key, node.index 1265 new_node = fun(node, *args, **kwargs) 1266 1267 if not root: 1268 root = new_node 1269 elif parent and arg_key and new_node is not node: 1270 parent.set(arg_key, new_node, index) 1271 1272 assert root 1273 return root 1274 1275 def replace(self, expression: T) -> T: 1276 parent = self.parent 1277 1278 if not parent or parent is expression: 1279 return expression 1280 1281 key = self.arg_key 1282 1283 if key: 1284 value = parent.args.get(key) 1285 1286 if type(expression) is list and isinstance(value, Expr): 1287 # We are trying to replace an Expr with a list, so it's assumed that 1288 # the intention was to really replace the parent of this expression. 1289 if value.parent: 1290 value.parent.replace(expression) 1291 else: 1292 parent.set(key, expression, self.index) 1293 1294 if expression is not self: 1295 self.parent = None 1296 self.arg_key = None 1297 self.index = None 1298 1299 return expression 1300 1301 def pop(self: E) -> E: 1302 self.replace(None) 1303 return self 1304 1305 def assert_is(self, type_: Type[E]) -> E: 1306 if not isinstance(self, type_): 1307 raise AssertionError(f"{self} is not {type_}.") 1308 return self 1309 1310 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1311 if UNITTEST: 1312 for k in self.args: 1313 if k not in self.arg_types: 1314 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1315 1316 errors: list[str] | None = None 1317 1318 for k in self.required_args: 1319 v = self.args.get(k) 1320 if v is None or (isinstance(v, list) and not v): 1321 if errors is None: 1322 errors = [] 1323 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1324 1325 if ( 1326 args 1327 and isinstance(self, Func) 1328 and len(args) > len(self.arg_types) 1329 and not self.is_var_len_args 1330 ): 1331 if errors is None: 1332 errors = [] 1333 errors.append( 1334 f"The number of provided arguments ({len(args)}) is greater than " 1335 f"the maximum number of supported arguments ({len(self.arg_types)})" 1336 ) 1337 1338 return errors or [] 1339 1340 def and_( 1341 self, 1342 *expressions: ExpOrStr | None, 1343 dialect: DialectType = None, 1344 copy: bool = True, 1345 wrap: bool = True, 1346 **opts: Unpack[ParserNoDialectArgs], 1347 ) -> Condition: 1348 return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1349 1350 def or_( 1351 self, 1352 *expressions: ExpOrStr | None, 1353 dialect: DialectType = None, 1354 copy: bool = True, 1355 wrap: bool = True, 1356 **opts: Unpack[ParserNoDialectArgs], 1357 ) -> Condition: 1358 return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts) 1359 1360 def not_(self, copy: bool = True) -> Not: 1361 return not_(self, copy=copy) 1362 1363 def update_positions( 1364 self: E, 1365 other: Token | Expr | None = None, 1366 line: int | None = None, 1367 col: int | None = None, 1368 start: int | None = None, 1369 end: int | None = None, 1370 ) -> E: 1371 if isinstance(other, Token): 1372 meta = self.meta 1373 meta["line"] = other.line 1374 meta["col"] = other.col 1375 meta["start"] = other.start 1376 meta["end"] = other.end 1377 elif other is not None: 1378 other_meta = other._meta 1379 if other_meta: 1380 meta = self.meta 1381 for k in POSITION_META_KEYS: 1382 if k in other_meta: 1383 meta[k] = other_meta[k] 1384 else: 1385 meta = self.meta 1386 meta["line"] = line 1387 meta["col"] = col 1388 meta["start"] = start 1389 meta["end"] = end 1390 return self 1391 1392 def as_( 1393 self, 1394 alias: str | Identifier, 1395 quoted: bool | None = None, 1396 dialect: DialectType = None, 1397 copy: bool = True, 1398 table: bool | Sequence[str | Identifier] = False, 1399 **opts: Unpack[ParserNoDialectArgs], 1400 ) -> Expr: 1401 return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, table=table, **opts) 1402 1403 def _binop(self, klass: Type[E], other: t.Any, reverse: bool = False) -> E: 1404 this = self.copy() 1405 other = convert(other, copy=True) 1406 if not isinstance(this, klass) and not isinstance(other, klass): 1407 this = _wrap(this, Binary) 1408 other = _wrap(other, Binary) 1409 if reverse: 1410 return klass(this=other, expression=this) 1411 return klass(this=this, expression=other) 1412 1413 def __getitem__(self, other: ExpOrStr | tuple[ExpOrStr, ...]) -> Bracket: 1414 return Bracket( 1415 this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)] 1416 ) 1417 1418 def __iter__(self) -> Iterator: 1419 if "expressions" in self.arg_types: 1420 return iter(self.args.get("expressions") or []) 1421 # We define this because __getitem__ converts Expr into an iterable, which is 1422 # problematic because one can hit infinite loops if they do "for x in some_expr: ..." 1423 # See: https://peps.python.org/pep-0234/ 1424 raise TypeError(f"'{self.__class__.__name__}' object is not iterable") 1425 1426 def isin( 1427 self, 1428 *expressions: t.Any, 1429 query: ExpOrStr | None = None, 1430 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 1431 dialect: DialectType = None, 1432 copy: bool = True, 1433 **opts: Unpack[ParserNoDialectArgs], 1434 ) -> In: 1435 from sqlglot.expressions.query import Query 1436 1437 subquery: Expr | None = None 1438 if query: 1439 subquery = maybe_parse(query, dialect=dialect, copy=copy, **opts) 1440 if isinstance(subquery, Query): 1441 subquery = subquery.subquery(copy=False) 1442 unnest_list: list[ExpOrStr] = ensure_list(unnest) 1443 return In( 1444 this=maybe_copy(self, copy), 1445 expressions=[convert(e, copy=copy) for e in expressions], 1446 query=subquery, 1447 unnest=( 1448 _lazy_unnest( 1449 expressions=[ 1450 maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in unnest_list 1451 ] 1452 ) 1453 if unnest 1454 else None 1455 ), 1456 ) 1457 1458 def between( 1459 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 1460 ) -> Between: 1461 between = Between( 1462 this=maybe_copy(self, copy), 1463 low=convert(low, copy=copy), 1464 high=convert(high, copy=copy), 1465 ) 1466 if symmetric is not None: 1467 between.set("symmetric", symmetric) 1468 1469 return between 1470 1471 def is_(self, other: ExpOrStr) -> Is: 1472 return self._binop(Is, other) 1473 1474 def like(self, other: ExpOrStr) -> Like: 1475 return self._binop(Like, other) 1476 1477 def ilike(self, other: ExpOrStr) -> ILike: 1478 return self._binop(ILike, other) 1479 1480 def eq(self, other: t.Any) -> EQ: 1481 return self._binop(EQ, other) 1482 1483 def neq(self, other: t.Any) -> NEQ: 1484 return self._binop(NEQ, other) 1485 1486 def rlike(self, other: ExpOrStr) -> RegexpLike: 1487 return self._binop(RegexpLike, other) 1488 1489 def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div: 1490 div = self._binop(Div, other) 1491 div.set("typed", typed) 1492 div.set("safe", safe) 1493 return div 1494 1495 def asc(self, nulls_first: bool = True) -> Ordered: 1496 return Ordered(this=self.copy(), nulls_first=nulls_first) 1497 1498 def desc(self, nulls_first: bool = False) -> Ordered: 1499 return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first) 1500 1501 def __lt__(self, other: t.Any) -> LT: 1502 return self._binop(LT, other) 1503 1504 def __le__(self, other: t.Any) -> LTE: 1505 return self._binop(LTE, other) 1506 1507 def __gt__(self, other: t.Any) -> GT: 1508 return self._binop(GT, other) 1509 1510 def __ge__(self, other: t.Any) -> GTE: 1511 return self._binop(GTE, other) 1512 1513 def __add__(self, other: t.Any) -> Add: 1514 return self._binop(Add, other) 1515 1516 def __radd__(self, other: t.Any) -> Add: 1517 return self._binop(Add, other, reverse=True) 1518 1519 def __sub__(self, other: t.Any) -> Sub: 1520 return self._binop(Sub, other) 1521 1522 def __rsub__(self, other: t.Any) -> Sub: 1523 return self._binop(Sub, other, reverse=True) 1524 1525 def __mul__(self, other: t.Any) -> Mul: 1526 return self._binop(Mul, other) 1527 1528 def __rmul__(self, other: t.Any) -> Mul: 1529 return self._binop(Mul, other, reverse=True) 1530 1531 def __truediv__(self, other: t.Any) -> Div: 1532 return self._binop(Div, other) 1533 1534 def __rtruediv__(self, other: t.Any) -> Div: 1535 return self._binop(Div, other, reverse=True) 1536 1537 def __floordiv__(self, other: t.Any) -> IntDiv: 1538 return self._binop(IntDiv, other) 1539 1540 def __rfloordiv__(self, other: t.Any) -> IntDiv: 1541 return self._binop(IntDiv, other, reverse=True) 1542 1543 def __mod__(self, other: t.Any) -> Mod: 1544 return self._binop(Mod, other) 1545 1546 def __rmod__(self, other: t.Any) -> Mod: 1547 return self._binop(Mod, other, reverse=True) 1548 1549 def __pow__(self, other: t.Any) -> Pow: 1550 return self._binop(Pow, other) 1551 1552 def __rpow__(self, other: t.Any) -> Pow: 1553 return self._binop(Pow, other, reverse=True) 1554 1555 def __and__(self, other: t.Any) -> And: 1556 return self._binop(And, other) 1557 1558 def __rand__(self, other: t.Any) -> And: 1559 return self._binop(And, other, reverse=True) 1560 1561 def __or__(self, other: t.Any) -> Or: 1562 return self._binop(Or, other) 1563 1564 def __ror__(self, other: t.Any) -> Or: 1565 return self._binop(Or, other, reverse=True) 1566 1567 def __neg__(self) -> Neg: 1568 return Neg(this=_wrap(self.copy(), Binary)) 1569 1570 def __invert__(self) -> Not: 1571 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 try: 938 return self.is_number and isinstance(self.to_py(), int) 939 except ValueError: 940 return False
Checks whether an expression is an integer.
942 @property 943 def is_star(self) -> bool: 944 return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
Checks whether an expression is a star.
946 @property 947 def alias(self) -> str: 948 alias = self.args.get("alias") 949 if isinstance(alias, Expression): 950 return alias.name 951 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 ''
1001 def meta_get(self, key: str, default: t.Any = None) -> t.Any: 1002 """Reads a meta value without allocating the meta dict (unlike the `meta` property).""" 1003 meta = self._meta 1004 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).
1043 def add_comments(self, comments: list[str] | None = None, prepend: bool = False) -> None: 1044 if self.comments is None: 1045 self.comments = [] 1046 1047 if comments: 1048 for comment in comments: 1049 _, *meta = comment.split(SQLGLOT_META) 1050 if meta: 1051 for kv in "".join(meta).split(","): 1052 k, *v = kv.split("=") 1053 self.meta[k.strip()] = to_bool(v[0].strip() if v else True) 1054 1055 if not prepend: 1056 self.comments.append(comment) 1057 1058 if prepend: 1059 self.comments = comments + self.comments
1066 def append(self, arg_key: str, value: t.Any) -> None: 1067 node: Expr | None = self 1068 while node and node._hash is not None: 1069 node._hash = None 1070 node = node.parent 1071 1072 if type(self.args.get(arg_key)) is not list: 1073 self.args[arg_key] = [] 1074 self._set_parent(arg_key, value) 1075 values = self.args[arg_key] 1076 if isinstance(value, Expr): 1077 value.index = len(values) 1078 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
1080 def set( 1081 self, 1082 arg_key: str, 1083 value: object, 1084 index: int | None = None, 1085 overwrite: bool = True, 1086 ) -> None: 1087 node: Expr | None = self 1088 1089 while node and node._hash is not None: 1090 node._hash = None 1091 node = node.parent 1092 1093 if index is not None: 1094 expressions = self.args.get(arg_key) or [] 1095 1096 if seq_get(expressions, index) is None: 1097 return 1098 1099 if value is None: 1100 expressions.pop(index) 1101 for v in expressions[index:]: 1102 v.index = v.index - 1 1103 return 1104 1105 if isinstance(value, list): 1106 expressions.pop(index) 1107 expressions[index:index] = value 1108 elif overwrite: 1109 expressions[index] = value 1110 else: 1111 expressions.insert(index, value) 1112 1113 value = expressions 1114 elif value is None: 1115 self.args.pop(arg_key, None) 1116 return 1117 1118 self.args[arg_key] = value 1119 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).
1133 def set_kwargs(self, kwargs: Mapping[str, object]) -> Self: 1134 """Set multiples keyword arguments at once, using `.set()` method. 1135 1136 Args: 1137 kwargs (Mapping[str, object]): a `Mapping` of arg keys to values to set. 1138 Returns: 1139 Self: The same `Expression` with the updated arguments. 1140 """ 1141 if kwargs: 1142 for k, v in kwargs.items(): 1143 self.set(k, v) 1144 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.
1146 @property 1147 def depth(self) -> int: 1148 if self.parent: 1149 return self.parent.depth + 1 1150 return 0
Returns the depth of this tree.
1152 def iter_expressions(self: E, reverse: bool = False) -> Iterator[E]: 1153 for vs in reversed(self.args.values()) if reverse else self.args.values(): 1154 if isinstance(vs, list): 1155 for v in reversed(vs) if reverse else vs: 1156 if isinstance(v, Expr): 1157 yield t.cast(E, v) 1158 elif isinstance(vs, Expr): 1159 yield t.cast(E, vs)
Yields the key and expression for all arguments, exploding list args.
1161 def find(self, *expression_types: Type[E], bfs: bool = True) -> E | None: 1162 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.
1164 def find_all(self, *expression_types: Type[E], bfs: bool = True) -> Iterator[E]: 1165 for expression in self.walk(bfs=bfs): 1166 if isinstance(expression, expression_types): 1167 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.
1169 def find_ancestor(self, *expression_types: Type[E]) -> E | None: 1170 ancestor = self.parent 1171 while ancestor and not isinstance(ancestor, expression_types): 1172 ancestor = ancestor.parent 1173 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.
1175 @property 1176 def parent_select(self) -> Select | None: 1177 from sqlglot.expressions.query import Select as _Select 1178 1179 return self.find_ancestor(_Select)
Returns the parent select statement.
1185 def root(self) -> Expr: 1186 expression: Expr = self 1187 while expression.parent: 1188 expression = expression.parent 1189 return expression
Returns the root expression of this tree.
1191 def walk( 1192 self, bfs: bool = True, prune: t.Callable[[Expr], bool] | None = None 1193 ) -> Iterator[Expr]: 1194 if bfs: 1195 yield from self.bfs(prune=prune) 1196 else: 1197 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.
1199 def dfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1200 stack = [self] 1201 1202 while stack: 1203 node = stack.pop() 1204 yield node 1205 if prune and prune(node): 1206 continue 1207 for v in node.iter_expressions(reverse=True): 1208 stack.append(v)
Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.
Returns:
The generator object.
1210 def bfs(self, prune: t.Callable[[Expr], bool] | None = None) -> Iterator[Expr]: 1211 queue: deque[Expr] = deque() 1212 queue.append(self) 1213 1214 while queue: 1215 node = queue.popleft() 1216 yield node 1217 if prune and prune(node): 1218 continue 1219 for v in node.iter_expressions(): 1220 queue.append(v)
Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.
Returns:
The generator object.
1222 def unnest(self) -> Expr: 1223 expression = self 1224 while type(expression) is Paren: 1225 expression = expression.this 1226 return expression
Returns the first non parenthesis child or self.
1228 def unalias(self) -> Expr: 1229 if isinstance(self, Alias): 1230 return self.this 1231 return self
Returns the inner expression if this is an Alias.
1233 def unnest_operands(self) -> tuple[Expr, ...]: 1234 return tuple(arg.unnest() for arg in self.iter_expressions())
Returns unnested operands as a tuple.
1236 def flatten(self, unnest: bool = True) -> Iterator[Expr]: 1237 for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)): 1238 if type(node) is not self.__class__: 1239 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.
1250 def sql( 1251 self, dialect: DialectType = None, copy: bool = True, **opts: Unpack[GeneratorNoDialectArgs] 1252 ) -> str: 1253 from sqlglot.dialects.dialect import Dialect 1254 1255 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.
1257 def transform( 1258 self, fun: t.Callable[..., T], *args: object, copy: bool = True, **kwargs: object 1259 ) -> T: 1260 root: t.Any = None 1261 new_node: t.Any = None 1262 1263 for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node): 1264 parent, arg_key, index = node.parent, node.arg_key, node.index 1265 new_node = fun(node, *args, **kwargs) 1266 1267 if not root: 1268 root = new_node 1269 elif parent and arg_key and new_node is not node: 1270 parent.set(arg_key, new_node, index) 1271 1272 assert root 1273 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.
1275 def replace(self, expression: T) -> T: 1276 parent = self.parent 1277 1278 if not parent or parent is expression: 1279 return expression 1280 1281 key = self.arg_key 1282 1283 if key: 1284 value = parent.args.get(key) 1285 1286 if type(expression) is list and isinstance(value, Expr): 1287 # We are trying to replace an Expr with a list, so it's assumed that 1288 # the intention was to really replace the parent of this expression. 1289 if value.parent: 1290 value.parent.replace(expression) 1291 else: 1292 parent.set(key, expression, self.index) 1293 1294 if expression is not self: 1295 self.parent = None 1296 self.arg_key = None 1297 self.index = None 1298 1299 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.
1305 def assert_is(self, type_: Type[E]) -> E: 1306 if not isinstance(self, type_): 1307 raise AssertionError(f"{self} is not {type_}.") 1308 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'
1310 def error_messages(self, args: Sequence[object] | None = None) -> list[str]: 1311 if UNITTEST: 1312 for k in self.args: 1313 if k not in self.arg_types: 1314 raise TypeError(f"Unexpected keyword: '{k}' for {self.__class__}") 1315 1316 errors: list[str] | None = None 1317 1318 for k in self.required_args: 1319 v = self.args.get(k) 1320 if v is None or (isinstance(v, list) and not v): 1321 if errors is None: 1322 errors = [] 1323 errors.append(f"Required keyword: '{k}' missing for {self.__class__}") 1324 1325 if ( 1326 args 1327 and isinstance(self, Func) 1328 and len(args) > len(self.arg_types) 1329 and not self.is_var_len_args 1330 ): 1331 if errors is None: 1332 errors = [] 1333 errors.append( 1334 f"The number of provided arguments ({len(args)}) is greater than " 1335 f"the maximum number of supported arguments ({len(self.arg_types)})" 1336 ) 1337 1338 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.
1340 def and_( 1341 self, 1342 *expressions: ExpOrStr | None, 1343 dialect: DialectType = None, 1344 copy: bool = True, 1345 wrap: bool = True, 1346 **opts: Unpack[ParserNoDialectArgs], 1347 ) -> Condition: 1348 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.
1350 def or_( 1351 self, 1352 *expressions: ExpOrStr | None, 1353 dialect: DialectType = None, 1354 copy: bool = True, 1355 wrap: bool = True, 1356 **opts: Unpack[ParserNoDialectArgs], 1357 ) -> Condition: 1358 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.
1363 def update_positions( 1364 self: E, 1365 other: Token | Expr | None = None, 1366 line: int | None = None, 1367 col: int | None = None, 1368 start: int | None = None, 1369 end: int | None = None, 1370 ) -> E: 1371 if isinstance(other, Token): 1372 meta = self.meta 1373 meta["line"] = other.line 1374 meta["col"] = other.col 1375 meta["start"] = other.start 1376 meta["end"] = other.end 1377 elif other is not None: 1378 other_meta = other._meta 1379 if other_meta: 1380 meta = self.meta 1381 for k in POSITION_META_KEYS: 1382 if k in other_meta: 1383 meta[k] = other_meta[k] 1384 else: 1385 meta = self.meta 1386 meta["line"] = line 1387 meta["col"] = col 1388 meta["start"] = start 1389 meta["end"] = end 1390 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.
1392 def as_( 1393 self, 1394 alias: str | Identifier, 1395 quoted: bool | None = None, 1396 dialect: DialectType = None, 1397 copy: bool = True, 1398 table: bool | Sequence[str | Identifier] = False, 1399 **opts: Unpack[ParserNoDialectArgs], 1400 ) -> Expr: 1401 return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, table=table, **opts)
1426 def isin( 1427 self, 1428 *expressions: t.Any, 1429 query: ExpOrStr | None = None, 1430 unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None, 1431 dialect: DialectType = None, 1432 copy: bool = True, 1433 **opts: Unpack[ParserNoDialectArgs], 1434 ) -> In: 1435 from sqlglot.expressions.query import Query 1436 1437 subquery: Expr | None = None 1438 if query: 1439 subquery = maybe_parse(query, dialect=dialect, copy=copy, **opts) 1440 if isinstance(subquery, Query): 1441 subquery = subquery.subquery(copy=False) 1442 unnest_list: list[ExpOrStr] = ensure_list(unnest) 1443 return In( 1444 this=maybe_copy(self, copy), 1445 expressions=[convert(e, copy=copy) for e in expressions], 1446 query=subquery, 1447 unnest=( 1448 _lazy_unnest( 1449 expressions=[ 1450 maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in unnest_list 1451 ] 1452 ) 1453 if unnest 1454 else None 1455 ), 1456 )
1458 def between( 1459 self, low: t.Any, high: t.Any, copy: bool = True, symmetric: bool | None = None 1460 ) -> Between: 1461 between = Between( 1462 this=maybe_copy(self, copy), 1463 low=convert(low, copy=copy), 1464 high=convert(high, copy=copy), 1465 ) 1466 if symmetric is not None: 1467 between.set("symmetric", symmetric) 1468 1469 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
1583@trait 1584class Predicate(Condition): 1585 """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
1588class Cache(Expression): 1589 arg_types = { 1590 "this": True, 1591 "lazy": False, 1592 "options": False, 1593 "expression": False, 1594 }
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
1601class Refresh(Expression): 1602 arg_types = { 1603 "this": True, 1604 "kind": True, 1605 "partition_start": False, 1606 "partition_end": False, 1607 "force": False, 1608 "mode": False, 1609 }
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
1634@trait 1635class Binary(Condition): 1636 arg_types: t.ClassVar[dict[str, bool]] = {"this": True, "expression": True} 1637 1638 @property 1639 def left(self) -> Expr: 1640 return self.args["this"] 1641 1642 @property 1643 def right(self) -> Expr: 1644 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
1652@trait 1653class Func(Condition): 1654 """ 1655 The base class for all function expressions. 1656 1657 Attributes: 1658 is_var_len_args (bool): if set to True the argument identified by var_len_arg_key will be 1659 treated as a variable length argument and the argument's value will be stored as a list. 1660 var_len_arg_key (str): the arg_types key that collects the variable length arguments. 1661 Arguments preceding it in arg_types are filled positionally; those following it (e.g. 1662 dialect flags) are never populated by from_arg_list. 1663 _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this 1664 function expression. These values are used to map this node to a name during parsing as 1665 well as to provide the function's name during SQL string generation. By default the SQL 1666 name is set to the expression's class name transformed to snake case. 1667 """ 1668 1669 is_var_len_args: t.ClassVar[bool] = False 1670 var_len_arg_key: t.ClassVar[str] = "expressions" 1671 _sql_names: t.ClassVar[list[str]] = [] 1672 1673 @classmethod 1674 def from_arg_list(cls, args: Sequence[object]) -> Self: 1675 if cls.is_var_len_args: 1676 all_arg_keys = tuple(cls.arg_types) 1677 var_len_index = all_arg_keys.index(cls.var_len_arg_key) 1678 1679 args_dict = {arg_key: arg for arg, arg_key in zip(args, all_arg_keys[:var_len_index])} 1680 args_dict[cls.var_len_arg_key] = args[var_len_index:] 1681 else: 1682 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} 1683 1684 return cls(**args_dict) 1685 1686 @classmethod 1687 def sql_names(cls) -> list[str]: 1688 if cls is Func: 1689 raise NotImplementedError( 1690 "SQL name is only supported by concrete function implementations" 1691 ) 1692 if not cls._sql_names: 1693 return [camel_to_snake_case(cls.__name__)] 1694 return cls._sql_names 1695 1696 @classmethod 1697 def sql_name(cls) -> str: 1698 sql_names = cls.sql_names() 1699 assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}." 1700 return sql_names[0] 1701 1702 @classmethod 1703 def default_parser_mappings(cls) -> dict[str, t.Callable[[Sequence[object]], Self]]: 1704 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.
1673 @classmethod 1674 def from_arg_list(cls, args: Sequence[object]) -> Self: 1675 if cls.is_var_len_args: 1676 all_arg_keys = tuple(cls.arg_types) 1677 var_len_index = all_arg_keys.index(cls.var_len_arg_key) 1678 1679 args_dict = {arg_key: arg for arg, arg_key in zip(args, all_arg_keys[:var_len_index])} 1680 args_dict[cls.var_len_arg_key] = args[var_len_index:] 1681 else: 1682 args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)} 1683 1684 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
1712class Column(Expression, Condition): 1713 # "shadow" marks a column whose qualifier is shadowed by a projection alias, so it must be 1714 # rendered unqualified in dialects where PROJECTION_ALIASES_SHADOW_SOURCE_NAMES is set 1715 arg_types = { 1716 "this": True, 1717 "table": False, 1718 "db": False, 1719 "catalog": False, 1720 "join_mark": False, 1721 "shadow": False, 1722 } 1723 1724 @property 1725 def table(self) -> str: 1726 return self.text("table") 1727 1728 @property 1729 def db(self) -> str: 1730 return self.text("db") 1731 1732 @property 1733 def catalog(self) -> str: 1734 return self.text("catalog") 1735 1736 @property 1737 def output_name(self) -> str: 1738 return self.name 1739 1740 @property 1741 def parts(self) -> list[Expr]: 1742 """Return the parts of a column in order catalog, db, table, name.""" 1743 return [ 1744 self.args[part] for part in ("catalog", "db", "table", "this") if self.args.get(part) 1745 ] 1746 1747 def to_dot(self, include_dots: bool = True) -> Expr: 1748 """Converts the column into a dot expression.""" 1749 parts = self.parts 1750 parent = self.parent 1751 1752 if include_dots: 1753 while isinstance(parent, Dot): 1754 parts.append(parent.expression) 1755 parent = parent.parent 1756 1757 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 ''
1740 @property 1741 def parts(self) -> list[Expr]: 1742 """Return the parts of a column in order catalog, db, table, name.""" 1743 return [ 1744 self.args[part] for part in ("catalog", "db", "table", "this") if self.args.get(part) 1745 ]
Return the parts of a column in order catalog, db, table, name.
1747 def to_dot(self, include_dots: bool = True) -> Expr: 1748 """Converts the column into a dot expression.""" 1749 parts = self.parts 1750 parent = self.parent 1751 1752 if include_dots: 1753 while isinstance(parent, Dot): 1754 parts.append(parent.expression) 1755 parent = parent.parent 1756 1757 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
1760class Literal(Expression, Condition): 1761 arg_types = {"this": True, "is_string": True} 1762 _hash_raw_args = True 1763 is_primitive = True 1764 1765 @classmethod 1766 def number(cls, number: object) -> Literal | Neg: 1767 lit = cls(this=str(number), is_string=False) 1768 try: 1769 to_py = lit.to_py() 1770 if not isinstance(to_py, str) and to_py < 0: 1771 lit.set("this", str(abs(to_py))) 1772 return Neg(this=lit) 1773 except Exception: 1774 pass 1775 return lit 1776 1777 @classmethod 1778 def string(cls, string: object) -> Literal: 1779 return cls(this=str(string), is_string=True) 1780 1781 @property 1782 def output_name(self) -> str: 1783 return self.name 1784 1785 def to_py(self) -> int | str | Decimal: 1786 if self.is_number: 1787 try: 1788 return int(self.this) 1789 except ValueError: 1790 try: 1791 return Decimal(self.this) 1792 except InvalidOperation as e: 1793 raise ValueError(f"Invalid numeric literal: {self.this!r}") from e 1794 return self.this
1765 @classmethod 1766 def number(cls, number: object) -> Literal | Neg: 1767 lit = cls(this=str(number), is_string=False) 1768 try: 1769 to_py = lit.to_py() 1770 if not isinstance(to_py, str) and to_py < 0: 1771 lit.set("this", str(abs(to_py))) 1772 return Neg(this=lit) 1773 except Exception: 1774 pass 1775 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 ''
1785 def to_py(self) -> int | str | Decimal: 1786 if self.is_number: 1787 try: 1788 return int(self.this) 1789 except ValueError: 1790 try: 1791 return Decimal(self.this) 1792 except InvalidOperation as e: 1793 raise ValueError(f"Invalid numeric literal: {self.this!r}") from e 1794 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
1817class Identifier(Expression): 1818 arg_types = { 1819 "this": True, 1820 "quoted": False, 1821 "global_": False, 1822 "temporary": False, 1823 } 1824 is_primitive = True 1825 _hash_raw_args = True 1826 1827 @property 1828 def quoted(self) -> bool: 1829 return bool(self.args.get("quoted")) 1830 1831 @property 1832 def output_name(self) -> str: 1833 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
1839class DynamicIdentifier(Expression, Func): 1840 arg_types = {"this": True, "expressions": False} 1841 1842 @property 1843 def name(self) -> str: 1844 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
1851class Star(Expression): 1852 arg_types = {"except_": False, "replace": False, "rename": False, "ilike": False} 1853 1854 @property 1855 def name(self) -> str: 1856 return "*" 1857 1858 @property 1859 def output_name(self) -> str: 1860 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
1871class Placeholder(Expression, Condition): 1872 arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False} 1873 _hash_raw_args = True 1874 1875 @property 1876 def name(self) -> str: 1877 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
1880class Null(Expression, Condition): 1881 arg_types = {} 1882 1883 @property 1884 def name(self) -> str: 1885 return "NULL" 1886 1887 def to_py(self) -> t.Literal[None]: 1888 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
1891class Boolean(Expression, Condition): 1892 is_primitive = True 1893 1894 def to_py(self) -> bool: 1895 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
1898class Dot(Expression, Binary): 1899 @property 1900 def is_star(self) -> bool: 1901 return self.expression.is_star 1902 1903 @property 1904 def name(self) -> str: 1905 return self.expression.name 1906 1907 @property 1908 def output_name(self) -> str: 1909 return self.name 1910 1911 @classmethod 1912 def build(cls, expressions: Sequence[Expr]) -> Dot: 1913 """Build a Dot object with a sequence of expressions.""" 1914 if len(expressions) < 2: 1915 raise ValueError("Dot requires >= 2 expressions.") 1916 1917 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) 1918 1919 @property 1920 def parts(self) -> list[Expr]: 1921 """Return the parts of a table / column in order catalog, db, table.""" 1922 this, *parts = self.flatten() 1923 1924 parts.reverse() 1925 1926 for arg in COLUMN_PARTS: 1927 part = this.args.get(arg) 1928 1929 if isinstance(part, Expr): 1930 parts.append(part) 1931 1932 parts.reverse() 1933 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 ''
1911 @classmethod 1912 def build(cls, expressions: Sequence[Expr]) -> Dot: 1913 """Build a Dot object with a sequence of expressions.""" 1914 if len(expressions) < 2: 1915 raise ValueError("Dot requires >= 2 expressions.") 1916 1917 return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
Build a Dot object with a sequence of expressions.
1919 @property 1920 def parts(self) -> list[Expr]: 1921 """Return the parts of a table / column in order catalog, db, table.""" 1922 this, *parts = self.flatten() 1923 1924 parts.reverse() 1925 1926 for arg in COLUMN_PARTS: 1927 part = this.args.get(arg) 1928 1929 if isinstance(part, Expr): 1930 parts.append(part) 1931 1932 parts.reverse() 1933 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
1940class Alias(Expression): 1941 arg_types = {"this": True, "alias": False} 1942 1943 @property 1944 def output_name(self) -> str: 1945 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
1956class Aliases(Expression): 1957 arg_types = {"this": True, "expressions": True} 1958 1959 @property 1960 def aliases(self) -> list[Expr]: 1961 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
1964class Bracket(Expression, Condition): 1965 # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator 1966 arg_types = { 1967 "this": True, 1968 "expressions": True, 1969 "offset": False, 1970 "safe": False, 1971 "returns_list_for_maps": False, 1972 "json_access": False, 1973 } 1974 1975 @property 1976 def output_name(self) -> str: 1977 if len(self.expressions) == 1: 1978 return self.expressions[0].output_name 1979 1980 return super().output_name
1975 @property 1976 def output_name(self) -> str: 1977 if len(self.expressions) == 1: 1978 return self.expressions[0].output_name 1979 1980 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
2007class ParameterizedAgg(Expression, AggFunc): 2008 arg_types = {"this": True, "expressions": True, "params": True} 2009 _hash_raw_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
2012class Anonymous(Expression, Func): 2013 arg_types = {"this": True, "expressions": False} 2014 is_var_len_args = True 2015 2016 @property 2017 def name(self) -> str: 2018 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
2021class AnonymousAggFunc(Expression, AggFunc): 2022 arg_types = {"this": True, "expressions": False} 2023 is_var_len_args = True 2024 _hash_raw_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
2031class CombinedParameterizedAgg(ParameterizedAgg): 2032 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
2035class HashAgg(Expression, AggFunc): 2036 arg_types = {"this": True, "expressions": False} 2037 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
2040class Hll(Expression, AggFunc): 2041 arg_types = {"this": True, "expressions": False} 2042 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
2045class ApproxDistinct(Expression, AggFunc): 2046 arg_types = {"this": True, "accuracy": False} 2047 _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
2054@trait 2055class TimeUnit(Expr): 2056 """Automatically converts unit arg into a var.""" 2057 2058 UNABBREVIATED_UNIT_NAME: t.ClassVar[dict[str, str]] = { 2059 "D": "DAY", 2060 "H": "HOUR", 2061 "M": "MINUTE", 2062 "MS": "MILLISECOND", 2063 "NS": "NANOSECOND", 2064 "Q": "QUARTER", 2065 "S": "SECOND", 2066 "US": "MICROSECOND", 2067 "W": "WEEK", 2068 "Y": "YEAR", 2069 } 2070 2071 VAR_LIKE: t.ClassVar[tuple[Type[Expr], ...]] = (Column, Literal, Var) 2072 2073 def __init__(self, **args: object) -> None: 2074 super().__init__(**args) 2075 2076 unit = self.args.get("unit") 2077 if ( 2078 unit 2079 and type(unit) in TimeUnit.VAR_LIKE 2080 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2081 ): 2082 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2083 self.args["unit"] = unit 2084 self._set_parent("unit", unit) 2085 elif type(unit).__name__ == "Week": 2086 unit.set("this", Var(this=unit.this.name.upper())) # type: ignore[union-attr] 2087 2088 @property 2089 def unit(self) -> Expr | None: 2090 return self.args.get("unit")
Automatically converts unit arg into a var.
2073 def __init__(self, **args: object) -> None: 2074 super().__init__(**args) 2075 2076 unit = self.args.get("unit") 2077 if ( 2078 unit 2079 and type(unit) in TimeUnit.VAR_LIKE 2080 and not (isinstance(unit, Column) and len(unit.parts) != 1) 2081 ): 2082 unit = Var(this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()) 2083 self.args["unit"] = unit 2084 self._set_parent("unit", unit) 2085 elif type(unit).__name__ == "Week": 2086 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
2099@trait 2100class IntervalOp(TimeUnit): 2101 def interval(self) -> Interval: 2102 from sqlglot.expressions.datatypes import Interval 2103 2104 expr = self.expression 2105 return Interval( 2106 this=expr.copy() if expr is not None else None, 2107 unit=self.unit.copy() if self.unit else None, 2108 )
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
- 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
2123class Ordered(Expression): 2124 arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False} 2125 2126 @property 2127 def name(self) -> str: 2128 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
2135class BitwiseAnd(Expression, Binary): 2136 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
2139class BitwiseLeftShift(Expression, Binary): 2140 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
2143class BitwiseOr(Expression, Binary): 2144 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
2147class BitwiseRightShift(Expression, Binary): 2148 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
2151class BitwiseXor(Expression, Binary): 2152 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
2155class Div(Expression, Binary): 2156 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
2171class DPipe(Expression, Binary): 2172 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
2215class ILike(Expression, Binary, Predicate): 2216 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
2223class Is(Expression, Binary, Predicate): 2224 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
2227class Like(Expression, Binary, Predicate): 2228 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
2231class Match(Expression, Binary, Predicate): 2232 arg_types = {"this": True, "expression": True, "kind": False, "analyzer": 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
2243class Mod(Expression, Binary): 2244 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
2259class Operator(Expression, Binary): 2260 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
2287class Paren(Unary): 2288 @property 2289 def output_name(self) -> str: 2290 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
2293class Neg(Unary): 2294 def to_py(self) -> int | Decimal: 2295 if self.is_number: 2296 return self.this.to_py() * -1 2297 return super().to_py()
2294 def to_py(self) -> int | Decimal: 2295 if self.is_number: 2296 return self.this.to_py() * -1 2297 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
2312class FormatPhrase(Expression): 2313 """Format override for a column in Teradata. 2314 Can be expanded to additional dialects as needed 2315 2316 https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT 2317 """ 2318 2319 arg_types = {"this": True, "format": True} 2320 2321 @property 2322 def name(self) -> str: 2323 return self.this.name 2324 2325 @property 2326 def output_name(self) -> str: 2327 return self.this.output_name
Format override for a column in Teradata. Can be expanded to additional dialects as needed
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
2330class TeradataTitle(Expression): 2331 """A Teradata TITLE display heading, which does not rename the expression.""" 2332 2333 arg_types = {"this": True, "title": True} 2334 2335 @property 2336 def name(self) -> str: 2337 return self.this.name 2338 2339 @property 2340 def output_name(self) -> str: 2341 return self.this.output_name
A Teradata TITLE display heading, which does not rename the expression.
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
2344class Between(Expression, Predicate): 2345 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
2352class In(Expression, Predicate): 2353 arg_types = { 2354 "this": True, 2355 "expressions": False, 2356 "query": False, 2357 "unnest": False, 2358 "field": False, 2359 "is_global": False, 2360 }
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
2371class Xor(Expression, Connector, Func): 2372 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
2379class RegexpLike(Expression, Binary, Predicate, Func): 2380 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
2383def not_( 2384 expression: ExpOrStr, 2385 dialect: DialectType = None, 2386 copy: bool = True, 2387 **opts: Unpack[ParserNoDialectArgs], 2388) -> Not: 2389 """ 2390 Wrap a condition with a NOT operator. 2391 2392 Example: 2393 >>> not_("this_suit='black'").sql() 2394 "NOT this_suit = 'black'" 2395 2396 Args: 2397 expression: the SQL code string to parse. 2398 If an Expr instance is passed, this is used as-is. 2399 dialect: the dialect used to parse the input expression. 2400 copy: whether to copy the expression or not. 2401 **opts: other options to use to parse the input expressions. 2402 2403 Returns: 2404 The new condition. 2405 """ 2406 this = condition( 2407 expression, 2408 dialect=dialect, 2409 copy=copy, 2410 **opts, 2411 ) 2412 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.
2421def convert(value: t.Any, copy: bool = False) -> Expr: 2422 """Convert a python value into an expression object. 2423 2424 Raises an error if a conversion is not possible. 2425 2426 Args: 2427 value: A python object. 2428 copy: Whether to copy `value` (only applies to Exprs and collections). 2429 2430 Returns: 2431 The equivalent expression object. 2432 """ 2433 if isinstance(value, Expr): 2434 return maybe_copy(value, copy) 2435 if isinstance(value, str): 2436 return Literal.string(value) 2437 if isinstance(value, bool): 2438 return Boolean(this=value) 2439 if value is None or (isinstance(value, float) and math.isnan(value)): 2440 return Null() 2441 if isinstance(value, numbers.Number): 2442 return Literal.number(value) 2443 if isinstance(value, bytes): 2444 from sqlglot.expressions.query import HexString as _HexString 2445 2446 return _HexString(this=value.hex()) 2447 if isinstance(value, datetime.datetime): 2448 datetime_literal = Literal.string(value.isoformat(sep=" ")) 2449 2450 tz = None 2451 if value.tzinfo: 2452 # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles" 2453 # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot 2454 tz = Literal.string(str(value.tzinfo)) 2455 2456 from sqlglot.expressions.temporal import TimeStrToTime as _TimeStrToTime 2457 2458 return _TimeStrToTime(this=datetime_literal, zone=tz) 2459 if isinstance(value, datetime.date): 2460 date_literal = Literal.string(value.strftime("%Y-%m-%d")) 2461 from sqlglot.expressions.temporal import DateStrToDate as _DateStrToDate 2462 2463 return _DateStrToDate(this=date_literal) 2464 if isinstance(value, datetime.time): 2465 time_literal = Literal.string(value.isoformat()) 2466 from sqlglot.expressions.temporal import TsOrDsToTime as _TsOrDsToTime 2467 2468 return _TsOrDsToTime(this=time_literal) 2469 if isinstance(value, tuple): 2470 if hasattr(value, "_fields"): 2471 from sqlglot.expressions.array import Struct as _Struct 2472 2473 return _Struct( 2474 expressions=[ 2475 PropertyEQ( 2476 this=to_identifier(k), expression=convert(getattr(value, k), copy=copy) 2477 ) 2478 for k in value._fields 2479 ] 2480 ) 2481 from sqlglot.expressions.query import Tuple as _Tuple 2482 2483 return _Tuple(expressions=[convert(v, copy=copy) for v in value]) 2484 if isinstance(value, list): 2485 from sqlglot.expressions.array import Array as _Array 2486 2487 return _Array(expressions=[convert(v, copy=copy) for v in value]) 2488 if isinstance(value, dict): 2489 from sqlglot.expressions.array import Array as _Array 2490 from sqlglot.expressions.array import Map as _Map 2491 2492 return _Map( 2493 keys=_Array(expressions=[convert(k, copy=copy) for k in value]), 2494 values=_Array(expressions=[convert(v, copy=copy) for v in value.values()]), 2495 ) 2496 if hasattr(value, "__dict__"): 2497 from sqlglot.expressions.array import Struct as _Struct 2498 2499 return _Struct( 2500 expressions=[ 2501 PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy)) 2502 for k, v in value.__dict__.items() 2503 ] 2504 ) 2505 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.
2570def maybe_parse( 2571 sql_or_expression: ExpOrStr, 2572 *, 2573 into: IntoType | None = None, 2574 dialect: DialectType = None, 2575 prefix: str | None = None, 2576 copy: bool = False, 2577 **opts: Unpack[ParserNoDialectArgs], 2578) -> Expr: 2579 """Gracefully handle a possible string or expression. 2580 2581 Example: 2582 >>> maybe_parse("1") 2583 Literal(this=1, is_string=False) 2584 >>> maybe_parse(to_identifier("x")) 2585 Identifier(this=x, quoted=False) 2586 2587 Args: 2588 sql_or_expression: the SQL code string or an expression 2589 into: the SQLGlot Expr to parse into 2590 dialect: the dialect used to parse the input expressions (in the case that an 2591 input expression is a SQL string). 2592 prefix: a string to prefix the sql with before it gets parsed 2593 (automatically includes a space) 2594 copy: whether to copy the expression. 2595 **opts: other options to use to parse the input expressions (again, in the case 2596 that an input expression is a SQL string). 2597 2598 Returns: 2599 Expr: the parsed or given expression. 2600 """ 2601 if isinstance(sql_or_expression, Expr): 2602 if copy: 2603 return sql_or_expression.copy() 2604 return sql_or_expression 2605 2606 if sql_or_expression is None: 2607 raise ParseError("SQL cannot be None") 2608 2609 import sqlglot 2610 2611 sql = str(sql_or_expression) 2612 if prefix: 2613 sql = f"{prefix} {sql}" 2614 2615 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.
2867def to_identifier(name, quoted=None, copy=True): 2868 """Builds an identifier. 2869 2870 Args: 2871 name: The name to turn into an identifier. 2872 quoted: Whether to force quote the identifier. 2873 copy: Whether to copy name if it's an Identifier. 2874 2875 Returns: 2876 The identifier ast node. 2877 """ 2878 2879 if name is None: 2880 return None 2881 2882 if isinstance(name, Identifier): 2883 identifier = maybe_copy(name, copy) 2884 elif isinstance(name, str): 2885 identifier = Identifier( 2886 this=name, 2887 quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted, 2888 ) 2889 else: 2890 raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}") 2891 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.
2894def condition( 2895 expression: ExpOrStr, 2896 dialect: DialectType = None, 2897 copy: bool = True, 2898 **opts: Unpack[ParserNoDialectArgs], 2899) -> Expr: 2900 """ 2901 Initialize a logical condition expression. 2902 2903 Example: 2904 >>> condition("x=1").sql() 2905 'x = 1' 2906 2907 This is helpful for composing larger logical syntax trees: 2908 >>> where = condition("x=1") 2909 >>> where = where.and_("y=1") 2910 >>> where.sql() 2911 'x = 1 AND y = 1' 2912 2913 Args: 2914 *expression: the SQL code string to parse. 2915 If an Expr instance is passed, this is used as-is. 2916 dialect: the dialect used to parse the input expression (in the case that the 2917 input expression is a SQL string). 2918 copy: Whether to copy `expression` (only applies to expressions). 2919 **opts: other options to use to parse the input expressions (again, in the case 2920 that the input expression is a SQL string). 2921 2922 Returns: 2923 The new Condition instance 2924 """ 2925 return maybe_parse( 2926 expression, 2927 into=Condition, 2928 dialect=dialect, 2929 copy=copy, 2930 **opts, 2931 )
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
2934def and_( 2935 *expressions: ExpOrStr | None, 2936 dialect: DialectType = None, 2937 copy: bool = True, 2938 wrap: bool = True, 2939 **opts: Unpack[ParserNoDialectArgs], 2940) -> Condition: 2941 """ 2942 Combine multiple conditions with an AND logical operator. 2943 2944 Example: 2945 >>> and_("x=1", and_("y=1", "z=1")).sql() 2946 'x = 1 AND (y = 1 AND z = 1)' 2947 2948 Args: 2949 *expressions: the SQL code strings to parse. 2950 If an Expr instance is passed, this is used as-is. 2951 dialect: the dialect used to parse the input expression. 2952 copy: whether to copy `expressions` (only applies to Exprs). 2953 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2954 precedence issues, but can be turned off when the produced AST is too deep and 2955 causes recursion-related issues. 2956 **opts: other options to use to parse the input expressions. 2957 2958 Returns: 2959 The new condition 2960 """ 2961 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
2964def or_( 2965 *expressions: ExpOrStr | None, 2966 dialect: DialectType = None, 2967 copy: bool = True, 2968 wrap: bool = True, 2969 **opts: Unpack[ParserNoDialectArgs], 2970) -> Condition: 2971 """ 2972 Combine multiple conditions with an OR logical operator. 2973 2974 Example: 2975 >>> or_("x=1", or_("y=1", "z=1")).sql() 2976 'x = 1 OR (y = 1 OR z = 1)' 2977 2978 Args: 2979 *expressions: the SQL code strings to parse. 2980 If an Expr instance is passed, this is used as-is. 2981 dialect: the dialect used to parse the input expression. 2982 copy: whether to copy `expressions` (only applies to Exprs). 2983 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 2984 precedence issues, but can be turned off when the produced AST is too deep and 2985 causes recursion-related issues. 2986 **opts: other options to use to parse the input expressions. 2987 2988 Returns: 2989 The new condition 2990 """ 2991 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
2994def xor( 2995 *expressions: ExpOrStr | None, 2996 dialect: DialectType = None, 2997 copy: bool = True, 2998 wrap: bool = True, 2999 **opts: Unpack[ParserNoDialectArgs], 3000) -> Condition: 3001 """ 3002 Combine multiple conditions with an XOR logical operator. 3003 3004 Example: 3005 >>> xor("x=1", xor("y=1", "z=1")).sql() 3006 'x = 1 XOR (y = 1 XOR z = 1)' 3007 3008 Args: 3009 *expressions: the SQL code strings to parse. 3010 If an Expr instance is passed, this is used as-is. 3011 dialect: the dialect used to parse the input expression. 3012 copy: whether to copy `expressions` (only applies to Exprs). 3013 wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid 3014 precedence issues, but can be turned off when the produced AST is too deep and 3015 causes recursion-related issues. 3016 **opts: other options to use to parse the input expressions. 3017 3018 Returns: 3019 The new condition 3020 """ 3021 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
3024def paren(expression: ExpOrStr, copy: bool = True) -> Paren: 3025 """ 3026 Wrap an expression in parentheses. 3027 3028 Example: 3029 >>> paren("5 + 3").sql() 3030 '(5 + 3)' 3031 3032 Args: 3033 expression: the SQL code string to parse. 3034 If an Expr instance is passed, this is used as-is. 3035 copy: whether to copy the expression or not. 3036 3037 Returns: 3038 The wrapped expression. 3039 """ 3040 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.
3043def alias_( 3044 expression: ExpOrStr, 3045 alias: str | Identifier | None, 3046 table: bool | Sequence[str | Identifier] = False, 3047 quoted: bool | None = None, 3048 dialect: DialectType = None, 3049 copy: bool = True, 3050 **opts: Unpack[ParserNoDialectArgs], 3051) -> Expr: 3052 """Create an Alias expression. 3053 3054 Example: 3055 >>> alias_('foo', 'bar').sql() 3056 'foo AS bar' 3057 3058 >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql() 3059 '(SELECT 1, 2) AS bar(a, b)' 3060 3061 Args: 3062 expression: the SQL code strings to parse. 3063 If an Expr instance is passed, this is used as-is. 3064 alias: the alias name to use. If the name has 3065 special characters it is quoted. 3066 table: Whether to create a table alias, can also be a list of columns. 3067 quoted: whether to quote the alias 3068 dialect: the dialect used to parse the input expression. 3069 copy: Whether to copy the expression. 3070 **opts: other options to use to parse the input expressions. 3071 3072 Returns: 3073 Alias: the aliased expression 3074 """ 3075 exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts) 3076 alias = to_identifier(alias, quoted=quoted) 3077 3078 if table: 3079 from sqlglot.expressions.query import TableAlias as _TableAlias 3080 3081 table_alias = _TableAlias(this=alias) 3082 exp.set("alias", table_alias) 3083 3084 if not isinstance(table, bool): 3085 for column in table: 3086 table_alias.append("columns", to_identifier(column, quoted=quoted)) 3087 3088 return exp 3089 3090 # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in 3091 # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node 3092 # for the complete Window expression. 3093 # 3094 # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls 3095 3096 if "alias" in exp.arg_types and type(exp).__name__ != "Window": 3097 exp.set("alias", alias) 3098 return exp 3099 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
3130def column( 3131 col, 3132 table=None, 3133 db=None, 3134 catalog=None, 3135 *, 3136 fields=None, 3137 quoted=None, 3138 copy: bool = True, 3139): 3140 """ 3141 Build a Column. 3142 3143 Args: 3144 col: Column name or expression. 3145 table: Table name. 3146 db: Database name. 3147 catalog: Catalog name. 3148 fields: Additional fields using dots. 3149 quoted: Whether to force quotes on the column's identifiers. 3150 copy: Whether to copy expressions if passed in. 3151 3152 Returns: 3153 The new Column instance. 3154 """ 3155 col = maybe_copy(col, copy) if isinstance(col, Expr) else to_identifier(col, quoted=quoted) 3156 3157 this: Column | Dot = Column( 3158 this=col, 3159 table=to_identifier(table, quoted=quoted, copy=copy), 3160 db=to_identifier(db, quoted=quoted, copy=copy), 3161 catalog=to_identifier(catalog, quoted=quoted, copy=copy), 3162 ) 3163 3164 if fields: 3165 this = Dot.build( 3166 (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields)) 3167 ) 3168 return this
Build a Column.
Arguments:
- col: Column name or expression.
- 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 expressions if passed in.
Returns:
The new Column instance.