Edit on GitHub

Expressions

Every AST node in SQLGlot is represented by a subclass of Expression.

This module contains the implementation of all supported Expression types. Additionally, it exposes a number of helper functions, which are mainly used to programmatically build SQL expressions, such as sqlglot.expressions.select.


   1"""
   2## Expressions
   3
   4Every AST node in SQLGlot is represented by a subclass of `Expression`.
   5
   6This module contains the implementation of all supported `Expression` types. Additionally,
   7it exposes a number of helper functions, which are mainly used to programmatically build
   8SQL expressions, such as `sqlglot.expressions.select`.
   9
  10----
  11"""
  12
  13from __future__ import annotations
  14
  15import datetime
  16import math
  17import numbers
  18import re
  19import textwrap
  20import typing as t
  21from collections import deque
  22from copy import deepcopy
  23from decimal import Decimal
  24from enum import auto
  25from functools import reduce
  26
  27from sqlglot.errors import ErrorLevel, ParseError
  28from sqlglot.helper import (
  29    AutoName,
  30    camel_to_snake_case,
  31    ensure_collection,
  32    ensure_list,
  33    seq_get,
  34    subclasses,
  35    to_bool,
  36)
  37from sqlglot.tokens import Token, TokenError
  38
  39if t.TYPE_CHECKING:
  40    from typing_extensions import Self
  41
  42    from sqlglot._typing import E, Lit
  43    from sqlglot.dialects.dialect import DialectType
  44
  45    Q = t.TypeVar("Q", bound="Query")
  46    S = t.TypeVar("S", bound="SetOperation")
  47
  48
  49class _Expression(type):
  50    def __new__(cls, clsname, bases, attrs):
  51        klass = super().__new__(cls, clsname, bases, attrs)
  52
  53        # When an Expression class is created, its key is automatically set to be
  54        # the lowercase version of the class' name.
  55        klass.key = clsname.lower()
  56
  57        # This is so that docstrings are not inherited in pdoc
  58        klass.__doc__ = klass.__doc__ or ""
  59
  60        return klass
  61
  62
  63SQLGLOT_META = "sqlglot.meta"
  64SQLGLOT_ANONYMOUS = "sqlglot.anonymous"
  65TABLE_PARTS = ("this", "db", "catalog")
  66COLUMN_PARTS = ("this", "table", "db", "catalog")
  67POSITION_META_KEYS = ("line", "col", "start", "end")
  68
  69
  70class Expression(metaclass=_Expression):
  71    """
  72    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  73    context, such as its child expressions, their names (arg keys), and whether a given child expression
  74    is optional or not.
  75
  76    Attributes:
  77        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  78            and representing expressions as strings.
  79        arg_types: determines the arguments (child nodes) supported by an expression. It maps
  80            arg keys to booleans that indicate whether the corresponding args are optional.
  81        parent: a reference to the parent expression (or None, in case of root expressions).
  82        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  83            uses to refer to it.
  84        index: the index of an expression if it is inside of a list argument in its parent.
  85        comments: a list of comments that are associated with a given expression. This is used in
  86            order to preserve comments when transpiling SQL code.
  87        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  88            optimizer, in order to enable some transformations that require type information.
  89        meta: a dictionary that can be used to store useful metadata for a given expression.
  90
  91    Example:
  92        >>> class Foo(Expression):
  93        ...     arg_types = {"this": True, "expression": False}
  94
  95        The above definition informs us that Foo is an Expression that requires an argument called
  96        "this" and may also optionally receive an argument called "expression".
  97
  98    Args:
  99        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
 100    """
 101
 102    key = "expression"
 103    arg_types = {"this": True}
 104    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
 105
 106    def __init__(self, **args: t.Any):
 107        self.args: t.Dict[str, t.Any] = args
 108        self.parent: t.Optional[Expression] = None
 109        self.arg_key: t.Optional[str] = None
 110        self.index: t.Optional[int] = None
 111        self.comments: t.Optional[t.List[str]] = None
 112        self._type: t.Optional[DataType] = None
 113        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 114        self._hash: t.Optional[int] = None
 115
 116        for arg_key, value in self.args.items():
 117            self._set_parent(arg_key, value)
 118
 119    def __eq__(self, other) -> bool:
 120        return type(self) is type(other) and hash(self) == hash(other)
 121
 122    @property
 123    def hashable_args(self) -> t.Any:
 124        return frozenset(
 125            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 126            for k, v in self.args.items()
 127            if not (v is None or v is False or (type(v) is list and not v))
 128        )
 129
 130    def __hash__(self) -> int:
 131        if self._hash is not None:
 132            return self._hash
 133
 134        return hash((self.__class__, self.hashable_args))
 135
 136    @property
 137    def this(self) -> t.Any:
 138        """
 139        Retrieves the argument with key "this".
 140        """
 141        return self.args.get("this")
 142
 143    @property
 144    def expression(self) -> t.Any:
 145        """
 146        Retrieves the argument with key "expression".
 147        """
 148        return self.args.get("expression")
 149
 150    @property
 151    def expressions(self) -> t.List[t.Any]:
 152        """
 153        Retrieves the argument with key "expressions".
 154        """
 155        return self.args.get("expressions") or []
 156
 157    def text(self, key) -> str:
 158        """
 159        Returns a textual representation of the argument corresponding to "key". This can only be used
 160        for args that are strings or leaf Expression instances, such as identifiers and literals.
 161        """
 162        field = self.args.get(key)
 163        if isinstance(field, str):
 164            return field
 165        if isinstance(field, (Identifier, Literal, Var)):
 166            return field.this
 167        if isinstance(field, (Star, Null)):
 168            return field.name
 169        return ""
 170
 171    @property
 172    def is_string(self) -> bool:
 173        """
 174        Checks whether a Literal expression is a string.
 175        """
 176        return isinstance(self, Literal) and self.args["is_string"]
 177
 178    @property
 179    def is_number(self) -> bool:
 180        """
 181        Checks whether a Literal expression is a number.
 182        """
 183        return (isinstance(self, Literal) and not self.args["is_string"]) or (
 184            isinstance(self, Neg) and self.this.is_number
 185        )
 186
 187    def to_py(self) -> t.Any:
 188        """
 189        Returns a Python object equivalent of the SQL node.
 190        """
 191        raise ValueError(f"{self} cannot be converted to a Python object.")
 192
 193    @property
 194    def is_int(self) -> bool:
 195        """
 196        Checks whether an expression is an integer.
 197        """
 198        return self.is_number and isinstance(self.to_py(), int)
 199
 200    @property
 201    def is_star(self) -> bool:
 202        """Checks whether an expression is a star."""
 203        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 204
 205    @property
 206    def alias(self) -> str:
 207        """
 208        Returns the alias of the expression, or an empty string if it's not aliased.
 209        """
 210        if isinstance(self.args.get("alias"), TableAlias):
 211            return self.args["alias"].name
 212        return self.text("alias")
 213
 214    @property
 215    def alias_column_names(self) -> t.List[str]:
 216        table_alias = self.args.get("alias")
 217        if not table_alias:
 218            return []
 219        return [c.name for c in table_alias.args.get("columns") or []]
 220
 221    @property
 222    def name(self) -> str:
 223        return self.text("this")
 224
 225    @property
 226    def alias_or_name(self) -> str:
 227        return self.alias or self.name
 228
 229    @property
 230    def output_name(self) -> str:
 231        """
 232        Name of the output column if this expression is a selection.
 233
 234        If the Expression has no output name, an empty string is returned.
 235
 236        Example:
 237            >>> from sqlglot import parse_one
 238            >>> parse_one("SELECT a").expressions[0].output_name
 239            'a'
 240            >>> parse_one("SELECT b AS c").expressions[0].output_name
 241            'c'
 242            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 243            ''
 244        """
 245        return ""
 246
 247    @property
 248    def type(self) -> t.Optional[DataType]:
 249        return self._type
 250
 251    @type.setter
 252    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 253        if dtype and not isinstance(dtype, DataType):
 254            dtype = DataType.build(dtype)
 255        self._type = dtype  # type: ignore
 256
 257    def is_type(self, *dtypes) -> bool:
 258        return self.type is not None and self.type.is_type(*dtypes)
 259
 260    def is_leaf(self) -> bool:
 261        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 262
 263    @property
 264    def meta(self) -> t.Dict[str, t.Any]:
 265        if self._meta is None:
 266            self._meta = {}
 267        return self._meta
 268
 269    def __deepcopy__(self, memo):
 270        root = self.__class__()
 271        stack = [(self, root)]
 272
 273        while stack:
 274            node, copy = stack.pop()
 275
 276            if node.comments is not None:
 277                copy.comments = deepcopy(node.comments)
 278            if node._type is not None:
 279                copy._type = deepcopy(node._type)
 280            if node._meta is not None:
 281                copy._meta = deepcopy(node._meta)
 282            if node._hash is not None:
 283                copy._hash = node._hash
 284
 285            for k, vs in node.args.items():
 286                if hasattr(vs, "parent"):
 287                    stack.append((vs, vs.__class__()))
 288                    copy.set(k, stack[-1][-1])
 289                elif type(vs) is list:
 290                    copy.args[k] = []
 291
 292                    for v in vs:
 293                        if hasattr(v, "parent"):
 294                            stack.append((v, v.__class__()))
 295                            copy.append(k, stack[-1][-1])
 296                        else:
 297                            copy.append(k, v)
 298                else:
 299                    copy.args[k] = vs
 300
 301        return root
 302
 303    def copy(self) -> Self:
 304        """
 305        Returns a deep copy of the expression.
 306        """
 307        return deepcopy(self)
 308
 309    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
 310        if self.comments is None:
 311            self.comments = []
 312
 313        if comments:
 314            for comment in comments:
 315                _, *meta = comment.split(SQLGLOT_META)
 316                if meta:
 317                    for kv in "".join(meta).split(","):
 318                        k, *v = kv.split("=")
 319                        value = v[0].strip() if v else True
 320                        self.meta[k.strip()] = to_bool(value)
 321
 322                if not prepend:
 323                    self.comments.append(comment)
 324
 325            if prepend:
 326                self.comments = comments + self.comments
 327
 328    def pop_comments(self) -> t.List[str]:
 329        comments = self.comments or []
 330        self.comments = None
 331        return comments
 332
 333    def append(self, arg_key: str, value: t.Any) -> None:
 334        """
 335        Appends value to arg_key if it's a list or sets it as a new list.
 336
 337        Args:
 338            arg_key (str): name of the list expression arg
 339            value (Any): value to append to the list
 340        """
 341        if type(self.args.get(arg_key)) is not list:
 342            self.args[arg_key] = []
 343        self._set_parent(arg_key, value)
 344        values = self.args[arg_key]
 345        if hasattr(value, "parent"):
 346            value.index = len(values)
 347        values.append(value)
 348
 349    def set(
 350        self,
 351        arg_key: str,
 352        value: t.Any,
 353        index: t.Optional[int] = None,
 354        overwrite: bool = True,
 355    ) -> None:
 356        """
 357        Sets arg_key to value.
 358
 359        Args:
 360            arg_key: name of the expression arg.
 361            value: value to set the arg to.
 362            index: if the arg is a list, this specifies what position to add the value in it.
 363            overwrite: assuming an index is given, this determines whether to overwrite the
 364                list entry instead of only inserting a new value (i.e., like list.insert).
 365        """
 366        if index is not None:
 367            expressions = self.args.get(arg_key) or []
 368
 369            if seq_get(expressions, index) is None:
 370                return
 371            if value is None:
 372                expressions.pop(index)
 373                for v in expressions[index:]:
 374                    v.index = v.index - 1
 375                return
 376
 377            if isinstance(value, list):
 378                expressions.pop(index)
 379                expressions[index:index] = value
 380            elif overwrite:
 381                expressions[index] = value
 382            else:
 383                expressions.insert(index, value)
 384
 385            value = expressions
 386        elif value is None:
 387            self.args.pop(arg_key, None)
 388            return
 389
 390        self.args[arg_key] = value
 391        self._set_parent(arg_key, value, index)
 392
 393    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 394        if hasattr(value, "parent"):
 395            value.parent = self
 396            value.arg_key = arg_key
 397            value.index = index
 398        elif type(value) is list:
 399            for index, v in enumerate(value):
 400                if hasattr(v, "parent"):
 401                    v.parent = self
 402                    v.arg_key = arg_key
 403                    v.index = index
 404
 405    @property
 406    def depth(self) -> int:
 407        """
 408        Returns the depth of this tree.
 409        """
 410        if self.parent:
 411            return self.parent.depth + 1
 412        return 0
 413
 414    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
 415        """Yields the key and expression for all arguments, exploding list args."""
 416        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
 417            if type(vs) is list:
 418                for v in reversed(vs) if reverse else vs:  # type: ignore
 419                    if hasattr(v, "parent"):
 420                        yield v
 421            else:
 422                if hasattr(vs, "parent"):
 423                    yield vs
 424
 425    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 426        """
 427        Returns the first node in this tree which matches at least one of
 428        the specified types.
 429
 430        Args:
 431            expression_types: the expression type(s) to match.
 432            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 433
 434        Returns:
 435            The node which matches the criteria or None if no such node was found.
 436        """
 437        return next(self.find_all(*expression_types, bfs=bfs), None)
 438
 439    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 440        """
 441        Returns a generator object which visits all nodes in this tree and only
 442        yields those that match at least one of the specified expression types.
 443
 444        Args:
 445            expression_types: the expression type(s) to match.
 446            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 447
 448        Returns:
 449            The generator object.
 450        """
 451        for expression in self.walk(bfs=bfs):
 452            if isinstance(expression, expression_types):
 453                yield expression
 454
 455    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 456        """
 457        Returns a nearest parent matching expression_types.
 458
 459        Args:
 460            expression_types: the expression type(s) to match.
 461
 462        Returns:
 463            The parent node.
 464        """
 465        ancestor = self.parent
 466        while ancestor and not isinstance(ancestor, expression_types):
 467            ancestor = ancestor.parent
 468        return ancestor  # type: ignore
 469
 470    @property
 471    def parent_select(self) -> t.Optional[Select]:
 472        """
 473        Returns the parent select statement.
 474        """
 475        return self.find_ancestor(Select)
 476
 477    @property
 478    def same_parent(self) -> bool:
 479        """Returns if the parent is the same class as itself."""
 480        return type(self.parent) is self.__class__
 481
 482    def root(self) -> Expression:
 483        """
 484        Returns the root expression of this tree.
 485        """
 486        expression = self
 487        while expression.parent:
 488            expression = expression.parent
 489        return expression
 490
 491    def walk(
 492        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
 493    ) -> t.Iterator[Expression]:
 494        """
 495        Returns a generator object which visits all nodes in this tree.
 496
 497        Args:
 498            bfs: if set to True the BFS traversal order will be applied,
 499                otherwise the DFS traversal will be used instead.
 500            prune: callable that returns True if the generator should stop traversing
 501                this branch of the tree.
 502
 503        Returns:
 504            the generator object.
 505        """
 506        if bfs:
 507            yield from self.bfs(prune=prune)
 508        else:
 509            yield from self.dfs(prune=prune)
 510
 511    def dfs(
 512        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 513    ) -> t.Iterator[Expression]:
 514        """
 515        Returns a generator object which visits all nodes in this tree in
 516        the DFS (Depth-first) order.
 517
 518        Returns:
 519            The generator object.
 520        """
 521        stack = [self]
 522
 523        while stack:
 524            node = stack.pop()
 525
 526            yield node
 527
 528            if prune and prune(node):
 529                continue
 530
 531            for v in node.iter_expressions(reverse=True):
 532                stack.append(v)
 533
 534    def bfs(
 535        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 536    ) -> t.Iterator[Expression]:
 537        """
 538        Returns a generator object which visits all nodes in this tree in
 539        the BFS (Breadth-first) order.
 540
 541        Returns:
 542            The generator object.
 543        """
 544        queue = deque([self])
 545
 546        while queue:
 547            node = queue.popleft()
 548
 549            yield node
 550
 551            if prune and prune(node):
 552                continue
 553
 554            for v in node.iter_expressions():
 555                queue.append(v)
 556
 557    def unnest(self):
 558        """
 559        Returns the first non parenthesis child or self.
 560        """
 561        expression = self
 562        while type(expression) is Paren:
 563            expression = expression.this
 564        return expression
 565
 566    def unalias(self):
 567        """
 568        Returns the inner expression if this is an Alias.
 569        """
 570        if isinstance(self, Alias):
 571            return self.this
 572        return self
 573
 574    def unnest_operands(self):
 575        """
 576        Returns unnested operands as a tuple.
 577        """
 578        return tuple(arg.unnest() for arg in self.iter_expressions())
 579
 580    def flatten(self, unnest=True):
 581        """
 582        Returns a generator which yields child nodes whose parents are the same class.
 583
 584        A AND B AND C -> [A, B, C]
 585        """
 586        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
 587            if type(node) is not self.__class__:
 588                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 589
 590    def __str__(self) -> str:
 591        return self.sql()
 592
 593    def __repr__(self) -> str:
 594        return _to_s(self)
 595
 596    def to_s(self) -> str:
 597        """
 598        Same as __repr__, but includes additional information which can be useful
 599        for debugging, like empty or missing args and the AST nodes' object IDs.
 600        """
 601        return _to_s(self, verbose=True)
 602
 603    def sql(self, dialect: DialectType = None, **opts) -> str:
 604        """
 605        Returns SQL string representation of this tree.
 606
 607        Args:
 608            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 609            opts: other `sqlglot.generator.Generator` options.
 610
 611        Returns:
 612            The SQL string.
 613        """
 614        from sqlglot.dialects import Dialect
 615
 616        return Dialect.get_or_raise(dialect).generate(self, **opts)
 617
 618    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
 619        """
 620        Visits all tree nodes (excluding already transformed ones)
 621        and applies the given transformation function to each node.
 622
 623        Args:
 624            fun: a function which takes a node as an argument and returns a
 625                new transformed node or the same node without modifications. If the function
 626                returns None, then the corresponding node will be removed from the syntax tree.
 627            copy: if set to True a new tree instance is constructed, otherwise the tree is
 628                modified in place.
 629
 630        Returns:
 631            The transformed tree.
 632        """
 633        root = None
 634        new_node = None
 635
 636        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
 637            parent, arg_key, index = node.parent, node.arg_key, node.index
 638            new_node = fun(node, *args, **kwargs)
 639
 640            if not root:
 641                root = new_node
 642            elif parent and arg_key and new_node is not node:
 643                parent.set(arg_key, new_node, index)
 644
 645        assert root
 646        return root.assert_is(Expression)
 647
 648    @t.overload
 649    def replace(self, expression: E) -> E: ...
 650
 651    @t.overload
 652    def replace(self, expression: None) -> None: ...
 653
 654    def replace(self, expression):
 655        """
 656        Swap out this expression with a new expression.
 657
 658        For example::
 659
 660            >>> tree = Select().select("x").from_("tbl")
 661            >>> tree.find(Column).replace(column("y"))
 662            Column(
 663              this=Identifier(this=y, quoted=False))
 664            >>> tree.sql()
 665            'SELECT y FROM tbl'
 666
 667        Args:
 668            expression: new node
 669
 670        Returns:
 671            The new expression or expressions.
 672        """
 673        parent = self.parent
 674
 675        if not parent or parent is expression:
 676            return expression
 677
 678        key = self.arg_key
 679        value = parent.args.get(key)
 680
 681        if type(expression) is list and isinstance(value, Expression):
 682            # We are trying to replace an Expression with a list, so it's assumed that
 683            # the intention was to really replace the parent of this expression.
 684            value.parent.replace(expression)
 685        else:
 686            parent.set(key, expression, self.index)
 687
 688        if expression is not self:
 689            self.parent = None
 690            self.arg_key = None
 691            self.index = None
 692
 693        return expression
 694
 695    def pop(self: E) -> E:
 696        """
 697        Remove this expression from its AST.
 698
 699        Returns:
 700            The popped expression.
 701        """
 702        self.replace(None)
 703        return self
 704
 705    def assert_is(self, type_: t.Type[E]) -> E:
 706        """
 707        Assert that this `Expression` is an instance of `type_`.
 708
 709        If it is NOT an instance of `type_`, this raises an assertion error.
 710        Otherwise, this returns this expression.
 711
 712        Examples:
 713            This is useful for type security in chained expressions:
 714
 715            >>> import sqlglot
 716            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 717            'SELECT x, z FROM y'
 718        """
 719        if not isinstance(self, type_):
 720            raise AssertionError(f"{self} is not {type_}.")
 721        return self
 722
 723    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 724        """
 725        Checks if this expression is valid (e.g. all mandatory args are set).
 726
 727        Args:
 728            args: a sequence of values that were used to instantiate a Func expression. This is used
 729                to check that the provided arguments don't exceed the function argument limit.
 730
 731        Returns:
 732            A list of error messages for all possible errors that were found.
 733        """
 734        errors: t.List[str] = []
 735
 736        for k in self.args:
 737            if k not in self.arg_types:
 738                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 739        for k, mandatory in self.arg_types.items():
 740            v = self.args.get(k)
 741            if mandatory and (v is None or (isinstance(v, list) and not v)):
 742                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 743
 744        if (
 745            args
 746            and isinstance(self, Func)
 747            and len(args) > len(self.arg_types)
 748            and not self.is_var_len_args
 749        ):
 750            errors.append(
 751                f"The number of provided arguments ({len(args)}) is greater than "
 752                f"the maximum number of supported arguments ({len(self.arg_types)})"
 753            )
 754
 755        return errors
 756
 757    def dump(self):
 758        """
 759        Dump this Expression to a JSON-serializable dict.
 760        """
 761        from sqlglot.serde import dump
 762
 763        return dump(self)
 764
 765    @classmethod
 766    def load(cls, obj):
 767        """
 768        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 769        """
 770        from sqlglot.serde import load
 771
 772        return load(obj)
 773
 774    def and_(
 775        self,
 776        *expressions: t.Optional[ExpOrStr],
 777        dialect: DialectType = None,
 778        copy: bool = True,
 779        wrap: bool = True,
 780        **opts,
 781    ) -> Condition:
 782        """
 783        AND this condition with one or multiple expressions.
 784
 785        Example:
 786            >>> condition("x=1").and_("y=1").sql()
 787            'x = 1 AND y = 1'
 788
 789        Args:
 790            *expressions: the SQL code strings to parse.
 791                If an `Expression` instance is passed, it will be used as-is.
 792            dialect: the dialect used to parse the input expression.
 793            copy: whether to copy the involved expressions (only applies to Expressions).
 794            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 795                precedence issues, but can be turned off when the produced AST is too deep and
 796                causes recursion-related issues.
 797            opts: other options to use to parse the input expressions.
 798
 799        Returns:
 800            The new And condition.
 801        """
 802        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 803
 804    def or_(
 805        self,
 806        *expressions: t.Optional[ExpOrStr],
 807        dialect: DialectType = None,
 808        copy: bool = True,
 809        wrap: bool = True,
 810        **opts,
 811    ) -> Condition:
 812        """
 813        OR this condition with one or multiple expressions.
 814
 815        Example:
 816            >>> condition("x=1").or_("y=1").sql()
 817            'x = 1 OR y = 1'
 818
 819        Args:
 820            *expressions: the SQL code strings to parse.
 821                If an `Expression` instance is passed, it will be used as-is.
 822            dialect: the dialect used to parse the input expression.
 823            copy: whether to copy the involved expressions (only applies to Expressions).
 824            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 825                precedence issues, but can be turned off when the produced AST is too deep and
 826                causes recursion-related issues.
 827            opts: other options to use to parse the input expressions.
 828
 829        Returns:
 830            The new Or condition.
 831        """
 832        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 833
 834    def not_(self, copy: bool = True):
 835        """
 836        Wrap this condition with NOT.
 837
 838        Example:
 839            >>> condition("x=1").not_().sql()
 840            'NOT x = 1'
 841
 842        Args:
 843            copy: whether to copy this object.
 844
 845        Returns:
 846            The new Not instance.
 847        """
 848        return not_(self, copy=copy)
 849
 850    def update_positions(
 851        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
 852    ) -> E:
 853        """
 854        Update this expression with positions from a token or other expression.
 855
 856        Args:
 857            other: a token or expression to update this expression with.
 858
 859        Returns:
 860            The updated expression.
 861        """
 862        if isinstance(other, Expression):
 863            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
 864        elif other is not None:
 865            self.meta.update(
 866                {
 867                    "line": other.line,
 868                    "col": other.col,
 869                    "start": other.start,
 870                    "end": other.end,
 871                }
 872            )
 873        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
 874        return self
 875
 876    def as_(
 877        self,
 878        alias: str | Identifier,
 879        quoted: t.Optional[bool] = None,
 880        dialect: DialectType = None,
 881        copy: bool = True,
 882        **opts,
 883    ) -> Alias:
 884        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 885
 886    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 887        this = self.copy()
 888        other = convert(other, copy=True)
 889        if not isinstance(this, klass) and not isinstance(other, klass):
 890            this = _wrap(this, Binary)
 891            other = _wrap(other, Binary)
 892        if reverse:
 893            return klass(this=other, expression=this)
 894        return klass(this=this, expression=other)
 895
 896    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 897        return Bracket(
 898            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 899        )
 900
 901    def __iter__(self) -> t.Iterator:
 902        if "expressions" in self.arg_types:
 903            return iter(self.args.get("expressions") or [])
 904        # We define this because __getitem__ converts Expression into an iterable, which is
 905        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 906        # See: https://peps.python.org/pep-0234/
 907        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 908
 909    def isin(
 910        self,
 911        *expressions: t.Any,
 912        query: t.Optional[ExpOrStr] = None,
 913        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 914        copy: bool = True,
 915        **opts,
 916    ) -> In:
 917        subquery = maybe_parse(query, copy=copy, **opts) if query else None
 918        if subquery and not isinstance(subquery, Subquery):
 919            subquery = subquery.subquery(copy=False)
 920
 921        return In(
 922            this=maybe_copy(self, copy),
 923            expressions=[convert(e, copy=copy) for e in expressions],
 924            query=subquery,
 925            unnest=(
 926                Unnest(
 927                    expressions=[
 928                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 929                        for e in ensure_list(unnest)
 930                    ]
 931                )
 932                if unnest
 933                else None
 934            ),
 935        )
 936
 937    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 938        return Between(
 939            this=maybe_copy(self, copy),
 940            low=convert(low, copy=copy, **opts),
 941            high=convert(high, copy=copy, **opts),
 942        )
 943
 944    def is_(self, other: ExpOrStr) -> Is:
 945        return self._binop(Is, other)
 946
 947    def like(self, other: ExpOrStr) -> Like:
 948        return self._binop(Like, other)
 949
 950    def ilike(self, other: ExpOrStr) -> ILike:
 951        return self._binop(ILike, other)
 952
 953    def eq(self, other: t.Any) -> EQ:
 954        return self._binop(EQ, other)
 955
 956    def neq(self, other: t.Any) -> NEQ:
 957        return self._binop(NEQ, other)
 958
 959    def rlike(self, other: ExpOrStr) -> RegexpLike:
 960        return self._binop(RegexpLike, other)
 961
 962    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 963        div = self._binop(Div, other)
 964        div.args["typed"] = typed
 965        div.args["safe"] = safe
 966        return div
 967
 968    def asc(self, nulls_first: bool = True) -> Ordered:
 969        return Ordered(this=self.copy(), nulls_first=nulls_first)
 970
 971    def desc(self, nulls_first: bool = False) -> Ordered:
 972        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 973
 974    def __lt__(self, other: t.Any) -> LT:
 975        return self._binop(LT, other)
 976
 977    def __le__(self, other: t.Any) -> LTE:
 978        return self._binop(LTE, other)
 979
 980    def __gt__(self, other: t.Any) -> GT:
 981        return self._binop(GT, other)
 982
 983    def __ge__(self, other: t.Any) -> GTE:
 984        return self._binop(GTE, other)
 985
 986    def __add__(self, other: t.Any) -> Add:
 987        return self._binop(Add, other)
 988
 989    def __radd__(self, other: t.Any) -> Add:
 990        return self._binop(Add, other, reverse=True)
 991
 992    def __sub__(self, other: t.Any) -> Sub:
 993        return self._binop(Sub, other)
 994
 995    def __rsub__(self, other: t.Any) -> Sub:
 996        return self._binop(Sub, other, reverse=True)
 997
 998    def __mul__(self, other: t.Any) -> Mul:
 999        return self._binop(Mul, other)
1000
1001    def __rmul__(self, other: t.Any) -> Mul:
1002        return self._binop(Mul, other, reverse=True)
1003
1004    def __truediv__(self, other: t.Any) -> Div:
1005        return self._binop(Div, other)
1006
1007    def __rtruediv__(self, other: t.Any) -> Div:
1008        return self._binop(Div, other, reverse=True)
1009
1010    def __floordiv__(self, other: t.Any) -> IntDiv:
1011        return self._binop(IntDiv, other)
1012
1013    def __rfloordiv__(self, other: t.Any) -> IntDiv:
1014        return self._binop(IntDiv, other, reverse=True)
1015
1016    def __mod__(self, other: t.Any) -> Mod:
1017        return self._binop(Mod, other)
1018
1019    def __rmod__(self, other: t.Any) -> Mod:
1020        return self._binop(Mod, other, reverse=True)
1021
1022    def __pow__(self, other: t.Any) -> Pow:
1023        return self._binop(Pow, other)
1024
1025    def __rpow__(self, other: t.Any) -> Pow:
1026        return self._binop(Pow, other, reverse=True)
1027
1028    def __and__(self, other: t.Any) -> And:
1029        return self._binop(And, other)
1030
1031    def __rand__(self, other: t.Any) -> And:
1032        return self._binop(And, other, reverse=True)
1033
1034    def __or__(self, other: t.Any) -> Or:
1035        return self._binop(Or, other)
1036
1037    def __ror__(self, other: t.Any) -> Or:
1038        return self._binop(Or, other, reverse=True)
1039
1040    def __neg__(self) -> Neg:
1041        return Neg(this=_wrap(self.copy(), Binary))
1042
1043    def __invert__(self) -> Not:
1044        return not_(self.copy())
1045
1046
1047IntoType = t.Union[
1048    str,
1049    t.Type[Expression],
1050    t.Collection[t.Union[str, t.Type[Expression]]],
1051]
1052ExpOrStr = t.Union[str, Expression]
1053
1054
1055class Condition(Expression):
1056    """Logical conditions like x AND y, or simply x"""
1057
1058
1059class Predicate(Condition):
1060    """Relationships like x = y, x > 1, x >= y."""
1061
1062
1063class DerivedTable(Expression):
1064    @property
1065    def selects(self) -> t.List[Expression]:
1066        return self.this.selects if isinstance(self.this, Query) else []
1067
1068    @property
1069    def named_selects(self) -> t.List[str]:
1070        return [select.output_name for select in self.selects]
1071
1072
1073class Query(Expression):
1074    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1075        """
1076        Returns a `Subquery` that wraps around this query.
1077
1078        Example:
1079            >>> subquery = Select().select("x").from_("tbl").subquery()
1080            >>> Select().select("x").from_(subquery).sql()
1081            'SELECT x FROM (SELECT x FROM tbl)'
1082
1083        Args:
1084            alias: an optional alias for the subquery.
1085            copy: if `False`, modify this expression instance in-place.
1086        """
1087        instance = maybe_copy(self, copy)
1088        if not isinstance(alias, Expression):
1089            alias = TableAlias(this=to_identifier(alias)) if alias else None
1090
1091        return Subquery(this=instance, alias=alias)
1092
1093    def limit(
1094        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1095    ) -> Q:
1096        """
1097        Adds a LIMIT clause to this query.
1098
1099        Example:
1100            >>> select("1").union(select("1")).limit(1).sql()
1101            'SELECT 1 UNION SELECT 1 LIMIT 1'
1102
1103        Args:
1104            expression: the SQL code string to parse.
1105                This can also be an integer.
1106                If a `Limit` instance is passed, it will be used as-is.
1107                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1108            dialect: the dialect used to parse the input expression.
1109            copy: if `False`, modify this expression instance in-place.
1110            opts: other options to use to parse the input expressions.
1111
1112        Returns:
1113            A limited Select expression.
1114        """
1115        return _apply_builder(
1116            expression=expression,
1117            instance=self,
1118            arg="limit",
1119            into=Limit,
1120            prefix="LIMIT",
1121            dialect=dialect,
1122            copy=copy,
1123            into_arg="expression",
1124            **opts,
1125        )
1126
1127    def offset(
1128        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1129    ) -> Q:
1130        """
1131        Set the OFFSET expression.
1132
1133        Example:
1134            >>> Select().from_("tbl").select("x").offset(10).sql()
1135            'SELECT x FROM tbl OFFSET 10'
1136
1137        Args:
1138            expression: the SQL code string to parse.
1139                This can also be an integer.
1140                If a `Offset` instance is passed, this is used as-is.
1141                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1142            dialect: the dialect used to parse the input expression.
1143            copy: if `False`, modify this expression instance in-place.
1144            opts: other options to use to parse the input expressions.
1145
1146        Returns:
1147            The modified Select expression.
1148        """
1149        return _apply_builder(
1150            expression=expression,
1151            instance=self,
1152            arg="offset",
1153            into=Offset,
1154            prefix="OFFSET",
1155            dialect=dialect,
1156            copy=copy,
1157            into_arg="expression",
1158            **opts,
1159        )
1160
1161    def order_by(
1162        self: Q,
1163        *expressions: t.Optional[ExpOrStr],
1164        append: bool = True,
1165        dialect: DialectType = None,
1166        copy: bool = True,
1167        **opts,
1168    ) -> Q:
1169        """
1170        Set the ORDER BY expression.
1171
1172        Example:
1173            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1174            'SELECT x FROM tbl ORDER BY x DESC'
1175
1176        Args:
1177            *expressions: the SQL code strings to parse.
1178                If a `Group` instance is passed, this is used as-is.
1179                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1180            append: if `True`, add to any existing expressions.
1181                Otherwise, this flattens all the `Order` expression into a single expression.
1182            dialect: the dialect used to parse the input expression.
1183            copy: if `False`, modify this expression instance in-place.
1184            opts: other options to use to parse the input expressions.
1185
1186        Returns:
1187            The modified Select expression.
1188        """
1189        return _apply_child_list_builder(
1190            *expressions,
1191            instance=self,
1192            arg="order",
1193            append=append,
1194            copy=copy,
1195            prefix="ORDER BY",
1196            into=Order,
1197            dialect=dialect,
1198            **opts,
1199        )
1200
1201    @property
1202    def ctes(self) -> t.List[CTE]:
1203        """Returns a list of all the CTEs attached to this query."""
1204        with_ = self.args.get("with")
1205        return with_.expressions if with_ else []
1206
1207    @property
1208    def selects(self) -> t.List[Expression]:
1209        """Returns the query's projections."""
1210        raise NotImplementedError("Query objects must implement `selects`")
1211
1212    @property
1213    def named_selects(self) -> t.List[str]:
1214        """Returns the output names of the query's projections."""
1215        raise NotImplementedError("Query objects must implement `named_selects`")
1216
1217    def select(
1218        self: Q,
1219        *expressions: t.Optional[ExpOrStr],
1220        append: bool = True,
1221        dialect: DialectType = None,
1222        copy: bool = True,
1223        **opts,
1224    ) -> Q:
1225        """
1226        Append to or set the SELECT expressions.
1227
1228        Example:
1229            >>> Select().select("x", "y").sql()
1230            'SELECT x, y'
1231
1232        Args:
1233            *expressions: the SQL code strings to parse.
1234                If an `Expression` instance is passed, it will be used as-is.
1235            append: if `True`, add to any existing expressions.
1236                Otherwise, this resets the expressions.
1237            dialect: the dialect used to parse the input expressions.
1238            copy: if `False`, modify this expression instance in-place.
1239            opts: other options to use to parse the input expressions.
1240
1241        Returns:
1242            The modified Query expression.
1243        """
1244        raise NotImplementedError("Query objects must implement `select`")
1245
1246    def where(
1247        self: Q,
1248        *expressions: t.Optional[ExpOrStr],
1249        append: bool = True,
1250        dialect: DialectType = None,
1251        copy: bool = True,
1252        **opts,
1253    ) -> Q:
1254        """
1255        Append to or set the WHERE expressions.
1256
1257        Examples:
1258            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1259            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1260
1261        Args:
1262            *expressions: the SQL code strings to parse.
1263                If an `Expression` instance is passed, it will be used as-is.
1264                Multiple expressions are combined with an AND operator.
1265            append: if `True`, AND the new expressions to any existing expression.
1266                Otherwise, this resets the expression.
1267            dialect: the dialect used to parse the input expressions.
1268            copy: if `False`, modify this expression instance in-place.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The modified expression.
1273        """
1274        return _apply_conjunction_builder(
1275            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1276            instance=self,
1277            arg="where",
1278            append=append,
1279            into=Where,
1280            dialect=dialect,
1281            copy=copy,
1282            **opts,
1283        )
1284
1285    def with_(
1286        self: Q,
1287        alias: ExpOrStr,
1288        as_: ExpOrStr,
1289        recursive: t.Optional[bool] = None,
1290        materialized: t.Optional[bool] = None,
1291        append: bool = True,
1292        dialect: DialectType = None,
1293        copy: bool = True,
1294        scalar: bool = False,
1295        **opts,
1296    ) -> Q:
1297        """
1298        Append to or set the common table expressions.
1299
1300        Example:
1301            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1302            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1303
1304        Args:
1305            alias: the SQL code string to parse as the table name.
1306                If an `Expression` instance is passed, this is used as-is.
1307            as_: the SQL code string to parse as the table expression.
1308                If an `Expression` instance is passed, it will be used as-is.
1309            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1310            materialized: set the MATERIALIZED part of the expression.
1311            append: if `True`, add to any existing expressions.
1312                Otherwise, this resets the expressions.
1313            dialect: the dialect used to parse the input expression.
1314            copy: if `False`, modify this expression instance in-place.
1315            scalar: if `True`, this is a scalar common table expression.
1316            opts: other options to use to parse the input expressions.
1317
1318        Returns:
1319            The modified expression.
1320        """
1321        return _apply_cte_builder(
1322            self,
1323            alias,
1324            as_,
1325            recursive=recursive,
1326            materialized=materialized,
1327            append=append,
1328            dialect=dialect,
1329            copy=copy,
1330            scalar=scalar,
1331            **opts,
1332        )
1333
1334    def union(
1335        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1336    ) -> Union:
1337        """
1338        Builds a UNION expression.
1339
1340        Example:
1341            >>> import sqlglot
1342            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1343            'SELECT * FROM foo UNION SELECT * FROM bla'
1344
1345        Args:
1346            expressions: the SQL code strings.
1347                If `Expression` instances are passed, they will be used as-is.
1348            distinct: set the DISTINCT flag if and only if this is true.
1349            dialect: the dialect used to parse the input expression.
1350            opts: other options to use to parse the input expressions.
1351
1352        Returns:
1353            The new Union expression.
1354        """
1355        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1356
1357    def intersect(
1358        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1359    ) -> Intersect:
1360        """
1361        Builds an INTERSECT expression.
1362
1363        Example:
1364            >>> import sqlglot
1365            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1366            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1367
1368        Args:
1369            expressions: the SQL code strings.
1370                If `Expression` instances are passed, they will be used as-is.
1371            distinct: set the DISTINCT flag if and only if this is true.
1372            dialect: the dialect used to parse the input expression.
1373            opts: other options to use to parse the input expressions.
1374
1375        Returns:
1376            The new Intersect expression.
1377        """
1378        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1379
1380    def except_(
1381        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1382    ) -> Except:
1383        """
1384        Builds an EXCEPT expression.
1385
1386        Example:
1387            >>> import sqlglot
1388            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1389            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1390
1391        Args:
1392            expressions: the SQL code strings.
1393                If `Expression` instance are passed, they will be used as-is.
1394            distinct: set the DISTINCT flag if and only if this is true.
1395            dialect: the dialect used to parse the input expression.
1396            opts: other options to use to parse the input expressions.
1397
1398        Returns:
1399            The new Except expression.
1400        """
1401        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1402
1403
1404class UDTF(DerivedTable):
1405    @property
1406    def selects(self) -> t.List[Expression]:
1407        alias = self.args.get("alias")
1408        return alias.columns if alias else []
1409
1410
1411class Cache(Expression):
1412    arg_types = {
1413        "this": True,
1414        "lazy": False,
1415        "options": False,
1416        "expression": False,
1417    }
1418
1419
1420class Uncache(Expression):
1421    arg_types = {"this": True, "exists": False}
1422
1423
1424class Refresh(Expression):
1425    pass
1426
1427
1428class DDL(Expression):
1429    @property
1430    def ctes(self) -> t.List[CTE]:
1431        """Returns a list of all the CTEs attached to this statement."""
1432        with_ = self.args.get("with")
1433        return with_.expressions if with_ else []
1434
1435    @property
1436    def selects(self) -> t.List[Expression]:
1437        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1438        return self.expression.selects if isinstance(self.expression, Query) else []
1439
1440    @property
1441    def named_selects(self) -> t.List[str]:
1442        """
1443        If this statement contains a query (e.g. a CTAS), this returns the output
1444        names of the query's projections.
1445        """
1446        return self.expression.named_selects if isinstance(self.expression, Query) else []
1447
1448
1449class DML(Expression):
1450    def returning(
1451        self,
1452        expression: ExpOrStr,
1453        dialect: DialectType = None,
1454        copy: bool = True,
1455        **opts,
1456    ) -> "Self":
1457        """
1458        Set the RETURNING expression. Not supported by all dialects.
1459
1460        Example:
1461            >>> delete("tbl").returning("*", dialect="postgres").sql()
1462            'DELETE FROM tbl RETURNING *'
1463
1464        Args:
1465            expression: the SQL code strings to parse.
1466                If an `Expression` instance is passed, it will be used as-is.
1467            dialect: the dialect used to parse the input expressions.
1468            copy: if `False`, modify this expression instance in-place.
1469            opts: other options to use to parse the input expressions.
1470
1471        Returns:
1472            Delete: the modified expression.
1473        """
1474        return _apply_builder(
1475            expression=expression,
1476            instance=self,
1477            arg="returning",
1478            prefix="RETURNING",
1479            dialect=dialect,
1480            copy=copy,
1481            into=Returning,
1482            **opts,
1483        )
1484
1485
1486class Create(DDL):
1487    arg_types = {
1488        "with": False,
1489        "this": True,
1490        "kind": True,
1491        "expression": False,
1492        "exists": False,
1493        "properties": False,
1494        "replace": False,
1495        "refresh": False,
1496        "unique": False,
1497        "indexes": False,
1498        "no_schema_binding": False,
1499        "begin": False,
1500        "end": False,
1501        "clone": False,
1502        "concurrently": False,
1503        "clustered": False,
1504    }
1505
1506    @property
1507    def kind(self) -> t.Optional[str]:
1508        kind = self.args.get("kind")
1509        return kind and kind.upper()
1510
1511
1512class SequenceProperties(Expression):
1513    arg_types = {
1514        "increment": False,
1515        "minvalue": False,
1516        "maxvalue": False,
1517        "cache": False,
1518        "start": False,
1519        "owned": False,
1520        "options": False,
1521    }
1522
1523
1524class TruncateTable(Expression):
1525    arg_types = {
1526        "expressions": True,
1527        "is_database": False,
1528        "exists": False,
1529        "only": False,
1530        "cluster": False,
1531        "identity": False,
1532        "option": False,
1533        "partition": False,
1534    }
1535
1536
1537# https://docs.snowflake.com/en/sql-reference/sql/create-clone
1538# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_clone_statement
1539# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_copy
1540class Clone(Expression):
1541    arg_types = {"this": True, "shallow": False, "copy": False}
1542
1543
1544class Describe(Expression):
1545    arg_types = {
1546        "this": True,
1547        "style": False,
1548        "kind": False,
1549        "expressions": False,
1550        "partition": False,
1551        "format": False,
1552    }
1553
1554
1555# https://duckdb.org/docs/sql/statements/attach.html#attach
1556class Attach(Expression):
1557    arg_types = {"this": True, "exists": False, "expressions": False}
1558
1559
1560# https://duckdb.org/docs/sql/statements/attach.html#detach
1561class Detach(Expression):
1562    arg_types = {"this": True, "exists": False}
1563
1564
1565# https://duckdb.org/docs/guides/meta/summarize.html
1566class Summarize(Expression):
1567    arg_types = {"this": True, "table": False}
1568
1569
1570class Kill(Expression):
1571    arg_types = {"this": True, "kind": False}
1572
1573
1574class Pragma(Expression):
1575    pass
1576
1577
1578class Declare(Expression):
1579    arg_types = {"expressions": True}
1580
1581
1582class DeclareItem(Expression):
1583    arg_types = {"this": True, "kind": True, "default": False}
1584
1585
1586class Set(Expression):
1587    arg_types = {"expressions": False, "unset": False, "tag": False}
1588
1589
1590class Heredoc(Expression):
1591    arg_types = {"this": True, "tag": False}
1592
1593
1594class SetItem(Expression):
1595    arg_types = {
1596        "this": False,
1597        "expressions": False,
1598        "kind": False,
1599        "collate": False,  # MySQL SET NAMES statement
1600        "global": False,
1601    }
1602
1603
1604class Show(Expression):
1605    arg_types = {
1606        "this": True,
1607        "history": False,
1608        "terse": False,
1609        "target": False,
1610        "offset": False,
1611        "starts_with": False,
1612        "limit": False,
1613        "from": False,
1614        "like": False,
1615        "where": False,
1616        "db": False,
1617        "scope": False,
1618        "scope_kind": False,
1619        "full": False,
1620        "mutex": False,
1621        "query": False,
1622        "channel": False,
1623        "global": False,
1624        "log": False,
1625        "position": False,
1626        "types": False,
1627        "privileges": False,
1628    }
1629
1630
1631class UserDefinedFunction(Expression):
1632    arg_types = {"this": True, "expressions": False, "wrapped": False}
1633
1634
1635class CharacterSet(Expression):
1636    arg_types = {"this": True, "default": False}
1637
1638
1639class RecursiveWithSearch(Expression):
1640    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
1641
1642
1643class With(Expression):
1644    arg_types = {"expressions": True, "recursive": False, "search": False}
1645
1646    @property
1647    def recursive(self) -> bool:
1648        return bool(self.args.get("recursive"))
1649
1650
1651class WithinGroup(Expression):
1652    arg_types = {"this": True, "expression": False}
1653
1654
1655# clickhouse supports scalar ctes
1656# https://clickhouse.com/docs/en/sql-reference/statements/select/with
1657class CTE(DerivedTable):
1658    arg_types = {
1659        "this": True,
1660        "alias": True,
1661        "scalar": False,
1662        "materialized": False,
1663    }
1664
1665
1666class ProjectionDef(Expression):
1667    arg_types = {"this": True, "expression": True}
1668
1669
1670class TableAlias(Expression):
1671    arg_types = {"this": False, "columns": False}
1672
1673    @property
1674    def columns(self):
1675        return self.args.get("columns") or []
1676
1677
1678class BitString(Condition):
1679    pass
1680
1681
1682class HexString(Condition):
1683    arg_types = {"this": True, "is_integer": False}
1684
1685
1686class ByteString(Condition):
1687    pass
1688
1689
1690class RawString(Condition):
1691    pass
1692
1693
1694class UnicodeString(Condition):
1695    arg_types = {"this": True, "escape": False}
1696
1697
1698class Column(Condition):
1699    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1700
1701    @property
1702    def table(self) -> str:
1703        return self.text("table")
1704
1705    @property
1706    def db(self) -> str:
1707        return self.text("db")
1708
1709    @property
1710    def catalog(self) -> str:
1711        return self.text("catalog")
1712
1713    @property
1714    def output_name(self) -> str:
1715        return self.name
1716
1717    @property
1718    def parts(self) -> t.List[Identifier]:
1719        """Return the parts of a column in order catalog, db, table, name."""
1720        return [
1721            t.cast(Identifier, self.args[part])
1722            for part in ("catalog", "db", "table", "this")
1723            if self.args.get(part)
1724        ]
1725
1726    def to_dot(self) -> Dot | Identifier:
1727        """Converts the column into a dot expression."""
1728        parts = self.parts
1729        parent = self.parent
1730
1731        while parent:
1732            if isinstance(parent, Dot):
1733                parts.append(parent.expression)
1734            parent = parent.parent
1735
1736        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
1737
1738
1739class ColumnPosition(Expression):
1740    arg_types = {"this": False, "position": True}
1741
1742
1743class ColumnDef(Expression):
1744    arg_types = {
1745        "this": True,
1746        "kind": False,
1747        "constraints": False,
1748        "exists": False,
1749        "position": False,
1750        "default": False,
1751        "output": False,
1752    }
1753
1754    @property
1755    def constraints(self) -> t.List[ColumnConstraint]:
1756        return self.args.get("constraints") or []
1757
1758    @property
1759    def kind(self) -> t.Optional[DataType]:
1760        return self.args.get("kind")
1761
1762
1763class AlterColumn(Expression):
1764    arg_types = {
1765        "this": True,
1766        "dtype": False,
1767        "collate": False,
1768        "using": False,
1769        "default": False,
1770        "drop": False,
1771        "comment": False,
1772        "allow_null": False,
1773        "visible": False,
1774    }
1775
1776
1777# https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
1778class AlterIndex(Expression):
1779    arg_types = {"this": True, "visible": True}
1780
1781
1782# https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
1783class AlterDistStyle(Expression):
1784    pass
1785
1786
1787class AlterSortKey(Expression):
1788    arg_types = {"this": False, "expressions": False, "compound": False}
1789
1790
1791class AlterSet(Expression):
1792    arg_types = {
1793        "expressions": False,
1794        "option": False,
1795        "tablespace": False,
1796        "access_method": False,
1797        "file_format": False,
1798        "copy_options": False,
1799        "tag": False,
1800        "location": False,
1801        "serde": False,
1802    }
1803
1804
1805class RenameColumn(Expression):
1806    arg_types = {"this": True, "to": True, "exists": False}
1807
1808
1809class AlterRename(Expression):
1810    pass
1811
1812
1813class SwapTable(Expression):
1814    pass
1815
1816
1817class Comment(Expression):
1818    arg_types = {
1819        "this": True,
1820        "kind": True,
1821        "expression": True,
1822        "exists": False,
1823        "materialized": False,
1824    }
1825
1826
1827class Comprehension(Expression):
1828    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
1829
1830
1831# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1832class MergeTreeTTLAction(Expression):
1833    arg_types = {
1834        "this": True,
1835        "delete": False,
1836        "recompress": False,
1837        "to_disk": False,
1838        "to_volume": False,
1839    }
1840
1841
1842# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1843class MergeTreeTTL(Expression):
1844    arg_types = {
1845        "expressions": True,
1846        "where": False,
1847        "group": False,
1848        "aggregates": False,
1849    }
1850
1851
1852# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1853class IndexConstraintOption(Expression):
1854    arg_types = {
1855        "key_block_size": False,
1856        "using": False,
1857        "parser": False,
1858        "comment": False,
1859        "visible": False,
1860        "engine_attr": False,
1861        "secondary_engine_attr": False,
1862    }
1863
1864
1865class ColumnConstraint(Expression):
1866    arg_types = {"this": False, "kind": True}
1867
1868    @property
1869    def kind(self) -> ColumnConstraintKind:
1870        return self.args["kind"]
1871
1872
1873class ColumnConstraintKind(Expression):
1874    pass
1875
1876
1877class AutoIncrementColumnConstraint(ColumnConstraintKind):
1878    pass
1879
1880
1881class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1882    arg_types = {"this": True, "expression": True}
1883
1884
1885class CaseSpecificColumnConstraint(ColumnConstraintKind):
1886    arg_types = {"not_": True}
1887
1888
1889class CharacterSetColumnConstraint(ColumnConstraintKind):
1890    arg_types = {"this": True}
1891
1892
1893class CheckColumnConstraint(ColumnConstraintKind):
1894    arg_types = {"this": True, "enforced": False}
1895
1896
1897class ClusteredColumnConstraint(ColumnConstraintKind):
1898    pass
1899
1900
1901class CollateColumnConstraint(ColumnConstraintKind):
1902    pass
1903
1904
1905class CommentColumnConstraint(ColumnConstraintKind):
1906    pass
1907
1908
1909class CompressColumnConstraint(ColumnConstraintKind):
1910    arg_types = {"this": False}
1911
1912
1913class DateFormatColumnConstraint(ColumnConstraintKind):
1914    arg_types = {"this": True}
1915
1916
1917class DefaultColumnConstraint(ColumnConstraintKind):
1918    pass
1919
1920
1921class EncodeColumnConstraint(ColumnConstraintKind):
1922    pass
1923
1924
1925# https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
1926class ExcludeColumnConstraint(ColumnConstraintKind):
1927    pass
1928
1929
1930class EphemeralColumnConstraint(ColumnConstraintKind):
1931    arg_types = {"this": False}
1932
1933
1934class WithOperator(Expression):
1935    arg_types = {"this": True, "op": True}
1936
1937
1938class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1939    # this: True -> ALWAYS, this: False -> BY DEFAULT
1940    arg_types = {
1941        "this": False,
1942        "expression": False,
1943        "on_null": False,
1944        "start": False,
1945        "increment": False,
1946        "minvalue": False,
1947        "maxvalue": False,
1948        "cycle": False,
1949    }
1950
1951
1952class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1953    arg_types = {"start": False, "hidden": False}
1954
1955
1956# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1957# https://github.com/ClickHouse/ClickHouse/blob/master/src/Parsers/ParserCreateQuery.h#L646
1958class IndexColumnConstraint(ColumnConstraintKind):
1959    arg_types = {
1960        "this": False,
1961        "expressions": False,
1962        "kind": False,
1963        "index_type": False,
1964        "options": False,
1965        "expression": False,  # Clickhouse
1966        "granularity": False,
1967    }
1968
1969
1970class InlineLengthColumnConstraint(ColumnConstraintKind):
1971    pass
1972
1973
1974class NonClusteredColumnConstraint(ColumnConstraintKind):
1975    pass
1976
1977
1978class NotForReplicationColumnConstraint(ColumnConstraintKind):
1979    arg_types = {}
1980
1981
1982# https://docs.snowflake.com/en/sql-reference/sql/create-table
1983class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1984    arg_types = {"this": True, "expressions": False}
1985
1986
1987class NotNullColumnConstraint(ColumnConstraintKind):
1988    arg_types = {"allow_null": False}
1989
1990
1991# https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
1992class OnUpdateColumnConstraint(ColumnConstraintKind):
1993    pass
1994
1995
1996# https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
1997class TransformColumnConstraint(ColumnConstraintKind):
1998    pass
1999
2000
2001class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2002    arg_types = {"desc": False, "options": False}
2003
2004
2005class TitleColumnConstraint(ColumnConstraintKind):
2006    pass
2007
2008
2009class UniqueColumnConstraint(ColumnConstraintKind):
2010    arg_types = {
2011        "this": False,
2012        "index_type": False,
2013        "on_conflict": False,
2014        "nulls": False,
2015        "options": False,
2016    }
2017
2018
2019class UppercaseColumnConstraint(ColumnConstraintKind):
2020    arg_types: t.Dict[str, t.Any] = {}
2021
2022
2023# https://docs.risingwave.com/processing/watermarks#syntax
2024class WatermarkColumnConstraint(Expression):
2025    arg_types = {"this": True, "expression": True}
2026
2027
2028class PathColumnConstraint(ColumnConstraintKind):
2029    pass
2030
2031
2032# https://docs.snowflake.com/en/sql-reference/sql/create-table
2033class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2034    pass
2035
2036
2037# computed column expression
2038# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver16
2039class ComputedColumnConstraint(ColumnConstraintKind):
2040    arg_types = {"this": True, "persisted": False, "not_null": False}
2041
2042
2043class Constraint(Expression):
2044    arg_types = {"this": True, "expressions": True}
2045
2046
2047class Delete(DML):
2048    arg_types = {
2049        "with": False,
2050        "this": False,
2051        "using": False,
2052        "where": False,
2053        "returning": False,
2054        "limit": False,
2055        "tables": False,  # Multiple-Table Syntax (MySQL)
2056        "cluster": False,  # Clickhouse
2057    }
2058
2059    def delete(
2060        self,
2061        table: ExpOrStr,
2062        dialect: DialectType = None,
2063        copy: bool = True,
2064        **opts,
2065    ) -> Delete:
2066        """
2067        Create a DELETE expression or replace the table on an existing DELETE expression.
2068
2069        Example:
2070            >>> delete("tbl").sql()
2071            'DELETE FROM tbl'
2072
2073        Args:
2074            table: the table from which to delete.
2075            dialect: the dialect used to parse the input expression.
2076            copy: if `False`, modify this expression instance in-place.
2077            opts: other options to use to parse the input expressions.
2078
2079        Returns:
2080            Delete: the modified expression.
2081        """
2082        return _apply_builder(
2083            expression=table,
2084            instance=self,
2085            arg="this",
2086            dialect=dialect,
2087            into=Table,
2088            copy=copy,
2089            **opts,
2090        )
2091
2092    def where(
2093        self,
2094        *expressions: t.Optional[ExpOrStr],
2095        append: bool = True,
2096        dialect: DialectType = None,
2097        copy: bool = True,
2098        **opts,
2099    ) -> Delete:
2100        """
2101        Append to or set the WHERE expressions.
2102
2103        Example:
2104            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2105            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2106
2107        Args:
2108            *expressions: the SQL code strings to parse.
2109                If an `Expression` instance is passed, it will be used as-is.
2110                Multiple expressions are combined with an AND operator.
2111            append: if `True`, AND the new expressions to any existing expression.
2112                Otherwise, this resets the expression.
2113            dialect: the dialect used to parse the input expressions.
2114            copy: if `False`, modify this expression instance in-place.
2115            opts: other options to use to parse the input expressions.
2116
2117        Returns:
2118            Delete: the modified expression.
2119        """
2120        return _apply_conjunction_builder(
2121            *expressions,
2122            instance=self,
2123            arg="where",
2124            append=append,
2125            into=Where,
2126            dialect=dialect,
2127            copy=copy,
2128            **opts,
2129        )
2130
2131
2132class Drop(Expression):
2133    arg_types = {
2134        "this": False,
2135        "kind": False,
2136        "expressions": False,
2137        "exists": False,
2138        "temporary": False,
2139        "materialized": False,
2140        "cascade": False,
2141        "constraints": False,
2142        "purge": False,
2143        "cluster": False,
2144        "concurrently": False,
2145    }
2146
2147    @property
2148    def kind(self) -> t.Optional[str]:
2149        kind = self.args.get("kind")
2150        return kind and kind.upper()
2151
2152
2153# https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements
2154class Export(Expression):
2155    arg_types = {"this": True, "connection": False, "options": True}
2156
2157
2158class Filter(Expression):
2159    arg_types = {"this": True, "expression": True}
2160
2161
2162class Check(Expression):
2163    pass
2164
2165
2166class Changes(Expression):
2167    arg_types = {"information": True, "at_before": False, "end": False}
2168
2169
2170# https://docs.snowflake.com/en/sql-reference/constructs/connect-by
2171class Connect(Expression):
2172    arg_types = {"start": False, "connect": True, "nocycle": False}
2173
2174
2175class CopyParameter(Expression):
2176    arg_types = {"this": True, "expression": False, "expressions": False}
2177
2178
2179class Copy(DML):
2180    arg_types = {
2181        "this": True,
2182        "kind": True,
2183        "files": True,
2184        "credentials": False,
2185        "format": False,
2186        "params": False,
2187    }
2188
2189
2190class Credentials(Expression):
2191    arg_types = {
2192        "credentials": False,
2193        "encryption": False,
2194        "storage": False,
2195        "iam_role": False,
2196        "region": False,
2197    }
2198
2199
2200class Prior(Expression):
2201    pass
2202
2203
2204class Directory(Expression):
2205    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2206    arg_types = {"this": True, "local": False, "row_format": False}
2207
2208
2209class ForeignKey(Expression):
2210    arg_types = {
2211        "expressions": False,
2212        "reference": False,
2213        "delete": False,
2214        "update": False,
2215        "options": False,
2216    }
2217
2218
2219class ColumnPrefix(Expression):
2220    arg_types = {"this": True, "expression": True}
2221
2222
2223class PrimaryKey(Expression):
2224    arg_types = {"expressions": True, "options": False}
2225
2226
2227# https://www.postgresql.org/docs/9.1/sql-selectinto.html
2228# https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_INTO.html#r_SELECT_INTO-examples
2229class Into(Expression):
2230    arg_types = {
2231        "this": False,
2232        "temporary": False,
2233        "unlogged": False,
2234        "bulk_collect": False,
2235        "expressions": False,
2236    }
2237
2238
2239class From(Expression):
2240    @property
2241    def name(self) -> str:
2242        return self.this.name
2243
2244    @property
2245    def alias_or_name(self) -> str:
2246        return self.this.alias_or_name
2247
2248
2249class Having(Expression):
2250    pass
2251
2252
2253class Hint(Expression):
2254    arg_types = {"expressions": True}
2255
2256
2257class JoinHint(Expression):
2258    arg_types = {"this": True, "expressions": True}
2259
2260
2261class Identifier(Expression):
2262    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2263
2264    @property
2265    def quoted(self) -> bool:
2266        return bool(self.args.get("quoted"))
2267
2268    @property
2269    def hashable_args(self) -> t.Any:
2270        return (self.this, self.quoted)
2271
2272    @property
2273    def output_name(self) -> str:
2274        return self.name
2275
2276
2277# https://www.postgresql.org/docs/current/indexes-opclass.html
2278class Opclass(Expression):
2279    arg_types = {"this": True, "expression": True}
2280
2281
2282class Index(Expression):
2283    arg_types = {
2284        "this": False,
2285        "table": False,
2286        "unique": False,
2287        "primary": False,
2288        "amp": False,  # teradata
2289        "params": False,
2290    }
2291
2292
2293class IndexParameters(Expression):
2294    arg_types = {
2295        "using": False,
2296        "include": False,
2297        "columns": False,
2298        "with_storage": False,
2299        "partition_by": False,
2300        "tablespace": False,
2301        "where": False,
2302        "on": False,
2303    }
2304
2305
2306class Insert(DDL, DML):
2307    arg_types = {
2308        "hint": False,
2309        "with": False,
2310        "is_function": False,
2311        "this": False,
2312        "expression": False,
2313        "conflict": False,
2314        "returning": False,
2315        "overwrite": False,
2316        "exists": False,
2317        "alternative": False,
2318        "where": False,
2319        "ignore": False,
2320        "by_name": False,
2321        "stored": False,
2322        "partition": False,
2323        "settings": False,
2324        "source": False,
2325    }
2326
2327    def with_(
2328        self,
2329        alias: ExpOrStr,
2330        as_: ExpOrStr,
2331        recursive: t.Optional[bool] = None,
2332        materialized: t.Optional[bool] = None,
2333        append: bool = True,
2334        dialect: DialectType = None,
2335        copy: bool = True,
2336        **opts,
2337    ) -> Insert:
2338        """
2339        Append to or set the common table expressions.
2340
2341        Example:
2342            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2343            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2344
2345        Args:
2346            alias: the SQL code string to parse as the table name.
2347                If an `Expression` instance is passed, this is used as-is.
2348            as_: the SQL code string to parse as the table expression.
2349                If an `Expression` instance is passed, it will be used as-is.
2350            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2351            materialized: set the MATERIALIZED part of the expression.
2352            append: if `True`, add to any existing expressions.
2353                Otherwise, this resets the expressions.
2354            dialect: the dialect used to parse the input expression.
2355            copy: if `False`, modify this expression instance in-place.
2356            opts: other options to use to parse the input expressions.
2357
2358        Returns:
2359            The modified expression.
2360        """
2361        return _apply_cte_builder(
2362            self,
2363            alias,
2364            as_,
2365            recursive=recursive,
2366            materialized=materialized,
2367            append=append,
2368            dialect=dialect,
2369            copy=copy,
2370            **opts,
2371        )
2372
2373
2374class ConditionalInsert(Expression):
2375    arg_types = {"this": True, "expression": False, "else_": False}
2376
2377
2378class MultitableInserts(Expression):
2379    arg_types = {"expressions": True, "kind": True, "source": True}
2380
2381
2382class OnConflict(Expression):
2383    arg_types = {
2384        "duplicate": False,
2385        "expressions": False,
2386        "action": False,
2387        "conflict_keys": False,
2388        "constraint": False,
2389        "where": False,
2390    }
2391
2392
2393class OnCondition(Expression):
2394    arg_types = {"error": False, "empty": False, "null": False}
2395
2396
2397class Returning(Expression):
2398    arg_types = {"expressions": True, "into": False}
2399
2400
2401# https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
2402class Introducer(Expression):
2403    arg_types = {"this": True, "expression": True}
2404
2405
2406# national char, like n'utf8'
2407class National(Expression):
2408    pass
2409
2410
2411class LoadData(Expression):
2412    arg_types = {
2413        "this": True,
2414        "local": False,
2415        "overwrite": False,
2416        "inpath": True,
2417        "partition": False,
2418        "input_format": False,
2419        "serde": False,
2420    }
2421
2422
2423class Partition(Expression):
2424    arg_types = {"expressions": True, "subpartition": False}
2425
2426
2427class PartitionRange(Expression):
2428    arg_types = {"this": True, "expression": True}
2429
2430
2431# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#how-to-set-partition-expression
2432class PartitionId(Expression):
2433    pass
2434
2435
2436class Fetch(Expression):
2437    arg_types = {
2438        "direction": False,
2439        "count": False,
2440        "limit_options": False,
2441    }
2442
2443
2444class Grant(Expression):
2445    arg_types = {
2446        "privileges": True,
2447        "kind": False,
2448        "securable": True,
2449        "principals": True,
2450        "grant_option": False,
2451    }
2452
2453
2454class Group(Expression):
2455    arg_types = {
2456        "expressions": False,
2457        "grouping_sets": False,
2458        "cube": False,
2459        "rollup": False,
2460        "totals": False,
2461        "all": False,
2462    }
2463
2464
2465class Cube(Expression):
2466    arg_types = {"expressions": False}
2467
2468
2469class Rollup(Expression):
2470    arg_types = {"expressions": False}
2471
2472
2473class GroupingSets(Expression):
2474    arg_types = {"expressions": True}
2475
2476
2477class Lambda(Expression):
2478    arg_types = {"this": True, "expressions": True}
2479
2480
2481class Limit(Expression):
2482    arg_types = {
2483        "this": False,
2484        "expression": True,
2485        "offset": False,
2486        "limit_options": False,
2487        "expressions": False,
2488    }
2489
2490
2491class LimitOptions(Expression):
2492    arg_types = {
2493        "percent": False,
2494        "rows": False,
2495        "with_ties": False,
2496    }
2497
2498
2499class Literal(Condition):
2500    arg_types = {"this": True, "is_string": True}
2501
2502    @property
2503    def hashable_args(self) -> t.Any:
2504        return (self.this, self.args.get("is_string"))
2505
2506    @classmethod
2507    def number(cls, number) -> Literal:
2508        return cls(this=str(number), is_string=False)
2509
2510    @classmethod
2511    def string(cls, string) -> Literal:
2512        return cls(this=str(string), is_string=True)
2513
2514    @property
2515    def output_name(self) -> str:
2516        return self.name
2517
2518    def to_py(self) -> int | str | Decimal:
2519        if self.is_number:
2520            try:
2521                return int(self.this)
2522            except ValueError:
2523                return Decimal(self.this)
2524        return self.this
2525
2526
2527class Join(Expression):
2528    arg_types = {
2529        "this": True,
2530        "on": False,
2531        "side": False,
2532        "kind": False,
2533        "using": False,
2534        "method": False,
2535        "global": False,
2536        "hint": False,
2537        "match_condition": False,  # Snowflake
2538        "expressions": False,
2539        "pivots": False,
2540    }
2541
2542    @property
2543    def method(self) -> str:
2544        return self.text("method").upper()
2545
2546    @property
2547    def kind(self) -> str:
2548        return self.text("kind").upper()
2549
2550    @property
2551    def side(self) -> str:
2552        return self.text("side").upper()
2553
2554    @property
2555    def hint(self) -> str:
2556        return self.text("hint").upper()
2557
2558    @property
2559    def alias_or_name(self) -> str:
2560        return self.this.alias_or_name
2561
2562    @property
2563    def is_semi_or_anti_join(self) -> bool:
2564        return self.kind in ("SEMI", "ANTI")
2565
2566    def on(
2567        self,
2568        *expressions: t.Optional[ExpOrStr],
2569        append: bool = True,
2570        dialect: DialectType = None,
2571        copy: bool = True,
2572        **opts,
2573    ) -> Join:
2574        """
2575        Append to or set the ON expressions.
2576
2577        Example:
2578            >>> import sqlglot
2579            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2580            'JOIN x ON y = 1'
2581
2582        Args:
2583            *expressions: the SQL code strings to parse.
2584                If an `Expression` instance is passed, it will be used as-is.
2585                Multiple expressions are combined with an AND operator.
2586            append: if `True`, AND the new expressions to any existing expression.
2587                Otherwise, this resets the expression.
2588            dialect: the dialect used to parse the input expressions.
2589            copy: if `False`, modify this expression instance in-place.
2590            opts: other options to use to parse the input expressions.
2591
2592        Returns:
2593            The modified Join expression.
2594        """
2595        join = _apply_conjunction_builder(
2596            *expressions,
2597            instance=self,
2598            arg="on",
2599            append=append,
2600            dialect=dialect,
2601            copy=copy,
2602            **opts,
2603        )
2604
2605        if join.kind == "CROSS":
2606            join.set("kind", None)
2607
2608        return join
2609
2610    def using(
2611        self,
2612        *expressions: t.Optional[ExpOrStr],
2613        append: bool = True,
2614        dialect: DialectType = None,
2615        copy: bool = True,
2616        **opts,
2617    ) -> Join:
2618        """
2619        Append to or set the USING expressions.
2620
2621        Example:
2622            >>> import sqlglot
2623            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2624            'JOIN x USING (foo, bla)'
2625
2626        Args:
2627            *expressions: the SQL code strings to parse.
2628                If an `Expression` instance is passed, it will be used as-is.
2629            append: if `True`, concatenate the new expressions to the existing "using" list.
2630                Otherwise, this resets the expression.
2631            dialect: the dialect used to parse the input expressions.
2632            copy: if `False`, modify this expression instance in-place.
2633            opts: other options to use to parse the input expressions.
2634
2635        Returns:
2636            The modified Join expression.
2637        """
2638        join = _apply_list_builder(
2639            *expressions,
2640            instance=self,
2641            arg="using",
2642            append=append,
2643            dialect=dialect,
2644            copy=copy,
2645            **opts,
2646        )
2647
2648        if join.kind == "CROSS":
2649            join.set("kind", None)
2650
2651        return join
2652
2653
2654class Lateral(UDTF):
2655    arg_types = {
2656        "this": True,
2657        "view": False,
2658        "outer": False,
2659        "alias": False,
2660        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2661        "ordinality": False,
2662    }
2663
2664
2665# https://docs.snowflake.com/sql-reference/literals-table
2666# https://docs.snowflake.com/en/sql-reference/functions-table#using-a-table-function
2667class TableFromRows(UDTF):
2668    arg_types = {
2669        "this": True,
2670        "alias": False,
2671        "joins": False,
2672        "pivots": False,
2673        "sample": False,
2674    }
2675
2676
2677class MatchRecognizeMeasure(Expression):
2678    arg_types = {
2679        "this": True,
2680        "window_frame": False,
2681    }
2682
2683
2684class MatchRecognize(Expression):
2685    arg_types = {
2686        "partition_by": False,
2687        "order": False,
2688        "measures": False,
2689        "rows": False,
2690        "after": False,
2691        "pattern": False,
2692        "define": False,
2693        "alias": False,
2694    }
2695
2696
2697# Clickhouse FROM FINAL modifier
2698# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
2699class Final(Expression):
2700    pass
2701
2702
2703class Offset(Expression):
2704    arg_types = {"this": False, "expression": True, "expressions": False}
2705
2706
2707class Order(Expression):
2708    arg_types = {"this": False, "expressions": True, "siblings": False}
2709
2710
2711# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
2712class WithFill(Expression):
2713    arg_types = {
2714        "from": False,
2715        "to": False,
2716        "step": False,
2717        "interpolate": False,
2718    }
2719
2720
2721# hive specific sorts
2722# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
2723class Cluster(Order):
2724    pass
2725
2726
2727class Distribute(Order):
2728    pass
2729
2730
2731class Sort(Order):
2732    pass
2733
2734
2735class Ordered(Expression):
2736    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2737
2738    @property
2739    def name(self) -> str:
2740        return self.this.name
2741
2742
2743class Property(Expression):
2744    arg_types = {"this": True, "value": True}
2745
2746
2747class GrantPrivilege(Expression):
2748    arg_types = {"this": True, "expressions": False}
2749
2750
2751class GrantPrincipal(Expression):
2752    arg_types = {"this": True, "kind": False}
2753
2754
2755class AllowedValuesProperty(Expression):
2756    arg_types = {"expressions": True}
2757
2758
2759class AlgorithmProperty(Property):
2760    arg_types = {"this": True}
2761
2762
2763class AutoIncrementProperty(Property):
2764    arg_types = {"this": True}
2765
2766
2767# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2768class AutoRefreshProperty(Property):
2769    arg_types = {"this": True}
2770
2771
2772class BackupProperty(Property):
2773    arg_types = {"this": True}
2774
2775
2776class BlockCompressionProperty(Property):
2777    arg_types = {
2778        "autotemp": False,
2779        "always": False,
2780        "default": False,
2781        "manual": False,
2782        "never": False,
2783    }
2784
2785
2786class CharacterSetProperty(Property):
2787    arg_types = {"this": True, "default": True}
2788
2789
2790class ChecksumProperty(Property):
2791    arg_types = {"on": False, "default": False}
2792
2793
2794class CollateProperty(Property):
2795    arg_types = {"this": True, "default": False}
2796
2797
2798class CopyGrantsProperty(Property):
2799    arg_types = {}
2800
2801
2802class DataBlocksizeProperty(Property):
2803    arg_types = {
2804        "size": False,
2805        "units": False,
2806        "minimum": False,
2807        "maximum": False,
2808        "default": False,
2809    }
2810
2811
2812class DataDeletionProperty(Property):
2813    arg_types = {"on": True, "filter_col": False, "retention_period": False}
2814
2815
2816class DefinerProperty(Property):
2817    arg_types = {"this": True}
2818
2819
2820class DistKeyProperty(Property):
2821    arg_types = {"this": True}
2822
2823
2824# https://docs.starrocks.io/docs/sql-reference/sql-statements/data-definition/CREATE_TABLE/#distribution_desc
2825# https://doris.apache.org/docs/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE?_highlight=create&_highlight=table#distribution_desc
2826class DistributedByProperty(Property):
2827    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
2828
2829
2830class DistStyleProperty(Property):
2831    arg_types = {"this": True}
2832
2833
2834class DuplicateKeyProperty(Property):
2835    arg_types = {"expressions": True}
2836
2837
2838class EngineProperty(Property):
2839    arg_types = {"this": True}
2840
2841
2842class HeapProperty(Property):
2843    arg_types = {}
2844
2845
2846class ToTableProperty(Property):
2847    arg_types = {"this": True}
2848
2849
2850class ExecuteAsProperty(Property):
2851    arg_types = {"this": True}
2852
2853
2854class ExternalProperty(Property):
2855    arg_types = {"this": False}
2856
2857
2858class FallbackProperty(Property):
2859    arg_types = {"no": True, "protection": False}
2860
2861
2862class FileFormatProperty(Property):
2863    arg_types = {"this": False, "expressions": False}
2864
2865
2866class CredentialsProperty(Property):
2867    arg_types = {"expressions": True}
2868
2869
2870class FreespaceProperty(Property):
2871    arg_types = {"this": True, "percent": False}
2872
2873
2874class GlobalProperty(Property):
2875    arg_types = {}
2876
2877
2878class IcebergProperty(Property):
2879    arg_types = {}
2880
2881
2882class InheritsProperty(Property):
2883    arg_types = {"expressions": True}
2884
2885
2886class InputModelProperty(Property):
2887    arg_types = {"this": True}
2888
2889
2890class OutputModelProperty(Property):
2891    arg_types = {"this": True}
2892
2893
2894class IsolatedLoadingProperty(Property):
2895    arg_types = {"no": False, "concurrent": False, "target": False}
2896
2897
2898class JournalProperty(Property):
2899    arg_types = {
2900        "no": False,
2901        "dual": False,
2902        "before": False,
2903        "local": False,
2904        "after": False,
2905    }
2906
2907
2908class LanguageProperty(Property):
2909    arg_types = {"this": True}
2910
2911
2912class EnviromentProperty(Property):
2913    arg_types = {"expressions": True}
2914
2915
2916# spark ddl
2917class ClusteredByProperty(Property):
2918    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2919
2920
2921class DictProperty(Property):
2922    arg_types = {"this": True, "kind": True, "settings": False}
2923
2924
2925class DictSubProperty(Property):
2926    pass
2927
2928
2929class DictRange(Property):
2930    arg_types = {"this": True, "min": True, "max": True}
2931
2932
2933class DynamicProperty(Property):
2934    arg_types = {}
2935
2936
2937# Clickhouse CREATE ... ON CLUSTER modifier
2938# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2939class OnCluster(Property):
2940    arg_types = {"this": True}
2941
2942
2943# Clickhouse EMPTY table "property"
2944class EmptyProperty(Property):
2945    arg_types = {}
2946
2947
2948class LikeProperty(Property):
2949    arg_types = {"this": True, "expressions": False}
2950
2951
2952class LocationProperty(Property):
2953    arg_types = {"this": True}
2954
2955
2956class LockProperty(Property):
2957    arg_types = {"this": True}
2958
2959
2960class LockingProperty(Property):
2961    arg_types = {
2962        "this": False,
2963        "kind": True,
2964        "for_or_in": False,
2965        "lock_type": True,
2966        "override": False,
2967    }
2968
2969
2970class LogProperty(Property):
2971    arg_types = {"no": True}
2972
2973
2974class MaterializedProperty(Property):
2975    arg_types = {"this": False}
2976
2977
2978class MergeBlockRatioProperty(Property):
2979    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2980
2981
2982class NoPrimaryIndexProperty(Property):
2983    arg_types = {}
2984
2985
2986class OnProperty(Property):
2987    arg_types = {"this": True}
2988
2989
2990class OnCommitProperty(Property):
2991    arg_types = {"delete": False}
2992
2993
2994class PartitionedByProperty(Property):
2995    arg_types = {"this": True}
2996
2997
2998class PartitionedByBucket(Property):
2999    arg_types = {"this": True, "expression": True}
3000
3001
3002class PartitionByTruncate(Property):
3003    arg_types = {"this": True, "expression": True}
3004
3005
3006# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
3007class PartitionByRangeProperty(Property):
3008    arg_types = {"partition_expressions": True, "create_expressions": True}
3009
3010
3011# https://docs.starrocks.io/docs/table_design/data_distribution/#range-partitioning
3012class PartitionByRangePropertyDynamic(Expression):
3013    arg_types = {"this": False, "start": True, "end": True, "every": True}
3014
3015
3016# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
3017class UniqueKeyProperty(Property):
3018    arg_types = {"expressions": True}
3019
3020
3021# https://www.postgresql.org/docs/current/sql-createtable.html
3022class PartitionBoundSpec(Expression):
3023    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3024    arg_types = {
3025        "this": False,
3026        "expression": False,
3027        "from_expressions": False,
3028        "to_expressions": False,
3029    }
3030
3031
3032class PartitionedOfProperty(Property):
3033    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3034    arg_types = {"this": True, "expression": True}
3035
3036
3037class StreamingTableProperty(Property):
3038    arg_types = {}
3039
3040
3041class RemoteWithConnectionModelProperty(Property):
3042    arg_types = {"this": True}
3043
3044
3045class ReturnsProperty(Property):
3046    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
3047
3048
3049class StrictProperty(Property):
3050    arg_types = {}
3051
3052
3053class RowFormatProperty(Property):
3054    arg_types = {"this": True}
3055
3056
3057class RowFormatDelimitedProperty(Property):
3058    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3059    arg_types = {
3060        "fields": False,
3061        "escaped": False,
3062        "collection_items": False,
3063        "map_keys": False,
3064        "lines": False,
3065        "null": False,
3066        "serde": False,
3067    }
3068
3069
3070class RowFormatSerdeProperty(Property):
3071    arg_types = {"this": True, "serde_properties": False}
3072
3073
3074# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
3075class QueryTransform(Expression):
3076    arg_types = {
3077        "expressions": True,
3078        "command_script": True,
3079        "schema": False,
3080        "row_format_before": False,
3081        "record_writer": False,
3082        "row_format_after": False,
3083        "record_reader": False,
3084    }
3085
3086
3087class SampleProperty(Property):
3088    arg_types = {"this": True}
3089
3090
3091# https://prestodb.io/docs/current/sql/create-view.html#synopsis
3092class SecurityProperty(Property):
3093    arg_types = {"this": True}
3094
3095
3096class SchemaCommentProperty(Property):
3097    arg_types = {"this": True}
3098
3099
3100class SerdeProperties(Property):
3101    arg_types = {"expressions": True, "with": False}
3102
3103
3104class SetProperty(Property):
3105    arg_types = {"multi": True}
3106
3107
3108class SharingProperty(Property):
3109    arg_types = {"this": False}
3110
3111
3112class SetConfigProperty(Property):
3113    arg_types = {"this": True}
3114
3115
3116class SettingsProperty(Property):
3117    arg_types = {"expressions": True}
3118
3119
3120class SortKeyProperty(Property):
3121    arg_types = {"this": True, "compound": False}
3122
3123
3124class SqlReadWriteProperty(Property):
3125    arg_types = {"this": True}
3126
3127
3128class SqlSecurityProperty(Property):
3129    arg_types = {"definer": True}
3130
3131
3132class StabilityProperty(Property):
3133    arg_types = {"this": True}
3134
3135
3136class StorageHandlerProperty(Property):
3137    arg_types = {"this": True}
3138
3139
3140class TemporaryProperty(Property):
3141    arg_types = {"this": False}
3142
3143
3144class SecureProperty(Property):
3145    arg_types = {}
3146
3147
3148# https://docs.snowflake.com/en/sql-reference/sql/create-table
3149class Tags(ColumnConstraintKind, Property):
3150    arg_types = {"expressions": True}
3151
3152
3153class TransformModelProperty(Property):
3154    arg_types = {"expressions": True}
3155
3156
3157class TransientProperty(Property):
3158    arg_types = {"this": False}
3159
3160
3161class UnloggedProperty(Property):
3162    arg_types = {}
3163
3164
3165# https://docs.snowflake.com/en/sql-reference/sql/create-table#create-table-using-template
3166class UsingTemplateProperty(Property):
3167    arg_types = {"this": True}
3168
3169
3170# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
3171class ViewAttributeProperty(Property):
3172    arg_types = {"this": True}
3173
3174
3175class VolatileProperty(Property):
3176    arg_types = {"this": False}
3177
3178
3179class WithDataProperty(Property):
3180    arg_types = {"no": True, "statistics": False}
3181
3182
3183class WithJournalTableProperty(Property):
3184    arg_types = {"this": True}
3185
3186
3187class WithSchemaBindingProperty(Property):
3188    arg_types = {"this": True}
3189
3190
3191class WithSystemVersioningProperty(Property):
3192    arg_types = {
3193        "on": False,
3194        "this": False,
3195        "data_consistency": False,
3196        "retention_period": False,
3197        "with": True,
3198    }
3199
3200
3201class WithProcedureOptions(Property):
3202    arg_types = {"expressions": True}
3203
3204
3205class EncodeProperty(Property):
3206    arg_types = {"this": True, "properties": False, "key": False}
3207
3208
3209class IncludeProperty(Property):
3210    arg_types = {"this": True, "alias": False, "column_def": False}
3211
3212
3213class ForceProperty(Property):
3214    arg_types = {}
3215
3216
3217class Properties(Expression):
3218    arg_types = {"expressions": True}
3219
3220    NAME_TO_PROPERTY = {
3221        "ALGORITHM": AlgorithmProperty,
3222        "AUTO_INCREMENT": AutoIncrementProperty,
3223        "CHARACTER SET": CharacterSetProperty,
3224        "CLUSTERED_BY": ClusteredByProperty,
3225        "COLLATE": CollateProperty,
3226        "COMMENT": SchemaCommentProperty,
3227        "CREDENTIALS": CredentialsProperty,
3228        "DEFINER": DefinerProperty,
3229        "DISTKEY": DistKeyProperty,
3230        "DISTRIBUTED_BY": DistributedByProperty,
3231        "DISTSTYLE": DistStyleProperty,
3232        "ENGINE": EngineProperty,
3233        "EXECUTE AS": ExecuteAsProperty,
3234        "FORMAT": FileFormatProperty,
3235        "LANGUAGE": LanguageProperty,
3236        "LOCATION": LocationProperty,
3237        "LOCK": LockProperty,
3238        "PARTITIONED_BY": PartitionedByProperty,
3239        "RETURNS": ReturnsProperty,
3240        "ROW_FORMAT": RowFormatProperty,
3241        "SORTKEY": SortKeyProperty,
3242        "ENCODE": EncodeProperty,
3243        "INCLUDE": IncludeProperty,
3244    }
3245
3246    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3247
3248    # CREATE property locations
3249    # Form: schema specified
3250    #   create [POST_CREATE]
3251    #     table a [POST_NAME]
3252    #     (b int) [POST_SCHEMA]
3253    #     with ([POST_WITH])
3254    #     index (b) [POST_INDEX]
3255    #
3256    # Form: alias selection
3257    #   create [POST_CREATE]
3258    #     table a [POST_NAME]
3259    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3260    #     index (c) [POST_INDEX]
3261    class Location(AutoName):
3262        POST_CREATE = auto()
3263        POST_NAME = auto()
3264        POST_SCHEMA = auto()
3265        POST_WITH = auto()
3266        POST_ALIAS = auto()
3267        POST_EXPRESSION = auto()
3268        POST_INDEX = auto()
3269        UNSUPPORTED = auto()
3270
3271    @classmethod
3272    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3273        expressions = []
3274        for key, value in properties_dict.items():
3275            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3276            if property_cls:
3277                expressions.append(property_cls(this=convert(value)))
3278            else:
3279                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3280
3281        return cls(expressions=expressions)
3282
3283
3284class Qualify(Expression):
3285    pass
3286
3287
3288class InputOutputFormat(Expression):
3289    arg_types = {"input_format": False, "output_format": False}
3290
3291
3292# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
3293class Return(Expression):
3294    pass
3295
3296
3297class Reference(Expression):
3298    arg_types = {"this": True, "expressions": False, "options": False}
3299
3300
3301class Tuple(Expression):
3302    arg_types = {"expressions": False}
3303
3304    def isin(
3305        self,
3306        *expressions: t.Any,
3307        query: t.Optional[ExpOrStr] = None,
3308        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3309        copy: bool = True,
3310        **opts,
3311    ) -> In:
3312        return In(
3313            this=maybe_copy(self, copy),
3314            expressions=[convert(e, copy=copy) for e in expressions],
3315            query=maybe_parse(query, copy=copy, **opts) if query else None,
3316            unnest=(
3317                Unnest(
3318                    expressions=[
3319                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3320                        for e in ensure_list(unnest)
3321                    ]
3322                )
3323                if unnest
3324                else None
3325            ),
3326        )
3327
3328
3329QUERY_MODIFIERS = {
3330    "match": False,
3331    "laterals": False,
3332    "joins": False,
3333    "connect": False,
3334    "pivots": False,
3335    "prewhere": False,
3336    "where": False,
3337    "group": False,
3338    "having": False,
3339    "qualify": False,
3340    "windows": False,
3341    "distribute": False,
3342    "sort": False,
3343    "cluster": False,
3344    "order": False,
3345    "limit": False,
3346    "offset": False,
3347    "locks": False,
3348    "sample": False,
3349    "settings": False,
3350    "format": False,
3351    "options": False,
3352}
3353
3354
3355# https://learn.microsoft.com/en-us/sql/t-sql/queries/option-clause-transact-sql?view=sql-server-ver16
3356# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-ver16
3357class QueryOption(Expression):
3358    arg_types = {"this": True, "expression": False}
3359
3360
3361# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
3362class WithTableHint(Expression):
3363    arg_types = {"expressions": True}
3364
3365
3366# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
3367class IndexTableHint(Expression):
3368    arg_types = {"this": True, "expressions": False, "target": False}
3369
3370
3371# https://docs.snowflake.com/en/sql-reference/constructs/at-before
3372class HistoricalData(Expression):
3373    arg_types = {"this": True, "kind": True, "expression": True}
3374
3375
3376# https://docs.snowflake.com/en/sql-reference/sql/put
3377class Put(Expression):
3378    arg_types = {"this": True, "target": True, "properties": False}
3379
3380
3381# https://docs.snowflake.com/en/sql-reference/sql/get
3382class Get(Expression):
3383    arg_types = {"this": True, "target": True, "properties": False}
3384
3385
3386class Table(Expression):
3387    arg_types = {
3388        "this": False,
3389        "alias": False,
3390        "db": False,
3391        "catalog": False,
3392        "laterals": False,
3393        "joins": False,
3394        "pivots": False,
3395        "hints": False,
3396        "system_time": False,
3397        "version": False,
3398        "format": False,
3399        "pattern": False,
3400        "ordinality": False,
3401        "when": False,
3402        "only": False,
3403        "partition": False,
3404        "changes": False,
3405        "rows_from": False,
3406        "sample": False,
3407    }
3408
3409    @property
3410    def name(self) -> str:
3411        if not self.this or isinstance(self.this, Func):
3412            return ""
3413        return self.this.name
3414
3415    @property
3416    def db(self) -> str:
3417        return self.text("db")
3418
3419    @property
3420    def catalog(self) -> str:
3421        return self.text("catalog")
3422
3423    @property
3424    def selects(self) -> t.List[Expression]:
3425        return []
3426
3427    @property
3428    def named_selects(self) -> t.List[str]:
3429        return []
3430
3431    @property
3432    def parts(self) -> t.List[Expression]:
3433        """Return the parts of a table in order catalog, db, table."""
3434        parts: t.List[Expression] = []
3435
3436        for arg in ("catalog", "db", "this"):
3437            part = self.args.get(arg)
3438
3439            if isinstance(part, Dot):
3440                parts.extend(part.flatten())
3441            elif isinstance(part, Expression):
3442                parts.append(part)
3443
3444        return parts
3445
3446    def to_column(self, copy: bool = True) -> Expression:
3447        parts = self.parts
3448        last_part = parts[-1]
3449
3450        if isinstance(last_part, Identifier):
3451            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3452        else:
3453            # This branch will be reached if a function or array is wrapped in a `Table`
3454            col = last_part
3455
3456        alias = self.args.get("alias")
3457        if alias:
3458            col = alias_(col, alias.this, copy=copy)
3459
3460        return col
3461
3462
3463class SetOperation(Query):
3464    arg_types = {
3465        "with": False,
3466        "this": True,
3467        "expression": True,
3468        "distinct": False,
3469        "by_name": False,
3470        "side": False,
3471        "kind": False,
3472        "on": False,
3473        **QUERY_MODIFIERS,
3474    }
3475
3476    def select(
3477        self: S,
3478        *expressions: t.Optional[ExpOrStr],
3479        append: bool = True,
3480        dialect: DialectType = None,
3481        copy: bool = True,
3482        **opts,
3483    ) -> S:
3484        this = maybe_copy(self, copy)
3485        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3486        this.expression.unnest().select(
3487            *expressions, append=append, dialect=dialect, copy=False, **opts
3488        )
3489        return this
3490
3491    @property
3492    def named_selects(self) -> t.List[str]:
3493        return self.this.unnest().named_selects
3494
3495    @property
3496    def is_star(self) -> bool:
3497        return self.this.is_star or self.expression.is_star
3498
3499    @property
3500    def selects(self) -> t.List[Expression]:
3501        return self.this.unnest().selects
3502
3503    @property
3504    def left(self) -> Query:
3505        return self.this
3506
3507    @property
3508    def right(self) -> Query:
3509        return self.expression
3510
3511    @property
3512    def kind(self) -> str:
3513        return self.text("kind").upper()
3514
3515    @property
3516    def side(self) -> str:
3517        return self.text("side").upper()
3518
3519
3520class Union(SetOperation):
3521    pass
3522
3523
3524class Except(SetOperation):
3525    pass
3526
3527
3528class Intersect(SetOperation):
3529    pass
3530
3531
3532class Update(DML):
3533    arg_types = {
3534        "with": False,
3535        "this": False,
3536        "expressions": True,
3537        "from": False,
3538        "where": False,
3539        "returning": False,
3540        "order": False,
3541        "limit": False,
3542    }
3543
3544    def table(
3545        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3546    ) -> Update:
3547        """
3548        Set the table to update.
3549
3550        Example:
3551            >>> Update().table("my_table").set_("x = 1").sql()
3552            'UPDATE my_table SET x = 1'
3553
3554        Args:
3555            expression : the SQL code strings to parse.
3556                If a `Table` instance is passed, this is used as-is.
3557                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3558            dialect: the dialect used to parse the input expression.
3559            copy: if `False`, modify this expression instance in-place.
3560            opts: other options to use to parse the input expressions.
3561
3562        Returns:
3563            The modified Update expression.
3564        """
3565        return _apply_builder(
3566            expression=expression,
3567            instance=self,
3568            arg="this",
3569            into=Table,
3570            prefix=None,
3571            dialect=dialect,
3572            copy=copy,
3573            **opts,
3574        )
3575
3576    def set_(
3577        self,
3578        *expressions: ExpOrStr,
3579        append: bool = True,
3580        dialect: DialectType = None,
3581        copy: bool = True,
3582        **opts,
3583    ) -> Update:
3584        """
3585        Append to or set the SET expressions.
3586
3587        Example:
3588            >>> Update().table("my_table").set_("x = 1").sql()
3589            'UPDATE my_table SET x = 1'
3590
3591        Args:
3592            *expressions: the SQL code strings to parse.
3593                If `Expression` instance(s) are passed, they will be used as-is.
3594                Multiple expressions are combined with a comma.
3595            append: if `True`, add the new expressions to any existing SET expressions.
3596                Otherwise, this resets the expressions.
3597            dialect: the dialect used to parse the input expressions.
3598            copy: if `False`, modify this expression instance in-place.
3599            opts: other options to use to parse the input expressions.
3600        """
3601        return _apply_list_builder(
3602            *expressions,
3603            instance=self,
3604            arg="expressions",
3605            append=append,
3606            into=Expression,
3607            prefix=None,
3608            dialect=dialect,
3609            copy=copy,
3610            **opts,
3611        )
3612
3613    def where(
3614        self,
3615        *expressions: t.Optional[ExpOrStr],
3616        append: bool = True,
3617        dialect: DialectType = None,
3618        copy: bool = True,
3619        **opts,
3620    ) -> Select:
3621        """
3622        Append to or set the WHERE expressions.
3623
3624        Example:
3625            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3626            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3627
3628        Args:
3629            *expressions: the SQL code strings to parse.
3630                If an `Expression` instance is passed, it will be used as-is.
3631                Multiple expressions are combined with an AND operator.
3632            append: if `True`, AND the new expressions to any existing expression.
3633                Otherwise, this resets the expression.
3634            dialect: the dialect used to parse the input expressions.
3635            copy: if `False`, modify this expression instance in-place.
3636            opts: other options to use to parse the input expressions.
3637
3638        Returns:
3639            Select: the modified expression.
3640        """
3641        return _apply_conjunction_builder(
3642            *expressions,
3643            instance=self,
3644            arg="where",
3645            append=append,
3646            into=Where,
3647            dialect=dialect,
3648            copy=copy,
3649            **opts,
3650        )
3651
3652    def from_(
3653        self,
3654        expression: t.Optional[ExpOrStr] = None,
3655        dialect: DialectType = None,
3656        copy: bool = True,
3657        **opts,
3658    ) -> Update:
3659        """
3660        Set the FROM expression.
3661
3662        Example:
3663            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3664            'UPDATE my_table SET x = 1 FROM baz'
3665
3666        Args:
3667            expression : the SQL code strings to parse.
3668                If a `From` instance is passed, this is used as-is.
3669                If another `Expression` instance is passed, it will be wrapped in a `From`.
3670                If nothing is passed in then a from is not applied to the expression
3671            dialect: the dialect used to parse the input expression.
3672            copy: if `False`, modify this expression instance in-place.
3673            opts: other options to use to parse the input expressions.
3674
3675        Returns:
3676            The modified Update expression.
3677        """
3678        if not expression:
3679            return maybe_copy(self, copy)
3680
3681        return _apply_builder(
3682            expression=expression,
3683            instance=self,
3684            arg="from",
3685            into=From,
3686            prefix="FROM",
3687            dialect=dialect,
3688            copy=copy,
3689            **opts,
3690        )
3691
3692    def with_(
3693        self,
3694        alias: ExpOrStr,
3695        as_: ExpOrStr,
3696        recursive: t.Optional[bool] = None,
3697        materialized: t.Optional[bool] = None,
3698        append: bool = True,
3699        dialect: DialectType = None,
3700        copy: bool = True,
3701        **opts,
3702    ) -> Update:
3703        """
3704        Append to or set the common table expressions.
3705
3706        Example:
3707            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3708            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3709
3710        Args:
3711            alias: the SQL code string to parse as the table name.
3712                If an `Expression` instance is passed, this is used as-is.
3713            as_: the SQL code string to parse as the table expression.
3714                If an `Expression` instance is passed, it will be used as-is.
3715            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3716            materialized: set the MATERIALIZED part of the expression.
3717            append: if `True`, add to any existing expressions.
3718                Otherwise, this resets the expressions.
3719            dialect: the dialect used to parse the input expression.
3720            copy: if `False`, modify this expression instance in-place.
3721            opts: other options to use to parse the input expressions.
3722
3723        Returns:
3724            The modified expression.
3725        """
3726        return _apply_cte_builder(
3727            self,
3728            alias,
3729            as_,
3730            recursive=recursive,
3731            materialized=materialized,
3732            append=append,
3733            dialect=dialect,
3734            copy=copy,
3735            **opts,
3736        )
3737
3738
3739class Values(UDTF):
3740    arg_types = {"expressions": True, "alias": False}
3741
3742
3743class Var(Expression):
3744    pass
3745
3746
3747class Version(Expression):
3748    """
3749    Time travel, iceberg, bigquery etc
3750    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3751    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3752    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3753    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3754    this is either TIMESTAMP or VERSION
3755    kind is ("AS OF", "BETWEEN")
3756    """
3757
3758    arg_types = {"this": True, "kind": True, "expression": False}
3759
3760
3761class Schema(Expression):
3762    arg_types = {"this": False, "expressions": False}
3763
3764
3765# https://dev.mysql.com/doc/refman/8.0/en/select.html
3766# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
3767class Lock(Expression):
3768    arg_types = {"update": True, "expressions": False, "wait": False}
3769
3770
3771class Select(Query):
3772    arg_types = {
3773        "with": False,
3774        "kind": False,
3775        "expressions": False,
3776        "hint": False,
3777        "distinct": False,
3778        "into": False,
3779        "from": False,
3780        "operation_modifiers": False,
3781        **QUERY_MODIFIERS,
3782    }
3783
3784    def from_(
3785        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3786    ) -> Select:
3787        """
3788        Set the FROM expression.
3789
3790        Example:
3791            >>> Select().from_("tbl").select("x").sql()
3792            'SELECT x FROM tbl'
3793
3794        Args:
3795            expression : the SQL code strings to parse.
3796                If a `From` instance is passed, this is used as-is.
3797                If another `Expression` instance is passed, it will be wrapped in a `From`.
3798            dialect: the dialect used to parse the input expression.
3799            copy: if `False`, modify this expression instance in-place.
3800            opts: other options to use to parse the input expressions.
3801
3802        Returns:
3803            The modified Select expression.
3804        """
3805        return _apply_builder(
3806            expression=expression,
3807            instance=self,
3808            arg="from",
3809            into=From,
3810            prefix="FROM",
3811            dialect=dialect,
3812            copy=copy,
3813            **opts,
3814        )
3815
3816    def group_by(
3817        self,
3818        *expressions: t.Optional[ExpOrStr],
3819        append: bool = True,
3820        dialect: DialectType = None,
3821        copy: bool = True,
3822        **opts,
3823    ) -> Select:
3824        """
3825        Set the GROUP BY expression.
3826
3827        Example:
3828            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3829            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3830
3831        Args:
3832            *expressions: the SQL code strings to parse.
3833                If a `Group` instance is passed, this is used as-is.
3834                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3835                If nothing is passed in then a group by is not applied to the expression
3836            append: if `True`, add to any existing expressions.
3837                Otherwise, this flattens all the `Group` expression into a single expression.
3838            dialect: the dialect used to parse the input expression.
3839            copy: if `False`, modify this expression instance in-place.
3840            opts: other options to use to parse the input expressions.
3841
3842        Returns:
3843            The modified Select expression.
3844        """
3845        if not expressions:
3846            return self if not copy else self.copy()
3847
3848        return _apply_child_list_builder(
3849            *expressions,
3850            instance=self,
3851            arg="group",
3852            append=append,
3853            copy=copy,
3854            prefix="GROUP BY",
3855            into=Group,
3856            dialect=dialect,
3857            **opts,
3858        )
3859
3860    def sort_by(
3861        self,
3862        *expressions: t.Optional[ExpOrStr],
3863        append: bool = True,
3864        dialect: DialectType = None,
3865        copy: bool = True,
3866        **opts,
3867    ) -> Select:
3868        """
3869        Set the SORT BY expression.
3870
3871        Example:
3872            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3873            'SELECT x FROM tbl SORT BY x DESC'
3874
3875        Args:
3876            *expressions: the SQL code strings to parse.
3877                If a `Group` instance is passed, this is used as-is.
3878                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3879            append: if `True`, add to any existing expressions.
3880                Otherwise, this flattens all the `Order` expression into a single expression.
3881            dialect: the dialect used to parse the input expression.
3882            copy: if `False`, modify this expression instance in-place.
3883            opts: other options to use to parse the input expressions.
3884
3885        Returns:
3886            The modified Select expression.
3887        """
3888        return _apply_child_list_builder(
3889            *expressions,
3890            instance=self,
3891            arg="sort",
3892            append=append,
3893            copy=copy,
3894            prefix="SORT BY",
3895            into=Sort,
3896            dialect=dialect,
3897            **opts,
3898        )
3899
3900    def cluster_by(
3901        self,
3902        *expressions: t.Optional[ExpOrStr],
3903        append: bool = True,
3904        dialect: DialectType = None,
3905        copy: bool = True,
3906        **opts,
3907    ) -> Select:
3908        """
3909        Set the CLUSTER BY expression.
3910
3911        Example:
3912            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3913            'SELECT x FROM tbl CLUSTER BY x DESC'
3914
3915        Args:
3916            *expressions: the SQL code strings to parse.
3917                If a `Group` instance is passed, this is used as-is.
3918                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3919            append: if `True`, add to any existing expressions.
3920                Otherwise, this flattens all the `Order` expression into a single expression.
3921            dialect: the dialect used to parse the input expression.
3922            copy: if `False`, modify this expression instance in-place.
3923            opts: other options to use to parse the input expressions.
3924
3925        Returns:
3926            The modified Select expression.
3927        """
3928        return _apply_child_list_builder(
3929            *expressions,
3930            instance=self,
3931            arg="cluster",
3932            append=append,
3933            copy=copy,
3934            prefix="CLUSTER BY",
3935            into=Cluster,
3936            dialect=dialect,
3937            **opts,
3938        )
3939
3940    def select(
3941        self,
3942        *expressions: t.Optional[ExpOrStr],
3943        append: bool = True,
3944        dialect: DialectType = None,
3945        copy: bool = True,
3946        **opts,
3947    ) -> Select:
3948        return _apply_list_builder(
3949            *expressions,
3950            instance=self,
3951            arg="expressions",
3952            append=append,
3953            dialect=dialect,
3954            into=Expression,
3955            copy=copy,
3956            **opts,
3957        )
3958
3959    def lateral(
3960        self,
3961        *expressions: t.Optional[ExpOrStr],
3962        append: bool = True,
3963        dialect: DialectType = None,
3964        copy: bool = True,
3965        **opts,
3966    ) -> Select:
3967        """
3968        Append to or set the LATERAL expressions.
3969
3970        Example:
3971            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3972            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3973
3974        Args:
3975            *expressions: the SQL code strings to parse.
3976                If an `Expression` instance is passed, it will be used as-is.
3977            append: if `True`, add to any existing expressions.
3978                Otherwise, this resets the expressions.
3979            dialect: the dialect used to parse the input expressions.
3980            copy: if `False`, modify this expression instance in-place.
3981            opts: other options to use to parse the input expressions.
3982
3983        Returns:
3984            The modified Select expression.
3985        """
3986        return _apply_list_builder(
3987            *expressions,
3988            instance=self,
3989            arg="laterals",
3990            append=append,
3991            into=Lateral,
3992            prefix="LATERAL VIEW",
3993            dialect=dialect,
3994            copy=copy,
3995            **opts,
3996        )
3997
3998    def join(
3999        self,
4000        expression: ExpOrStr,
4001        on: t.Optional[ExpOrStr] = None,
4002        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4003        append: bool = True,
4004        join_type: t.Optional[str] = None,
4005        join_alias: t.Optional[Identifier | str] = None,
4006        dialect: DialectType = None,
4007        copy: bool = True,
4008        **opts,
4009    ) -> Select:
4010        """
4011        Append to or set the JOIN expressions.
4012
4013        Example:
4014            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4015            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4016
4017            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4018            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4019
4020            Use `join_type` to change the type of join:
4021
4022            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4023            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4024
4025        Args:
4026            expression: the SQL code string to parse.
4027                If an `Expression` instance is passed, it will be used as-is.
4028            on: optionally specify the join "on" criteria as a SQL string.
4029                If an `Expression` instance is passed, it will be used as-is.
4030            using: optionally specify the join "using" criteria as a SQL string.
4031                If an `Expression` instance is passed, it will be used as-is.
4032            append: if `True`, add to any existing expressions.
4033                Otherwise, this resets the expressions.
4034            join_type: if set, alter the parsed join type.
4035            join_alias: an optional alias for the joined source.
4036            dialect: the dialect used to parse the input expressions.
4037            copy: if `False`, modify this expression instance in-place.
4038            opts: other options to use to parse the input expressions.
4039
4040        Returns:
4041            Select: the modified expression.
4042        """
4043        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4044
4045        try:
4046            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4047        except ParseError:
4048            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4049
4050        join = expression if isinstance(expression, Join) else Join(this=expression)
4051
4052        if isinstance(join.this, Select):
4053            join.this.replace(join.this.subquery())
4054
4055        if join_type:
4056            method: t.Optional[Token]
4057            side: t.Optional[Token]
4058            kind: t.Optional[Token]
4059
4060            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4061
4062            if method:
4063                join.set("method", method.text)
4064            if side:
4065                join.set("side", side.text)
4066            if kind:
4067                join.set("kind", kind.text)
4068
4069        if on:
4070            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4071            join.set("on", on)
4072
4073        if using:
4074            join = _apply_list_builder(
4075                *ensure_list(using),
4076                instance=join,
4077                arg="using",
4078                append=append,
4079                copy=copy,
4080                into=Identifier,
4081                **opts,
4082            )
4083
4084        if join_alias:
4085            join.set("this", alias_(join.this, join_alias, table=True))
4086
4087        return _apply_list_builder(
4088            join,
4089            instance=self,
4090            arg="joins",
4091            append=append,
4092            copy=copy,
4093            **opts,
4094        )
4095
4096    def having(
4097        self,
4098        *expressions: t.Optional[ExpOrStr],
4099        append: bool = True,
4100        dialect: DialectType = None,
4101        copy: bool = True,
4102        **opts,
4103    ) -> Select:
4104        """
4105        Append to or set the HAVING expressions.
4106
4107        Example:
4108            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4109            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4110
4111        Args:
4112            *expressions: the SQL code strings to parse.
4113                If an `Expression` instance is passed, it will be used as-is.
4114                Multiple expressions are combined with an AND operator.
4115            append: if `True`, AND the new expressions to any existing expression.
4116                Otherwise, this resets the expression.
4117            dialect: the dialect used to parse the input expressions.
4118            copy: if `False`, modify this expression instance in-place.
4119            opts: other options to use to parse the input expressions.
4120
4121        Returns:
4122            The modified Select expression.
4123        """
4124        return _apply_conjunction_builder(
4125            *expressions,
4126            instance=self,
4127            arg="having",
4128            append=append,
4129            into=Having,
4130            dialect=dialect,
4131            copy=copy,
4132            **opts,
4133        )
4134
4135    def window(
4136        self,
4137        *expressions: t.Optional[ExpOrStr],
4138        append: bool = True,
4139        dialect: DialectType = None,
4140        copy: bool = True,
4141        **opts,
4142    ) -> Select:
4143        return _apply_list_builder(
4144            *expressions,
4145            instance=self,
4146            arg="windows",
4147            append=append,
4148            into=Window,
4149            dialect=dialect,
4150            copy=copy,
4151            **opts,
4152        )
4153
4154    def qualify(
4155        self,
4156        *expressions: t.Optional[ExpOrStr],
4157        append: bool = True,
4158        dialect: DialectType = None,
4159        copy: bool = True,
4160        **opts,
4161    ) -> Select:
4162        return _apply_conjunction_builder(
4163            *expressions,
4164            instance=self,
4165            arg="qualify",
4166            append=append,
4167            into=Qualify,
4168            dialect=dialect,
4169            copy=copy,
4170            **opts,
4171        )
4172
4173    def distinct(
4174        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4175    ) -> Select:
4176        """
4177        Set the OFFSET expression.
4178
4179        Example:
4180            >>> Select().from_("tbl").select("x").distinct().sql()
4181            'SELECT DISTINCT x FROM tbl'
4182
4183        Args:
4184            ons: the expressions to distinct on
4185            distinct: whether the Select should be distinct
4186            copy: if `False`, modify this expression instance in-place.
4187
4188        Returns:
4189            Select: the modified expression.
4190        """
4191        instance = maybe_copy(self, copy)
4192        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4193        instance.set("distinct", Distinct(on=on) if distinct else None)
4194        return instance
4195
4196    def ctas(
4197        self,
4198        table: ExpOrStr,
4199        properties: t.Optional[t.Dict] = None,
4200        dialect: DialectType = None,
4201        copy: bool = True,
4202        **opts,
4203    ) -> Create:
4204        """
4205        Convert this expression to a CREATE TABLE AS statement.
4206
4207        Example:
4208            >>> Select().select("*").from_("tbl").ctas("x").sql()
4209            'CREATE TABLE x AS SELECT * FROM tbl'
4210
4211        Args:
4212            table: the SQL code string to parse as the table name.
4213                If another `Expression` instance is passed, it will be used as-is.
4214            properties: an optional mapping of table properties
4215            dialect: the dialect used to parse the input table.
4216            copy: if `False`, modify this expression instance in-place.
4217            opts: other options to use to parse the input table.
4218
4219        Returns:
4220            The new Create expression.
4221        """
4222        instance = maybe_copy(self, copy)
4223        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4224
4225        properties_expression = None
4226        if properties:
4227            properties_expression = Properties.from_dict(properties)
4228
4229        return Create(
4230            this=table_expression,
4231            kind="TABLE",
4232            expression=instance,
4233            properties=properties_expression,
4234        )
4235
4236    def lock(self, update: bool = True, copy: bool = True) -> Select:
4237        """
4238        Set the locking read mode for this expression.
4239
4240        Examples:
4241            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4242            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4243
4244            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4245            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4246
4247        Args:
4248            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4249            copy: if `False`, modify this expression instance in-place.
4250
4251        Returns:
4252            The modified expression.
4253        """
4254        inst = maybe_copy(self, copy)
4255        inst.set("locks", [Lock(update=update)])
4256
4257        return inst
4258
4259    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4260        """
4261        Set hints for this expression.
4262
4263        Examples:
4264            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4265            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4266
4267        Args:
4268            hints: The SQL code strings to parse as the hints.
4269                If an `Expression` instance is passed, it will be used as-is.
4270            dialect: The dialect used to parse the hints.
4271            copy: If `False`, modify this expression instance in-place.
4272
4273        Returns:
4274            The modified expression.
4275        """
4276        inst = maybe_copy(self, copy)
4277        inst.set(
4278            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4279        )
4280
4281        return inst
4282
4283    @property
4284    def named_selects(self) -> t.List[str]:
4285        return [e.output_name for e in self.expressions if e.alias_or_name]
4286
4287    @property
4288    def is_star(self) -> bool:
4289        return any(expression.is_star for expression in self.expressions)
4290
4291    @property
4292    def selects(self) -> t.List[Expression]:
4293        return self.expressions
4294
4295
4296UNWRAPPED_QUERIES = (Select, SetOperation)
4297
4298
4299class Subquery(DerivedTable, Query):
4300    arg_types = {
4301        "this": True,
4302        "alias": False,
4303        "with": False,
4304        **QUERY_MODIFIERS,
4305    }
4306
4307    def unnest(self):
4308        """Returns the first non subquery."""
4309        expression = self
4310        while isinstance(expression, Subquery):
4311            expression = expression.this
4312        return expression
4313
4314    def unwrap(self) -> Subquery:
4315        expression = self
4316        while expression.same_parent and expression.is_wrapper:
4317            expression = t.cast(Subquery, expression.parent)
4318        return expression
4319
4320    def select(
4321        self,
4322        *expressions: t.Optional[ExpOrStr],
4323        append: bool = True,
4324        dialect: DialectType = None,
4325        copy: bool = True,
4326        **opts,
4327    ) -> Subquery:
4328        this = maybe_copy(self, copy)
4329        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4330        return this
4331
4332    @property
4333    def is_wrapper(self) -> bool:
4334        """
4335        Whether this Subquery acts as a simple wrapper around another expression.
4336
4337        SELECT * FROM (((SELECT * FROM t)))
4338                      ^
4339                      This corresponds to a "wrapper" Subquery node
4340        """
4341        return all(v is None for k, v in self.args.items() if k != "this")
4342
4343    @property
4344    def is_star(self) -> bool:
4345        return self.this.is_star
4346
4347    @property
4348    def output_name(self) -> str:
4349        return self.alias
4350
4351
4352class TableSample(Expression):
4353    arg_types = {
4354        "expressions": False,
4355        "method": False,
4356        "bucket_numerator": False,
4357        "bucket_denominator": False,
4358        "bucket_field": False,
4359        "percent": False,
4360        "rows": False,
4361        "size": False,
4362        "seed": False,
4363    }
4364
4365
4366class Tag(Expression):
4367    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4368
4369    arg_types = {
4370        "this": False,
4371        "prefix": False,
4372        "postfix": False,
4373    }
4374
4375
4376# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
4377# https://duckdb.org/docs/sql/statements/pivot
4378class Pivot(Expression):
4379    arg_types = {
4380        "this": False,
4381        "alias": False,
4382        "expressions": False,
4383        "fields": False,
4384        "unpivot": False,
4385        "using": False,
4386        "group": False,
4387        "columns": False,
4388        "include_nulls": False,
4389        "default_on_null": False,
4390        "into": False,
4391    }
4392
4393    @property
4394    def unpivot(self) -> bool:
4395        return bool(self.args.get("unpivot"))
4396
4397    @property
4398    def fields(self) -> t.List[Expression]:
4399        return self.args.get("fields", [])
4400
4401
4402# https://duckdb.org/docs/sql/statements/unpivot#simplified-unpivot-syntax
4403# UNPIVOT ... INTO [NAME <col_name> VALUE <col_value>][...,]
4404class UnpivotColumns(Expression):
4405    arg_types = {"this": True, "expressions": True}
4406
4407
4408class Window(Condition):
4409    arg_types = {
4410        "this": True,
4411        "partition_by": False,
4412        "order": False,
4413        "spec": False,
4414        "alias": False,
4415        "over": False,
4416        "first": False,
4417    }
4418
4419
4420class WindowSpec(Expression):
4421    arg_types = {
4422        "kind": False,
4423        "start": False,
4424        "start_side": False,
4425        "end": False,
4426        "end_side": False,
4427        "exclude": False,
4428    }
4429
4430
4431class PreWhere(Expression):
4432    pass
4433
4434
4435class Where(Expression):
4436    pass
4437
4438
4439class Star(Expression):
4440    arg_types = {"except": False, "replace": False, "rename": False}
4441
4442    @property
4443    def name(self) -> str:
4444        return "*"
4445
4446    @property
4447    def output_name(self) -> str:
4448        return self.name
4449
4450
4451class Parameter(Condition):
4452    arg_types = {"this": True, "expression": False}
4453
4454
4455class SessionParameter(Condition):
4456    arg_types = {"this": True, "kind": False}
4457
4458
4459class Placeholder(Condition):
4460    arg_types = {"this": False, "kind": False}
4461
4462    @property
4463    def name(self) -> str:
4464        return self.this or "?"
4465
4466
4467class Null(Condition):
4468    arg_types: t.Dict[str, t.Any] = {}
4469
4470    @property
4471    def name(self) -> str:
4472        return "NULL"
4473
4474    def to_py(self) -> Lit[None]:
4475        return None
4476
4477
4478class Boolean(Condition):
4479    def to_py(self) -> bool:
4480        return self.this
4481
4482
4483class DataTypeParam(Expression):
4484    arg_types = {"this": True, "expression": False}
4485
4486    @property
4487    def name(self) -> str:
4488        return self.this.name
4489
4490
4491# The `nullable` arg is helpful when transpiling types from other dialects to ClickHouse, which
4492# assumes non-nullable types by default. Values `None` and `True` mean the type is nullable.
4493class DataType(Expression):
4494    arg_types = {
4495        "this": True,
4496        "expressions": False,
4497        "nested": False,
4498        "values": False,
4499        "prefix": False,
4500        "kind": False,
4501        "nullable": False,
4502    }
4503
4504    class Type(AutoName):
4505        ARRAY = auto()
4506        AGGREGATEFUNCTION = auto()
4507        SIMPLEAGGREGATEFUNCTION = auto()
4508        BIGDECIMAL = auto()
4509        BIGINT = auto()
4510        BIGSERIAL = auto()
4511        BINARY = auto()
4512        BIT = auto()
4513        BLOB = auto()
4514        BOOLEAN = auto()
4515        BPCHAR = auto()
4516        CHAR = auto()
4517        DATE = auto()
4518        DATE32 = auto()
4519        DATEMULTIRANGE = auto()
4520        DATERANGE = auto()
4521        DATETIME = auto()
4522        DATETIME2 = auto()
4523        DATETIME64 = auto()
4524        DECIMAL = auto()
4525        DECIMAL32 = auto()
4526        DECIMAL64 = auto()
4527        DECIMAL128 = auto()
4528        DECIMAL256 = auto()
4529        DOUBLE = auto()
4530        DYNAMIC = auto()
4531        ENUM = auto()
4532        ENUM8 = auto()
4533        ENUM16 = auto()
4534        FIXEDSTRING = auto()
4535        FLOAT = auto()
4536        GEOGRAPHY = auto()
4537        GEOMETRY = auto()
4538        POINT = auto()
4539        RING = auto()
4540        LINESTRING = auto()
4541        MULTILINESTRING = auto()
4542        POLYGON = auto()
4543        MULTIPOLYGON = auto()
4544        HLLSKETCH = auto()
4545        HSTORE = auto()
4546        IMAGE = auto()
4547        INET = auto()
4548        INT = auto()
4549        INT128 = auto()
4550        INT256 = auto()
4551        INT4MULTIRANGE = auto()
4552        INT4RANGE = auto()
4553        INT8MULTIRANGE = auto()
4554        INT8RANGE = auto()
4555        INTERVAL = auto()
4556        IPADDRESS = auto()
4557        IPPREFIX = auto()
4558        IPV4 = auto()
4559        IPV6 = auto()
4560        JSON = auto()
4561        JSONB = auto()
4562        LIST = auto()
4563        LONGBLOB = auto()
4564        LONGTEXT = auto()
4565        LOWCARDINALITY = auto()
4566        MAP = auto()
4567        MEDIUMBLOB = auto()
4568        MEDIUMINT = auto()
4569        MEDIUMTEXT = auto()
4570        MONEY = auto()
4571        NAME = auto()
4572        NCHAR = auto()
4573        NESTED = auto()
4574        NOTHING = auto()
4575        NULL = auto()
4576        NUMMULTIRANGE = auto()
4577        NUMRANGE = auto()
4578        NVARCHAR = auto()
4579        OBJECT = auto()
4580        RANGE = auto()
4581        ROWVERSION = auto()
4582        SERIAL = auto()
4583        SET = auto()
4584        SMALLDATETIME = auto()
4585        SMALLINT = auto()
4586        SMALLMONEY = auto()
4587        SMALLSERIAL = auto()
4588        STRUCT = auto()
4589        SUPER = auto()
4590        TEXT = auto()
4591        TINYBLOB = auto()
4592        TINYTEXT = auto()
4593        TIME = auto()
4594        TIMETZ = auto()
4595        TIMESTAMP = auto()
4596        TIMESTAMPNTZ = auto()
4597        TIMESTAMPLTZ = auto()
4598        TIMESTAMPTZ = auto()
4599        TIMESTAMP_S = auto()
4600        TIMESTAMP_MS = auto()
4601        TIMESTAMP_NS = auto()
4602        TINYINT = auto()
4603        TSMULTIRANGE = auto()
4604        TSRANGE = auto()
4605        TSTZMULTIRANGE = auto()
4606        TSTZRANGE = auto()
4607        UBIGINT = auto()
4608        UINT = auto()
4609        UINT128 = auto()
4610        UINT256 = auto()
4611        UMEDIUMINT = auto()
4612        UDECIMAL = auto()
4613        UDOUBLE = auto()
4614        UNION = auto()
4615        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4616        USERDEFINED = "USER-DEFINED"
4617        USMALLINT = auto()
4618        UTINYINT = auto()
4619        UUID = auto()
4620        VARBINARY = auto()
4621        VARCHAR = auto()
4622        VARIANT = auto()
4623        VECTOR = auto()
4624        XML = auto()
4625        YEAR = auto()
4626        TDIGEST = auto()
4627
4628    STRUCT_TYPES = {
4629        Type.NESTED,
4630        Type.OBJECT,
4631        Type.STRUCT,
4632        Type.UNION,
4633    }
4634
4635    ARRAY_TYPES = {
4636        Type.ARRAY,
4637        Type.LIST,
4638    }
4639
4640    NESTED_TYPES = {
4641        *STRUCT_TYPES,
4642        *ARRAY_TYPES,
4643        Type.MAP,
4644    }
4645
4646    TEXT_TYPES = {
4647        Type.CHAR,
4648        Type.NCHAR,
4649        Type.NVARCHAR,
4650        Type.TEXT,
4651        Type.VARCHAR,
4652        Type.NAME,
4653    }
4654
4655    SIGNED_INTEGER_TYPES = {
4656        Type.BIGINT,
4657        Type.INT,
4658        Type.INT128,
4659        Type.INT256,
4660        Type.MEDIUMINT,
4661        Type.SMALLINT,
4662        Type.TINYINT,
4663    }
4664
4665    UNSIGNED_INTEGER_TYPES = {
4666        Type.UBIGINT,
4667        Type.UINT,
4668        Type.UINT128,
4669        Type.UINT256,
4670        Type.UMEDIUMINT,
4671        Type.USMALLINT,
4672        Type.UTINYINT,
4673    }
4674
4675    INTEGER_TYPES = {
4676        *SIGNED_INTEGER_TYPES,
4677        *UNSIGNED_INTEGER_TYPES,
4678        Type.BIT,
4679    }
4680
4681    FLOAT_TYPES = {
4682        Type.DOUBLE,
4683        Type.FLOAT,
4684    }
4685
4686    REAL_TYPES = {
4687        *FLOAT_TYPES,
4688        Type.BIGDECIMAL,
4689        Type.DECIMAL,
4690        Type.DECIMAL32,
4691        Type.DECIMAL64,
4692        Type.DECIMAL128,
4693        Type.DECIMAL256,
4694        Type.MONEY,
4695        Type.SMALLMONEY,
4696        Type.UDECIMAL,
4697        Type.UDOUBLE,
4698    }
4699
4700    NUMERIC_TYPES = {
4701        *INTEGER_TYPES,
4702        *REAL_TYPES,
4703    }
4704
4705    TEMPORAL_TYPES = {
4706        Type.DATE,
4707        Type.DATE32,
4708        Type.DATETIME,
4709        Type.DATETIME2,
4710        Type.DATETIME64,
4711        Type.SMALLDATETIME,
4712        Type.TIME,
4713        Type.TIMESTAMP,
4714        Type.TIMESTAMPNTZ,
4715        Type.TIMESTAMPLTZ,
4716        Type.TIMESTAMPTZ,
4717        Type.TIMESTAMP_MS,
4718        Type.TIMESTAMP_NS,
4719        Type.TIMESTAMP_S,
4720        Type.TIMETZ,
4721    }
4722
4723    @classmethod
4724    def build(
4725        cls,
4726        dtype: DATA_TYPE,
4727        dialect: DialectType = None,
4728        udt: bool = False,
4729        copy: bool = True,
4730        **kwargs,
4731    ) -> DataType:
4732        """
4733        Constructs a DataType object.
4734
4735        Args:
4736            dtype: the data type of interest.
4737            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4738            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4739                DataType, thus creating a user-defined type.
4740            copy: whether to copy the data type.
4741            kwargs: additional arguments to pass in the constructor of DataType.
4742
4743        Returns:
4744            The constructed DataType object.
4745        """
4746        from sqlglot import parse_one
4747
4748        if isinstance(dtype, str):
4749            if dtype.upper() == "UNKNOWN":
4750                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4751
4752            try:
4753                data_type_exp = parse_one(
4754                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4755                )
4756            except ParseError:
4757                if udt:
4758                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4759                raise
4760        elif isinstance(dtype, DataType.Type):
4761            data_type_exp = DataType(this=dtype)
4762        elif isinstance(dtype, DataType):
4763            return maybe_copy(dtype, copy)
4764        else:
4765            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4766
4767        return DataType(**{**data_type_exp.args, **kwargs})
4768
4769    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4770        """
4771        Checks whether this DataType matches one of the provided data types. Nested types or precision
4772        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4773
4774        Args:
4775            dtypes: the data types to compare this DataType to.
4776            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4777                If false, it means that NULLABLE<INT> is equivalent to INT.
4778
4779        Returns:
4780            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4781        """
4782        self_is_nullable = self.args.get("nullable")
4783        for dtype in dtypes:
4784            other_type = DataType.build(dtype, copy=False, udt=True)
4785            other_is_nullable = other_type.args.get("nullable")
4786            if (
4787                other_type.expressions
4788                or (check_nullable and (self_is_nullable or other_is_nullable))
4789                or self.this == DataType.Type.USERDEFINED
4790                or other_type.this == DataType.Type.USERDEFINED
4791            ):
4792                matches = self == other_type
4793            else:
4794                matches = self.this == other_type.this
4795
4796            if matches:
4797                return True
4798        return False
4799
4800
4801DATA_TYPE = t.Union[str, DataType, DataType.Type]
4802
4803
4804# https://www.postgresql.org/docs/15/datatype-pseudo.html
4805class PseudoType(DataType):
4806    arg_types = {"this": True}
4807
4808
4809# https://www.postgresql.org/docs/15/datatype-oid.html
4810class ObjectIdentifier(DataType):
4811    arg_types = {"this": True}
4812
4813
4814# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4815class SubqueryPredicate(Predicate):
4816    pass
4817
4818
4819class All(SubqueryPredicate):
4820    pass
4821
4822
4823class Any(SubqueryPredicate):
4824    pass
4825
4826
4827# Commands to interact with the databases or engines. For most of the command
4828# expressions we parse whatever comes after the command's name as a string.
4829class Command(Expression):
4830    arg_types = {"this": True, "expression": False}
4831
4832
4833class Transaction(Expression):
4834    arg_types = {"this": False, "modes": False, "mark": False}
4835
4836
4837class Commit(Expression):
4838    arg_types = {"chain": False, "this": False, "durability": False}
4839
4840
4841class Rollback(Expression):
4842    arg_types = {"savepoint": False, "this": False}
4843
4844
4845class Alter(Expression):
4846    arg_types = {
4847        "this": True,
4848        "kind": True,
4849        "actions": True,
4850        "exists": False,
4851        "only": False,
4852        "options": False,
4853        "cluster": False,
4854        "not_valid": False,
4855    }
4856
4857    @property
4858    def kind(self) -> t.Optional[str]:
4859        kind = self.args.get("kind")
4860        return kind and kind.upper()
4861
4862    @property
4863    def actions(self) -> t.List[Expression]:
4864        return self.args.get("actions") or []
4865
4866
4867class Analyze(Expression):
4868    arg_types = {
4869        "kind": False,
4870        "this": False,
4871        "options": False,
4872        "mode": False,
4873        "partition": False,
4874        "expression": False,
4875        "properties": False,
4876    }
4877
4878
4879class AnalyzeStatistics(Expression):
4880    arg_types = {
4881        "kind": True,
4882        "option": False,
4883        "this": False,
4884        "expressions": False,
4885    }
4886
4887
4888class AnalyzeHistogram(Expression):
4889    arg_types = {
4890        "this": True,
4891        "expressions": True,
4892        "expression": False,
4893        "update_options": False,
4894    }
4895
4896
4897class AnalyzeSample(Expression):
4898    arg_types = {"kind": True, "sample": True}
4899
4900
4901class AnalyzeListChainedRows(Expression):
4902    arg_types = {"expression": False}
4903
4904
4905class AnalyzeDelete(Expression):
4906    arg_types = {"kind": False}
4907
4908
4909class AnalyzeWith(Expression):
4910    arg_types = {"expressions": True}
4911
4912
4913class AnalyzeValidate(Expression):
4914    arg_types = {
4915        "kind": True,
4916        "this": False,
4917        "expression": False,
4918    }
4919
4920
4921class AnalyzeColumns(Expression):
4922    pass
4923
4924
4925class UsingData(Expression):
4926    pass
4927
4928
4929class AddConstraint(Expression):
4930    arg_types = {"expressions": True}
4931
4932
4933class AttachOption(Expression):
4934    arg_types = {"this": True, "expression": False}
4935
4936
4937class DropPartition(Expression):
4938    arg_types = {"expressions": True, "exists": False}
4939
4940
4941# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#replace-partition
4942class ReplacePartition(Expression):
4943    arg_types = {"expression": True, "source": True}
4944
4945
4946# Binary expressions like (ADD a b)
4947class Binary(Condition):
4948    arg_types = {"this": True, "expression": True}
4949
4950    @property
4951    def left(self) -> Expression:
4952        return self.this
4953
4954    @property
4955    def right(self) -> Expression:
4956        return self.expression
4957
4958
4959class Add(Binary):
4960    pass
4961
4962
4963class Connector(Binary):
4964    pass
4965
4966
4967class BitwiseAnd(Binary):
4968    pass
4969
4970
4971class BitwiseLeftShift(Binary):
4972    pass
4973
4974
4975class BitwiseOr(Binary):
4976    pass
4977
4978
4979class BitwiseRightShift(Binary):
4980    pass
4981
4982
4983class BitwiseXor(Binary):
4984    pass
4985
4986
4987class Div(Binary):
4988    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4989
4990
4991class Overlaps(Binary):
4992    pass
4993
4994
4995class Dot(Binary):
4996    @property
4997    def is_star(self) -> bool:
4998        return self.expression.is_star
4999
5000    @property
5001    def name(self) -> str:
5002        return self.expression.name
5003
5004    @property
5005    def output_name(self) -> str:
5006        return self.name
5007
5008    @classmethod
5009    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5010        """Build a Dot object with a sequence of expressions."""
5011        if len(expressions) < 2:
5012            raise ValueError("Dot requires >= 2 expressions.")
5013
5014        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5015
5016    @property
5017    def parts(self) -> t.List[Expression]:
5018        """Return the parts of a table / column in order catalog, db, table."""
5019        this, *parts = self.flatten()
5020
5021        parts.reverse()
5022
5023        for arg in COLUMN_PARTS:
5024            part = this.args.get(arg)
5025
5026            if isinstance(part, Expression):
5027                parts.append(part)
5028
5029        parts.reverse()
5030        return parts
5031
5032
5033class DPipe(Binary):
5034    arg_types = {"this": True, "expression": True, "safe": False}
5035
5036
5037class EQ(Binary, Predicate):
5038    pass
5039
5040
5041class NullSafeEQ(Binary, Predicate):
5042    pass
5043
5044
5045class NullSafeNEQ(Binary, Predicate):
5046    pass
5047
5048
5049# Represents e.g. := in DuckDB which is mostly used for setting parameters
5050class PropertyEQ(Binary):
5051    pass
5052
5053
5054class Distance(Binary):
5055    pass
5056
5057
5058class Escape(Binary):
5059    pass
5060
5061
5062class Glob(Binary, Predicate):
5063    pass
5064
5065
5066class GT(Binary, Predicate):
5067    pass
5068
5069
5070class GTE(Binary, Predicate):
5071    pass
5072
5073
5074class ILike(Binary, Predicate):
5075    pass
5076
5077
5078class ILikeAny(Binary, Predicate):
5079    pass
5080
5081
5082class IntDiv(Binary):
5083    pass
5084
5085
5086class Is(Binary, Predicate):
5087    pass
5088
5089
5090class Kwarg(Binary):
5091    """Kwarg in special functions like func(kwarg => y)."""
5092
5093
5094class Like(Binary, Predicate):
5095    pass
5096
5097
5098class LikeAny(Binary, Predicate):
5099    pass
5100
5101
5102class LT(Binary, Predicate):
5103    pass
5104
5105
5106class LTE(Binary, Predicate):
5107    pass
5108
5109
5110class Mod(Binary):
5111    pass
5112
5113
5114class Mul(Binary):
5115    pass
5116
5117
5118class NEQ(Binary, Predicate):
5119    pass
5120
5121
5122# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
5123class Operator(Binary):
5124    arg_types = {"this": True, "operator": True, "expression": True}
5125
5126
5127class SimilarTo(Binary, Predicate):
5128    pass
5129
5130
5131class Slice(Binary):
5132    arg_types = {"this": False, "expression": False}
5133
5134
5135class Sub(Binary):
5136    pass
5137
5138
5139# Unary Expressions
5140# (NOT a)
5141class Unary(Condition):
5142    pass
5143
5144
5145class BitwiseNot(Unary):
5146    pass
5147
5148
5149class Not(Unary):
5150    pass
5151
5152
5153class Paren(Unary):
5154    @property
5155    def output_name(self) -> str:
5156        return self.this.name
5157
5158
5159class Neg(Unary):
5160    def to_py(self) -> int | Decimal:
5161        if self.is_number:
5162            return self.this.to_py() * -1
5163        return super().to_py()
5164
5165
5166class Alias(Expression):
5167    arg_types = {"this": True, "alias": False}
5168
5169    @property
5170    def output_name(self) -> str:
5171        return self.alias
5172
5173
5174# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
5175# other dialects require identifiers. This enables us to transpile between them easily.
5176class PivotAlias(Alias):
5177    pass
5178
5179
5180# Represents Snowflake's ANY [ ORDER BY ... ] syntax
5181# https://docs.snowflake.com/en/sql-reference/constructs/pivot
5182class PivotAny(Expression):
5183    arg_types = {"this": False}
5184
5185
5186class Aliases(Expression):
5187    arg_types = {"this": True, "expressions": True}
5188
5189    @property
5190    def aliases(self):
5191        return self.expressions
5192
5193
5194# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
5195class AtIndex(Expression):
5196    arg_types = {"this": True, "expression": True}
5197
5198
5199class AtTimeZone(Expression):
5200    arg_types = {"this": True, "zone": True}
5201
5202
5203class FromTimeZone(Expression):
5204    arg_types = {"this": True, "zone": True}
5205
5206
5207class Between(Predicate):
5208    arg_types = {"this": True, "low": True, "high": True}
5209
5210
5211class Bracket(Condition):
5212    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5213    arg_types = {
5214        "this": True,
5215        "expressions": True,
5216        "offset": False,
5217        "safe": False,
5218        "returns_list_for_maps": False,
5219    }
5220
5221    @property
5222    def output_name(self) -> str:
5223        if len(self.expressions) == 1:
5224            return self.expressions[0].output_name
5225
5226        return super().output_name
5227
5228
5229class Distinct(Expression):
5230    arg_types = {"expressions": False, "on": False}
5231
5232
5233class In(Predicate):
5234    arg_types = {
5235        "this": True,
5236        "expressions": False,
5237        "query": False,
5238        "unnest": False,
5239        "field": False,
5240        "is_global": False,
5241    }
5242
5243
5244# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
5245class ForIn(Expression):
5246    arg_types = {"this": True, "expression": True}
5247
5248
5249class TimeUnit(Expression):
5250    """Automatically converts unit arg into a var."""
5251
5252    arg_types = {"unit": False}
5253
5254    UNABBREVIATED_UNIT_NAME = {
5255        "D": "DAY",
5256        "H": "HOUR",
5257        "M": "MINUTE",
5258        "MS": "MILLISECOND",
5259        "NS": "NANOSECOND",
5260        "Q": "QUARTER",
5261        "S": "SECOND",
5262        "US": "MICROSECOND",
5263        "W": "WEEK",
5264        "Y": "YEAR",
5265    }
5266
5267    VAR_LIKE = (Column, Literal, Var)
5268
5269    def __init__(self, **args):
5270        unit = args.get("unit")
5271        if isinstance(unit, self.VAR_LIKE):
5272            args["unit"] = Var(
5273                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5274            )
5275        elif isinstance(unit, Week):
5276            unit.set("this", Var(this=unit.this.name.upper()))
5277
5278        super().__init__(**args)
5279
5280    @property
5281    def unit(self) -> t.Optional[Var | IntervalSpan]:
5282        return self.args.get("unit")
5283
5284
5285class IntervalOp(TimeUnit):
5286    arg_types = {"unit": False, "expression": True}
5287
5288    def interval(self):
5289        return Interval(
5290            this=self.expression.copy(),
5291            unit=self.unit.copy() if self.unit else None,
5292        )
5293
5294
5295# https://www.oracletutorial.com/oracle-basics/oracle-interval/
5296# https://trino.io/docs/current/language/types.html#interval-day-to-second
5297# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
5298class IntervalSpan(DataType):
5299    arg_types = {"this": True, "expression": True}
5300
5301
5302class Interval(TimeUnit):
5303    arg_types = {"this": False, "unit": False}
5304
5305
5306class IgnoreNulls(Expression):
5307    pass
5308
5309
5310class RespectNulls(Expression):
5311    pass
5312
5313
5314# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
5315class HavingMax(Expression):
5316    arg_types = {"this": True, "expression": True, "max": True}
5317
5318
5319# Functions
5320class Func(Condition):
5321    """
5322    The base class for all function expressions.
5323
5324    Attributes:
5325        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5326            treated as a variable length argument and the argument's value will be stored as a list.
5327        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5328            function expression. These values are used to map this node to a name during parsing as
5329            well as to provide the function's name during SQL string generation. By default the SQL
5330            name is set to the expression's class name transformed to snake case.
5331    """
5332
5333    is_var_len_args = False
5334
5335    @classmethod
5336    def from_arg_list(cls, args):
5337        if cls.is_var_len_args:
5338            all_arg_keys = list(cls.arg_types)
5339            # If this function supports variable length argument treat the last argument as such.
5340            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5341            num_non_var = len(non_var_len_arg_keys)
5342
5343            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5344            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5345        else:
5346            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5347
5348        return cls(**args_dict)
5349
5350    @classmethod
5351    def sql_names(cls):
5352        if cls is Func:
5353            raise NotImplementedError(
5354                "SQL name is only supported by concrete function implementations"
5355            )
5356        if "_sql_names" not in cls.__dict__:
5357            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5358        return cls._sql_names
5359
5360    @classmethod
5361    def sql_name(cls):
5362        return cls.sql_names()[0]
5363
5364    @classmethod
5365    def default_parser_mappings(cls):
5366        return {name: cls.from_arg_list for name in cls.sql_names()}
5367
5368
5369class AggFunc(Func):
5370    pass
5371
5372
5373class ArrayRemove(Func):
5374    arg_types = {"this": True, "expression": True}
5375
5376
5377class ParameterizedAgg(AggFunc):
5378    arg_types = {"this": True, "expressions": True, "params": True}
5379
5380
5381class Abs(Func):
5382    pass
5383
5384
5385class ArgMax(AggFunc):
5386    arg_types = {"this": True, "expression": True, "count": False}
5387    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
5388
5389
5390class ArgMin(AggFunc):
5391    arg_types = {"this": True, "expression": True, "count": False}
5392    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
5393
5394
5395class ApproxTopK(AggFunc):
5396    arg_types = {"this": True, "expression": False, "counters": False}
5397
5398
5399class Flatten(Func):
5400    pass
5401
5402
5403# https://spark.apache.org/docs/latest/api/sql/index.html#transform
5404class Transform(Func):
5405    arg_types = {"this": True, "expression": True}
5406
5407
5408class Anonymous(Func):
5409    arg_types = {"this": True, "expressions": False}
5410    is_var_len_args = True
5411
5412    @property
5413    def name(self) -> str:
5414        return self.this if isinstance(self.this, str) else self.this.name
5415
5416
5417class AnonymousAggFunc(AggFunc):
5418    arg_types = {"this": True, "expressions": False}
5419    is_var_len_args = True
5420
5421
5422# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
5423class CombinedAggFunc(AnonymousAggFunc):
5424    arg_types = {"this": True, "expressions": False}
5425
5426
5427class CombinedParameterizedAgg(ParameterizedAgg):
5428    arg_types = {"this": True, "expressions": True, "params": True}
5429
5430
5431# https://docs.snowflake.com/en/sql-reference/functions/hll
5432# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
5433class Hll(AggFunc):
5434    arg_types = {"this": True, "expressions": False}
5435    is_var_len_args = True
5436
5437
5438class ApproxDistinct(AggFunc):
5439    arg_types = {"this": True, "accuracy": False}
5440    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
5441
5442
5443class Apply(Func):
5444    arg_types = {"this": True, "expression": True}
5445
5446
5447class Array(Func):
5448    arg_types = {"expressions": False, "bracket_notation": False}
5449    is_var_len_args = True
5450
5451
5452# https://docs.snowflake.com/en/sql-reference/functions/to_array
5453class ToArray(Func):
5454    pass
5455
5456
5457# https://materialize.com/docs/sql/types/list/
5458class List(Func):
5459    arg_types = {"expressions": False}
5460    is_var_len_args = True
5461
5462
5463# String pad, kind True -> LPAD, False -> RPAD
5464class Pad(Func):
5465    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
5466
5467
5468# https://docs.snowflake.com/en/sql-reference/functions/to_char
5469# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
5470class ToChar(Func):
5471    arg_types = {"this": True, "format": False, "nlsparam": False}
5472
5473
5474# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
5475# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
5476class ToNumber(Func):
5477    arg_types = {
5478        "this": True,
5479        "format": False,
5480        "nlsparam": False,
5481        "precision": False,
5482        "scale": False,
5483    }
5484
5485
5486# https://docs.snowflake.com/en/sql-reference/functions/to_double
5487class ToDouble(Func):
5488    arg_types = {
5489        "this": True,
5490        "format": False,
5491    }
5492
5493
5494class Columns(Func):
5495    arg_types = {"this": True, "unpack": False}
5496
5497
5498# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
5499class Convert(Func):
5500    arg_types = {"this": True, "expression": True, "style": False}
5501
5502
5503# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/CONVERT.html
5504class ConvertToCharset(Func):
5505    arg_types = {"this": True, "dest": True, "source": False}
5506
5507
5508class ConvertTimezone(Func):
5509    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
5510
5511
5512class GenerateSeries(Func):
5513    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
5514
5515
5516# Postgres' GENERATE_SERIES function returns a row set, i.e. it implicitly explodes when it's
5517# used in a projection, so this expression is a helper that facilitates transpilation to other
5518# dialects. For example, we'd generate UNNEST(GENERATE_SERIES(...)) in DuckDB
5519class ExplodingGenerateSeries(GenerateSeries):
5520    pass
5521
5522
5523class ArrayAgg(AggFunc):
5524    arg_types = {"this": True, "nulls_excluded": False}
5525
5526
5527class ArrayUniqueAgg(AggFunc):
5528    pass
5529
5530
5531class ArrayAll(Func):
5532    arg_types = {"this": True, "expression": True}
5533
5534
5535# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
5536class ArrayAny(Func):
5537    arg_types = {"this": True, "expression": True}
5538
5539
5540class ArrayConcat(Func):
5541    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5542    arg_types = {"this": True, "expressions": False}
5543    is_var_len_args = True
5544
5545
5546class ArrayConcatAgg(AggFunc):
5547    pass
5548
5549
5550class ArrayConstructCompact(Func):
5551    arg_types = {"expressions": True}
5552    is_var_len_args = True
5553
5554
5555class ArrayContains(Binary, Func):
5556    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5557
5558
5559class ArrayContainsAll(Binary, Func):
5560    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5561
5562
5563class ArrayFilter(Func):
5564    arg_types = {"this": True, "expression": True}
5565    _sql_names = ["FILTER", "ARRAY_FILTER"]
5566
5567
5568class ArrayToString(Func):
5569    arg_types = {"this": True, "expression": True, "null": False}
5570    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5571
5572
5573# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5574class String(Func):
5575    arg_types = {"this": True, "zone": False}
5576
5577
5578class StringToArray(Func):
5579    arg_types = {"this": True, "expression": True, "null": False}
5580    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
5581
5582
5583class ArrayOverlaps(Binary, Func):
5584    pass
5585
5586
5587class ArraySize(Func):
5588    arg_types = {"this": True, "expression": False}
5589    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5590
5591
5592class ArraySort(Func):
5593    arg_types = {"this": True, "expression": False}
5594
5595
5596class ArraySum(Func):
5597    arg_types = {"this": True, "expression": False}
5598
5599
5600class ArrayUnionAgg(AggFunc):
5601    pass
5602
5603
5604class Avg(AggFunc):
5605    pass
5606
5607
5608class AnyValue(AggFunc):
5609    pass
5610
5611
5612class Lag(AggFunc):
5613    arg_types = {"this": True, "offset": False, "default": False}
5614
5615
5616class Lead(AggFunc):
5617    arg_types = {"this": True, "offset": False, "default": False}
5618
5619
5620# some dialects have a distinction between first and first_value, usually first is an aggregate func
5621# and first_value is a window func
5622class First(AggFunc):
5623    pass
5624
5625
5626class Last(AggFunc):
5627    pass
5628
5629
5630class FirstValue(AggFunc):
5631    pass
5632
5633
5634class LastValue(AggFunc):
5635    pass
5636
5637
5638class NthValue(AggFunc):
5639    arg_types = {"this": True, "offset": True}
5640
5641
5642class Case(Func):
5643    arg_types = {"this": False, "ifs": True, "default": False}
5644
5645    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5646        instance = maybe_copy(self, copy)
5647        instance.append(
5648            "ifs",
5649            If(
5650                this=maybe_parse(condition, copy=copy, **opts),
5651                true=maybe_parse(then, copy=copy, **opts),
5652            ),
5653        )
5654        return instance
5655
5656    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5657        instance = maybe_copy(self, copy)
5658        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5659        return instance
5660
5661
5662class Cast(Func):
5663    arg_types = {
5664        "this": True,
5665        "to": True,
5666        "format": False,
5667        "safe": False,
5668        "action": False,
5669        "default": False,
5670    }
5671
5672    @property
5673    def name(self) -> str:
5674        return self.this.name
5675
5676    @property
5677    def to(self) -> DataType:
5678        return self.args["to"]
5679
5680    @property
5681    def output_name(self) -> str:
5682        return self.name
5683
5684    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5685        """
5686        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5687        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5688        array<int> != array<float>.
5689
5690        Args:
5691            dtypes: the data types to compare this Cast's DataType to.
5692
5693        Returns:
5694            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5695        """
5696        return self.to.is_type(*dtypes)
5697
5698
5699class TryCast(Cast):
5700    pass
5701
5702
5703# https://clickhouse.com/docs/sql-reference/data-types/newjson#reading-json-paths-as-sub-columns
5704class JSONCast(Cast):
5705    pass
5706
5707
5708class Try(Func):
5709    pass
5710
5711
5712class CastToStrType(Func):
5713    arg_types = {"this": True, "to": True}
5714
5715
5716# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/String-Operators-and-Functions/TRANSLATE/TRANSLATE-Function-Syntax
5717class TranslateCharacters(Expression):
5718    arg_types = {"this": True, "expression": True, "with_error": False}
5719
5720
5721class Collate(Binary, Func):
5722    pass
5723
5724
5725class Ceil(Func):
5726    arg_types = {"this": True, "decimals": False, "to": False}
5727    _sql_names = ["CEIL", "CEILING"]
5728
5729
5730class Coalesce(Func):
5731    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5732    is_var_len_args = True
5733    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5734
5735
5736class Chr(Func):
5737    arg_types = {"expressions": True, "charset": False}
5738    is_var_len_args = True
5739    _sql_names = ["CHR", "CHAR"]
5740
5741
5742class Concat(Func):
5743    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5744    is_var_len_args = True
5745
5746
5747class ConcatWs(Concat):
5748    _sql_names = ["CONCAT_WS"]
5749
5750
5751class Contains(Func):
5752    arg_types = {"this": True, "expression": True}
5753
5754
5755# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5756class ConnectByRoot(Func):
5757    pass
5758
5759
5760class Count(AggFunc):
5761    arg_types = {"this": False, "expressions": False, "big_int": False}
5762    is_var_len_args = True
5763
5764
5765class CountIf(AggFunc):
5766    _sql_names = ["COUNT_IF", "COUNTIF"]
5767
5768
5769# cube root
5770class Cbrt(Func):
5771    pass
5772
5773
5774class CurrentDate(Func):
5775    arg_types = {"this": False}
5776
5777
5778class CurrentDatetime(Func):
5779    arg_types = {"this": False}
5780
5781
5782class CurrentTime(Func):
5783    arg_types = {"this": False}
5784
5785
5786class CurrentTimestamp(Func):
5787    arg_types = {"this": False, "sysdate": False}
5788
5789
5790class CurrentSchema(Func):
5791    arg_types = {"this": False}
5792
5793
5794class CurrentUser(Func):
5795    arg_types = {"this": False}
5796
5797
5798class DateAdd(Func, IntervalOp):
5799    arg_types = {"this": True, "expression": True, "unit": False}
5800
5801
5802class DateBin(Func, IntervalOp):
5803    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5804
5805
5806class DateSub(Func, IntervalOp):
5807    arg_types = {"this": True, "expression": True, "unit": False}
5808
5809
5810class DateDiff(Func, TimeUnit):
5811    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5812    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5813
5814
5815class DateTrunc(Func):
5816    arg_types = {"unit": True, "this": True, "zone": False}
5817
5818    def __init__(self, **args):
5819        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5820        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5821        unabbreviate = args.pop("unabbreviate", True)
5822
5823        unit = args.get("unit")
5824        if isinstance(unit, TimeUnit.VAR_LIKE):
5825            unit_name = unit.name.upper()
5826            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5827                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5828
5829            args["unit"] = Literal.string(unit_name)
5830        elif isinstance(unit, Week):
5831            unit.set("this", Literal.string(unit.this.name.upper()))
5832
5833        super().__init__(**args)
5834
5835    @property
5836    def unit(self) -> Expression:
5837        return self.args["unit"]
5838
5839
5840# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5841# expression can either be time_expr or time_zone
5842class Datetime(Func):
5843    arg_types = {"this": True, "expression": False}
5844
5845
5846class DatetimeAdd(Func, IntervalOp):
5847    arg_types = {"this": True, "expression": True, "unit": False}
5848
5849
5850class DatetimeSub(Func, IntervalOp):
5851    arg_types = {"this": True, "expression": True, "unit": False}
5852
5853
5854class DatetimeDiff(Func, TimeUnit):
5855    arg_types = {"this": True, "expression": True, "unit": False}
5856
5857
5858class DatetimeTrunc(Func, TimeUnit):
5859    arg_types = {"this": True, "unit": True, "zone": False}
5860
5861
5862class DayOfWeek(Func):
5863    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5864
5865
5866# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5867# ISO day of week function in duckdb is ISODOW
5868class DayOfWeekIso(Func):
5869    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5870
5871
5872class DayOfMonth(Func):
5873    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5874
5875
5876class DayOfYear(Func):
5877    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5878
5879
5880class ToDays(Func):
5881    pass
5882
5883
5884class WeekOfYear(Func):
5885    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5886
5887
5888class MonthsBetween(Func):
5889    arg_types = {"this": True, "expression": True, "roundoff": False}
5890
5891
5892class MakeInterval(Func):
5893    arg_types = {
5894        "year": False,
5895        "month": False,
5896        "day": False,
5897        "hour": False,
5898        "minute": False,
5899        "second": False,
5900    }
5901
5902
5903class LastDay(Func, TimeUnit):
5904    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5905    arg_types = {"this": True, "unit": False}
5906
5907
5908class Extract(Func):
5909    arg_types = {"this": True, "expression": True}
5910
5911
5912class Exists(Func, SubqueryPredicate):
5913    arg_types = {"this": True, "expression": False}
5914
5915
5916class Timestamp(Func):
5917    arg_types = {"this": False, "zone": False, "with_tz": False}
5918
5919
5920class TimestampAdd(Func, TimeUnit):
5921    arg_types = {"this": True, "expression": True, "unit": False}
5922
5923
5924class TimestampSub(Func, TimeUnit):
5925    arg_types = {"this": True, "expression": True, "unit": False}
5926
5927
5928class TimestampDiff(Func, TimeUnit):
5929    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5930    arg_types = {"this": True, "expression": True, "unit": False}
5931
5932
5933class TimestampTrunc(Func, TimeUnit):
5934    arg_types = {"this": True, "unit": True, "zone": False}
5935
5936
5937class TimeAdd(Func, TimeUnit):
5938    arg_types = {"this": True, "expression": True, "unit": False}
5939
5940
5941class TimeSub(Func, TimeUnit):
5942    arg_types = {"this": True, "expression": True, "unit": False}
5943
5944
5945class TimeDiff(Func, TimeUnit):
5946    arg_types = {"this": True, "expression": True, "unit": False}
5947
5948
5949class TimeTrunc(Func, TimeUnit):
5950    arg_types = {"this": True, "unit": True, "zone": False}
5951
5952
5953class DateFromParts(Func):
5954    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5955    arg_types = {"year": True, "month": True, "day": True}
5956
5957
5958class TimeFromParts(Func):
5959    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5960    arg_types = {
5961        "hour": True,
5962        "min": True,
5963        "sec": True,
5964        "nano": False,
5965        "fractions": False,
5966        "precision": False,
5967    }
5968
5969
5970class DateStrToDate(Func):
5971    pass
5972
5973
5974class DateToDateStr(Func):
5975    pass
5976
5977
5978class DateToDi(Func):
5979    pass
5980
5981
5982# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5983class Date(Func):
5984    arg_types = {"this": False, "zone": False, "expressions": False}
5985    is_var_len_args = True
5986
5987
5988class Day(Func):
5989    pass
5990
5991
5992class Decode(Func):
5993    arg_types = {"this": True, "charset": True, "replace": False}
5994
5995
5996class DiToDate(Func):
5997    pass
5998
5999
6000class Encode(Func):
6001    arg_types = {"this": True, "charset": True}
6002
6003
6004class Exp(Func):
6005    pass
6006
6007
6008# https://docs.snowflake.com/en/sql-reference/functions/flatten
6009class Explode(Func, UDTF):
6010    arg_types = {"this": True, "expressions": False}
6011    is_var_len_args = True
6012
6013
6014# https://spark.apache.org/docs/latest/api/sql/#inline
6015class Inline(Func):
6016    pass
6017
6018
6019class ExplodeOuter(Explode):
6020    pass
6021
6022
6023class Posexplode(Explode):
6024    pass
6025
6026
6027class PosexplodeOuter(Posexplode, ExplodeOuter):
6028    pass
6029
6030
6031class Unnest(Func, UDTF):
6032    arg_types = {
6033        "expressions": True,
6034        "alias": False,
6035        "offset": False,
6036        "explode_array": False,
6037    }
6038
6039    @property
6040    def selects(self) -> t.List[Expression]:
6041        columns = super().selects
6042        offset = self.args.get("offset")
6043        if offset:
6044            columns = columns + [to_identifier("offset") if offset is True else offset]
6045        return columns
6046
6047
6048class Floor(Func):
6049    arg_types = {"this": True, "decimals": False, "to": False}
6050
6051
6052class FromBase64(Func):
6053    pass
6054
6055
6056class FeaturesAtTime(Func):
6057    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
6058
6059
6060class ToBase64(Func):
6061    pass
6062
6063
6064# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
6065class FromISO8601Timestamp(Func):
6066    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
6067
6068
6069class GapFill(Func):
6070    arg_types = {
6071        "this": True,
6072        "ts_column": True,
6073        "bucket_width": True,
6074        "partitioning_columns": False,
6075        "value_columns": False,
6076        "origin": False,
6077        "ignore_nulls": False,
6078    }
6079
6080
6081# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
6082class GenerateDateArray(Func):
6083    arg_types = {"start": True, "end": True, "step": False}
6084
6085
6086# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
6087class GenerateTimestampArray(Func):
6088    arg_types = {"start": True, "end": True, "step": True}
6089
6090
6091class Greatest(Func):
6092    arg_types = {"this": True, "expressions": False}
6093    is_var_len_args = True
6094
6095
6096# Trino's `ON OVERFLOW TRUNCATE [filler_string] {WITH | WITHOUT} COUNT`
6097# https://trino.io/docs/current/functions/aggregate.html#listagg
6098class OverflowTruncateBehavior(Expression):
6099    arg_types = {"this": False, "with_count": True}
6100
6101
6102class GroupConcat(AggFunc):
6103    arg_types = {"this": True, "separator": False, "on_overflow": False}
6104
6105
6106class Hex(Func):
6107    pass
6108
6109
6110class LowerHex(Hex):
6111    pass
6112
6113
6114class And(Connector, Func):
6115    pass
6116
6117
6118class Or(Connector, Func):
6119    pass
6120
6121
6122class Xor(Connector, Func):
6123    arg_types = {"this": False, "expression": False, "expressions": False}
6124
6125
6126class If(Func):
6127    arg_types = {"this": True, "true": True, "false": False}
6128    _sql_names = ["IF", "IIF"]
6129
6130
6131class Nullif(Func):
6132    arg_types = {"this": True, "expression": True}
6133
6134
6135class Initcap(Func):
6136    arg_types = {"this": True, "expression": False}
6137
6138
6139class IsAscii(Func):
6140    pass
6141
6142
6143class IsNan(Func):
6144    _sql_names = ["IS_NAN", "ISNAN"]
6145
6146
6147# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#int64_for_json
6148class Int64(Func):
6149    pass
6150
6151
6152class IsInf(Func):
6153    _sql_names = ["IS_INF", "ISINF"]
6154
6155
6156# https://www.postgresql.org/docs/current/functions-json.html
6157class JSON(Expression):
6158    arg_types = {"this": False, "with": False, "unique": False}
6159
6160
6161class JSONPath(Expression):
6162    arg_types = {"expressions": True, "escape": False}
6163
6164    @property
6165    def output_name(self) -> str:
6166        last_segment = self.expressions[-1].this
6167        return last_segment if isinstance(last_segment, str) else ""
6168
6169
6170class JSONPathPart(Expression):
6171    arg_types = {}
6172
6173
6174class JSONPathFilter(JSONPathPart):
6175    arg_types = {"this": True}
6176
6177
6178class JSONPathKey(JSONPathPart):
6179    arg_types = {"this": True}
6180
6181
6182class JSONPathRecursive(JSONPathPart):
6183    arg_types = {"this": False}
6184
6185
6186class JSONPathRoot(JSONPathPart):
6187    pass
6188
6189
6190class JSONPathScript(JSONPathPart):
6191    arg_types = {"this": True}
6192
6193
6194class JSONPathSlice(JSONPathPart):
6195    arg_types = {"start": False, "end": False, "step": False}
6196
6197
6198class JSONPathSelector(JSONPathPart):
6199    arg_types = {"this": True}
6200
6201
6202class JSONPathSubscript(JSONPathPart):
6203    arg_types = {"this": True}
6204
6205
6206class JSONPathUnion(JSONPathPart):
6207    arg_types = {"expressions": True}
6208
6209
6210class JSONPathWildcard(JSONPathPart):
6211    pass
6212
6213
6214class FormatJson(Expression):
6215    pass
6216
6217
6218class JSONKeyValue(Expression):
6219    arg_types = {"this": True, "expression": True}
6220
6221
6222class JSONObject(Func):
6223    arg_types = {
6224        "expressions": False,
6225        "null_handling": False,
6226        "unique_keys": False,
6227        "return_type": False,
6228        "encoding": False,
6229    }
6230
6231
6232class JSONObjectAgg(AggFunc):
6233    arg_types = {
6234        "expressions": False,
6235        "null_handling": False,
6236        "unique_keys": False,
6237        "return_type": False,
6238        "encoding": False,
6239    }
6240
6241
6242# https://www.postgresql.org/docs/9.5/functions-aggregate.html
6243class JSONBObjectAgg(AggFunc):
6244    arg_types = {"this": True, "expression": True}
6245
6246
6247# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
6248class JSONArray(Func):
6249    arg_types = {
6250        "expressions": True,
6251        "null_handling": False,
6252        "return_type": False,
6253        "strict": False,
6254    }
6255
6256
6257# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
6258class JSONArrayAgg(Func):
6259    arg_types = {
6260        "this": True,
6261        "order": False,
6262        "null_handling": False,
6263        "return_type": False,
6264        "strict": False,
6265    }
6266
6267
6268class JSONExists(Func):
6269    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
6270
6271
6272# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6273# Note: parsing of JSON column definitions is currently incomplete.
6274class JSONColumnDef(Expression):
6275    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
6276
6277
6278class JSONSchema(Expression):
6279    arg_types = {"expressions": True}
6280
6281
6282# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
6283class JSONValue(Expression):
6284    arg_types = {
6285        "this": True,
6286        "path": True,
6287        "returning": False,
6288        "on_condition": False,
6289    }
6290
6291
6292class JSONValueArray(Func):
6293    arg_types = {"this": True, "expression": False}
6294
6295
6296# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6297class JSONTable(Func):
6298    arg_types = {
6299        "this": True,
6300        "schema": True,
6301        "path": False,
6302        "error_handling": False,
6303        "empty_handling": False,
6304    }
6305
6306
6307# https://docs.snowflake.com/en/sql-reference/functions/object_insert
6308class ObjectInsert(Func):
6309    arg_types = {
6310        "this": True,
6311        "key": True,
6312        "value": True,
6313        "update_flag": False,
6314    }
6315
6316
6317class OpenJSONColumnDef(Expression):
6318    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
6319
6320
6321class OpenJSON(Func):
6322    arg_types = {"this": True, "path": False, "expressions": False}
6323
6324
6325class JSONBContains(Binary, Func):
6326    _sql_names = ["JSONB_CONTAINS"]
6327
6328
6329class JSONBExists(Func):
6330    arg_types = {"this": True, "path": True}
6331    _sql_names = ["JSONB_EXISTS"]
6332
6333
6334class JSONExtract(Binary, Func):
6335    arg_types = {
6336        "this": True,
6337        "expression": True,
6338        "only_json_types": False,
6339        "expressions": False,
6340        "variant_extract": False,
6341        "json_query": False,
6342        "option": False,
6343        "quote": False,
6344        "on_condition": False,
6345    }
6346    _sql_names = ["JSON_EXTRACT"]
6347    is_var_len_args = True
6348
6349    @property
6350    def output_name(self) -> str:
6351        return self.expression.output_name if not self.expressions else ""
6352
6353
6354# https://trino.io/docs/current/functions/json.html#json-query
6355class JSONExtractQuote(Expression):
6356    arg_types = {
6357        "option": True,
6358        "scalar": False,
6359    }
6360
6361
6362class JSONExtractArray(Func):
6363    arg_types = {"this": True, "expression": False}
6364    _sql_names = ["JSON_EXTRACT_ARRAY"]
6365
6366
6367class JSONExtractScalar(Binary, Func):
6368    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6369    _sql_names = ["JSON_EXTRACT_SCALAR"]
6370    is_var_len_args = True
6371
6372    @property
6373    def output_name(self) -> str:
6374        return self.expression.output_name
6375
6376
6377class JSONBExtract(Binary, Func):
6378    _sql_names = ["JSONB_EXTRACT"]
6379
6380
6381class JSONBExtractScalar(Binary, Func):
6382    _sql_names = ["JSONB_EXTRACT_SCALAR"]
6383
6384
6385class JSONFormat(Func):
6386    arg_types = {"this": False, "options": False, "is_json": False}
6387    _sql_names = ["JSON_FORMAT"]
6388
6389
6390# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
6391class JSONArrayContains(Binary, Predicate, Func):
6392    _sql_names = ["JSON_ARRAY_CONTAINS"]
6393
6394
6395class ParseJSON(Func):
6396    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6397    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6398    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6399    arg_types = {"this": True, "expression": False, "safe": False}
6400
6401
6402class Least(Func):
6403    arg_types = {"this": True, "expressions": False}
6404    is_var_len_args = True
6405
6406
6407class Left(Func):
6408    arg_types = {"this": True, "expression": True}
6409
6410
6411class Right(Func):
6412    arg_types = {"this": True, "expression": True}
6413
6414
6415class Length(Func):
6416    arg_types = {"this": True, "binary": False, "encoding": False}
6417    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
6418
6419
6420class Levenshtein(Func):
6421    arg_types = {
6422        "this": True,
6423        "expression": False,
6424        "ins_cost": False,
6425        "del_cost": False,
6426        "sub_cost": False,
6427        "max_dist": False,
6428    }
6429
6430
6431class Ln(Func):
6432    pass
6433
6434
6435class Log(Func):
6436    arg_types = {"this": True, "expression": False}
6437
6438
6439class LogicalOr(AggFunc):
6440    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
6441
6442
6443class LogicalAnd(AggFunc):
6444    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
6445
6446
6447class Lower(Func):
6448    _sql_names = ["LOWER", "LCASE"]
6449
6450
6451class Map(Func):
6452    arg_types = {"keys": False, "values": False}
6453
6454    @property
6455    def keys(self) -> t.List[Expression]:
6456        keys = self.args.get("keys")
6457        return keys.expressions if keys else []
6458
6459    @property
6460    def values(self) -> t.List[Expression]:
6461        values = self.args.get("values")
6462        return values.expressions if values else []
6463
6464
6465# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
6466class ToMap(Func):
6467    pass
6468
6469
6470class MapFromEntries(Func):
6471    pass
6472
6473
6474# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
6475class ScopeResolution(Expression):
6476    arg_types = {"this": False, "expression": True}
6477
6478
6479class Stream(Expression):
6480    pass
6481
6482
6483class StarMap(Func):
6484    pass
6485
6486
6487class VarMap(Func):
6488    arg_types = {"keys": True, "values": True}
6489    is_var_len_args = True
6490
6491    @property
6492    def keys(self) -> t.List[Expression]:
6493        return self.args["keys"].expressions
6494
6495    @property
6496    def values(self) -> t.List[Expression]:
6497        return self.args["values"].expressions
6498
6499
6500# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
6501class MatchAgainst(Func):
6502    arg_types = {"this": True, "expressions": True, "modifier": False}
6503
6504
6505class Max(AggFunc):
6506    arg_types = {"this": True, "expressions": False}
6507    is_var_len_args = True
6508
6509
6510class MD5(Func):
6511    _sql_names = ["MD5"]
6512
6513
6514# Represents the variant of the MD5 function that returns a binary value
6515class MD5Digest(Func):
6516    _sql_names = ["MD5_DIGEST"]
6517
6518
6519class Median(AggFunc):
6520    pass
6521
6522
6523class Min(AggFunc):
6524    arg_types = {"this": True, "expressions": False}
6525    is_var_len_args = True
6526
6527
6528class Month(Func):
6529    pass
6530
6531
6532class AddMonths(Func):
6533    arg_types = {"this": True, "expression": True}
6534
6535
6536class Nvl2(Func):
6537    arg_types = {"this": True, "true": True, "false": False}
6538
6539
6540class Normalize(Func):
6541    arg_types = {"this": True, "form": False}
6542
6543
6544class Overlay(Func):
6545    arg_types = {"this": True, "expression": True, "from": True, "for": False}
6546
6547
6548# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
6549class Predict(Func):
6550    arg_types = {"this": True, "expression": True, "params_struct": False}
6551
6552
6553class Pow(Binary, Func):
6554    _sql_names = ["POWER", "POW"]
6555
6556
6557class PercentileCont(AggFunc):
6558    arg_types = {"this": True, "expression": False}
6559
6560
6561class PercentileDisc(AggFunc):
6562    arg_types = {"this": True, "expression": False}
6563
6564
6565class Quantile(AggFunc):
6566    arg_types = {"this": True, "quantile": True}
6567
6568
6569class ApproxQuantile(Quantile):
6570    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
6571
6572
6573class Quarter(Func):
6574    pass
6575
6576
6577# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
6578# teradata lower and upper bounds
6579class Rand(Func):
6580    _sql_names = ["RAND", "RANDOM"]
6581    arg_types = {"this": False, "lower": False, "upper": False}
6582
6583
6584class Randn(Func):
6585    arg_types = {"this": False}
6586
6587
6588class RangeN(Func):
6589    arg_types = {"this": True, "expressions": True, "each": False}
6590
6591
6592class ReadCSV(Func):
6593    _sql_names = ["READ_CSV"]
6594    is_var_len_args = True
6595    arg_types = {"this": True, "expressions": False}
6596
6597
6598class Reduce(Func):
6599    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
6600
6601
6602class RegexpExtract(Func):
6603    arg_types = {
6604        "this": True,
6605        "expression": True,
6606        "position": False,
6607        "occurrence": False,
6608        "parameters": False,
6609        "group": False,
6610    }
6611
6612
6613class RegexpExtractAll(Func):
6614    arg_types = {
6615        "this": True,
6616        "expression": True,
6617        "position": False,
6618        "occurrence": False,
6619        "parameters": False,
6620        "group": False,
6621    }
6622
6623
6624class RegexpReplace(Func):
6625    arg_types = {
6626        "this": True,
6627        "expression": True,
6628        "replacement": False,
6629        "position": False,
6630        "occurrence": False,
6631        "modifiers": False,
6632    }
6633
6634
6635class RegexpLike(Binary, Func):
6636    arg_types = {"this": True, "expression": True, "flag": False}
6637
6638
6639class RegexpILike(Binary, Func):
6640    arg_types = {"this": True, "expression": True, "flag": False}
6641
6642
6643# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6644# limit is the number of times a pattern is applied
6645class RegexpSplit(Func):
6646    arg_types = {"this": True, "expression": True, "limit": False}
6647
6648
6649class Repeat(Func):
6650    arg_types = {"this": True, "times": True}
6651
6652
6653# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6654# tsql third argument function == trunctaion if not 0
6655class Round(Func):
6656    arg_types = {"this": True, "decimals": False, "truncate": False}
6657
6658
6659class RowNumber(Func):
6660    arg_types = {"this": False}
6661
6662
6663class SafeDivide(Func):
6664    arg_types = {"this": True, "expression": True}
6665
6666
6667class SHA(Func):
6668    _sql_names = ["SHA", "SHA1"]
6669
6670
6671class SHA2(Func):
6672    _sql_names = ["SHA2"]
6673    arg_types = {"this": True, "length": False}
6674
6675
6676class Sign(Func):
6677    _sql_names = ["SIGN", "SIGNUM"]
6678
6679
6680class SortArray(Func):
6681    arg_types = {"this": True, "asc": False}
6682
6683
6684class Split(Func):
6685    arg_types = {"this": True, "expression": True, "limit": False}
6686
6687
6688# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split_part.html
6689class SplitPart(Func):
6690    arg_types = {"this": True, "delimiter": True, "part_index": True}
6691
6692
6693# Start may be omitted in the case of postgres
6694# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6695class Substring(Func):
6696    _sql_names = ["SUBSTRING", "SUBSTR"]
6697    arg_types = {"this": True, "start": False, "length": False}
6698
6699
6700class StandardHash(Func):
6701    arg_types = {"this": True, "expression": False}
6702
6703
6704class StartsWith(Func):
6705    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6706    arg_types = {"this": True, "expression": True}
6707
6708
6709class StrPosition(Func):
6710    arg_types = {
6711        "this": True,
6712        "substr": True,
6713        "position": False,
6714        "occurrence": False,
6715    }
6716
6717
6718class StrToDate(Func):
6719    arg_types = {"this": True, "format": False, "safe": False}
6720
6721
6722class StrToTime(Func):
6723    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6724
6725
6726# Spark allows unix_timestamp()
6727# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6728class StrToUnix(Func):
6729    arg_types = {"this": False, "format": False}
6730
6731
6732# https://prestodb.io/docs/current/functions/string.html
6733# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6734class StrToMap(Func):
6735    arg_types = {
6736        "this": True,
6737        "pair_delim": False,
6738        "key_value_delim": False,
6739        "duplicate_resolution_callback": False,
6740    }
6741
6742
6743class NumberToStr(Func):
6744    arg_types = {"this": True, "format": True, "culture": False}
6745
6746
6747class FromBase(Func):
6748    arg_types = {"this": True, "expression": True}
6749
6750
6751class Struct(Func):
6752    arg_types = {"expressions": False}
6753    is_var_len_args = True
6754
6755
6756class StructExtract(Func):
6757    arg_types = {"this": True, "expression": True}
6758
6759
6760# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6761# https://docs.snowflake.com/en/sql-reference/functions/insert
6762class Stuff(Func):
6763    _sql_names = ["STUFF", "INSERT"]
6764    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6765
6766
6767class Sum(AggFunc):
6768    pass
6769
6770
6771class Sqrt(Func):
6772    pass
6773
6774
6775class Stddev(AggFunc):
6776    _sql_names = ["STDDEV", "STDEV"]
6777
6778
6779class StddevPop(AggFunc):
6780    pass
6781
6782
6783class StddevSamp(AggFunc):
6784    pass
6785
6786
6787# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6788class Time(Func):
6789    arg_types = {"this": False, "zone": False}
6790
6791
6792class TimeToStr(Func):
6793    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6794
6795
6796class TimeToTimeStr(Func):
6797    pass
6798
6799
6800class TimeToUnix(Func):
6801    pass
6802
6803
6804class TimeStrToDate(Func):
6805    pass
6806
6807
6808class TimeStrToTime(Func):
6809    arg_types = {"this": True, "zone": False}
6810
6811
6812class TimeStrToUnix(Func):
6813    pass
6814
6815
6816class Trim(Func):
6817    arg_types = {
6818        "this": True,
6819        "expression": False,
6820        "position": False,
6821        "collation": False,
6822    }
6823
6824
6825class TsOrDsAdd(Func, TimeUnit):
6826    # return_type is used to correctly cast the arguments of this expression when transpiling it
6827    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6828
6829    @property
6830    def return_type(self) -> DataType:
6831        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
6832
6833
6834class TsOrDsDiff(Func, TimeUnit):
6835    arg_types = {"this": True, "expression": True, "unit": False}
6836
6837
6838class TsOrDsToDateStr(Func):
6839    pass
6840
6841
6842class TsOrDsToDate(Func):
6843    arg_types = {"this": True, "format": False, "safe": False}
6844
6845
6846class TsOrDsToDatetime(Func):
6847    pass
6848
6849
6850class TsOrDsToTime(Func):
6851    arg_types = {"this": True, "format": False, "safe": False}
6852
6853
6854class TsOrDsToTimestamp(Func):
6855    pass
6856
6857
6858class TsOrDiToDi(Func):
6859    pass
6860
6861
6862class Unhex(Func):
6863    arg_types = {"this": True, "expression": False}
6864
6865
6866class Unicode(Func):
6867    pass
6868
6869
6870# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
6871class UnixDate(Func):
6872    pass
6873
6874
6875class UnixToStr(Func):
6876    arg_types = {"this": True, "format": False}
6877
6878
6879# https://prestodb.io/docs/current/functions/datetime.html
6880# presto has weird zone/hours/minutes
6881class UnixToTime(Func):
6882    arg_types = {
6883        "this": True,
6884        "scale": False,
6885        "zone": False,
6886        "hours": False,
6887        "minutes": False,
6888        "format": False,
6889    }
6890
6891    SECONDS = Literal.number(0)
6892    DECIS = Literal.number(1)
6893    CENTIS = Literal.number(2)
6894    MILLIS = Literal.number(3)
6895    DECIMILLIS = Literal.number(4)
6896    CENTIMILLIS = Literal.number(5)
6897    MICROS = Literal.number(6)
6898    DECIMICROS = Literal.number(7)
6899    CENTIMICROS = Literal.number(8)
6900    NANOS = Literal.number(9)
6901
6902
6903class UnixToTimeStr(Func):
6904    pass
6905
6906
6907class UnixSeconds(Func):
6908    pass
6909
6910
6911class Uuid(Func):
6912    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6913
6914    arg_types = {"this": False, "name": False}
6915
6916
6917class TimestampFromParts(Func):
6918    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6919    arg_types = {
6920        "year": True,
6921        "month": True,
6922        "day": True,
6923        "hour": True,
6924        "min": True,
6925        "sec": True,
6926        "nano": False,
6927        "zone": False,
6928        "milli": False,
6929    }
6930
6931
6932class Upper(Func):
6933    _sql_names = ["UPPER", "UCASE"]
6934
6935
6936class Corr(Binary, AggFunc):
6937    pass
6938
6939
6940class Variance(AggFunc):
6941    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6942
6943
6944class VariancePop(AggFunc):
6945    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6946
6947
6948class CovarSamp(Binary, AggFunc):
6949    pass
6950
6951
6952class CovarPop(Binary, AggFunc):
6953    pass
6954
6955
6956class Week(Func):
6957    arg_types = {"this": True, "mode": False}
6958
6959
6960class XMLElement(Func):
6961    _sql_names = ["XMLELEMENT"]
6962    arg_types = {"this": True, "expressions": False}
6963
6964
6965class XMLTable(Func):
6966    arg_types = {
6967        "this": True,
6968        "namespaces": False,
6969        "passing": False,
6970        "columns": False,
6971        "by_ref": False,
6972    }
6973
6974
6975class XMLNamespace(Expression):
6976    pass
6977
6978
6979# https://learn.microsoft.com/en-us/sql/t-sql/queries/select-for-clause-transact-sql?view=sql-server-ver17#syntax
6980class XMLKeyValueOption(Expression):
6981    arg_types = {"this": True, "expression": False}
6982
6983
6984class Year(Func):
6985    pass
6986
6987
6988class Use(Expression):
6989    arg_types = {"this": False, "expressions": False, "kind": False}
6990
6991
6992class Merge(DML):
6993    arg_types = {
6994        "this": True,
6995        "using": True,
6996        "on": True,
6997        "whens": True,
6998        "with": False,
6999        "returning": False,
7000    }
7001
7002
7003class When(Expression):
7004    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
7005
7006
7007class Whens(Expression):
7008    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7009
7010    arg_types = {"expressions": True}
7011
7012
7013# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
7014# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
7015class NextValueFor(Func):
7016    arg_types = {"this": True, "order": False}
7017
7018
7019# Refers to a trailing semi-colon. This is only used to preserve trailing comments
7020# select 1; -- my comment
7021class Semicolon(Expression):
7022    arg_types = {}
7023
7024
7025def _norm_arg(arg):
7026    return arg.lower() if type(arg) is str else arg
7027
7028
7029ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
7030FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
7031
7032JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
7033
7034PERCENTILES = (PercentileCont, PercentileDisc)
7035
7036
7037# Helpers
7038@t.overload
7039def maybe_parse(
7040    sql_or_expression: ExpOrStr,
7041    *,
7042    into: t.Type[E],
7043    dialect: DialectType = None,
7044    prefix: t.Optional[str] = None,
7045    copy: bool = False,
7046    **opts,
7047) -> E: ...
7048
7049
7050@t.overload
7051def maybe_parse(
7052    sql_or_expression: str | E,
7053    *,
7054    into: t.Optional[IntoType] = None,
7055    dialect: DialectType = None,
7056    prefix: t.Optional[str] = None,
7057    copy: bool = False,
7058    **opts,
7059) -> E: ...
7060
7061
7062def maybe_parse(
7063    sql_or_expression: ExpOrStr,
7064    *,
7065    into: t.Optional[IntoType] = None,
7066    dialect: DialectType = None,
7067    prefix: t.Optional[str] = None,
7068    copy: bool = False,
7069    **opts,
7070) -> Expression:
7071    """Gracefully handle a possible string or expression.
7072
7073    Example:
7074        >>> maybe_parse("1")
7075        Literal(this=1, is_string=False)
7076        >>> maybe_parse(to_identifier("x"))
7077        Identifier(this=x, quoted=False)
7078
7079    Args:
7080        sql_or_expression: the SQL code string or an expression
7081        into: the SQLGlot Expression to parse into
7082        dialect: the dialect used to parse the input expressions (in the case that an
7083            input expression is a SQL string).
7084        prefix: a string to prefix the sql with before it gets parsed
7085            (automatically includes a space)
7086        copy: whether to copy the expression.
7087        **opts: other options to use to parse the input expressions (again, in the case
7088            that an input expression is a SQL string).
7089
7090    Returns:
7091        Expression: the parsed or given expression.
7092    """
7093    if isinstance(sql_or_expression, Expression):
7094        if copy:
7095            return sql_or_expression.copy()
7096        return sql_or_expression
7097
7098    if sql_or_expression is None:
7099        raise ParseError("SQL cannot be None")
7100
7101    import sqlglot
7102
7103    sql = str(sql_or_expression)
7104    if prefix:
7105        sql = f"{prefix} {sql}"
7106
7107    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
7108
7109
7110@t.overload
7111def maybe_copy(instance: None, copy: bool = True) -> None: ...
7112
7113
7114@t.overload
7115def maybe_copy(instance: E, copy: bool = True) -> E: ...
7116
7117
7118def maybe_copy(instance, copy=True):
7119    return instance.copy() if copy and instance else instance
7120
7121
7122def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str:
7123    """Generate a textual representation of an Expression tree"""
7124    indent = "\n" + ("  " * (level + 1))
7125    delim = f",{indent}"
7126
7127    if isinstance(node, Expression):
7128        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
7129
7130        if (node.type or verbose) and not isinstance(node, DataType):
7131            args["_type"] = node.type
7132        if node.comments or verbose:
7133            args["_comments"] = node.comments
7134
7135        if verbose:
7136            args["_id"] = id(node)
7137
7138        # Inline leaves for a more compact representation
7139        if node.is_leaf():
7140            indent = ""
7141            delim = ", "
7142
7143        repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted)
7144        items = delim.join(
7145            [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()]
7146        )
7147        return f"{node.__class__.__name__}({indent}{items})"
7148
7149    if isinstance(node, list):
7150        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
7151        items = f"{indent}{items}" if items else ""
7152        return f"[{items}]"
7153
7154    # We use the representation of the string to avoid stripping out important whitespace
7155    if repr_str and isinstance(node, str):
7156        node = repr(node)
7157
7158    # Indent multiline strings to match the current level
7159    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
7160
7161
7162def _is_wrong_expression(expression, into):
7163    return isinstance(expression, Expression) and not isinstance(expression, into)
7164
7165
7166def _apply_builder(
7167    expression,
7168    instance,
7169    arg,
7170    copy=True,
7171    prefix=None,
7172    into=None,
7173    dialect=None,
7174    into_arg="this",
7175    **opts,
7176):
7177    if _is_wrong_expression(expression, into):
7178        expression = into(**{into_arg: expression})
7179    instance = maybe_copy(instance, copy)
7180    expression = maybe_parse(
7181        sql_or_expression=expression,
7182        prefix=prefix,
7183        into=into,
7184        dialect=dialect,
7185        **opts,
7186    )
7187    instance.set(arg, expression)
7188    return instance
7189
7190
7191def _apply_child_list_builder(
7192    *expressions,
7193    instance,
7194    arg,
7195    append=True,
7196    copy=True,
7197    prefix=None,
7198    into=None,
7199    dialect=None,
7200    properties=None,
7201    **opts,
7202):
7203    instance = maybe_copy(instance, copy)
7204    parsed = []
7205    properties = {} if properties is None else properties
7206
7207    for expression in expressions:
7208        if expression is not None:
7209            if _is_wrong_expression(expression, into):
7210                expression = into(expressions=[expression])
7211
7212            expression = maybe_parse(
7213                expression,
7214                into=into,
7215                dialect=dialect,
7216                prefix=prefix,
7217                **opts,
7218            )
7219            for k, v in expression.args.items():
7220                if k == "expressions":
7221                    parsed.extend(v)
7222                else:
7223                    properties[k] = v
7224
7225    existing = instance.args.get(arg)
7226    if append and existing:
7227        parsed = existing.expressions + parsed
7228
7229    child = into(expressions=parsed)
7230    for k, v in properties.items():
7231        child.set(k, v)
7232    instance.set(arg, child)
7233
7234    return instance
7235
7236
7237def _apply_list_builder(
7238    *expressions,
7239    instance,
7240    arg,
7241    append=True,
7242    copy=True,
7243    prefix=None,
7244    into=None,
7245    dialect=None,
7246    **opts,
7247):
7248    inst = maybe_copy(instance, copy)
7249
7250    expressions = [
7251        maybe_parse(
7252            sql_or_expression=expression,
7253            into=into,
7254            prefix=prefix,
7255            dialect=dialect,
7256            **opts,
7257        )
7258        for expression in expressions
7259        if expression is not None
7260    ]
7261
7262    existing_expressions = inst.args.get(arg)
7263    if append and existing_expressions:
7264        expressions = existing_expressions + expressions
7265
7266    inst.set(arg, expressions)
7267    return inst
7268
7269
7270def _apply_conjunction_builder(
7271    *expressions,
7272    instance,
7273    arg,
7274    into=None,
7275    append=True,
7276    copy=True,
7277    dialect=None,
7278    **opts,
7279):
7280    expressions = [exp for exp in expressions if exp is not None and exp != ""]
7281    if not expressions:
7282        return instance
7283
7284    inst = maybe_copy(instance, copy)
7285
7286    existing = inst.args.get(arg)
7287    if append and existing is not None:
7288        expressions = [existing.this if into else existing] + list(expressions)
7289
7290    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
7291
7292    inst.set(arg, into(this=node) if into else node)
7293    return inst
7294
7295
7296def _apply_cte_builder(
7297    instance: E,
7298    alias: ExpOrStr,
7299    as_: ExpOrStr,
7300    recursive: t.Optional[bool] = None,
7301    materialized: t.Optional[bool] = None,
7302    append: bool = True,
7303    dialect: DialectType = None,
7304    copy: bool = True,
7305    scalar: bool = False,
7306    **opts,
7307) -> E:
7308    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
7309    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
7310    if scalar and not isinstance(as_expression, Subquery):
7311        # scalar CTE must be wrapped in a subquery
7312        as_expression = Subquery(this=as_expression)
7313    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
7314    return _apply_child_list_builder(
7315        cte,
7316        instance=instance,
7317        arg="with",
7318        append=append,
7319        copy=copy,
7320        into=With,
7321        properties={"recursive": recursive or False},
7322    )
7323
7324
7325def _combine(
7326    expressions: t.Sequence[t.Optional[ExpOrStr]],
7327    operator: t.Type[Connector],
7328    dialect: DialectType = None,
7329    copy: bool = True,
7330    wrap: bool = True,
7331    **opts,
7332) -> Expression:
7333    conditions = [
7334        condition(expression, dialect=dialect, copy=copy, **opts)
7335        for expression in expressions
7336        if expression is not None
7337    ]
7338
7339    this, *rest = conditions
7340    if rest and wrap:
7341        this = _wrap(this, Connector)
7342    for expression in rest:
7343        this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression)
7344
7345    return this
7346
7347
7348@t.overload
7349def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
7350
7351
7352@t.overload
7353def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
7354
7355
7356def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
7357    return Paren(this=expression) if isinstance(expression, kind) else expression
7358
7359
7360def _apply_set_operation(
7361    *expressions: ExpOrStr,
7362    set_operation: t.Type[S],
7363    distinct: bool = True,
7364    dialect: DialectType = None,
7365    copy: bool = True,
7366    **opts,
7367) -> S:
7368    return reduce(
7369        lambda x, y: set_operation(this=x, expression=y, distinct=distinct),
7370        (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7371    )
7372
7373
7374def union(
7375    *expressions: ExpOrStr,
7376    distinct: bool = True,
7377    dialect: DialectType = None,
7378    copy: bool = True,
7379    **opts,
7380) -> Union:
7381    """
7382    Initializes a syntax tree for the `UNION` operation.
7383
7384    Example:
7385        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7386        'SELECT * FROM foo UNION SELECT * FROM bla'
7387
7388    Args:
7389        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7390            If `Expression` instances are passed, they will be used as-is.
7391        distinct: set the DISTINCT flag if and only if this is true.
7392        dialect: the dialect used to parse the input expression.
7393        copy: whether to copy the expression.
7394        opts: other options to use to parse the input expressions.
7395
7396    Returns:
7397        The new Union instance.
7398    """
7399    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7400    return _apply_set_operation(
7401        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7402    )
7403
7404
7405def intersect(
7406    *expressions: ExpOrStr,
7407    distinct: bool = True,
7408    dialect: DialectType = None,
7409    copy: bool = True,
7410    **opts,
7411) -> Intersect:
7412    """
7413    Initializes a syntax tree for the `INTERSECT` operation.
7414
7415    Example:
7416        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7417        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7418
7419    Args:
7420        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7421            If `Expression` instances are passed, they will be used as-is.
7422        distinct: set the DISTINCT flag if and only if this is true.
7423        dialect: the dialect used to parse the input expression.
7424        copy: whether to copy the expression.
7425        opts: other options to use to parse the input expressions.
7426
7427    Returns:
7428        The new Intersect instance.
7429    """
7430    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7431    return _apply_set_operation(
7432        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7433    )
7434
7435
7436def except_(
7437    *expressions: ExpOrStr,
7438    distinct: bool = True,
7439    dialect: DialectType = None,
7440    copy: bool = True,
7441    **opts,
7442) -> Except:
7443    """
7444    Initializes a syntax tree for the `EXCEPT` operation.
7445
7446    Example:
7447        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7448        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7449
7450    Args:
7451        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7452            If `Expression` instances are passed, they will be used as-is.
7453        distinct: set the DISTINCT flag if and only if this is true.
7454        dialect: the dialect used to parse the input expression.
7455        copy: whether to copy the expression.
7456        opts: other options to use to parse the input expressions.
7457
7458    Returns:
7459        The new Except instance.
7460    """
7461    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7462    return _apply_set_operation(
7463        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7464    )
7465
7466
7467def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7468    """
7469    Initializes a syntax tree from one or multiple SELECT expressions.
7470
7471    Example:
7472        >>> select("col1", "col2").from_("tbl").sql()
7473        'SELECT col1, col2 FROM tbl'
7474
7475    Args:
7476        *expressions: the SQL code string to parse as the expressions of a
7477            SELECT statement. If an Expression instance is passed, this is used as-is.
7478        dialect: the dialect used to parse the input expressions (in the case that an
7479            input expression is a SQL string).
7480        **opts: other options to use to parse the input expressions (again, in the case
7481            that an input expression is a SQL string).
7482
7483    Returns:
7484        Select: the syntax tree for the SELECT statement.
7485    """
7486    return Select().select(*expressions, dialect=dialect, **opts)
7487
7488
7489def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7490    """
7491    Initializes a syntax tree from a FROM expression.
7492
7493    Example:
7494        >>> from_("tbl").select("col1", "col2").sql()
7495        'SELECT col1, col2 FROM tbl'
7496
7497    Args:
7498        *expression: the SQL code string to parse as the FROM expressions of a
7499            SELECT statement. If an Expression instance is passed, this is used as-is.
7500        dialect: the dialect used to parse the input expression (in the case that the
7501            input expression is a SQL string).
7502        **opts: other options to use to parse the input expressions (again, in the case
7503            that the input expression is a SQL string).
7504
7505    Returns:
7506        Select: the syntax tree for the SELECT statement.
7507    """
7508    return Select().from_(expression, dialect=dialect, **opts)
7509
7510
7511def update(
7512    table: str | Table,
7513    properties: t.Optional[dict] = None,
7514    where: t.Optional[ExpOrStr] = None,
7515    from_: t.Optional[ExpOrStr] = None,
7516    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7517    dialect: DialectType = None,
7518    **opts,
7519) -> Update:
7520    """
7521    Creates an update statement.
7522
7523    Example:
7524        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
7525        "WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
7526
7527    Args:
7528        properties: dictionary of properties to SET which are
7529            auto converted to sql objects eg None -> NULL
7530        where: sql conditional parsed into a WHERE statement
7531        from_: sql statement parsed into a FROM statement
7532        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7533        dialect: the dialect used to parse the input expressions.
7534        **opts: other options to use to parse the input expressions.
7535
7536    Returns:
7537        Update: the syntax tree for the UPDATE statement.
7538    """
7539    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7540    if properties:
7541        update_expr.set(
7542            "expressions",
7543            [
7544                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7545                for k, v in properties.items()
7546            ],
7547        )
7548    if from_:
7549        update_expr.set(
7550            "from",
7551            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7552        )
7553    if isinstance(where, Condition):
7554        where = Where(this=where)
7555    if where:
7556        update_expr.set(
7557            "where",
7558            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7559        )
7560    if with_:
7561        cte_list = [
7562            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7563            for alias, qry in with_.items()
7564        ]
7565        update_expr.set(
7566            "with",
7567            With(expressions=cte_list),
7568        )
7569    return update_expr
7570
7571
7572def delete(
7573    table: ExpOrStr,
7574    where: t.Optional[ExpOrStr] = None,
7575    returning: t.Optional[ExpOrStr] = None,
7576    dialect: DialectType = None,
7577    **opts,
7578) -> Delete:
7579    """
7580    Builds a delete statement.
7581
7582    Example:
7583        >>> delete("my_table", where="id > 1").sql()
7584        'DELETE FROM my_table WHERE id > 1'
7585
7586    Args:
7587        where: sql conditional parsed into a WHERE statement
7588        returning: sql conditional parsed into a RETURNING statement
7589        dialect: the dialect used to parse the input expressions.
7590        **opts: other options to use to parse the input expressions.
7591
7592    Returns:
7593        Delete: the syntax tree for the DELETE statement.
7594    """
7595    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7596    if where:
7597        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7598    if returning:
7599        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7600    return delete_expr
7601
7602
7603def insert(
7604    expression: ExpOrStr,
7605    into: ExpOrStr,
7606    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7607    overwrite: t.Optional[bool] = None,
7608    returning: t.Optional[ExpOrStr] = None,
7609    dialect: DialectType = None,
7610    copy: bool = True,
7611    **opts,
7612) -> Insert:
7613    """
7614    Builds an INSERT statement.
7615
7616    Example:
7617        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7618        'INSERT INTO tbl VALUES (1, 2, 3)'
7619
7620    Args:
7621        expression: the sql string or expression of the INSERT statement
7622        into: the tbl to insert data to.
7623        columns: optionally the table's column names.
7624        overwrite: whether to INSERT OVERWRITE or not.
7625        returning: sql conditional parsed into a RETURNING statement
7626        dialect: the dialect used to parse the input expressions.
7627        copy: whether to copy the expression.
7628        **opts: other options to use to parse the input expressions.
7629
7630    Returns:
7631        Insert: the syntax tree for the INSERT statement.
7632    """
7633    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7634    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7635
7636    if columns:
7637        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7638
7639    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7640
7641    if returning:
7642        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7643
7644    return insert
7645
7646
7647def merge(
7648    *when_exprs: ExpOrStr,
7649    into: ExpOrStr,
7650    using: ExpOrStr,
7651    on: ExpOrStr,
7652    returning: t.Optional[ExpOrStr] = None,
7653    dialect: DialectType = None,
7654    copy: bool = True,
7655    **opts,
7656) -> Merge:
7657    """
7658    Builds a MERGE statement.
7659
7660    Example:
7661        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7662        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7663        ...       into="my_table",
7664        ...       using="source_table",
7665        ...       on="my_table.id = source_table.id").sql()
7666        'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
7667
7668    Args:
7669        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7670        into: The target table to merge data into.
7671        using: The source table to merge data from.
7672        on: The join condition for the merge.
7673        returning: The columns to return from the merge.
7674        dialect: The dialect used to parse the input expressions.
7675        copy: Whether to copy the expression.
7676        **opts: Other options to use to parse the input expressions.
7677
7678    Returns:
7679        Merge: The syntax tree for the MERGE statement.
7680    """
7681    expressions: t.List[Expression] = []
7682    for when_expr in when_exprs:
7683        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7684        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7685
7686    merge = Merge(
7687        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7688        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7689        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7690        whens=Whens(expressions=expressions),
7691    )
7692    if returning:
7693        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7694
7695    return merge
7696
7697
7698def condition(
7699    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7700) -> Condition:
7701    """
7702    Initialize a logical condition expression.
7703
7704    Example:
7705        >>> condition("x=1").sql()
7706        'x = 1'
7707
7708        This is helpful for composing larger logical syntax trees:
7709        >>> where = condition("x=1")
7710        >>> where = where.and_("y=1")
7711        >>> Select().from_("tbl").select("*").where(where).sql()
7712        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7713
7714    Args:
7715        *expression: the SQL code string to parse.
7716            If an Expression instance is passed, this is used as-is.
7717        dialect: the dialect used to parse the input expression (in the case that the
7718            input expression is a SQL string).
7719        copy: Whether to copy `expression` (only applies to expressions).
7720        **opts: other options to use to parse the input expressions (again, in the case
7721            that the input expression is a SQL string).
7722
7723    Returns:
7724        The new Condition instance
7725    """
7726    return maybe_parse(
7727        expression,
7728        into=Condition,
7729        dialect=dialect,
7730        copy=copy,
7731        **opts,
7732    )
7733
7734
7735def and_(
7736    *expressions: t.Optional[ExpOrStr],
7737    dialect: DialectType = None,
7738    copy: bool = True,
7739    wrap: bool = True,
7740    **opts,
7741) -> Condition:
7742    """
7743    Combine multiple conditions with an AND logical operator.
7744
7745    Example:
7746        >>> and_("x=1", and_("y=1", "z=1")).sql()
7747        'x = 1 AND (y = 1 AND z = 1)'
7748
7749    Args:
7750        *expressions: the SQL code strings to parse.
7751            If an Expression instance is passed, this is used as-is.
7752        dialect: the dialect used to parse the input expression.
7753        copy: whether to copy `expressions` (only applies to Expressions).
7754        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7755            precedence issues, but can be turned off when the produced AST is too deep and
7756            causes recursion-related issues.
7757        **opts: other options to use to parse the input expressions.
7758
7759    Returns:
7760        The new condition
7761    """
7762    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
7763
7764
7765def or_(
7766    *expressions: t.Optional[ExpOrStr],
7767    dialect: DialectType = None,
7768    copy: bool = True,
7769    wrap: bool = True,
7770    **opts,
7771) -> Condition:
7772    """
7773    Combine multiple conditions with an OR logical operator.
7774
7775    Example:
7776        >>> or_("x=1", or_("y=1", "z=1")).sql()
7777        'x = 1 OR (y = 1 OR z = 1)'
7778
7779    Args:
7780        *expressions: the SQL code strings to parse.
7781            If an Expression instance is passed, this is used as-is.
7782        dialect: the dialect used to parse the input expression.
7783        copy: whether to copy `expressions` (only applies to Expressions).
7784        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7785            precedence issues, but can be turned off when the produced AST is too deep and
7786            causes recursion-related issues.
7787        **opts: other options to use to parse the input expressions.
7788
7789    Returns:
7790        The new condition
7791    """
7792    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
7793
7794
7795def xor(
7796    *expressions: t.Optional[ExpOrStr],
7797    dialect: DialectType = None,
7798    copy: bool = True,
7799    wrap: bool = True,
7800    **opts,
7801) -> Condition:
7802    """
7803    Combine multiple conditions with an XOR logical operator.
7804
7805    Example:
7806        >>> xor("x=1", xor("y=1", "z=1")).sql()
7807        'x = 1 XOR (y = 1 XOR z = 1)'
7808
7809    Args:
7810        *expressions: the SQL code strings to parse.
7811            If an Expression instance is passed, this is used as-is.
7812        dialect: the dialect used to parse the input expression.
7813        copy: whether to copy `expressions` (only applies to Expressions).
7814        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7815            precedence issues, but can be turned off when the produced AST is too deep and
7816            causes recursion-related issues.
7817        **opts: other options to use to parse the input expressions.
7818
7819    Returns:
7820        The new condition
7821    """
7822    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
7823
7824
7825def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7826    """
7827    Wrap a condition with a NOT operator.
7828
7829    Example:
7830        >>> not_("this_suit='black'").sql()
7831        "NOT this_suit = 'black'"
7832
7833    Args:
7834        expression: the SQL code string to parse.
7835            If an Expression instance is passed, this is used as-is.
7836        dialect: the dialect used to parse the input expression.
7837        copy: whether to copy the expression or not.
7838        **opts: other options to use to parse the input expressions.
7839
7840    Returns:
7841        The new condition.
7842    """
7843    this = condition(
7844        expression,
7845        dialect=dialect,
7846        copy=copy,
7847        **opts,
7848    )
7849    return Not(this=_wrap(this, Connector))
7850
7851
7852def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7853    """
7854    Wrap an expression in parentheses.
7855
7856    Example:
7857        >>> paren("5 + 3").sql()
7858        '(5 + 3)'
7859
7860    Args:
7861        expression: the SQL code string to parse.
7862            If an Expression instance is passed, this is used as-is.
7863        copy: whether to copy the expression or not.
7864
7865    Returns:
7866        The wrapped expression.
7867    """
7868    return Paren(this=maybe_parse(expression, copy=copy))
7869
7870
7871SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
7872
7873
7874@t.overload
7875def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
7876
7877
7878@t.overload
7879def to_identifier(
7880    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
7881) -> Identifier: ...
7882
7883
7884def to_identifier(name, quoted=None, copy=True):
7885    """Builds an identifier.
7886
7887    Args:
7888        name: The name to turn into an identifier.
7889        quoted: Whether to force quote the identifier.
7890        copy: Whether to copy name if it's an Identifier.
7891
7892    Returns:
7893        The identifier ast node.
7894    """
7895
7896    if name is None:
7897        return None
7898
7899    if isinstance(name, Identifier):
7900        identifier = maybe_copy(name, copy)
7901    elif isinstance(name, str):
7902        identifier = Identifier(
7903            this=name,
7904            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7905        )
7906    else:
7907        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7908    return identifier
7909
7910
7911def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7912    """
7913    Parses a given string into an identifier.
7914
7915    Args:
7916        name: The name to parse into an identifier.
7917        dialect: The dialect to parse against.
7918
7919    Returns:
7920        The identifier ast node.
7921    """
7922    try:
7923        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7924    except (ParseError, TokenError):
7925        expression = to_identifier(name)
7926
7927    return expression
7928
7929
7930INTERVAL_STRING_RE = re.compile(r"\s*(-?[0-9]+(?:\.[0-9]+)?)\s*([a-zA-Z]+)\s*")
7931
7932
7933def to_interval(interval: str | Literal) -> Interval:
7934    """Builds an interval expression from a string like '1 day' or '5 months'."""
7935    if isinstance(interval, Literal):
7936        if not interval.is_string:
7937            raise ValueError("Invalid interval string.")
7938
7939        interval = interval.this
7940
7941    interval = maybe_parse(f"INTERVAL {interval}")
7942    assert isinstance(interval, Interval)
7943    return interval
7944
7945
7946def to_table(
7947    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7948) -> Table:
7949    """
7950    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7951    If a table is passed in then that table is returned.
7952
7953    Args:
7954        sql_path: a `[catalog].[schema].[table]` string.
7955        dialect: the source dialect according to which the table name will be parsed.
7956        copy: Whether to copy a table if it is passed in.
7957        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7958
7959    Returns:
7960        A table expression.
7961    """
7962    if isinstance(sql_path, Table):
7963        return maybe_copy(sql_path, copy=copy)
7964
7965    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7966
7967    for k, v in kwargs.items():
7968        table.set(k, v)
7969
7970    return table
7971
7972
7973def to_column(
7974    sql_path: str | Column,
7975    quoted: t.Optional[bool] = None,
7976    dialect: DialectType = None,
7977    copy: bool = True,
7978    **kwargs,
7979) -> Column:
7980    """
7981    Create a column from a `[table].[column]` sql path. Table is optional.
7982    If a column is passed in then that column is returned.
7983
7984    Args:
7985        sql_path: a `[table].[column]` string.
7986        quoted: Whether or not to force quote identifiers.
7987        dialect: the source dialect according to which the column name will be parsed.
7988        copy: Whether to copy a column if it is passed in.
7989        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7990
7991    Returns:
7992        A column expression.
7993    """
7994    if isinstance(sql_path, Column):
7995        return maybe_copy(sql_path, copy=copy)
7996
7997    try:
7998        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7999    except ParseError:
8000        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8001
8002    for k, v in kwargs.items():
8003        col.set(k, v)
8004
8005    if quoted:
8006        for i in col.find_all(Identifier):
8007            i.set("quoted", True)
8008
8009    return col
8010
8011
8012def alias_(
8013    expression: ExpOrStr,
8014    alias: t.Optional[str | Identifier],
8015    table: bool | t.Sequence[str | Identifier] = False,
8016    quoted: t.Optional[bool] = None,
8017    dialect: DialectType = None,
8018    copy: bool = True,
8019    **opts,
8020):
8021    """Create an Alias expression.
8022
8023    Example:
8024        >>> alias_('foo', 'bar').sql()
8025        'foo AS bar'
8026
8027        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8028        '(SELECT 1, 2) AS bar(a, b)'
8029
8030    Args:
8031        expression: the SQL code strings to parse.
8032            If an Expression instance is passed, this is used as-is.
8033        alias: the alias name to use. If the name has
8034            special characters it is quoted.
8035        table: Whether to create a table alias, can also be a list of columns.
8036        quoted: whether to quote the alias
8037        dialect: the dialect used to parse the input expression.
8038        copy: Whether to copy the expression.
8039        **opts: other options to use to parse the input expressions.
8040
8041    Returns:
8042        Alias: the aliased expression
8043    """
8044    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8045    alias = to_identifier(alias, quoted=quoted)
8046
8047    if table:
8048        table_alias = TableAlias(this=alias)
8049        exp.set("alias", table_alias)
8050
8051        if not isinstance(table, bool):
8052            for column in table:
8053                table_alias.append("columns", to_identifier(column, quoted=quoted))
8054
8055        return exp
8056
8057    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8058    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8059    # for the complete Window expression.
8060    #
8061    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8062
8063    if "alias" in exp.arg_types and not isinstance(exp, Window):
8064        exp.set("alias", alias)
8065        return exp
8066    return Alias(this=exp, alias=alias)
8067
8068
8069def subquery(
8070    expression: ExpOrStr,
8071    alias: t.Optional[Identifier | str] = None,
8072    dialect: DialectType = None,
8073    **opts,
8074) -> Select:
8075    """
8076    Build a subquery expression that's selected from.
8077
8078    Example:
8079        >>> subquery('select x from tbl', 'bar').select('x').sql()
8080        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8081
8082    Args:
8083        expression: the SQL code strings to parse.
8084            If an Expression instance is passed, this is used as-is.
8085        alias: the alias name to use.
8086        dialect: the dialect used to parse the input expression.
8087        **opts: other options to use to parse the input expressions.
8088
8089    Returns:
8090        A new Select instance with the subquery expression included.
8091    """
8092
8093    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8094    return Select().from_(expression, dialect=dialect, **opts)
8095
8096
8097@t.overload
8098def column(
8099    col: str | Identifier,
8100    table: t.Optional[str | Identifier] = None,
8101    db: t.Optional[str | Identifier] = None,
8102    catalog: t.Optional[str | Identifier] = None,
8103    *,
8104    fields: t.Collection[t.Union[str, Identifier]],
8105    quoted: t.Optional[bool] = None,
8106    copy: bool = True,
8107) -> Dot:
8108    pass
8109
8110
8111@t.overload
8112def column(
8113    col: str | Identifier,
8114    table: t.Optional[str | Identifier] = None,
8115    db: t.Optional[str | Identifier] = None,
8116    catalog: t.Optional[str | Identifier] = None,
8117    *,
8118    fields: Lit[None] = None,
8119    quoted: t.Optional[bool] = None,
8120    copy: bool = True,
8121) -> Column:
8122    pass
8123
8124
8125def column(
8126    col,
8127    table=None,
8128    db=None,
8129    catalog=None,
8130    *,
8131    fields=None,
8132    quoted=None,
8133    copy=True,
8134):
8135    """
8136    Build a Column.
8137
8138    Args:
8139        col: Column name.
8140        table: Table name.
8141        db: Database name.
8142        catalog: Catalog name.
8143        fields: Additional fields using dots.
8144        quoted: Whether to force quotes on the column's identifiers.
8145        copy: Whether to copy identifiers if passed in.
8146
8147    Returns:
8148        The new Column instance.
8149    """
8150    this = Column(
8151        this=to_identifier(col, quoted=quoted, copy=copy),
8152        table=to_identifier(table, quoted=quoted, copy=copy),
8153        db=to_identifier(db, quoted=quoted, copy=copy),
8154        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8155    )
8156
8157    if fields:
8158        this = Dot.build(
8159            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8160        )
8161    return this
8162
8163
8164def cast(
8165    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8166) -> Cast:
8167    """Cast an expression to a data type.
8168
8169    Example:
8170        >>> cast('x + 1', 'int').sql()
8171        'CAST(x + 1 AS INT)'
8172
8173    Args:
8174        expression: The expression to cast.
8175        to: The datatype to cast to.
8176        copy: Whether to copy the supplied expressions.
8177        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8178            - The expression to be cast is already a exp.Cast expression
8179            - The existing cast is to a type that is logically equivalent to new type
8180
8181            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8182            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8183            and instead just return the original expression `CAST(x as DATETIME)`.
8184
8185            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8186            mapping is applied in the target dialect generator.
8187
8188    Returns:
8189        The new Cast instance.
8190    """
8191    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8192    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8193
8194    # dont re-cast if the expression is already a cast to the correct type
8195    if isinstance(expr, Cast):
8196        from sqlglot.dialects.dialect import Dialect
8197
8198        target_dialect = Dialect.get_or_raise(dialect)
8199        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8200
8201        existing_cast_type: DataType.Type = expr.to.this
8202        new_cast_type: DataType.Type = data_type.this
8203        types_are_equivalent = type_mapping.get(
8204            existing_cast_type, existing_cast_type.value
8205        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8206
8207        if expr.is_type(data_type) or types_are_equivalent:
8208            return expr
8209
8210    expr = Cast(this=expr, to=data_type)
8211    expr.type = data_type
8212
8213    return expr
8214
8215
8216def table_(
8217    table: Identifier | str,
8218    db: t.Optional[Identifier | str] = None,
8219    catalog: t.Optional[Identifier | str] = None,
8220    quoted: t.Optional[bool] = None,
8221    alias: t.Optional[Identifier | str] = None,
8222) -> Table:
8223    """Build a Table.
8224
8225    Args:
8226        table: Table name.
8227        db: Database name.
8228        catalog: Catalog name.
8229        quote: Whether to force quotes on the table's identifiers.
8230        alias: Table's alias.
8231
8232    Returns:
8233        The new Table instance.
8234    """
8235    return Table(
8236        this=to_identifier(table, quoted=quoted) if table else None,
8237        db=to_identifier(db, quoted=quoted) if db else None,
8238        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8239        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8240    )
8241
8242
8243def values(
8244    values: t.Iterable[t.Tuple[t.Any, ...]],
8245    alias: t.Optional[str] = None,
8246    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8247) -> Values:
8248    """Build VALUES statement.
8249
8250    Example:
8251        >>> values([(1, '2')]).sql()
8252        "VALUES (1, '2')"
8253
8254    Args:
8255        values: values statements that will be converted to SQL
8256        alias: optional alias
8257        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8258         If either are provided then an alias is also required.
8259
8260    Returns:
8261        Values: the Values expression object
8262    """
8263    if columns and not alias:
8264        raise ValueError("Alias is required when providing columns")
8265
8266    return Values(
8267        expressions=[convert(tup) for tup in values],
8268        alias=(
8269            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8270            if columns
8271            else (TableAlias(this=to_identifier(alias)) if alias else None)
8272        ),
8273    )
8274
8275
8276def var(name: t.Optional[ExpOrStr]) -> Var:
8277    """Build a SQL variable.
8278
8279    Example:
8280        >>> repr(var('x'))
8281        'Var(this=x)'
8282
8283        >>> repr(var(column('x', table='y')))
8284        'Var(this=x)'
8285
8286    Args:
8287        name: The name of the var or an expression who's name will become the var.
8288
8289    Returns:
8290        The new variable node.
8291    """
8292    if not name:
8293        raise ValueError("Cannot convert empty name into var.")
8294
8295    if isinstance(name, Expression):
8296        name = name.name
8297    return Var(this=name)
8298
8299
8300def rename_table(
8301    old_name: str | Table,
8302    new_name: str | Table,
8303    dialect: DialectType = None,
8304) -> Alter:
8305    """Build ALTER TABLE... RENAME... expression
8306
8307    Args:
8308        old_name: The old name of the table
8309        new_name: The new name of the table
8310        dialect: The dialect to parse the table.
8311
8312    Returns:
8313        Alter table expression
8314    """
8315    old_table = to_table(old_name, dialect=dialect)
8316    new_table = to_table(new_name, dialect=dialect)
8317    return Alter(
8318        this=old_table,
8319        kind="TABLE",
8320        actions=[
8321            AlterRename(this=new_table),
8322        ],
8323    )
8324
8325
8326def rename_column(
8327    table_name: str | Table,
8328    old_column_name: str | Column,
8329    new_column_name: str | Column,
8330    exists: t.Optional[bool] = None,
8331    dialect: DialectType = None,
8332) -> Alter:
8333    """Build ALTER TABLE... RENAME COLUMN... expression
8334
8335    Args:
8336        table_name: Name of the table
8337        old_column: The old name of the column
8338        new_column: The new name of the column
8339        exists: Whether to add the `IF EXISTS` clause
8340        dialect: The dialect to parse the table/column.
8341
8342    Returns:
8343        Alter table expression
8344    """
8345    table = to_table(table_name, dialect=dialect)
8346    old_column = to_column(old_column_name, dialect=dialect)
8347    new_column = to_column(new_column_name, dialect=dialect)
8348    return Alter(
8349        this=table,
8350        kind="TABLE",
8351        actions=[
8352            RenameColumn(this=old_column, to=new_column, exists=exists),
8353        ],
8354    )
8355
8356
8357def convert(value: t.Any, copy: bool = False) -> Expression:
8358    """Convert a python value into an expression object.
8359
8360    Raises an error if a conversion is not possible.
8361
8362    Args:
8363        value: A python object.
8364        copy: Whether to copy `value` (only applies to Expressions and collections).
8365
8366    Returns:
8367        The equivalent expression object.
8368    """
8369    if isinstance(value, Expression):
8370        return maybe_copy(value, copy)
8371    if isinstance(value, str):
8372        return Literal.string(value)
8373    if isinstance(value, bool):
8374        return Boolean(this=value)
8375    if value is None or (isinstance(value, float) and math.isnan(value)):
8376        return null()
8377    if isinstance(value, numbers.Number):
8378        return Literal.number(value)
8379    if isinstance(value, bytes):
8380        return HexString(this=value.hex())
8381    if isinstance(value, datetime.datetime):
8382        datetime_literal = Literal.string(value.isoformat(sep=" "))
8383
8384        tz = None
8385        if value.tzinfo:
8386            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8387            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8388            tz = Literal.string(str(value.tzinfo))
8389
8390        return TimeStrToTime(this=datetime_literal, zone=tz)
8391    if isinstance(value, datetime.date):
8392        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8393        return DateStrToDate(this=date_literal)
8394    if isinstance(value, tuple):
8395        if hasattr(value, "_fields"):
8396            return Struct(
8397                expressions=[
8398                    PropertyEQ(
8399                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8400                    )
8401                    for k in value._fields
8402                ]
8403            )
8404        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8405    if isinstance(value, list):
8406        return Array(expressions=[convert(v, copy=copy) for v in value])
8407    if isinstance(value, dict):
8408        return Map(
8409            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8410            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8411        )
8412    if hasattr(value, "__dict__"):
8413        return Struct(
8414            expressions=[
8415                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8416                for k, v in value.__dict__.items()
8417            ]
8418        )
8419    raise ValueError(f"Cannot convert {value}")
8420
8421
8422def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8423    """
8424    Replace children of an expression with the result of a lambda fun(child) -> exp.
8425    """
8426    for k, v in tuple(expression.args.items()):
8427        is_list_arg = type(v) is list
8428
8429        child_nodes = v if is_list_arg else [v]
8430        new_child_nodes = []
8431
8432        for cn in child_nodes:
8433            if isinstance(cn, Expression):
8434                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8435                    new_child_nodes.append(child_node)
8436            else:
8437                new_child_nodes.append(cn)
8438
8439        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
8440
8441
8442def replace_tree(
8443    expression: Expression,
8444    fun: t.Callable,
8445    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8446) -> Expression:
8447    """
8448    Replace an entire tree with the result of function calls on each node.
8449
8450    This will be traversed in reverse dfs, so leaves first.
8451    If new nodes are created as a result of function calls, they will also be traversed.
8452    """
8453    stack = list(expression.dfs(prune=prune))
8454
8455    while stack:
8456        node = stack.pop()
8457        new_node = fun(node)
8458
8459        if new_node is not node:
8460            node.replace(new_node)
8461
8462            if isinstance(new_node, Expression):
8463                stack.append(new_node)
8464
8465    return new_node
8466
8467
8468def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8469    """
8470    Return all table names referenced through columns in an expression.
8471
8472    Example:
8473        >>> import sqlglot
8474        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8475        ['a', 'c']
8476
8477    Args:
8478        expression: expression to find table names.
8479        exclude: a table name to exclude
8480
8481    Returns:
8482        A list of unique names.
8483    """
8484    return {
8485        table
8486        for table in (column.table for column in expression.find_all(Column))
8487        if table and table != exclude
8488    }
8489
8490
8491def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8492    """Get the full name of a table as a string.
8493
8494    Args:
8495        table: Table expression node or string.
8496        dialect: The dialect to generate the table name for.
8497        identify: Determines when an identifier should be quoted. Possible values are:
8498            False (default): Never quote, except in cases where it's mandatory by the dialect.
8499            True: Always quote.
8500
8501    Examples:
8502        >>> from sqlglot import exp, parse_one
8503        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8504        'a.b.c'
8505
8506    Returns:
8507        The table name.
8508    """
8509
8510    table = maybe_parse(table, into=Table, dialect=dialect)
8511
8512    if not table:
8513        raise ValueError(f"Cannot parse {table}")
8514
8515    return ".".join(
8516        (
8517            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8518            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8519            else part.name
8520        )
8521        for part in table.parts
8522    )
8523
8524
8525def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8526    """Returns a case normalized table name without quotes.
8527
8528    Args:
8529        table: the table to normalize
8530        dialect: the dialect to use for normalization rules
8531        copy: whether to copy the expression.
8532
8533    Examples:
8534        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8535        'A-B.c'
8536    """
8537    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8538
8539    return ".".join(
8540        p.name
8541        for p in normalize_identifiers(
8542            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8543        ).parts
8544    )
8545
8546
8547def replace_tables(
8548    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8549) -> E:
8550    """Replace all tables in expression according to the mapping.
8551
8552    Args:
8553        expression: expression node to be transformed and replaced.
8554        mapping: mapping of table names.
8555        dialect: the dialect of the mapping table
8556        copy: whether to copy the expression.
8557
8558    Examples:
8559        >>> from sqlglot import exp, parse_one
8560        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8561        'SELECT * FROM c /* a.b */'
8562
8563    Returns:
8564        The mapped expression.
8565    """
8566
8567    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8568
8569    def _replace_tables(node: Expression) -> Expression:
8570        if isinstance(node, Table) and node.meta.get("replace") is not False:
8571            original = normalize_table_name(node, dialect=dialect)
8572            new_name = mapping.get(original)
8573
8574            if new_name:
8575                table = to_table(
8576                    new_name,
8577                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8578                    dialect=dialect,
8579                )
8580                table.add_comments([original])
8581                return table
8582        return node
8583
8584    return expression.transform(_replace_tables, copy=copy)  # type: ignore
8585
8586
8587def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8588    """Replace placeholders in an expression.
8589
8590    Args:
8591        expression: expression node to be transformed and replaced.
8592        args: positional names that will substitute unnamed placeholders in the given order.
8593        kwargs: keyword arguments that will substitute named placeholders.
8594
8595    Examples:
8596        >>> from sqlglot import exp, parse_one
8597        >>> replace_placeholders(
8598        ...     parse_one("select * from :tbl where ? = ?"),
8599        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8600        ... ).sql()
8601        "SELECT * FROM foo WHERE str_col = 'b'"
8602
8603    Returns:
8604        The mapped expression.
8605    """
8606
8607    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8608        if isinstance(node, Placeholder):
8609            if node.this:
8610                new_name = kwargs.get(node.this)
8611                if new_name is not None:
8612                    return convert(new_name)
8613            else:
8614                try:
8615                    return convert(next(args))
8616                except StopIteration:
8617                    pass
8618        return node
8619
8620    return expression.transform(_replace_placeholders, iter(args), **kwargs)
8621
8622
8623def expand(
8624    expression: Expression,
8625    sources: t.Dict[str, Query | t.Callable[[], Query]],
8626    dialect: DialectType = None,
8627    copy: bool = True,
8628) -> Expression:
8629    """Transforms an expression by expanding all referenced sources into subqueries.
8630
8631    Examples:
8632        >>> from sqlglot import parse_one
8633        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8634        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8635
8636        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8637        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8638
8639    Args:
8640        expression: The expression to expand.
8641        sources: A dict of name to query or a callable that provides a query on demand.
8642        dialect: The dialect of the sources dict or the callable.
8643        copy: Whether to copy the expression during transformation. Defaults to True.
8644
8645    Returns:
8646        The transformed expression.
8647    """
8648    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8649
8650    def _expand(node: Expression):
8651        if isinstance(node, Table):
8652            name = normalize_table_name(node, dialect=dialect)
8653            source = normalized_sources.get(name)
8654
8655            if source:
8656                # Create a subquery with the same alias (or table name if no alias)
8657                parsed_source = source() if callable(source) else source
8658                subquery = parsed_source.subquery(node.alias or name)
8659                subquery.comments = [f"source: {name}"]
8660
8661                # Continue expanding within the subquery
8662                return subquery.transform(_expand, copy=False)
8663
8664        return node
8665
8666    return expression.transform(_expand, copy=copy)
8667
8668
8669def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8670    """
8671    Returns a Func expression.
8672
8673    Examples:
8674        >>> func("abs", 5).sql()
8675        'ABS(5)'
8676
8677        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8678        'CAST(5 AS DOUBLE)'
8679
8680    Args:
8681        name: the name of the function to build.
8682        args: the args used to instantiate the function of interest.
8683        copy: whether to copy the argument expressions.
8684        dialect: the source dialect.
8685        kwargs: the kwargs used to instantiate the function of interest.
8686
8687    Note:
8688        The arguments `args` and `kwargs` are mutually exclusive.
8689
8690    Returns:
8691        An instance of the function of interest, or an anonymous function, if `name` doesn't
8692        correspond to an existing `sqlglot.expressions.Func` class.
8693    """
8694    if args and kwargs:
8695        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8696
8697    from sqlglot.dialects.dialect import Dialect
8698
8699    dialect = Dialect.get_or_raise(dialect)
8700
8701    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8702    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8703
8704    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8705    if constructor:
8706        if converted:
8707            if "dialect" in constructor.__code__.co_varnames:
8708                function = constructor(converted, dialect=dialect)
8709            else:
8710                function = constructor(converted)
8711        elif constructor.__name__ == "from_arg_list":
8712            function = constructor.__self__(**kwargs)  # type: ignore
8713        else:
8714            constructor = FUNCTION_BY_NAME.get(name.upper())
8715            if constructor:
8716                function = constructor(**kwargs)
8717            else:
8718                raise ValueError(
8719                    f"Unable to convert '{name}' into a Func. Either manually construct "
8720                    "the Func expression of interest or parse the function call."
8721                )
8722    else:
8723        kwargs = kwargs or {"expressions": converted}
8724        function = Anonymous(this=name, **kwargs)
8725
8726    for error_message in function.error_messages(converted):
8727        raise ValueError(error_message)
8728
8729    return function
8730
8731
8732def case(
8733    expression: t.Optional[ExpOrStr] = None,
8734    **opts,
8735) -> Case:
8736    """
8737    Initialize a CASE statement.
8738
8739    Example:
8740        case().when("a = 1", "foo").else_("bar")
8741
8742    Args:
8743        expression: Optionally, the input expression (not all dialects support this)
8744        **opts: Extra keyword arguments for parsing `expression`
8745    """
8746    if expression is not None:
8747        this = maybe_parse(expression, **opts)
8748    else:
8749        this = None
8750    return Case(this=this, ifs=[])
8751
8752
8753def array(
8754    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8755) -> Array:
8756    """
8757    Returns an array.
8758
8759    Examples:
8760        >>> array(1, 'x').sql()
8761        'ARRAY(1, x)'
8762
8763    Args:
8764        expressions: the expressions to add to the array.
8765        copy: whether to copy the argument expressions.
8766        dialect: the source dialect.
8767        kwargs: the kwargs used to instantiate the function of interest.
8768
8769    Returns:
8770        An array expression.
8771    """
8772    return Array(
8773        expressions=[
8774            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8775            for expression in expressions
8776        ]
8777    )
8778
8779
8780def tuple_(
8781    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8782) -> Tuple:
8783    """
8784    Returns an tuple.
8785
8786    Examples:
8787        >>> tuple_(1, 'x').sql()
8788        '(1, x)'
8789
8790    Args:
8791        expressions: the expressions to add to the tuple.
8792        copy: whether to copy the argument expressions.
8793        dialect: the source dialect.
8794        kwargs: the kwargs used to instantiate the function of interest.
8795
8796    Returns:
8797        A tuple expression.
8798    """
8799    return Tuple(
8800        expressions=[
8801            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8802            for expression in expressions
8803        ]
8804    )
8805
8806
8807def true() -> Boolean:
8808    """
8809    Returns a true Boolean expression.
8810    """
8811    return Boolean(this=True)
8812
8813
8814def false() -> Boolean:
8815    """
8816    Returns a false Boolean expression.
8817    """
8818    return Boolean(this=False)
8819
8820
8821def null() -> Null:
8822    """
8823    Returns a Null expression.
8824    """
8825    return Null()
8826
8827
8828NONNULL_CONSTANTS = (
8829    Literal,
8830    Boolean,
8831)
8832
8833CONSTANTS = (
8834    Literal,
8835    Boolean,
8836    Null,
8837)
SQLGLOT_META = 'sqlglot.meta'
SQLGLOT_ANONYMOUS = 'sqlglot.anonymous'
TABLE_PARTS = ('this', 'db', 'catalog')
COLUMN_PARTS = ('this', 'table', 'db', 'catalog')
POSITION_META_KEYS = ('line', 'col', 'start', 'end')
class Expression:
  71class Expression(metaclass=_Expression):
  72    """
  73    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
  74    context, such as its child expressions, their names (arg keys), and whether a given child expression
  75    is optional or not.
  76
  77    Attributes:
  78        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
  79            and representing expressions as strings.
  80        arg_types: determines the arguments (child nodes) supported by an expression. It maps
  81            arg keys to booleans that indicate whether the corresponding args are optional.
  82        parent: a reference to the parent expression (or None, in case of root expressions).
  83        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
  84            uses to refer to it.
  85        index: the index of an expression if it is inside of a list argument in its parent.
  86        comments: a list of comments that are associated with a given expression. This is used in
  87            order to preserve comments when transpiling SQL code.
  88        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
  89            optimizer, in order to enable some transformations that require type information.
  90        meta: a dictionary that can be used to store useful metadata for a given expression.
  91
  92    Example:
  93        >>> class Foo(Expression):
  94        ...     arg_types = {"this": True, "expression": False}
  95
  96        The above definition informs us that Foo is an Expression that requires an argument called
  97        "this" and may also optionally receive an argument called "expression".
  98
  99    Args:
 100        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
 101    """
 102
 103    key = "expression"
 104    arg_types = {"this": True}
 105    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
 106
 107    def __init__(self, **args: t.Any):
 108        self.args: t.Dict[str, t.Any] = args
 109        self.parent: t.Optional[Expression] = None
 110        self.arg_key: t.Optional[str] = None
 111        self.index: t.Optional[int] = None
 112        self.comments: t.Optional[t.List[str]] = None
 113        self._type: t.Optional[DataType] = None
 114        self._meta: t.Optional[t.Dict[str, t.Any]] = None
 115        self._hash: t.Optional[int] = None
 116
 117        for arg_key, value in self.args.items():
 118            self._set_parent(arg_key, value)
 119
 120    def __eq__(self, other) -> bool:
 121        return type(self) is type(other) and hash(self) == hash(other)
 122
 123    @property
 124    def hashable_args(self) -> t.Any:
 125        return frozenset(
 126            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
 127            for k, v in self.args.items()
 128            if not (v is None or v is False or (type(v) is list and not v))
 129        )
 130
 131    def __hash__(self) -> int:
 132        if self._hash is not None:
 133            return self._hash
 134
 135        return hash((self.__class__, self.hashable_args))
 136
 137    @property
 138    def this(self) -> t.Any:
 139        """
 140        Retrieves the argument with key "this".
 141        """
 142        return self.args.get("this")
 143
 144    @property
 145    def expression(self) -> t.Any:
 146        """
 147        Retrieves the argument with key "expression".
 148        """
 149        return self.args.get("expression")
 150
 151    @property
 152    def expressions(self) -> t.List[t.Any]:
 153        """
 154        Retrieves the argument with key "expressions".
 155        """
 156        return self.args.get("expressions") or []
 157
 158    def text(self, key) -> str:
 159        """
 160        Returns a textual representation of the argument corresponding to "key". This can only be used
 161        for args that are strings or leaf Expression instances, such as identifiers and literals.
 162        """
 163        field = self.args.get(key)
 164        if isinstance(field, str):
 165            return field
 166        if isinstance(field, (Identifier, Literal, Var)):
 167            return field.this
 168        if isinstance(field, (Star, Null)):
 169            return field.name
 170        return ""
 171
 172    @property
 173    def is_string(self) -> bool:
 174        """
 175        Checks whether a Literal expression is a string.
 176        """
 177        return isinstance(self, Literal) and self.args["is_string"]
 178
 179    @property
 180    def is_number(self) -> bool:
 181        """
 182        Checks whether a Literal expression is a number.
 183        """
 184        return (isinstance(self, Literal) and not self.args["is_string"]) or (
 185            isinstance(self, Neg) and self.this.is_number
 186        )
 187
 188    def to_py(self) -> t.Any:
 189        """
 190        Returns a Python object equivalent of the SQL node.
 191        """
 192        raise ValueError(f"{self} cannot be converted to a Python object.")
 193
 194    @property
 195    def is_int(self) -> bool:
 196        """
 197        Checks whether an expression is an integer.
 198        """
 199        return self.is_number and isinstance(self.to_py(), int)
 200
 201    @property
 202    def is_star(self) -> bool:
 203        """Checks whether an expression is a star."""
 204        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))
 205
 206    @property
 207    def alias(self) -> str:
 208        """
 209        Returns the alias of the expression, or an empty string if it's not aliased.
 210        """
 211        if isinstance(self.args.get("alias"), TableAlias):
 212            return self.args["alias"].name
 213        return self.text("alias")
 214
 215    @property
 216    def alias_column_names(self) -> t.List[str]:
 217        table_alias = self.args.get("alias")
 218        if not table_alias:
 219            return []
 220        return [c.name for c in table_alias.args.get("columns") or []]
 221
 222    @property
 223    def name(self) -> str:
 224        return self.text("this")
 225
 226    @property
 227    def alias_or_name(self) -> str:
 228        return self.alias or self.name
 229
 230    @property
 231    def output_name(self) -> str:
 232        """
 233        Name of the output column if this expression is a selection.
 234
 235        If the Expression has no output name, an empty string is returned.
 236
 237        Example:
 238            >>> from sqlglot import parse_one
 239            >>> parse_one("SELECT a").expressions[0].output_name
 240            'a'
 241            >>> parse_one("SELECT b AS c").expressions[0].output_name
 242            'c'
 243            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
 244            ''
 245        """
 246        return ""
 247
 248    @property
 249    def type(self) -> t.Optional[DataType]:
 250        return self._type
 251
 252    @type.setter
 253    def type(self, dtype: t.Optional[DataType | DataType.Type | str]) -> None:
 254        if dtype and not isinstance(dtype, DataType):
 255            dtype = DataType.build(dtype)
 256        self._type = dtype  # type: ignore
 257
 258    def is_type(self, *dtypes) -> bool:
 259        return self.type is not None and self.type.is_type(*dtypes)
 260
 261    def is_leaf(self) -> bool:
 262        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
 263
 264    @property
 265    def meta(self) -> t.Dict[str, t.Any]:
 266        if self._meta is None:
 267            self._meta = {}
 268        return self._meta
 269
 270    def __deepcopy__(self, memo):
 271        root = self.__class__()
 272        stack = [(self, root)]
 273
 274        while stack:
 275            node, copy = stack.pop()
 276
 277            if node.comments is not None:
 278                copy.comments = deepcopy(node.comments)
 279            if node._type is not None:
 280                copy._type = deepcopy(node._type)
 281            if node._meta is not None:
 282                copy._meta = deepcopy(node._meta)
 283            if node._hash is not None:
 284                copy._hash = node._hash
 285
 286            for k, vs in node.args.items():
 287                if hasattr(vs, "parent"):
 288                    stack.append((vs, vs.__class__()))
 289                    copy.set(k, stack[-1][-1])
 290                elif type(vs) is list:
 291                    copy.args[k] = []
 292
 293                    for v in vs:
 294                        if hasattr(v, "parent"):
 295                            stack.append((v, v.__class__()))
 296                            copy.append(k, stack[-1][-1])
 297                        else:
 298                            copy.append(k, v)
 299                else:
 300                    copy.args[k] = vs
 301
 302        return root
 303
 304    def copy(self) -> Self:
 305        """
 306        Returns a deep copy of the expression.
 307        """
 308        return deepcopy(self)
 309
 310    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
 311        if self.comments is None:
 312            self.comments = []
 313
 314        if comments:
 315            for comment in comments:
 316                _, *meta = comment.split(SQLGLOT_META)
 317                if meta:
 318                    for kv in "".join(meta).split(","):
 319                        k, *v = kv.split("=")
 320                        value = v[0].strip() if v else True
 321                        self.meta[k.strip()] = to_bool(value)
 322
 323                if not prepend:
 324                    self.comments.append(comment)
 325
 326            if prepend:
 327                self.comments = comments + self.comments
 328
 329    def pop_comments(self) -> t.List[str]:
 330        comments = self.comments or []
 331        self.comments = None
 332        return comments
 333
 334    def append(self, arg_key: str, value: t.Any) -> None:
 335        """
 336        Appends value to arg_key if it's a list or sets it as a new list.
 337
 338        Args:
 339            arg_key (str): name of the list expression arg
 340            value (Any): value to append to the list
 341        """
 342        if type(self.args.get(arg_key)) is not list:
 343            self.args[arg_key] = []
 344        self._set_parent(arg_key, value)
 345        values = self.args[arg_key]
 346        if hasattr(value, "parent"):
 347            value.index = len(values)
 348        values.append(value)
 349
 350    def set(
 351        self,
 352        arg_key: str,
 353        value: t.Any,
 354        index: t.Optional[int] = None,
 355        overwrite: bool = True,
 356    ) -> None:
 357        """
 358        Sets arg_key to value.
 359
 360        Args:
 361            arg_key: name of the expression arg.
 362            value: value to set the arg to.
 363            index: if the arg is a list, this specifies what position to add the value in it.
 364            overwrite: assuming an index is given, this determines whether to overwrite the
 365                list entry instead of only inserting a new value (i.e., like list.insert).
 366        """
 367        if index is not None:
 368            expressions = self.args.get(arg_key) or []
 369
 370            if seq_get(expressions, index) is None:
 371                return
 372            if value is None:
 373                expressions.pop(index)
 374                for v in expressions[index:]:
 375                    v.index = v.index - 1
 376                return
 377
 378            if isinstance(value, list):
 379                expressions.pop(index)
 380                expressions[index:index] = value
 381            elif overwrite:
 382                expressions[index] = value
 383            else:
 384                expressions.insert(index, value)
 385
 386            value = expressions
 387        elif value is None:
 388            self.args.pop(arg_key, None)
 389            return
 390
 391        self.args[arg_key] = value
 392        self._set_parent(arg_key, value, index)
 393
 394    def _set_parent(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
 395        if hasattr(value, "parent"):
 396            value.parent = self
 397            value.arg_key = arg_key
 398            value.index = index
 399        elif type(value) is list:
 400            for index, v in enumerate(value):
 401                if hasattr(v, "parent"):
 402                    v.parent = self
 403                    v.arg_key = arg_key
 404                    v.index = index
 405
 406    @property
 407    def depth(self) -> int:
 408        """
 409        Returns the depth of this tree.
 410        """
 411        if self.parent:
 412            return self.parent.depth + 1
 413        return 0
 414
 415    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
 416        """Yields the key and expression for all arguments, exploding list args."""
 417        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
 418            if type(vs) is list:
 419                for v in reversed(vs) if reverse else vs:  # type: ignore
 420                    if hasattr(v, "parent"):
 421                        yield v
 422            else:
 423                if hasattr(vs, "parent"):
 424                    yield vs
 425
 426    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
 427        """
 428        Returns the first node in this tree which matches at least one of
 429        the specified types.
 430
 431        Args:
 432            expression_types: the expression type(s) to match.
 433            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 434
 435        Returns:
 436            The node which matches the criteria or None if no such node was found.
 437        """
 438        return next(self.find_all(*expression_types, bfs=bfs), None)
 439
 440    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
 441        """
 442        Returns a generator object which visits all nodes in this tree and only
 443        yields those that match at least one of the specified expression types.
 444
 445        Args:
 446            expression_types: the expression type(s) to match.
 447            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
 448
 449        Returns:
 450            The generator object.
 451        """
 452        for expression in self.walk(bfs=bfs):
 453            if isinstance(expression, expression_types):
 454                yield expression
 455
 456    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
 457        """
 458        Returns a nearest parent matching expression_types.
 459
 460        Args:
 461            expression_types: the expression type(s) to match.
 462
 463        Returns:
 464            The parent node.
 465        """
 466        ancestor = self.parent
 467        while ancestor and not isinstance(ancestor, expression_types):
 468            ancestor = ancestor.parent
 469        return ancestor  # type: ignore
 470
 471    @property
 472    def parent_select(self) -> t.Optional[Select]:
 473        """
 474        Returns the parent select statement.
 475        """
 476        return self.find_ancestor(Select)
 477
 478    @property
 479    def same_parent(self) -> bool:
 480        """Returns if the parent is the same class as itself."""
 481        return type(self.parent) is self.__class__
 482
 483    def root(self) -> Expression:
 484        """
 485        Returns the root expression of this tree.
 486        """
 487        expression = self
 488        while expression.parent:
 489            expression = expression.parent
 490        return expression
 491
 492    def walk(
 493        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
 494    ) -> t.Iterator[Expression]:
 495        """
 496        Returns a generator object which visits all nodes in this tree.
 497
 498        Args:
 499            bfs: if set to True the BFS traversal order will be applied,
 500                otherwise the DFS traversal will be used instead.
 501            prune: callable that returns True if the generator should stop traversing
 502                this branch of the tree.
 503
 504        Returns:
 505            the generator object.
 506        """
 507        if bfs:
 508            yield from self.bfs(prune=prune)
 509        else:
 510            yield from self.dfs(prune=prune)
 511
 512    def dfs(
 513        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 514    ) -> t.Iterator[Expression]:
 515        """
 516        Returns a generator object which visits all nodes in this tree in
 517        the DFS (Depth-first) order.
 518
 519        Returns:
 520            The generator object.
 521        """
 522        stack = [self]
 523
 524        while stack:
 525            node = stack.pop()
 526
 527            yield node
 528
 529            if prune and prune(node):
 530                continue
 531
 532            for v in node.iter_expressions(reverse=True):
 533                stack.append(v)
 534
 535    def bfs(
 536        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
 537    ) -> t.Iterator[Expression]:
 538        """
 539        Returns a generator object which visits all nodes in this tree in
 540        the BFS (Breadth-first) order.
 541
 542        Returns:
 543            The generator object.
 544        """
 545        queue = deque([self])
 546
 547        while queue:
 548            node = queue.popleft()
 549
 550            yield node
 551
 552            if prune and prune(node):
 553                continue
 554
 555            for v in node.iter_expressions():
 556                queue.append(v)
 557
 558    def unnest(self):
 559        """
 560        Returns the first non parenthesis child or self.
 561        """
 562        expression = self
 563        while type(expression) is Paren:
 564            expression = expression.this
 565        return expression
 566
 567    def unalias(self):
 568        """
 569        Returns the inner expression if this is an Alias.
 570        """
 571        if isinstance(self, Alias):
 572            return self.this
 573        return self
 574
 575    def unnest_operands(self):
 576        """
 577        Returns unnested operands as a tuple.
 578        """
 579        return tuple(arg.unnest() for arg in self.iter_expressions())
 580
 581    def flatten(self, unnest=True):
 582        """
 583        Returns a generator which yields child nodes whose parents are the same class.
 584
 585        A AND B AND C -> [A, B, C]
 586        """
 587        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
 588            if type(node) is not self.__class__:
 589                yield node.unnest() if unnest and not isinstance(node, Subquery) else node
 590
 591    def __str__(self) -> str:
 592        return self.sql()
 593
 594    def __repr__(self) -> str:
 595        return _to_s(self)
 596
 597    def to_s(self) -> str:
 598        """
 599        Same as __repr__, but includes additional information which can be useful
 600        for debugging, like empty or missing args and the AST nodes' object IDs.
 601        """
 602        return _to_s(self, verbose=True)
 603
 604    def sql(self, dialect: DialectType = None, **opts) -> str:
 605        """
 606        Returns SQL string representation of this tree.
 607
 608        Args:
 609            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
 610            opts: other `sqlglot.generator.Generator` options.
 611
 612        Returns:
 613            The SQL string.
 614        """
 615        from sqlglot.dialects import Dialect
 616
 617        return Dialect.get_or_raise(dialect).generate(self, **opts)
 618
 619    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
 620        """
 621        Visits all tree nodes (excluding already transformed ones)
 622        and applies the given transformation function to each node.
 623
 624        Args:
 625            fun: a function which takes a node as an argument and returns a
 626                new transformed node or the same node without modifications. If the function
 627                returns None, then the corresponding node will be removed from the syntax tree.
 628            copy: if set to True a new tree instance is constructed, otherwise the tree is
 629                modified in place.
 630
 631        Returns:
 632            The transformed tree.
 633        """
 634        root = None
 635        new_node = None
 636
 637        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
 638            parent, arg_key, index = node.parent, node.arg_key, node.index
 639            new_node = fun(node, *args, **kwargs)
 640
 641            if not root:
 642                root = new_node
 643            elif parent and arg_key and new_node is not node:
 644                parent.set(arg_key, new_node, index)
 645
 646        assert root
 647        return root.assert_is(Expression)
 648
 649    @t.overload
 650    def replace(self, expression: E) -> E: ...
 651
 652    @t.overload
 653    def replace(self, expression: None) -> None: ...
 654
 655    def replace(self, expression):
 656        """
 657        Swap out this expression with a new expression.
 658
 659        For example::
 660
 661            >>> tree = Select().select("x").from_("tbl")
 662            >>> tree.find(Column).replace(column("y"))
 663            Column(
 664              this=Identifier(this=y, quoted=False))
 665            >>> tree.sql()
 666            'SELECT y FROM tbl'
 667
 668        Args:
 669            expression: new node
 670
 671        Returns:
 672            The new expression or expressions.
 673        """
 674        parent = self.parent
 675
 676        if not parent or parent is expression:
 677            return expression
 678
 679        key = self.arg_key
 680        value = parent.args.get(key)
 681
 682        if type(expression) is list and isinstance(value, Expression):
 683            # We are trying to replace an Expression with a list, so it's assumed that
 684            # the intention was to really replace the parent of this expression.
 685            value.parent.replace(expression)
 686        else:
 687            parent.set(key, expression, self.index)
 688
 689        if expression is not self:
 690            self.parent = None
 691            self.arg_key = None
 692            self.index = None
 693
 694        return expression
 695
 696    def pop(self: E) -> E:
 697        """
 698        Remove this expression from its AST.
 699
 700        Returns:
 701            The popped expression.
 702        """
 703        self.replace(None)
 704        return self
 705
 706    def assert_is(self, type_: t.Type[E]) -> E:
 707        """
 708        Assert that this `Expression` is an instance of `type_`.
 709
 710        If it is NOT an instance of `type_`, this raises an assertion error.
 711        Otherwise, this returns this expression.
 712
 713        Examples:
 714            This is useful for type security in chained expressions:
 715
 716            >>> import sqlglot
 717            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
 718            'SELECT x, z FROM y'
 719        """
 720        if not isinstance(self, type_):
 721            raise AssertionError(f"{self} is not {type_}.")
 722        return self
 723
 724    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
 725        """
 726        Checks if this expression is valid (e.g. all mandatory args are set).
 727
 728        Args:
 729            args: a sequence of values that were used to instantiate a Func expression. This is used
 730                to check that the provided arguments don't exceed the function argument limit.
 731
 732        Returns:
 733            A list of error messages for all possible errors that were found.
 734        """
 735        errors: t.List[str] = []
 736
 737        for k in self.args:
 738            if k not in self.arg_types:
 739                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
 740        for k, mandatory in self.arg_types.items():
 741            v = self.args.get(k)
 742            if mandatory and (v is None or (isinstance(v, list) and not v)):
 743                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
 744
 745        if (
 746            args
 747            and isinstance(self, Func)
 748            and len(args) > len(self.arg_types)
 749            and not self.is_var_len_args
 750        ):
 751            errors.append(
 752                f"The number of provided arguments ({len(args)}) is greater than "
 753                f"the maximum number of supported arguments ({len(self.arg_types)})"
 754            )
 755
 756        return errors
 757
 758    def dump(self):
 759        """
 760        Dump this Expression to a JSON-serializable dict.
 761        """
 762        from sqlglot.serde import dump
 763
 764        return dump(self)
 765
 766    @classmethod
 767    def load(cls, obj):
 768        """
 769        Load a dict (as returned by `Expression.dump`) into an Expression instance.
 770        """
 771        from sqlglot.serde import load
 772
 773        return load(obj)
 774
 775    def and_(
 776        self,
 777        *expressions: t.Optional[ExpOrStr],
 778        dialect: DialectType = None,
 779        copy: bool = True,
 780        wrap: bool = True,
 781        **opts,
 782    ) -> Condition:
 783        """
 784        AND this condition with one or multiple expressions.
 785
 786        Example:
 787            >>> condition("x=1").and_("y=1").sql()
 788            'x = 1 AND y = 1'
 789
 790        Args:
 791            *expressions: the SQL code strings to parse.
 792                If an `Expression` instance is passed, it will be used as-is.
 793            dialect: the dialect used to parse the input expression.
 794            copy: whether to copy the involved expressions (only applies to Expressions).
 795            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 796                precedence issues, but can be turned off when the produced AST is too deep and
 797                causes recursion-related issues.
 798            opts: other options to use to parse the input expressions.
 799
 800        Returns:
 801            The new And condition.
 802        """
 803        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 804
 805    def or_(
 806        self,
 807        *expressions: t.Optional[ExpOrStr],
 808        dialect: DialectType = None,
 809        copy: bool = True,
 810        wrap: bool = True,
 811        **opts,
 812    ) -> Condition:
 813        """
 814        OR this condition with one or multiple expressions.
 815
 816        Example:
 817            >>> condition("x=1").or_("y=1").sql()
 818            'x = 1 OR y = 1'
 819
 820        Args:
 821            *expressions: the SQL code strings to parse.
 822                If an `Expression` instance is passed, it will be used as-is.
 823            dialect: the dialect used to parse the input expression.
 824            copy: whether to copy the involved expressions (only applies to Expressions).
 825            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
 826                precedence issues, but can be turned off when the produced AST is too deep and
 827                causes recursion-related issues.
 828            opts: other options to use to parse the input expressions.
 829
 830        Returns:
 831            The new Or condition.
 832        """
 833        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)
 834
 835    def not_(self, copy: bool = True):
 836        """
 837        Wrap this condition with NOT.
 838
 839        Example:
 840            >>> condition("x=1").not_().sql()
 841            'NOT x = 1'
 842
 843        Args:
 844            copy: whether to copy this object.
 845
 846        Returns:
 847            The new Not instance.
 848        """
 849        return not_(self, copy=copy)
 850
 851    def update_positions(
 852        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
 853    ) -> E:
 854        """
 855        Update this expression with positions from a token or other expression.
 856
 857        Args:
 858            other: a token or expression to update this expression with.
 859
 860        Returns:
 861            The updated expression.
 862        """
 863        if isinstance(other, Expression):
 864            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
 865        elif other is not None:
 866            self.meta.update(
 867                {
 868                    "line": other.line,
 869                    "col": other.col,
 870                    "start": other.start,
 871                    "end": other.end,
 872                }
 873            )
 874        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
 875        return self
 876
 877    def as_(
 878        self,
 879        alias: str | Identifier,
 880        quoted: t.Optional[bool] = None,
 881        dialect: DialectType = None,
 882        copy: bool = True,
 883        **opts,
 884    ) -> Alias:
 885        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
 886
 887    def _binop(self, klass: t.Type[E], other: t.Any, reverse: bool = False) -> E:
 888        this = self.copy()
 889        other = convert(other, copy=True)
 890        if not isinstance(this, klass) and not isinstance(other, klass):
 891            this = _wrap(this, Binary)
 892            other = _wrap(other, Binary)
 893        if reverse:
 894            return klass(this=other, expression=this)
 895        return klass(this=this, expression=other)
 896
 897    def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
 898        return Bracket(
 899            this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
 900        )
 901
 902    def __iter__(self) -> t.Iterator:
 903        if "expressions" in self.arg_types:
 904            return iter(self.args.get("expressions") or [])
 905        # We define this because __getitem__ converts Expression into an iterable, which is
 906        # problematic because one can hit infinite loops if they do "for x in some_expr: ..."
 907        # See: https://peps.python.org/pep-0234/
 908        raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
 909
 910    def isin(
 911        self,
 912        *expressions: t.Any,
 913        query: t.Optional[ExpOrStr] = None,
 914        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
 915        copy: bool = True,
 916        **opts,
 917    ) -> In:
 918        subquery = maybe_parse(query, copy=copy, **opts) if query else None
 919        if subquery and not isinstance(subquery, Subquery):
 920            subquery = subquery.subquery(copy=False)
 921
 922        return In(
 923            this=maybe_copy(self, copy),
 924            expressions=[convert(e, copy=copy) for e in expressions],
 925            query=subquery,
 926            unnest=(
 927                Unnest(
 928                    expressions=[
 929                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
 930                        for e in ensure_list(unnest)
 931                    ]
 932                )
 933                if unnest
 934                else None
 935            ),
 936        )
 937
 938    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
 939        return Between(
 940            this=maybe_copy(self, copy),
 941            low=convert(low, copy=copy, **opts),
 942            high=convert(high, copy=copy, **opts),
 943        )
 944
 945    def is_(self, other: ExpOrStr) -> Is:
 946        return self._binop(Is, other)
 947
 948    def like(self, other: ExpOrStr) -> Like:
 949        return self._binop(Like, other)
 950
 951    def ilike(self, other: ExpOrStr) -> ILike:
 952        return self._binop(ILike, other)
 953
 954    def eq(self, other: t.Any) -> EQ:
 955        return self._binop(EQ, other)
 956
 957    def neq(self, other: t.Any) -> NEQ:
 958        return self._binop(NEQ, other)
 959
 960    def rlike(self, other: ExpOrStr) -> RegexpLike:
 961        return self._binop(RegexpLike, other)
 962
 963    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
 964        div = self._binop(Div, other)
 965        div.args["typed"] = typed
 966        div.args["safe"] = safe
 967        return div
 968
 969    def asc(self, nulls_first: bool = True) -> Ordered:
 970        return Ordered(this=self.copy(), nulls_first=nulls_first)
 971
 972    def desc(self, nulls_first: bool = False) -> Ordered:
 973        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
 974
 975    def __lt__(self, other: t.Any) -> LT:
 976        return self._binop(LT, other)
 977
 978    def __le__(self, other: t.Any) -> LTE:
 979        return self._binop(LTE, other)
 980
 981    def __gt__(self, other: t.Any) -> GT:
 982        return self._binop(GT, other)
 983
 984    def __ge__(self, other: t.Any) -> GTE:
 985        return self._binop(GTE, other)
 986
 987    def __add__(self, other: t.Any) -> Add:
 988        return self._binop(Add, other)
 989
 990    def __radd__(self, other: t.Any) -> Add:
 991        return self._binop(Add, other, reverse=True)
 992
 993    def __sub__(self, other: t.Any) -> Sub:
 994        return self._binop(Sub, other)
 995
 996    def __rsub__(self, other: t.Any) -> Sub:
 997        return self._binop(Sub, other, reverse=True)
 998
 999    def __mul__(self, other: t.Any) -> Mul:
1000        return self._binop(Mul, other)
1001
1002    def __rmul__(self, other: t.Any) -> Mul:
1003        return self._binop(Mul, other, reverse=True)
1004
1005    def __truediv__(self, other: t.Any) -> Div:
1006        return self._binop(Div, other)
1007
1008    def __rtruediv__(self, other: t.Any) -> Div:
1009        return self._binop(Div, other, reverse=True)
1010
1011    def __floordiv__(self, other: t.Any) -> IntDiv:
1012        return self._binop(IntDiv, other)
1013
1014    def __rfloordiv__(self, other: t.Any) -> IntDiv:
1015        return self._binop(IntDiv, other, reverse=True)
1016
1017    def __mod__(self, other: t.Any) -> Mod:
1018        return self._binop(Mod, other)
1019
1020    def __rmod__(self, other: t.Any) -> Mod:
1021        return self._binop(Mod, other, reverse=True)
1022
1023    def __pow__(self, other: t.Any) -> Pow:
1024        return self._binop(Pow, other)
1025
1026    def __rpow__(self, other: t.Any) -> Pow:
1027        return self._binop(Pow, other, reverse=True)
1028
1029    def __and__(self, other: t.Any) -> And:
1030        return self._binop(And, other)
1031
1032    def __rand__(self, other: t.Any) -> And:
1033        return self._binop(And, other, reverse=True)
1034
1035    def __or__(self, other: t.Any) -> Or:
1036        return self._binop(Or, other)
1037
1038    def __ror__(self, other: t.Any) -> Or:
1039        return self._binop(Or, other, reverse=True)
1040
1041    def __neg__(self) -> Neg:
1042        return Neg(this=_wrap(self.copy(), Binary))
1043
1044    def __invert__(self) -> Not:
1045        return not_(self.copy())

The base class for all expressions in a syntax tree. Each Expression 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 Expression 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.DataType type 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(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression 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.
Expression(**args: Any)
107    def __init__(self, **args: t.Any):
108        self.args: t.Dict[str, t.Any] = args
109        self.parent: t.Optional[Expression] = None
110        self.arg_key: t.Optional[str] = None
111        self.index: t.Optional[int] = None
112        self.comments: t.Optional[t.List[str]] = None
113        self._type: t.Optional[DataType] = None
114        self._meta: t.Optional[t.Dict[str, t.Any]] = None
115        self._hash: t.Optional[int] = None
116
117        for arg_key, value in self.args.items():
118            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
hashable_args: Any
123    @property
124    def hashable_args(self) -> t.Any:
125        return frozenset(
126            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
127            for k, v in self.args.items()
128            if not (v is None or v is False or (type(v) is list and not v))
129        )
this: Any
137    @property
138    def this(self) -> t.Any:
139        """
140        Retrieves the argument with key "this".
141        """
142        return self.args.get("this")

Retrieves the argument with key "this".

expression: Any
144    @property
145    def expression(self) -> t.Any:
146        """
147        Retrieves the argument with key "expression".
148        """
149        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
151    @property
152    def expressions(self) -> t.List[t.Any]:
153        """
154        Retrieves the argument with key "expressions".
155        """
156        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
158    def text(self, key) -> str:
159        """
160        Returns a textual representation of the argument corresponding to "key". This can only be used
161        for args that are strings or leaf Expression instances, such as identifiers and literals.
162        """
163        field = self.args.get(key)
164        if isinstance(field, str):
165            return field
166        if isinstance(field, (Identifier, Literal, Var)):
167            return field.this
168        if isinstance(field, (Star, Null)):
169            return field.name
170        return ""

Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expression instances, such as identifiers and literals.

is_string: bool
172    @property
173    def is_string(self) -> bool:
174        """
175        Checks whether a Literal expression is a string.
176        """
177        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
179    @property
180    def is_number(self) -> bool:
181        """
182        Checks whether a Literal expression is a number.
183        """
184        return (isinstance(self, Literal) and not self.args["is_string"]) or (
185            isinstance(self, Neg) and self.this.is_number
186        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
188    def to_py(self) -> t.Any:
189        """
190        Returns a Python object equivalent of the SQL node.
191        """
192        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
194    @property
195    def is_int(self) -> bool:
196        """
197        Checks whether an expression is an integer.
198        """
199        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
201    @property
202    def is_star(self) -> bool:
203        """Checks whether an expression is a star."""
204        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
206    @property
207    def alias(self) -> str:
208        """
209        Returns the alias of the expression, or an empty string if it's not aliased.
210        """
211        if isinstance(self.args.get("alias"), TableAlias):
212            return self.args["alias"].name
213        return self.text("alias")

Returns the alias of the expression, or an empty string if it's not aliased.

alias_column_names: List[str]
215    @property
216    def alias_column_names(self) -> t.List[str]:
217        table_alias = self.args.get("alias")
218        if not table_alias:
219            return []
220        return [c.name for c in table_alias.args.get("columns") or []]
name: str
222    @property
223    def name(self) -> str:
224        return self.text("this")
alias_or_name: str
226    @property
227    def alias_or_name(self) -> str:
228        return self.alias or self.name
output_name: str
230    @property
231    def output_name(self) -> str:
232        """
233        Name of the output column if this expression is a selection.
234
235        If the Expression has no output name, an empty string is returned.
236
237        Example:
238            >>> from sqlglot import parse_one
239            >>> parse_one("SELECT a").expressions[0].output_name
240            'a'
241            >>> parse_one("SELECT b AS c").expressions[0].output_name
242            'c'
243            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
244            ''
245        """
246        return ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
248    @property
249    def type(self) -> t.Optional[DataType]:
250        return self._type
def is_type(self, *dtypes) -> bool:
258    def is_type(self, *dtypes) -> bool:
259        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
261    def is_leaf(self) -> bool:
262        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
264    @property
265    def meta(self) -> t.Dict[str, t.Any]:
266        if self._meta is None:
267            self._meta = {}
268        return self._meta
def copy(self) -> typing_extensions.Self:
304    def copy(self) -> Self:
305        """
306        Returns a deep copy of the expression.
307        """
308        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
310    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
311        if self.comments is None:
312            self.comments = []
313
314        if comments:
315            for comment in comments:
316                _, *meta = comment.split(SQLGLOT_META)
317                if meta:
318                    for kv in "".join(meta).split(","):
319                        k, *v = kv.split("=")
320                        value = v[0].strip() if v else True
321                        self.meta[k.strip()] = to_bool(value)
322
323                if not prepend:
324                    self.comments.append(comment)
325
326            if prepend:
327                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
329    def pop_comments(self) -> t.List[str]:
330        comments = self.comments or []
331        self.comments = None
332        return comments
def append(self, arg_key: str, value: Any) -> None:
334    def append(self, arg_key: str, value: t.Any) -> None:
335        """
336        Appends value to arg_key if it's a list or sets it as a new list.
337
338        Args:
339            arg_key (str): name of the list expression arg
340            value (Any): value to append to the list
341        """
342        if type(self.args.get(arg_key)) is not list:
343            self.args[arg_key] = []
344        self._set_parent(arg_key, value)
345        values = self.args[arg_key]
346        if hasattr(value, "parent"):
347            value.index = len(values)
348        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
def set( self, arg_key: str, value: Any, index: Optional[int] = None, overwrite: bool = True) -> None:
350    def set(
351        self,
352        arg_key: str,
353        value: t.Any,
354        index: t.Optional[int] = None,
355        overwrite: bool = True,
356    ) -> None:
357        """
358        Sets arg_key to value.
359
360        Args:
361            arg_key: name of the expression arg.
362            value: value to set the arg to.
363            index: if the arg is a list, this specifies what position to add the value in it.
364            overwrite: assuming an index is given, this determines whether to overwrite the
365                list entry instead of only inserting a new value (i.e., like list.insert).
366        """
367        if index is not None:
368            expressions = self.args.get(arg_key) or []
369
370            if seq_get(expressions, index) is None:
371                return
372            if value is None:
373                expressions.pop(index)
374                for v in expressions[index:]:
375                    v.index = v.index - 1
376                return
377
378            if isinstance(value, list):
379                expressions.pop(index)
380                expressions[index:index] = value
381            elif overwrite:
382                expressions[index] = value
383            else:
384                expressions.insert(index, value)
385
386            value = expressions
387        elif value is None:
388            self.args.pop(arg_key, None)
389            return
390
391        self.args[arg_key] = value
392        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).
depth: int
406    @property
407    def depth(self) -> int:
408        """
409        Returns the depth of this tree.
410        """
411        if self.parent:
412            return self.parent.depth + 1
413        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
415    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
416        """Yields the key and expression for all arguments, exploding list args."""
417        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
418            if type(vs) is list:
419                for v in reversed(vs) if reverse else vs:  # type: ignore
420                    if hasattr(v, "parent"):
421                        yield v
422            else:
423                if hasattr(vs, "parent"):
424                    yield vs

Yields the key and expression for all arguments, exploding list args.

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
426    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
427        """
428        Returns the first node in this tree which matches at least one of
429        the specified types.
430
431        Args:
432            expression_types: the expression type(s) to match.
433            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
434
435        Returns:
436            The node which matches the criteria or None if no such node was found.
437        """
438        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.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
440    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
441        """
442        Returns a generator object which visits all nodes in this tree and only
443        yields those that match at least one of the specified expression types.
444
445        Args:
446            expression_types: the expression type(s) to match.
447            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
448
449        Returns:
450            The generator object.
451        """
452        for expression in self.walk(bfs=bfs):
453            if isinstance(expression, expression_types):
454                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.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
456    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
457        """
458        Returns a nearest parent matching expression_types.
459
460        Args:
461            expression_types: the expression type(s) to match.
462
463        Returns:
464            The parent node.
465        """
466        ancestor = self.parent
467        while ancestor and not isinstance(ancestor, expression_types):
468            ancestor = ancestor.parent
469        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]
471    @property
472    def parent_select(self) -> t.Optional[Select]:
473        """
474        Returns the parent select statement.
475        """
476        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
478    @property
479    def same_parent(self) -> bool:
480        """Returns if the parent is the same class as itself."""
481        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
483    def root(self) -> Expression:
484        """
485        Returns the root expression of this tree.
486        """
487        expression = self
488        while expression.parent:
489            expression = expression.parent
490        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
492    def walk(
493        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
494    ) -> t.Iterator[Expression]:
495        """
496        Returns a generator object which visits all nodes in this tree.
497
498        Args:
499            bfs: if set to True the BFS traversal order will be applied,
500                otherwise the DFS traversal will be used instead.
501            prune: callable that returns True if the generator should stop traversing
502                this branch of the tree.
503
504        Returns:
505            the generator object.
506        """
507        if bfs:
508            yield from self.bfs(prune=prune)
509        else:
510            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.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
512    def dfs(
513        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
514    ) -> t.Iterator[Expression]:
515        """
516        Returns a generator object which visits all nodes in this tree in
517        the DFS (Depth-first) order.
518
519        Returns:
520            The generator object.
521        """
522        stack = [self]
523
524        while stack:
525            node = stack.pop()
526
527            yield node
528
529            if prune and prune(node):
530                continue
531
532            for v in node.iter_expressions(reverse=True):
533                stack.append(v)

Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.

Returns:

The generator object.

def bfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
535    def bfs(
536        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
537    ) -> t.Iterator[Expression]:
538        """
539        Returns a generator object which visits all nodes in this tree in
540        the BFS (Breadth-first) order.
541
542        Returns:
543            The generator object.
544        """
545        queue = deque([self])
546
547        while queue:
548            node = queue.popleft()
549
550            yield node
551
552            if prune and prune(node):
553                continue
554
555            for v in node.iter_expressions():
556                queue.append(v)

Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.

Returns:

The generator object.

def unnest(self):
558    def unnest(self):
559        """
560        Returns the first non parenthesis child or self.
561        """
562        expression = self
563        while type(expression) is Paren:
564            expression = expression.this
565        return expression

Returns the first non parenthesis child or self.

def unalias(self):
567    def unalias(self):
568        """
569        Returns the inner expression if this is an Alias.
570        """
571        if isinstance(self, Alias):
572            return self.this
573        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
575    def unnest_operands(self):
576        """
577        Returns unnested operands as a tuple.
578        """
579        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
581    def flatten(self, unnest=True):
582        """
583        Returns a generator which yields child nodes whose parents are the same class.
584
585        A AND B AND C -> [A, B, C]
586        """
587        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
588            if type(node) is not self.__class__:
589                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
597    def to_s(self) -> str:
598        """
599        Same as __repr__, but includes additional information which can be useful
600        for debugging, like empty or missing args and the AST nodes' object IDs.
601        """
602        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> str:
604    def sql(self, dialect: DialectType = None, **opts) -> str:
605        """
606        Returns SQL string representation of this tree.
607
608        Args:
609            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
610            opts: other `sqlglot.generator.Generator` options.
611
612        Returns:
613            The SQL string.
614        """
615        from sqlglot.dialects import Dialect
616
617        return Dialect.get_or_raise(dialect).generate(self, **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.Generator options.
Returns:

The SQL string.

def transform( self, fun: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
619    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
620        """
621        Visits all tree nodes (excluding already transformed ones)
622        and applies the given transformation function to each node.
623
624        Args:
625            fun: a function which takes a node as an argument and returns a
626                new transformed node or the same node without modifications. If the function
627                returns None, then the corresponding node will be removed from the syntax tree.
628            copy: if set to True a new tree instance is constructed, otherwise the tree is
629                modified in place.
630
631        Returns:
632            The transformed tree.
633        """
634        root = None
635        new_node = None
636
637        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
638            parent, arg_key, index = node.parent, node.arg_key, node.index
639            new_node = fun(node, *args, **kwargs)
640
641            if not root:
642                root = new_node
643            elif parent and arg_key and new_node is not node:
644                parent.set(arg_key, new_node, index)
645
646        assert root
647        return root.assert_is(Expression)

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.

def replace(self, expression):
655    def replace(self, expression):
656        """
657        Swap out this expression with a new expression.
658
659        For example::
660
661            >>> tree = Select().select("x").from_("tbl")
662            >>> tree.find(Column).replace(column("y"))
663            Column(
664              this=Identifier(this=y, quoted=False))
665            >>> tree.sql()
666            'SELECT y FROM tbl'
667
668        Args:
669            expression: new node
670
671        Returns:
672            The new expression or expressions.
673        """
674        parent = self.parent
675
676        if not parent or parent is expression:
677            return expression
678
679        key = self.arg_key
680        value = parent.args.get(key)
681
682        if type(expression) is list and isinstance(value, Expression):
683            # We are trying to replace an Expression with a list, so it's assumed that
684            # the intention was to really replace the parent of this expression.
685            value.parent.replace(expression)
686        else:
687            parent.set(key, expression, self.index)
688
689        if expression is not self:
690            self.parent = None
691            self.arg_key = None
692            self.index = None
693
694        return expression

Swap out this expression with a new expression.

For example::

>>> tree = Select().select("x").from_("tbl")
>>> tree.find(Column).replace(column("y"))
Column(
  this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
696    def pop(self: E) -> E:
697        """
698        Remove this expression from its AST.
699
700        Returns:
701            The popped expression.
702        """
703        self.replace(None)
704        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
706    def assert_is(self, type_: t.Type[E]) -> E:
707        """
708        Assert that this `Expression` is an instance of `type_`.
709
710        If it is NOT an instance of `type_`, this raises an assertion error.
711        Otherwise, this returns this expression.
712
713        Examples:
714            This is useful for type security in chained expressions:
715
716            >>> import sqlglot
717            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
718            'SELECT x, z FROM y'
719        """
720        if not isinstance(self, type_):
721            raise AssertionError(f"{self} is not {type_}.")
722        return self

Assert that this Expression 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(Select).select("z").sql()
'SELECT x, z FROM y'
def error_messages(self, args: Optional[Sequence] = None) -> List[str]:
724    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
725        """
726        Checks if this expression is valid (e.g. all mandatory args are set).
727
728        Args:
729            args: a sequence of values that were used to instantiate a Func expression. This is used
730                to check that the provided arguments don't exceed the function argument limit.
731
732        Returns:
733            A list of error messages for all possible errors that were found.
734        """
735        errors: t.List[str] = []
736
737        for k in self.args:
738            if k not in self.arg_types:
739                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
740        for k, mandatory in self.arg_types.items():
741            v = self.args.get(k)
742            if mandatory and (v is None or (isinstance(v, list) and not v)):
743                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
744
745        if (
746            args
747            and isinstance(self, Func)
748            and len(args) > len(self.arg_types)
749            and not self.is_var_len_args
750        ):
751            errors.append(
752                f"The number of provided arguments ({len(args)}) is greater than "
753                f"the maximum number of supported arguments ({len(self.arg_types)})"
754            )
755
756        return errors

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.

def dump(self):
758    def dump(self):
759        """
760        Dump this Expression to a JSON-serializable dict.
761        """
762        from sqlglot.serde import dump
763
764        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
766    @classmethod
767    def load(cls, obj):
768        """
769        Load a dict (as returned by `Expression.dump`) into an Expression instance.
770        """
771        from sqlglot.serde import load
772
773        return load(obj)

Load a dict (as returned by Expression.dump) into an Expression instance.

def and_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
775    def and_(
776        self,
777        *expressions: t.Optional[ExpOrStr],
778        dialect: DialectType = None,
779        copy: bool = True,
780        wrap: bool = True,
781        **opts,
782    ) -> Condition:
783        """
784        AND this condition with one or multiple expressions.
785
786        Example:
787            >>> condition("x=1").and_("y=1").sql()
788            'x = 1 AND y = 1'
789
790        Args:
791            *expressions: the SQL code strings to parse.
792                If an `Expression` instance is passed, it will be used as-is.
793            dialect: the dialect used to parse the input expression.
794            copy: whether to copy the involved expressions (only applies to Expressions).
795            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
796                precedence issues, but can be turned off when the produced AST is too deep and
797                causes recursion-related issues.
798            opts: other options to use to parse the input expressions.
799
800        Returns:
801            The new And condition.
802        """
803        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 Expression instance 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 Expressions).
  • 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.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
805    def or_(
806        self,
807        *expressions: t.Optional[ExpOrStr],
808        dialect: DialectType = None,
809        copy: bool = True,
810        wrap: bool = True,
811        **opts,
812    ) -> Condition:
813        """
814        OR this condition with one or multiple expressions.
815
816        Example:
817            >>> condition("x=1").or_("y=1").sql()
818            'x = 1 OR y = 1'
819
820        Args:
821            *expressions: the SQL code strings to parse.
822                If an `Expression` instance is passed, it will be used as-is.
823            dialect: the dialect used to parse the input expression.
824            copy: whether to copy the involved expressions (only applies to Expressions).
825            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
826                precedence issues, but can be turned off when the produced AST is too deep and
827                causes recursion-related issues.
828            opts: other options to use to parse the input expressions.
829
830        Returns:
831            The new Or condition.
832        """
833        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 Expression instance 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 Expressions).
  • 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.

def not_(self, copy: bool = True):
835    def not_(self, copy: bool = True):
836        """
837        Wrap this condition with NOT.
838
839        Example:
840            >>> condition("x=1").not_().sql()
841            'NOT x = 1'
842
843        Args:
844            copy: whether to copy this object.
845
846        Returns:
847            The new Not instance.
848        """
849        return not_(self, copy=copy)

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.

def update_positions( self: ~E, other: Union[sqlglot.tokens.Token, Expression, NoneType] = None, **kwargs: Any) -> ~E:
851    def update_positions(
852        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
853    ) -> E:
854        """
855        Update this expression with positions from a token or other expression.
856
857        Args:
858            other: a token or expression to update this expression with.
859
860        Returns:
861            The updated expression.
862        """
863        if isinstance(other, Expression):
864            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
865        elif other is not None:
866            self.meta.update(
867                {
868                    "line": other.line,
869                    "col": other.col,
870                    "start": other.start,
871                    "end": other.end,
872                }
873            )
874        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
875        return self

Update this expression with positions from a token or other expression.

Arguments:
  • other: a token or expression to update this expression with.
Returns:

The updated expression.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
877    def as_(
878        self,
879        alias: str | Identifier,
880        quoted: t.Optional[bool] = None,
881        dialect: DialectType = None,
882        copy: bool = True,
883        **opts,
884    ) -> Alias:
885        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
910    def isin(
911        self,
912        *expressions: t.Any,
913        query: t.Optional[ExpOrStr] = None,
914        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
915        copy: bool = True,
916        **opts,
917    ) -> In:
918        subquery = maybe_parse(query, copy=copy, **opts) if query else None
919        if subquery and not isinstance(subquery, Subquery):
920            subquery = subquery.subquery(copy=False)
921
922        return In(
923            this=maybe_copy(self, copy),
924            expressions=[convert(e, copy=copy) for e in expressions],
925            query=subquery,
926            unnest=(
927                Unnest(
928                    expressions=[
929                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
930                        for e in ensure_list(unnest)
931                    ]
932                )
933                if unnest
934                else None
935            ),
936        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
938    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
939        return Between(
940            this=maybe_copy(self, copy),
941            low=convert(low, copy=copy, **opts),
942            high=convert(high, copy=copy, **opts),
943        )
def is_( self, other: Union[str, Expression]) -> Is:
945    def is_(self, other: ExpOrStr) -> Is:
946        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
948    def like(self, other: ExpOrStr) -> Like:
949        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
951    def ilike(self, other: ExpOrStr) -> ILike:
952        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
954    def eq(self, other: t.Any) -> EQ:
955        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
957    def neq(self, other: t.Any) -> NEQ:
958        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
960    def rlike(self, other: ExpOrStr) -> RegexpLike:
961        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
963    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
964        div = self._binop(Div, other)
965        div.args["typed"] = typed
966        div.args["safe"] = safe
967        return div
def asc(self, nulls_first: bool = True) -> Ordered:
969    def asc(self, nulls_first: bool = True) -> Ordered:
970        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
972    def desc(self, nulls_first: bool = False) -> Ordered:
973        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
1056class Condition(Expression):
1057    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

key = 'condition'
class Predicate(Condition):
1060class Predicate(Condition):
1061    """Relationships like x = y, x > 1, x >= y."""

Relationships like x = y, x > 1, x >= y.

key = 'predicate'
class DerivedTable(Expression):
1064class DerivedTable(Expression):
1065    @property
1066    def selects(self) -> t.List[Expression]:
1067        return self.this.selects if isinstance(self.this, Query) else []
1068
1069    @property
1070    def named_selects(self) -> t.List[str]:
1071        return [select.output_name for select in self.selects]
selects: List[Expression]
1065    @property
1066    def selects(self) -> t.List[Expression]:
1067        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1069    @property
1070    def named_selects(self) -> t.List[str]:
1071        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1074class Query(Expression):
1075    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1076        """
1077        Returns a `Subquery` that wraps around this query.
1078
1079        Example:
1080            >>> subquery = Select().select("x").from_("tbl").subquery()
1081            >>> Select().select("x").from_(subquery).sql()
1082            'SELECT x FROM (SELECT x FROM tbl)'
1083
1084        Args:
1085            alias: an optional alias for the subquery.
1086            copy: if `False`, modify this expression instance in-place.
1087        """
1088        instance = maybe_copy(self, copy)
1089        if not isinstance(alias, Expression):
1090            alias = TableAlias(this=to_identifier(alias)) if alias else None
1091
1092        return Subquery(this=instance, alias=alias)
1093
1094    def limit(
1095        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1096    ) -> Q:
1097        """
1098        Adds a LIMIT clause to this query.
1099
1100        Example:
1101            >>> select("1").union(select("1")).limit(1).sql()
1102            'SELECT 1 UNION SELECT 1 LIMIT 1'
1103
1104        Args:
1105            expression: the SQL code string to parse.
1106                This can also be an integer.
1107                If a `Limit` instance is passed, it will be used as-is.
1108                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1109            dialect: the dialect used to parse the input expression.
1110            copy: if `False`, modify this expression instance in-place.
1111            opts: other options to use to parse the input expressions.
1112
1113        Returns:
1114            A limited Select expression.
1115        """
1116        return _apply_builder(
1117            expression=expression,
1118            instance=self,
1119            arg="limit",
1120            into=Limit,
1121            prefix="LIMIT",
1122            dialect=dialect,
1123            copy=copy,
1124            into_arg="expression",
1125            **opts,
1126        )
1127
1128    def offset(
1129        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1130    ) -> Q:
1131        """
1132        Set the OFFSET expression.
1133
1134        Example:
1135            >>> Select().from_("tbl").select("x").offset(10).sql()
1136            'SELECT x FROM tbl OFFSET 10'
1137
1138        Args:
1139            expression: the SQL code string to parse.
1140                This can also be an integer.
1141                If a `Offset` instance is passed, this is used as-is.
1142                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1143            dialect: the dialect used to parse the input expression.
1144            copy: if `False`, modify this expression instance in-place.
1145            opts: other options to use to parse the input expressions.
1146
1147        Returns:
1148            The modified Select expression.
1149        """
1150        return _apply_builder(
1151            expression=expression,
1152            instance=self,
1153            arg="offset",
1154            into=Offset,
1155            prefix="OFFSET",
1156            dialect=dialect,
1157            copy=copy,
1158            into_arg="expression",
1159            **opts,
1160        )
1161
1162    def order_by(
1163        self: Q,
1164        *expressions: t.Optional[ExpOrStr],
1165        append: bool = True,
1166        dialect: DialectType = None,
1167        copy: bool = True,
1168        **opts,
1169    ) -> Q:
1170        """
1171        Set the ORDER BY expression.
1172
1173        Example:
1174            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1175            'SELECT x FROM tbl ORDER BY x DESC'
1176
1177        Args:
1178            *expressions: the SQL code strings to parse.
1179                If a `Group` instance is passed, this is used as-is.
1180                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1181            append: if `True`, add to any existing expressions.
1182                Otherwise, this flattens all the `Order` expression into a single expression.
1183            dialect: the dialect used to parse the input expression.
1184            copy: if `False`, modify this expression instance in-place.
1185            opts: other options to use to parse the input expressions.
1186
1187        Returns:
1188            The modified Select expression.
1189        """
1190        return _apply_child_list_builder(
1191            *expressions,
1192            instance=self,
1193            arg="order",
1194            append=append,
1195            copy=copy,
1196            prefix="ORDER BY",
1197            into=Order,
1198            dialect=dialect,
1199            **opts,
1200        )
1201
1202    @property
1203    def ctes(self) -> t.List[CTE]:
1204        """Returns a list of all the CTEs attached to this query."""
1205        with_ = self.args.get("with")
1206        return with_.expressions if with_ else []
1207
1208    @property
1209    def selects(self) -> t.List[Expression]:
1210        """Returns the query's projections."""
1211        raise NotImplementedError("Query objects must implement `selects`")
1212
1213    @property
1214    def named_selects(self) -> t.List[str]:
1215        """Returns the output names of the query's projections."""
1216        raise NotImplementedError("Query objects must implement `named_selects`")
1217
1218    def select(
1219        self: Q,
1220        *expressions: t.Optional[ExpOrStr],
1221        append: bool = True,
1222        dialect: DialectType = None,
1223        copy: bool = True,
1224        **opts,
1225    ) -> Q:
1226        """
1227        Append to or set the SELECT expressions.
1228
1229        Example:
1230            >>> Select().select("x", "y").sql()
1231            'SELECT x, y'
1232
1233        Args:
1234            *expressions: the SQL code strings to parse.
1235                If an `Expression` instance is passed, it will be used as-is.
1236            append: if `True`, add to any existing expressions.
1237                Otherwise, this resets the expressions.
1238            dialect: the dialect used to parse the input expressions.
1239            copy: if `False`, modify this expression instance in-place.
1240            opts: other options to use to parse the input expressions.
1241
1242        Returns:
1243            The modified Query expression.
1244        """
1245        raise NotImplementedError("Query objects must implement `select`")
1246
1247    def where(
1248        self: Q,
1249        *expressions: t.Optional[ExpOrStr],
1250        append: bool = True,
1251        dialect: DialectType = None,
1252        copy: bool = True,
1253        **opts,
1254    ) -> Q:
1255        """
1256        Append to or set the WHERE expressions.
1257
1258        Examples:
1259            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1260            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1261
1262        Args:
1263            *expressions: the SQL code strings to parse.
1264                If an `Expression` instance is passed, it will be used as-is.
1265                Multiple expressions are combined with an AND operator.
1266            append: if `True`, AND the new expressions to any existing expression.
1267                Otherwise, this resets the expression.
1268            dialect: the dialect used to parse the input expressions.
1269            copy: if `False`, modify this expression instance in-place.
1270            opts: other options to use to parse the input expressions.
1271
1272        Returns:
1273            The modified expression.
1274        """
1275        return _apply_conjunction_builder(
1276            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1277            instance=self,
1278            arg="where",
1279            append=append,
1280            into=Where,
1281            dialect=dialect,
1282            copy=copy,
1283            **opts,
1284        )
1285
1286    def with_(
1287        self: Q,
1288        alias: ExpOrStr,
1289        as_: ExpOrStr,
1290        recursive: t.Optional[bool] = None,
1291        materialized: t.Optional[bool] = None,
1292        append: bool = True,
1293        dialect: DialectType = None,
1294        copy: bool = True,
1295        scalar: bool = False,
1296        **opts,
1297    ) -> Q:
1298        """
1299        Append to or set the common table expressions.
1300
1301        Example:
1302            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1303            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1304
1305        Args:
1306            alias: the SQL code string to parse as the table name.
1307                If an `Expression` instance is passed, this is used as-is.
1308            as_: the SQL code string to parse as the table expression.
1309                If an `Expression` instance is passed, it will be used as-is.
1310            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1311            materialized: set the MATERIALIZED part of the expression.
1312            append: if `True`, add to any existing expressions.
1313                Otherwise, this resets the expressions.
1314            dialect: the dialect used to parse the input expression.
1315            copy: if `False`, modify this expression instance in-place.
1316            scalar: if `True`, this is a scalar common table expression.
1317            opts: other options to use to parse the input expressions.
1318
1319        Returns:
1320            The modified expression.
1321        """
1322        return _apply_cte_builder(
1323            self,
1324            alias,
1325            as_,
1326            recursive=recursive,
1327            materialized=materialized,
1328            append=append,
1329            dialect=dialect,
1330            copy=copy,
1331            scalar=scalar,
1332            **opts,
1333        )
1334
1335    def union(
1336        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1337    ) -> Union:
1338        """
1339        Builds a UNION expression.
1340
1341        Example:
1342            >>> import sqlglot
1343            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1344            'SELECT * FROM foo UNION SELECT * FROM bla'
1345
1346        Args:
1347            expressions: the SQL code strings.
1348                If `Expression` instances are passed, they will be used as-is.
1349            distinct: set the DISTINCT flag if and only if this is true.
1350            dialect: the dialect used to parse the input expression.
1351            opts: other options to use to parse the input expressions.
1352
1353        Returns:
1354            The new Union expression.
1355        """
1356        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1357
1358    def intersect(
1359        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1360    ) -> Intersect:
1361        """
1362        Builds an INTERSECT expression.
1363
1364        Example:
1365            >>> import sqlglot
1366            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1367            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1368
1369        Args:
1370            expressions: the SQL code strings.
1371                If `Expression` instances are passed, they will be used as-is.
1372            distinct: set the DISTINCT flag if and only if this is true.
1373            dialect: the dialect used to parse the input expression.
1374            opts: other options to use to parse the input expressions.
1375
1376        Returns:
1377            The new Intersect expression.
1378        """
1379        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1380
1381    def except_(
1382        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1383    ) -> Except:
1384        """
1385        Builds an EXCEPT expression.
1386
1387        Example:
1388            >>> import sqlglot
1389            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1390            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1391
1392        Args:
1393            expressions: the SQL code strings.
1394                If `Expression` instance are passed, they will be used as-is.
1395            distinct: set the DISTINCT flag if and only if this is true.
1396            dialect: the dialect used to parse the input expression.
1397            opts: other options to use to parse the input expressions.
1398
1399        Returns:
1400            The new Except expression.
1401        """
1402        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1075    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1076        """
1077        Returns a `Subquery` that wraps around this query.
1078
1079        Example:
1080            >>> subquery = Select().select("x").from_("tbl").subquery()
1081            >>> Select().select("x").from_(subquery).sql()
1082            'SELECT x FROM (SELECT x FROM tbl)'
1083
1084        Args:
1085            alias: an optional alias for the subquery.
1086            copy: if `False`, modify this expression instance in-place.
1087        """
1088        instance = maybe_copy(self, copy)
1089        if not isinstance(alias, Expression):
1090            alias = TableAlias(this=to_identifier(alias)) if alias else None
1091
1092        return Subquery(this=instance, alias=alias)

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1094    def limit(
1095        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1096    ) -> Q:
1097        """
1098        Adds a LIMIT clause to this query.
1099
1100        Example:
1101            >>> select("1").union(select("1")).limit(1).sql()
1102            'SELECT 1 UNION SELECT 1 LIMIT 1'
1103
1104        Args:
1105            expression: the SQL code string to parse.
1106                This can also be an integer.
1107                If a `Limit` instance is passed, it will be used as-is.
1108                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1109            dialect: the dialect used to parse the input expression.
1110            copy: if `False`, modify this expression instance in-place.
1111            opts: other options to use to parse the input expressions.
1112
1113        Returns:
1114            A limited Select expression.
1115        """
1116        return _apply_builder(
1117            expression=expression,
1118            instance=self,
1119            arg="limit",
1120            into=Limit,
1121            prefix="LIMIT",
1122            dialect=dialect,
1123            copy=copy,
1124            into_arg="expression",
1125            **opts,
1126        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT 1 UNION SELECT 1 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

def offset( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1128    def offset(
1129        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1130    ) -> Q:
1131        """
1132        Set the OFFSET expression.
1133
1134        Example:
1135            >>> Select().from_("tbl").select("x").offset(10).sql()
1136            'SELECT x FROM tbl OFFSET 10'
1137
1138        Args:
1139            expression: the SQL code string to parse.
1140                This can also be an integer.
1141                If a `Offset` instance is passed, this is used as-is.
1142                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1143            dialect: the dialect used to parse the input expression.
1144            copy: if `False`, modify this expression instance in-place.
1145            opts: other options to use to parse the input expressions.
1146
1147        Returns:
1148            The modified Select expression.
1149        """
1150        return _apply_builder(
1151            expression=expression,
1152            instance=self,
1153            arg="offset",
1154            into=Offset,
1155            prefix="OFFSET",
1156            dialect=dialect,
1157            copy=copy,
1158            into_arg="expression",
1159            **opts,
1160        )

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").offset(10).sql()
'SELECT x FROM tbl OFFSET 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Offset instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Offset.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def order_by( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1162    def order_by(
1163        self: Q,
1164        *expressions: t.Optional[ExpOrStr],
1165        append: bool = True,
1166        dialect: DialectType = None,
1167        copy: bool = True,
1168        **opts,
1169    ) -> Q:
1170        """
1171        Set the ORDER BY expression.
1172
1173        Example:
1174            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1175            'SELECT x FROM tbl ORDER BY x DESC'
1176
1177        Args:
1178            *expressions: the SQL code strings to parse.
1179                If a `Group` instance is passed, this is used as-is.
1180                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1181            append: if `True`, add to any existing expressions.
1182                Otherwise, this flattens all the `Order` expression into a single expression.
1183            dialect: the dialect used to parse the input expression.
1184            copy: if `False`, modify this expression instance in-place.
1185            opts: other options to use to parse the input expressions.
1186
1187        Returns:
1188            The modified Select expression.
1189        """
1190        return _apply_child_list_builder(
1191            *expressions,
1192            instance=self,
1193            arg="order",
1194            append=append,
1195            copy=copy,
1196            prefix="ORDER BY",
1197            into=Order,
1198            dialect=dialect,
1199            **opts,
1200        )

Set the ORDER BY expression.

Example:
>>> Select().from_("tbl").select("x").order_by("x DESC").sql()
'SELECT x FROM tbl ORDER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Order.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

ctes: List[CTE]
1202    @property
1203    def ctes(self) -> t.List[CTE]:
1204        """Returns a list of all the CTEs attached to this query."""
1205        with_ = self.args.get("with")
1206        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this query.

selects: List[Expression]
1208    @property
1209    def selects(self) -> t.List[Expression]:
1210        """Returns the query's projections."""
1211        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1213    @property
1214    def named_selects(self) -> t.List[str]:
1215        """Returns the output names of the query's projections."""
1216        raise NotImplementedError("Query objects must implement `named_selects`")

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1218    def select(
1219        self: Q,
1220        *expressions: t.Optional[ExpOrStr],
1221        append: bool = True,
1222        dialect: DialectType = None,
1223        copy: bool = True,
1224        **opts,
1225    ) -> Q:
1226        """
1227        Append to or set the SELECT expressions.
1228
1229        Example:
1230            >>> Select().select("x", "y").sql()
1231            'SELECT x, y'
1232
1233        Args:
1234            *expressions: the SQL code strings to parse.
1235                If an `Expression` instance is passed, it will be used as-is.
1236            append: if `True`, add to any existing expressions.
1237                Otherwise, this resets the expressions.
1238            dialect: the dialect used to parse the input expressions.
1239            copy: if `False`, modify this expression instance in-place.
1240            opts: other options to use to parse the input expressions.
1241
1242        Returns:
1243            The modified Query expression.
1244        """
1245        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

def where( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1247    def where(
1248        self: Q,
1249        *expressions: t.Optional[ExpOrStr],
1250        append: bool = True,
1251        dialect: DialectType = None,
1252        copy: bool = True,
1253        **opts,
1254    ) -> Q:
1255        """
1256        Append to or set the WHERE expressions.
1257
1258        Examples:
1259            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1260            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1261
1262        Args:
1263            *expressions: the SQL code strings to parse.
1264                If an `Expression` instance is passed, it will be used as-is.
1265                Multiple expressions are combined with an AND operator.
1266            append: if `True`, AND the new expressions to any existing expression.
1267                Otherwise, this resets the expression.
1268            dialect: the dialect used to parse the input expressions.
1269            copy: if `False`, modify this expression instance in-place.
1270            opts: other options to use to parse the input expressions.
1271
1272        Returns:
1273            The modified expression.
1274        """
1275        return _apply_conjunction_builder(
1276            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1277            instance=self,
1278            arg="where",
1279            append=append,
1280            into=Where,
1281            dialect=dialect,
1282            copy=copy,
1283            **opts,
1284        )

Append to or set the WHERE expressions.

Examples:
>>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
"SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: bool = False, **opts) -> ~Q:
1286    def with_(
1287        self: Q,
1288        alias: ExpOrStr,
1289        as_: ExpOrStr,
1290        recursive: t.Optional[bool] = None,
1291        materialized: t.Optional[bool] = None,
1292        append: bool = True,
1293        dialect: DialectType = None,
1294        copy: bool = True,
1295        scalar: bool = False,
1296        **opts,
1297    ) -> Q:
1298        """
1299        Append to or set the common table expressions.
1300
1301        Example:
1302            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1303            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1304
1305        Args:
1306            alias: the SQL code string to parse as the table name.
1307                If an `Expression` instance is passed, this is used as-is.
1308            as_: the SQL code string to parse as the table expression.
1309                If an `Expression` instance is passed, it will be used as-is.
1310            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1311            materialized: set the MATERIALIZED part of the expression.
1312            append: if `True`, add to any existing expressions.
1313                Otherwise, this resets the expressions.
1314            dialect: the dialect used to parse the input expression.
1315            copy: if `False`, modify this expression instance in-place.
1316            scalar: if `True`, this is a scalar common table expression.
1317            opts: other options to use to parse the input expressions.
1318
1319        Returns:
1320            The modified expression.
1321        """
1322        return _apply_cte_builder(
1323            self,
1324            alias,
1325            as_,
1326            recursive=recursive,
1327            materialized=materialized,
1328            append=append,
1329            dialect=dialect,
1330            copy=copy,
1331            scalar=scalar,
1332            **opts,
1333        )

Append to or set the common table expressions.

Example:
>>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • materialized: set the MATERIALIZED part of the expression.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • scalar: if True, this is a scalar common table expression.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Union:
1335    def union(
1336        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1337    ) -> Union:
1338        """
1339        Builds a UNION expression.
1340
1341        Example:
1342            >>> import sqlglot
1343            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1344            'SELECT * FROM foo UNION SELECT * FROM bla'
1345
1346        Args:
1347            expressions: the SQL code strings.
1348                If `Expression` instances are passed, they will be used as-is.
1349            distinct: set the DISTINCT flag if and only if this is true.
1350            dialect: the dialect used to parse the input expression.
1351            opts: other options to use to parse the input expressions.
1352
1353        Returns:
1354            The new Union expression.
1355        """
1356        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union expression.

def intersect( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Intersect:
1358    def intersect(
1359        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1360    ) -> Intersect:
1361        """
1362        Builds an INTERSECT expression.
1363
1364        Example:
1365            >>> import sqlglot
1366            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1367            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1368
1369        Args:
1370            expressions: the SQL code strings.
1371                If `Expression` instances are passed, they will be used as-is.
1372            distinct: set the DISTINCT flag if and only if this is true.
1373            dialect: the dialect used to parse the input expression.
1374            opts: other options to use to parse the input expressions.
1375
1376        Returns:
1377            The new Intersect expression.
1378        """
1379        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect expression.

def except_( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Except:
1381    def except_(
1382        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1383    ) -> Except:
1384        """
1385        Builds an EXCEPT expression.
1386
1387        Example:
1388            >>> import sqlglot
1389            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1390            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1391
1392        Args:
1393            expressions: the SQL code strings.
1394                If `Expression` instance are passed, they will be used as-is.
1395            distinct: set the DISTINCT flag if and only if this is true.
1396            dialect: the dialect used to parse the input expression.
1397            opts: other options to use to parse the input expressions.
1398
1399        Returns:
1400            The new Except expression.
1401        """
1402        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instance are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1405class UDTF(DerivedTable):
1406    @property
1407    def selects(self) -> t.List[Expression]:
1408        alias = self.args.get("alias")
1409        return alias.columns if alias else []
selects: List[Expression]
1406    @property
1407    def selects(self) -> t.List[Expression]:
1408        alias = self.args.get("alias")
1409        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1412class Cache(Expression):
1413    arg_types = {
1414        "this": True,
1415        "lazy": False,
1416        "options": False,
1417        "expression": False,
1418    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1421class Uncache(Expression):
1422    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1425class Refresh(Expression):
1426    pass
key = 'refresh'
class DDL(Expression):
1429class DDL(Expression):
1430    @property
1431    def ctes(self) -> t.List[CTE]:
1432        """Returns a list of all the CTEs attached to this statement."""
1433        with_ = self.args.get("with")
1434        return with_.expressions if with_ else []
1435
1436    @property
1437    def selects(self) -> t.List[Expression]:
1438        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1439        return self.expression.selects if isinstance(self.expression, Query) else []
1440
1441    @property
1442    def named_selects(self) -> t.List[str]:
1443        """
1444        If this statement contains a query (e.g. a CTAS), this returns the output
1445        names of the query's projections.
1446        """
1447        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1430    @property
1431    def ctes(self) -> t.List[CTE]:
1432        """Returns a list of all the CTEs attached to this statement."""
1433        with_ = self.args.get("with")
1434        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this statement.

selects: List[Expression]
1436    @property
1437    def selects(self) -> t.List[Expression]:
1438        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1439        return self.expression.selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the query's projections.

named_selects: List[str]
1441    @property
1442    def named_selects(self) -> t.List[str]:
1443        """
1444        If this statement contains a query (e.g. a CTAS), this returns the output
1445        names of the query's projections.
1446        """
1447        return self.expression.named_selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the output names of the query's projections.

key = 'ddl'
class DML(Expression):
1450class DML(Expression):
1451    def returning(
1452        self,
1453        expression: ExpOrStr,
1454        dialect: DialectType = None,
1455        copy: bool = True,
1456        **opts,
1457    ) -> "Self":
1458        """
1459        Set the RETURNING expression. Not supported by all dialects.
1460
1461        Example:
1462            >>> delete("tbl").returning("*", dialect="postgres").sql()
1463            'DELETE FROM tbl RETURNING *'
1464
1465        Args:
1466            expression: the SQL code strings to parse.
1467                If an `Expression` instance is passed, it will be used as-is.
1468            dialect: the dialect used to parse the input expressions.
1469            copy: if `False`, modify this expression instance in-place.
1470            opts: other options to use to parse the input expressions.
1471
1472        Returns:
1473            Delete: the modified expression.
1474        """
1475        return _apply_builder(
1476            expression=expression,
1477            instance=self,
1478            arg="returning",
1479            prefix="RETURNING",
1480            dialect=dialect,
1481            copy=copy,
1482            into=Returning,
1483            **opts,
1484        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1451    def returning(
1452        self,
1453        expression: ExpOrStr,
1454        dialect: DialectType = None,
1455        copy: bool = True,
1456        **opts,
1457    ) -> "Self":
1458        """
1459        Set the RETURNING expression. Not supported by all dialects.
1460
1461        Example:
1462            >>> delete("tbl").returning("*", dialect="postgres").sql()
1463            'DELETE FROM tbl RETURNING *'
1464
1465        Args:
1466            expression: the SQL code strings to parse.
1467                If an `Expression` instance is passed, it will be used as-is.
1468            dialect: the dialect used to parse the input expressions.
1469            copy: if `False`, modify this expression instance in-place.
1470            opts: other options to use to parse the input expressions.
1471
1472        Returns:
1473            Delete: the modified expression.
1474        """
1475        return _apply_builder(
1476            expression=expression,
1477            instance=self,
1478            arg="returning",
1479            prefix="RETURNING",
1480            dialect=dialect,
1481            copy=copy,
1482            into=Returning,
1483            **opts,
1484        )

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1487class Create(DDL):
1488    arg_types = {
1489        "with": False,
1490        "this": True,
1491        "kind": True,
1492        "expression": False,
1493        "exists": False,
1494        "properties": False,
1495        "replace": False,
1496        "refresh": False,
1497        "unique": False,
1498        "indexes": False,
1499        "no_schema_binding": False,
1500        "begin": False,
1501        "end": False,
1502        "clone": False,
1503        "concurrently": False,
1504        "clustered": False,
1505    }
1506
1507    @property
1508    def kind(self) -> t.Optional[str]:
1509        kind = self.args.get("kind")
1510        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'refresh': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False, 'concurrently': False, 'clustered': False}
kind: Optional[str]
1507    @property
1508    def kind(self) -> t.Optional[str]:
1509        kind = self.args.get("kind")
1510        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1513class SequenceProperties(Expression):
1514    arg_types = {
1515        "increment": False,
1516        "minvalue": False,
1517        "maxvalue": False,
1518        "cache": False,
1519        "start": False,
1520        "owned": False,
1521        "options": False,
1522    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1525class TruncateTable(Expression):
1526    arg_types = {
1527        "expressions": True,
1528        "is_database": False,
1529        "exists": False,
1530        "only": False,
1531        "cluster": False,
1532        "identity": False,
1533        "option": False,
1534        "partition": False,
1535    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1541class Clone(Expression):
1542    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1545class Describe(Expression):
1546    arg_types = {
1547        "this": True,
1548        "style": False,
1549        "kind": False,
1550        "expressions": False,
1551        "partition": False,
1552        "format": False,
1553    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1557class Attach(Expression):
1558    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1562class Detach(Expression):
1563    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1567class Summarize(Expression):
1568    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1571class Kill(Expression):
1572    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1575class Pragma(Expression):
1576    pass
key = 'pragma'
class Declare(Expression):
1579class Declare(Expression):
1580    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1583class DeclareItem(Expression):
1584    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1587class Set(Expression):
1588    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1591class Heredoc(Expression):
1592    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1595class SetItem(Expression):
1596    arg_types = {
1597        "this": False,
1598        "expressions": False,
1599        "kind": False,
1600        "collate": False,  # MySQL SET NAMES statement
1601        "global": False,
1602    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1605class Show(Expression):
1606    arg_types = {
1607        "this": True,
1608        "history": False,
1609        "terse": False,
1610        "target": False,
1611        "offset": False,
1612        "starts_with": False,
1613        "limit": False,
1614        "from": False,
1615        "like": False,
1616        "where": False,
1617        "db": False,
1618        "scope": False,
1619        "scope_kind": False,
1620        "full": False,
1621        "mutex": False,
1622        "query": False,
1623        "channel": False,
1624        "global": False,
1625        "log": False,
1626        "position": False,
1627        "types": False,
1628        "privileges": False,
1629    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False, 'privileges': False}
key = 'show'
class UserDefinedFunction(Expression):
1632class UserDefinedFunction(Expression):
1633    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1636class CharacterSet(Expression):
1637    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1640class RecursiveWithSearch(Expression):
1641    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key = 'recursivewithsearch'
class With(Expression):
1644class With(Expression):
1645    arg_types = {"expressions": True, "recursive": False, "search": False}
1646
1647    @property
1648    def recursive(self) -> bool:
1649        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1647    @property
1648    def recursive(self) -> bool:
1649        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1652class WithinGroup(Expression):
1653    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1658class CTE(DerivedTable):
1659    arg_types = {
1660        "this": True,
1661        "alias": True,
1662        "scalar": False,
1663        "materialized": False,
1664    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1667class ProjectionDef(Expression):
1668    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1671class TableAlias(Expression):
1672    arg_types = {"this": False, "columns": False}
1673
1674    @property
1675    def columns(self):
1676        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1674    @property
1675    def columns(self):
1676        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1679class BitString(Condition):
1680    pass
key = 'bitstring'
class HexString(Condition):
1683class HexString(Condition):
1684    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1687class ByteString(Condition):
1688    pass
key = 'bytestring'
class RawString(Condition):
1691class RawString(Condition):
1692    pass
key = 'rawstring'
class UnicodeString(Condition):
1695class UnicodeString(Condition):
1696    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1699class Column(Condition):
1700    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1701
1702    @property
1703    def table(self) -> str:
1704        return self.text("table")
1705
1706    @property
1707    def db(self) -> str:
1708        return self.text("db")
1709
1710    @property
1711    def catalog(self) -> str:
1712        return self.text("catalog")
1713
1714    @property
1715    def output_name(self) -> str:
1716        return self.name
1717
1718    @property
1719    def parts(self) -> t.List[Identifier]:
1720        """Return the parts of a column in order catalog, db, table, name."""
1721        return [
1722            t.cast(Identifier, self.args[part])
1723            for part in ("catalog", "db", "table", "this")
1724            if self.args.get(part)
1725        ]
1726
1727    def to_dot(self) -> Dot | Identifier:
1728        """Converts the column into a dot expression."""
1729        parts = self.parts
1730        parent = self.parent
1731
1732        while parent:
1733            if isinstance(parent, Dot):
1734                parts.append(parent.expression)
1735            parent = parent.parent
1736
1737        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1702    @property
1703    def table(self) -> str:
1704        return self.text("table")
db: str
1706    @property
1707    def db(self) -> str:
1708        return self.text("db")
catalog: str
1710    @property
1711    def catalog(self) -> str:
1712        return self.text("catalog")
output_name: str
1714    @property
1715    def output_name(self) -> str:
1716        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1718    @property
1719    def parts(self) -> t.List[Identifier]:
1720        """Return the parts of a column in order catalog, db, table, name."""
1721        return [
1722            t.cast(Identifier, self.args[part])
1723            for part in ("catalog", "db", "table", "this")
1724            if self.args.get(part)
1725        ]

Return the parts of a column in order catalog, db, table, name.

def to_dot(self) -> Dot | Identifier:
1727    def to_dot(self) -> Dot | Identifier:
1728        """Converts the column into a dot expression."""
1729        parts = self.parts
1730        parent = self.parent
1731
1732        while parent:
1733            if isinstance(parent, Dot):
1734                parts.append(parent.expression)
1735            parent = parent.parent
1736
1737        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1740class ColumnPosition(Expression):
1741    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1744class ColumnDef(Expression):
1745    arg_types = {
1746        "this": True,
1747        "kind": False,
1748        "constraints": False,
1749        "exists": False,
1750        "position": False,
1751        "default": False,
1752        "output": False,
1753    }
1754
1755    @property
1756    def constraints(self) -> t.List[ColumnConstraint]:
1757        return self.args.get("constraints") or []
1758
1759    @property
1760    def kind(self) -> t.Optional[DataType]:
1761        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1755    @property
1756    def constraints(self) -> t.List[ColumnConstraint]:
1757        return self.args.get("constraints") or []
kind: Optional[DataType]
1759    @property
1760    def kind(self) -> t.Optional[DataType]:
1761        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1764class AlterColumn(Expression):
1765    arg_types = {
1766        "this": True,
1767        "dtype": False,
1768        "collate": False,
1769        "using": False,
1770        "default": False,
1771        "drop": False,
1772        "comment": False,
1773        "allow_null": False,
1774        "visible": False,
1775    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False}
key = 'altercolumn'
class AlterIndex(Expression):
1779class AlterIndex(Expression):
1780    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1784class AlterDistStyle(Expression):
1785    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1788class AlterSortKey(Expression):
1789    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1792class AlterSet(Expression):
1793    arg_types = {
1794        "expressions": False,
1795        "option": False,
1796        "tablespace": False,
1797        "access_method": False,
1798        "file_format": False,
1799        "copy_options": False,
1800        "tag": False,
1801        "location": False,
1802        "serde": False,
1803    }
arg_types = {'expressions': False, 'option': False, 'tablespace': False, 'access_method': False, 'file_format': False, 'copy_options': False, 'tag': False, 'location': False, 'serde': False}
key = 'alterset'
class RenameColumn(Expression):
1806class RenameColumn(Expression):
1807    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1810class AlterRename(Expression):
1811    pass
key = 'alterrename'
class SwapTable(Expression):
1814class SwapTable(Expression):
1815    pass
key = 'swaptable'
class Comment(Expression):
1818class Comment(Expression):
1819    arg_types = {
1820        "this": True,
1821        "kind": True,
1822        "expression": True,
1823        "exists": False,
1824        "materialized": False,
1825    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1828class Comprehension(Expression):
1829    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
arg_types = {'this': True, 'expression': True, 'iterator': True, 'condition': False}
key = 'comprehension'
class MergeTreeTTLAction(Expression):
1833class MergeTreeTTLAction(Expression):
1834    arg_types = {
1835        "this": True,
1836        "delete": False,
1837        "recompress": False,
1838        "to_disk": False,
1839        "to_volume": False,
1840    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1844class MergeTreeTTL(Expression):
1845    arg_types = {
1846        "expressions": True,
1847        "where": False,
1848        "group": False,
1849        "aggregates": False,
1850    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1854class IndexConstraintOption(Expression):
1855    arg_types = {
1856        "key_block_size": False,
1857        "using": False,
1858        "parser": False,
1859        "comment": False,
1860        "visible": False,
1861        "engine_attr": False,
1862        "secondary_engine_attr": False,
1863    }
arg_types = {'key_block_size': False, 'using': False, 'parser': False, 'comment': False, 'visible': False, 'engine_attr': False, 'secondary_engine_attr': False}
key = 'indexconstraintoption'
class ColumnConstraint(Expression):
1866class ColumnConstraint(Expression):
1867    arg_types = {"this": False, "kind": True}
1868
1869    @property
1870    def kind(self) -> ColumnConstraintKind:
1871        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1869    @property
1870    def kind(self) -> ColumnConstraintKind:
1871        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1874class ColumnConstraintKind(Expression):
1875    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1878class AutoIncrementColumnConstraint(ColumnConstraintKind):
1879    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1882class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1883    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1886class CaseSpecificColumnConstraint(ColumnConstraintKind):
1887    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1890class CharacterSetColumnConstraint(ColumnConstraintKind):
1891    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1894class CheckColumnConstraint(ColumnConstraintKind):
1895    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1898class ClusteredColumnConstraint(ColumnConstraintKind):
1899    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1902class CollateColumnConstraint(ColumnConstraintKind):
1903    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1906class CommentColumnConstraint(ColumnConstraintKind):
1907    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1910class CompressColumnConstraint(ColumnConstraintKind):
1911    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1914class DateFormatColumnConstraint(ColumnConstraintKind):
1915    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1918class DefaultColumnConstraint(ColumnConstraintKind):
1919    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1922class EncodeColumnConstraint(ColumnConstraintKind):
1923    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1927class ExcludeColumnConstraint(ColumnConstraintKind):
1928    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1931class EphemeralColumnConstraint(ColumnConstraintKind):
1932    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1935class WithOperator(Expression):
1936    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1939class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1940    # this: True -> ALWAYS, this: False -> BY DEFAULT
1941    arg_types = {
1942        "this": False,
1943        "expression": False,
1944        "on_null": False,
1945        "start": False,
1946        "increment": False,
1947        "minvalue": False,
1948        "maxvalue": False,
1949        "cycle": False,
1950    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1953class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1954    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1959class IndexColumnConstraint(ColumnConstraintKind):
1960    arg_types = {
1961        "this": False,
1962        "expressions": False,
1963        "kind": False,
1964        "index_type": False,
1965        "options": False,
1966        "expression": False,  # Clickhouse
1967        "granularity": False,
1968    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1971class InlineLengthColumnConstraint(ColumnConstraintKind):
1972    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1975class NonClusteredColumnConstraint(ColumnConstraintKind):
1976    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1979class NotForReplicationColumnConstraint(ColumnConstraintKind):
1980    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1984class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1985    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1988class NotNullColumnConstraint(ColumnConstraintKind):
1989    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1993class OnUpdateColumnConstraint(ColumnConstraintKind):
1994    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1998class TransformColumnConstraint(ColumnConstraintKind):
1999    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2002class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2003    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2006class TitleColumnConstraint(ColumnConstraintKind):
2007    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2010class UniqueColumnConstraint(ColumnConstraintKind):
2011    arg_types = {
2012        "this": False,
2013        "index_type": False,
2014        "on_conflict": False,
2015        "nulls": False,
2016        "options": False,
2017    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2020class UppercaseColumnConstraint(ColumnConstraintKind):
2021    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2025class WatermarkColumnConstraint(Expression):
2026    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2029class PathColumnConstraint(ColumnConstraintKind):
2030    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2034class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2035    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2040class ComputedColumnConstraint(ColumnConstraintKind):
2041    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2044class Constraint(Expression):
2045    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2048class Delete(DML):
2049    arg_types = {
2050        "with": False,
2051        "this": False,
2052        "using": False,
2053        "where": False,
2054        "returning": False,
2055        "limit": False,
2056        "tables": False,  # Multiple-Table Syntax (MySQL)
2057        "cluster": False,  # Clickhouse
2058    }
2059
2060    def delete(
2061        self,
2062        table: ExpOrStr,
2063        dialect: DialectType = None,
2064        copy: bool = True,
2065        **opts,
2066    ) -> Delete:
2067        """
2068        Create a DELETE expression or replace the table on an existing DELETE expression.
2069
2070        Example:
2071            >>> delete("tbl").sql()
2072            'DELETE FROM tbl'
2073
2074        Args:
2075            table: the table from which to delete.
2076            dialect: the dialect used to parse the input expression.
2077            copy: if `False`, modify this expression instance in-place.
2078            opts: other options to use to parse the input expressions.
2079
2080        Returns:
2081            Delete: the modified expression.
2082        """
2083        return _apply_builder(
2084            expression=table,
2085            instance=self,
2086            arg="this",
2087            dialect=dialect,
2088            into=Table,
2089            copy=copy,
2090            **opts,
2091        )
2092
2093    def where(
2094        self,
2095        *expressions: t.Optional[ExpOrStr],
2096        append: bool = True,
2097        dialect: DialectType = None,
2098        copy: bool = True,
2099        **opts,
2100    ) -> Delete:
2101        """
2102        Append to or set the WHERE expressions.
2103
2104        Example:
2105            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2106            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2107
2108        Args:
2109            *expressions: the SQL code strings to parse.
2110                If an `Expression` instance is passed, it will be used as-is.
2111                Multiple expressions are combined with an AND operator.
2112            append: if `True`, AND the new expressions to any existing expression.
2113                Otherwise, this resets the expression.
2114            dialect: the dialect used to parse the input expressions.
2115            copy: if `False`, modify this expression instance in-place.
2116            opts: other options to use to parse the input expressions.
2117
2118        Returns:
2119            Delete: the modified expression.
2120        """
2121        return _apply_conjunction_builder(
2122            *expressions,
2123            instance=self,
2124            arg="where",
2125            append=append,
2126            into=Where,
2127            dialect=dialect,
2128            copy=copy,
2129            **opts,
2130        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2060    def delete(
2061        self,
2062        table: ExpOrStr,
2063        dialect: DialectType = None,
2064        copy: bool = True,
2065        **opts,
2066    ) -> Delete:
2067        """
2068        Create a DELETE expression or replace the table on an existing DELETE expression.
2069
2070        Example:
2071            >>> delete("tbl").sql()
2072            'DELETE FROM tbl'
2073
2074        Args:
2075            table: the table from which to delete.
2076            dialect: the dialect used to parse the input expression.
2077            copy: if `False`, modify this expression instance in-place.
2078            opts: other options to use to parse the input expressions.
2079
2080        Returns:
2081            Delete: the modified expression.
2082        """
2083        return _apply_builder(
2084            expression=table,
2085            instance=self,
2086            arg="this",
2087            dialect=dialect,
2088            into=Table,
2089            copy=copy,
2090            **opts,
2091        )

Create a DELETE expression or replace the table on an existing DELETE expression.

Example:
>>> delete("tbl").sql()
'DELETE FROM tbl'
Arguments:
  • table: the table from which to delete.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2093    def where(
2094        self,
2095        *expressions: t.Optional[ExpOrStr],
2096        append: bool = True,
2097        dialect: DialectType = None,
2098        copy: bool = True,
2099        **opts,
2100    ) -> Delete:
2101        """
2102        Append to or set the WHERE expressions.
2103
2104        Example:
2105            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2106            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2107
2108        Args:
2109            *expressions: the SQL code strings to parse.
2110                If an `Expression` instance is passed, it will be used as-is.
2111                Multiple expressions are combined with an AND operator.
2112            append: if `True`, AND the new expressions to any existing expression.
2113                Otherwise, this resets the expression.
2114            dialect: the dialect used to parse the input expressions.
2115            copy: if `False`, modify this expression instance in-place.
2116            opts: other options to use to parse the input expressions.
2117
2118        Returns:
2119            Delete: the modified expression.
2120        """
2121        return _apply_conjunction_builder(
2122            *expressions,
2123            instance=self,
2124            arg="where",
2125            append=append,
2126            into=Where,
2127            dialect=dialect,
2128            copy=copy,
2129            **opts,
2130        )

Append to or set the WHERE expressions.

Example:
>>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
"DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
2133class Drop(Expression):
2134    arg_types = {
2135        "this": False,
2136        "kind": False,
2137        "expressions": False,
2138        "exists": False,
2139        "temporary": False,
2140        "materialized": False,
2141        "cascade": False,
2142        "constraints": False,
2143        "purge": False,
2144        "cluster": False,
2145        "concurrently": False,
2146    }
2147
2148    @property
2149    def kind(self) -> t.Optional[str]:
2150        kind = self.args.get("kind")
2151        return kind and kind.upper()
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False, 'concurrently': False}
kind: Optional[str]
2148    @property
2149    def kind(self) -> t.Optional[str]:
2150        kind = self.args.get("kind")
2151        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2155class Export(Expression):
2156    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2159class Filter(Expression):
2160    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2163class Check(Expression):
2164    pass
key = 'check'
class Changes(Expression):
2167class Changes(Expression):
2168    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2172class Connect(Expression):
2173    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2176class CopyParameter(Expression):
2177    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2180class Copy(DML):
2181    arg_types = {
2182        "this": True,
2183        "kind": True,
2184        "files": True,
2185        "credentials": False,
2186        "format": False,
2187        "params": False,
2188    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2191class Credentials(Expression):
2192    arg_types = {
2193        "credentials": False,
2194        "encryption": False,
2195        "storage": False,
2196        "iam_role": False,
2197        "region": False,
2198    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2201class Prior(Expression):
2202    pass
key = 'prior'
class Directory(Expression):
2205class Directory(Expression):
2206    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2207    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2210class ForeignKey(Expression):
2211    arg_types = {
2212        "expressions": False,
2213        "reference": False,
2214        "delete": False,
2215        "update": False,
2216        "options": False,
2217    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2220class ColumnPrefix(Expression):
2221    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2224class PrimaryKey(Expression):
2225    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2230class Into(Expression):
2231    arg_types = {
2232        "this": False,
2233        "temporary": False,
2234        "unlogged": False,
2235        "bulk_collect": False,
2236        "expressions": False,
2237    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2240class From(Expression):
2241    @property
2242    def name(self) -> str:
2243        return self.this.name
2244
2245    @property
2246    def alias_or_name(self) -> str:
2247        return self.this.alias_or_name
name: str
2241    @property
2242    def name(self) -> str:
2243        return self.this.name
alias_or_name: str
2245    @property
2246    def alias_or_name(self) -> str:
2247        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2250class Having(Expression):
2251    pass
key = 'having'
class Hint(Expression):
2254class Hint(Expression):
2255    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2258class JoinHint(Expression):
2259    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2262class Identifier(Expression):
2263    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2264
2265    @property
2266    def quoted(self) -> bool:
2267        return bool(self.args.get("quoted"))
2268
2269    @property
2270    def hashable_args(self) -> t.Any:
2271        return (self.this, self.quoted)
2272
2273    @property
2274    def output_name(self) -> str:
2275        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2265    @property
2266    def quoted(self) -> bool:
2267        return bool(self.args.get("quoted"))
hashable_args: Any
2269    @property
2270    def hashable_args(self) -> t.Any:
2271        return (self.this, self.quoted)
output_name: str
2273    @property
2274    def output_name(self) -> str:
2275        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
2279class Opclass(Expression):
2280    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2283class Index(Expression):
2284    arg_types = {
2285        "this": False,
2286        "table": False,
2287        "unique": False,
2288        "primary": False,
2289        "amp": False,  # teradata
2290        "params": False,
2291    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2294class IndexParameters(Expression):
2295    arg_types = {
2296        "using": False,
2297        "include": False,
2298        "columns": False,
2299        "with_storage": False,
2300        "partition_by": False,
2301        "tablespace": False,
2302        "where": False,
2303        "on": False,
2304    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
class Insert(DDL, DML):
2307class Insert(DDL, DML):
2308    arg_types = {
2309        "hint": False,
2310        "with": False,
2311        "is_function": False,
2312        "this": False,
2313        "expression": False,
2314        "conflict": False,
2315        "returning": False,
2316        "overwrite": False,
2317        "exists": False,
2318        "alternative": False,
2319        "where": False,
2320        "ignore": False,
2321        "by_name": False,
2322        "stored": False,
2323        "partition": False,
2324        "settings": False,
2325        "source": False,
2326    }
2327
2328    def with_(
2329        self,
2330        alias: ExpOrStr,
2331        as_: ExpOrStr,
2332        recursive: t.Optional[bool] = None,
2333        materialized: t.Optional[bool] = None,
2334        append: bool = True,
2335        dialect: DialectType = None,
2336        copy: bool = True,
2337        **opts,
2338    ) -> Insert:
2339        """
2340        Append to or set the common table expressions.
2341
2342        Example:
2343            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2344            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2345
2346        Args:
2347            alias: the SQL code string to parse as the table name.
2348                If an `Expression` instance is passed, this is used as-is.
2349            as_: the SQL code string to parse as the table expression.
2350                If an `Expression` instance is passed, it will be used as-is.
2351            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2352            materialized: set the MATERIALIZED part of the expression.
2353            append: if `True`, add to any existing expressions.
2354                Otherwise, this resets the expressions.
2355            dialect: the dialect used to parse the input expression.
2356            copy: if `False`, modify this expression instance in-place.
2357            opts: other options to use to parse the input expressions.
2358
2359        Returns:
2360            The modified expression.
2361        """
2362        return _apply_cte_builder(
2363            self,
2364            alias,
2365            as_,
2366            recursive=recursive,
2367            materialized=materialized,
2368            append=append,
2369            dialect=dialect,
2370            copy=copy,
2371            **opts,
2372        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2328    def with_(
2329        self,
2330        alias: ExpOrStr,
2331        as_: ExpOrStr,
2332        recursive: t.Optional[bool] = None,
2333        materialized: t.Optional[bool] = None,
2334        append: bool = True,
2335        dialect: DialectType = None,
2336        copy: bool = True,
2337        **opts,
2338    ) -> Insert:
2339        """
2340        Append to or set the common table expressions.
2341
2342        Example:
2343            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2344            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2345
2346        Args:
2347            alias: the SQL code string to parse as the table name.
2348                If an `Expression` instance is passed, this is used as-is.
2349            as_: the SQL code string to parse as the table expression.
2350                If an `Expression` instance is passed, it will be used as-is.
2351            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2352            materialized: set the MATERIALIZED part of the expression.
2353            append: if `True`, add to any existing expressions.
2354                Otherwise, this resets the expressions.
2355            dialect: the dialect used to parse the input expression.
2356            copy: if `False`, modify this expression instance in-place.
2357            opts: other options to use to parse the input expressions.
2358
2359        Returns:
2360            The modified expression.
2361        """
2362        return _apply_cte_builder(
2363            self,
2364            alias,
2365            as_,
2366            recursive=recursive,
2367            materialized=materialized,
2368            append=append,
2369            dialect=dialect,
2370            copy=copy,
2371            **opts,
2372        )

Append to or set the common table expressions.

Example:
>>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • materialized: set the MATERIALIZED part of the expression.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

key = 'insert'
class ConditionalInsert(Expression):
2375class ConditionalInsert(Expression):
2376    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2379class MultitableInserts(Expression):
2380    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2383class OnConflict(Expression):
2384    arg_types = {
2385        "duplicate": False,
2386        "expressions": False,
2387        "action": False,
2388        "conflict_keys": False,
2389        "constraint": False,
2390        "where": False,
2391    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2394class OnCondition(Expression):
2395    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2398class Returning(Expression):
2399    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2403class Introducer(Expression):
2404    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2408class National(Expression):
2409    pass
key = 'national'
class LoadData(Expression):
2412class LoadData(Expression):
2413    arg_types = {
2414        "this": True,
2415        "local": False,
2416        "overwrite": False,
2417        "inpath": True,
2418        "partition": False,
2419        "input_format": False,
2420        "serde": False,
2421    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2424class Partition(Expression):
2425    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2428class PartitionRange(Expression):
2429    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2433class PartitionId(Expression):
2434    pass
key = 'partitionid'
class Fetch(Expression):
2437class Fetch(Expression):
2438    arg_types = {
2439        "direction": False,
2440        "count": False,
2441        "limit_options": False,
2442    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2445class Grant(Expression):
2446    arg_types = {
2447        "privileges": True,
2448        "kind": False,
2449        "securable": True,
2450        "principals": True,
2451        "grant_option": False,
2452    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2455class Group(Expression):
2456    arg_types = {
2457        "expressions": False,
2458        "grouping_sets": False,
2459        "cube": False,
2460        "rollup": False,
2461        "totals": False,
2462        "all": False,
2463    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2466class Cube(Expression):
2467    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2470class Rollup(Expression):
2471    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2474class GroupingSets(Expression):
2475    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2478class Lambda(Expression):
2479    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2482class Limit(Expression):
2483    arg_types = {
2484        "this": False,
2485        "expression": True,
2486        "offset": False,
2487        "limit_options": False,
2488        "expressions": False,
2489    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2492class LimitOptions(Expression):
2493    arg_types = {
2494        "percent": False,
2495        "rows": False,
2496        "with_ties": False,
2497    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2500class Literal(Condition):
2501    arg_types = {"this": True, "is_string": True}
2502
2503    @property
2504    def hashable_args(self) -> t.Any:
2505        return (self.this, self.args.get("is_string"))
2506
2507    @classmethod
2508    def number(cls, number) -> Literal:
2509        return cls(this=str(number), is_string=False)
2510
2511    @classmethod
2512    def string(cls, string) -> Literal:
2513        return cls(this=str(string), is_string=True)
2514
2515    @property
2516    def output_name(self) -> str:
2517        return self.name
2518
2519    def to_py(self) -> int | str | Decimal:
2520        if self.is_number:
2521            try:
2522                return int(self.this)
2523            except ValueError:
2524                return Decimal(self.this)
2525        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2503    @property
2504    def hashable_args(self) -> t.Any:
2505        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2507    @classmethod
2508    def number(cls, number) -> Literal:
2509        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2511    @classmethod
2512    def string(cls, string) -> Literal:
2513        return cls(this=str(string), is_string=True)
output_name: str
2515    @property
2516    def output_name(self) -> str:
2517        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def to_py(self) -> int | str | decimal.Decimal:
2519    def to_py(self) -> int | str | Decimal:
2520        if self.is_number:
2521            try:
2522                return int(self.this)
2523            except ValueError:
2524                return Decimal(self.this)
2525        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2528class Join(Expression):
2529    arg_types = {
2530        "this": True,
2531        "on": False,
2532        "side": False,
2533        "kind": False,
2534        "using": False,
2535        "method": False,
2536        "global": False,
2537        "hint": False,
2538        "match_condition": False,  # Snowflake
2539        "expressions": False,
2540        "pivots": False,
2541    }
2542
2543    @property
2544    def method(self) -> str:
2545        return self.text("method").upper()
2546
2547    @property
2548    def kind(self) -> str:
2549        return self.text("kind").upper()
2550
2551    @property
2552    def side(self) -> str:
2553        return self.text("side").upper()
2554
2555    @property
2556    def hint(self) -> str:
2557        return self.text("hint").upper()
2558
2559    @property
2560    def alias_or_name(self) -> str:
2561        return self.this.alias_or_name
2562
2563    @property
2564    def is_semi_or_anti_join(self) -> bool:
2565        return self.kind in ("SEMI", "ANTI")
2566
2567    def on(
2568        self,
2569        *expressions: t.Optional[ExpOrStr],
2570        append: bool = True,
2571        dialect: DialectType = None,
2572        copy: bool = True,
2573        **opts,
2574    ) -> Join:
2575        """
2576        Append to or set the ON expressions.
2577
2578        Example:
2579            >>> import sqlglot
2580            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2581            'JOIN x ON y = 1'
2582
2583        Args:
2584            *expressions: the SQL code strings to parse.
2585                If an `Expression` instance is passed, it will be used as-is.
2586                Multiple expressions are combined with an AND operator.
2587            append: if `True`, AND the new expressions to any existing expression.
2588                Otherwise, this resets the expression.
2589            dialect: the dialect used to parse the input expressions.
2590            copy: if `False`, modify this expression instance in-place.
2591            opts: other options to use to parse the input expressions.
2592
2593        Returns:
2594            The modified Join expression.
2595        """
2596        join = _apply_conjunction_builder(
2597            *expressions,
2598            instance=self,
2599            arg="on",
2600            append=append,
2601            dialect=dialect,
2602            copy=copy,
2603            **opts,
2604        )
2605
2606        if join.kind == "CROSS":
2607            join.set("kind", None)
2608
2609        return join
2610
2611    def using(
2612        self,
2613        *expressions: t.Optional[ExpOrStr],
2614        append: bool = True,
2615        dialect: DialectType = None,
2616        copy: bool = True,
2617        **opts,
2618    ) -> Join:
2619        """
2620        Append to or set the USING expressions.
2621
2622        Example:
2623            >>> import sqlglot
2624            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2625            'JOIN x USING (foo, bla)'
2626
2627        Args:
2628            *expressions: the SQL code strings to parse.
2629                If an `Expression` instance is passed, it will be used as-is.
2630            append: if `True`, concatenate the new expressions to the existing "using" list.
2631                Otherwise, this resets the expression.
2632            dialect: the dialect used to parse the input expressions.
2633            copy: if `False`, modify this expression instance in-place.
2634            opts: other options to use to parse the input expressions.
2635
2636        Returns:
2637            The modified Join expression.
2638        """
2639        join = _apply_list_builder(
2640            *expressions,
2641            instance=self,
2642            arg="using",
2643            append=append,
2644            dialect=dialect,
2645            copy=copy,
2646            **opts,
2647        )
2648
2649        if join.kind == "CROSS":
2650            join.set("kind", None)
2651
2652        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False, 'pivots': False}
method: str
2543    @property
2544    def method(self) -> str:
2545        return self.text("method").upper()
kind: str
2547    @property
2548    def kind(self) -> str:
2549        return self.text("kind").upper()
side: str
2551    @property
2552    def side(self) -> str:
2553        return self.text("side").upper()
hint: str
2555    @property
2556    def hint(self) -> str:
2557        return self.text("hint").upper()
alias_or_name: str
2559    @property
2560    def alias_or_name(self) -> str:
2561        return self.this.alias_or_name
is_semi_or_anti_join: bool
2563    @property
2564    def is_semi_or_anti_join(self) -> bool:
2565        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2567    def on(
2568        self,
2569        *expressions: t.Optional[ExpOrStr],
2570        append: bool = True,
2571        dialect: DialectType = None,
2572        copy: bool = True,
2573        **opts,
2574    ) -> Join:
2575        """
2576        Append to or set the ON expressions.
2577
2578        Example:
2579            >>> import sqlglot
2580            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2581            'JOIN x ON y = 1'
2582
2583        Args:
2584            *expressions: the SQL code strings to parse.
2585                If an `Expression` instance is passed, it will be used as-is.
2586                Multiple expressions are combined with an AND operator.
2587            append: if `True`, AND the new expressions to any existing expression.
2588                Otherwise, this resets the expression.
2589            dialect: the dialect used to parse the input expressions.
2590            copy: if `False`, modify this expression instance in-place.
2591            opts: other options to use to parse the input expressions.
2592
2593        Returns:
2594            The modified Join expression.
2595        """
2596        join = _apply_conjunction_builder(
2597            *expressions,
2598            instance=self,
2599            arg="on",
2600            append=append,
2601            dialect=dialect,
2602            copy=copy,
2603            **opts,
2604        )
2605
2606        if join.kind == "CROSS":
2607            join.set("kind", None)
2608
2609        return join

Append to or set the ON expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
'JOIN x ON y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2611    def using(
2612        self,
2613        *expressions: t.Optional[ExpOrStr],
2614        append: bool = True,
2615        dialect: DialectType = None,
2616        copy: bool = True,
2617        **opts,
2618    ) -> Join:
2619        """
2620        Append to or set the USING expressions.
2621
2622        Example:
2623            >>> import sqlglot
2624            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2625            'JOIN x USING (foo, bla)'
2626
2627        Args:
2628            *expressions: the SQL code strings to parse.
2629                If an `Expression` instance is passed, it will be used as-is.
2630            append: if `True`, concatenate the new expressions to the existing "using" list.
2631                Otherwise, this resets the expression.
2632            dialect: the dialect used to parse the input expressions.
2633            copy: if `False`, modify this expression instance in-place.
2634            opts: other options to use to parse the input expressions.
2635
2636        Returns:
2637            The modified Join expression.
2638        """
2639        join = _apply_list_builder(
2640            *expressions,
2641            instance=self,
2642            arg="using",
2643            append=append,
2644            dialect=dialect,
2645            copy=copy,
2646            **opts,
2647        )
2648
2649        if join.kind == "CROSS":
2650            join.set("kind", None)
2651
2652        return join

Append to or set the USING expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
'JOIN x USING (foo, bla)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, concatenate the new expressions to the existing "using" list. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

key = 'join'
class Lateral(UDTF):
2655class Lateral(UDTF):
2656    arg_types = {
2657        "this": True,
2658        "view": False,
2659        "outer": False,
2660        "alias": False,
2661        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2662        "ordinality": False,
2663    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2668class TableFromRows(UDTF):
2669    arg_types = {
2670        "this": True,
2671        "alias": False,
2672        "joins": False,
2673        "pivots": False,
2674        "sample": False,
2675    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2678class MatchRecognizeMeasure(Expression):
2679    arg_types = {
2680        "this": True,
2681        "window_frame": False,
2682    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2685class MatchRecognize(Expression):
2686    arg_types = {
2687        "partition_by": False,
2688        "order": False,
2689        "measures": False,
2690        "rows": False,
2691        "after": False,
2692        "pattern": False,
2693        "define": False,
2694        "alias": False,
2695    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2700class Final(Expression):
2701    pass
key = 'final'
class Offset(Expression):
2704class Offset(Expression):
2705    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2708class Order(Expression):
2709    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2713class WithFill(Expression):
2714    arg_types = {
2715        "from": False,
2716        "to": False,
2717        "step": False,
2718        "interpolate": False,
2719    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2724class Cluster(Order):
2725    pass
key = 'cluster'
class Distribute(Order):
2728class Distribute(Order):
2729    pass
key = 'distribute'
class Sort(Order):
2732class Sort(Order):
2733    pass
key = 'sort'
class Ordered(Expression):
2736class Ordered(Expression):
2737    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2738
2739    @property
2740    def name(self) -> str:
2741        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2739    @property
2740    def name(self) -> str:
2741        return self.this.name
key = 'ordered'
class Property(Expression):
2744class Property(Expression):
2745    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2748class GrantPrivilege(Expression):
2749    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2752class GrantPrincipal(Expression):
2753    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2756class AllowedValuesProperty(Expression):
2757    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2760class AlgorithmProperty(Property):
2761    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2764class AutoIncrementProperty(Property):
2765    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2769class AutoRefreshProperty(Property):
2770    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2773class BackupProperty(Property):
2774    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2777class BlockCompressionProperty(Property):
2778    arg_types = {
2779        "autotemp": False,
2780        "always": False,
2781        "default": False,
2782        "manual": False,
2783        "never": False,
2784    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2787class CharacterSetProperty(Property):
2788    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2791class ChecksumProperty(Property):
2792    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2795class CollateProperty(Property):
2796    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2799class CopyGrantsProperty(Property):
2800    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2803class DataBlocksizeProperty(Property):
2804    arg_types = {
2805        "size": False,
2806        "units": False,
2807        "minimum": False,
2808        "maximum": False,
2809        "default": False,
2810    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2813class DataDeletionProperty(Property):
2814    arg_types = {"on": True, "filter_col": False, "retention_period": False}
arg_types = {'on': True, 'filter_col': False, 'retention_period': False}
key = 'datadeletionproperty'
class DefinerProperty(Property):
2817class DefinerProperty(Property):
2818    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2821class DistKeyProperty(Property):
2822    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2827class DistributedByProperty(Property):
2828    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
arg_types = {'expressions': False, 'kind': True, 'buckets': False, 'order': False}
key = 'distributedbyproperty'
class DistStyleProperty(Property):
2831class DistStyleProperty(Property):
2832    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2835class DuplicateKeyProperty(Property):
2836    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2839class EngineProperty(Property):
2840    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2843class HeapProperty(Property):
2844    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2847class ToTableProperty(Property):
2848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2851class ExecuteAsProperty(Property):
2852    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2855class ExternalProperty(Property):
2856    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2859class FallbackProperty(Property):
2860    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2863class FileFormatProperty(Property):
2864    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2867class CredentialsProperty(Property):
2868    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2871class FreespaceProperty(Property):
2872    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2875class GlobalProperty(Property):
2876    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2879class IcebergProperty(Property):
2880    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2883class InheritsProperty(Property):
2884    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2887class InputModelProperty(Property):
2888    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2891class OutputModelProperty(Property):
2892    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2895class IsolatedLoadingProperty(Property):
2896    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2899class JournalProperty(Property):
2900    arg_types = {
2901        "no": False,
2902        "dual": False,
2903        "before": False,
2904        "local": False,
2905        "after": False,
2906    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2909class LanguageProperty(Property):
2910    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2913class EnviromentProperty(Property):
2914    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2918class ClusteredByProperty(Property):
2919    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2922class DictProperty(Property):
2923    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2926class DictSubProperty(Property):
2927    pass
key = 'dictsubproperty'
class DictRange(Property):
2930class DictRange(Property):
2931    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2934class DynamicProperty(Property):
2935    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2940class OnCluster(Property):
2941    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2945class EmptyProperty(Property):
2946    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2949class LikeProperty(Property):
2950    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2953class LocationProperty(Property):
2954    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2957class LockProperty(Property):
2958    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2961class LockingProperty(Property):
2962    arg_types = {
2963        "this": False,
2964        "kind": True,
2965        "for_or_in": False,
2966        "lock_type": True,
2967        "override": False,
2968    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2971class LogProperty(Property):
2972    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2975class MaterializedProperty(Property):
2976    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2979class MergeBlockRatioProperty(Property):
2980    arg_types = {"this": False, "no": False, "default": False, "percent": False}
arg_types = {'this': False, 'no': False, 'default': False, 'percent': False}
key = 'mergeblockratioproperty'
class NoPrimaryIndexProperty(Property):
2983class NoPrimaryIndexProperty(Property):
2984    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2987class OnProperty(Property):
2988    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2991class OnCommitProperty(Property):
2992    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2995class PartitionedByProperty(Property):
2996    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
2999class PartitionedByBucket(Property):
3000    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3003class PartitionByTruncate(Property):
3004    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3008class PartitionByRangeProperty(Property):
3009    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3013class PartitionByRangePropertyDynamic(Expression):
3014    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class UniqueKeyProperty(Property):
3018class UniqueKeyProperty(Property):
3019    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3023class PartitionBoundSpec(Expression):
3024    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3025    arg_types = {
3026        "this": False,
3027        "expression": False,
3028        "from_expressions": False,
3029        "to_expressions": False,
3030    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3033class PartitionedOfProperty(Property):
3034    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3035    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3038class StreamingTableProperty(Property):
3039    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3042class RemoteWithConnectionModelProperty(Property):
3043    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3046class ReturnsProperty(Property):
3047    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
arg_types = {'this': False, 'is_table': False, 'table': False, 'null': False}
key = 'returnsproperty'
class StrictProperty(Property):
3050class StrictProperty(Property):
3051    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3054class RowFormatProperty(Property):
3055    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3058class RowFormatDelimitedProperty(Property):
3059    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3060    arg_types = {
3061        "fields": False,
3062        "escaped": False,
3063        "collection_items": False,
3064        "map_keys": False,
3065        "lines": False,
3066        "null": False,
3067        "serde": False,
3068    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3071class RowFormatSerdeProperty(Property):
3072    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3076class QueryTransform(Expression):
3077    arg_types = {
3078        "expressions": True,
3079        "command_script": True,
3080        "schema": False,
3081        "row_format_before": False,
3082        "record_writer": False,
3083        "row_format_after": False,
3084        "record_reader": False,
3085    }
arg_types = {'expressions': True, 'command_script': True, 'schema': False, 'row_format_before': False, 'record_writer': False, 'row_format_after': False, 'record_reader': False}
key = 'querytransform'
class SampleProperty(Property):
3088class SampleProperty(Property):
3089    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3093class SecurityProperty(Property):
3094    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3097class SchemaCommentProperty(Property):
3098    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
3101class SerdeProperties(Property):
3102    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3105class SetProperty(Property):
3106    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3109class SharingProperty(Property):
3110    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3113class SetConfigProperty(Property):
3114    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3117class SettingsProperty(Property):
3118    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3121class SortKeyProperty(Property):
3122    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3125class SqlReadWriteProperty(Property):
3126    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3129class SqlSecurityProperty(Property):
3130    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3133class StabilityProperty(Property):
3134    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3137class StorageHandlerProperty(Property):
3138    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3141class TemporaryProperty(Property):
3142    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3145class SecureProperty(Property):
3146    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3150class Tags(ColumnConstraintKind, Property):
3151    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3154class TransformModelProperty(Property):
3155    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3158class TransientProperty(Property):
3159    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3162class UnloggedProperty(Property):
3163    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3167class UsingTemplateProperty(Property):
3168    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3172class ViewAttributeProperty(Property):
3173    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3176class VolatileProperty(Property):
3177    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3180class WithDataProperty(Property):
3181    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3184class WithJournalTableProperty(Property):
3185    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3188class WithSchemaBindingProperty(Property):
3189    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3192class WithSystemVersioningProperty(Property):
3193    arg_types = {
3194        "on": False,
3195        "this": False,
3196        "data_consistency": False,
3197        "retention_period": False,
3198        "with": True,
3199    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3202class WithProcedureOptions(Property):
3203    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3206class EncodeProperty(Property):
3207    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3210class IncludeProperty(Property):
3211    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3214class ForceProperty(Property):
3215    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3218class Properties(Expression):
3219    arg_types = {"expressions": True}
3220
3221    NAME_TO_PROPERTY = {
3222        "ALGORITHM": AlgorithmProperty,
3223        "AUTO_INCREMENT": AutoIncrementProperty,
3224        "CHARACTER SET": CharacterSetProperty,
3225        "CLUSTERED_BY": ClusteredByProperty,
3226        "COLLATE": CollateProperty,
3227        "COMMENT": SchemaCommentProperty,
3228        "CREDENTIALS": CredentialsProperty,
3229        "DEFINER": DefinerProperty,
3230        "DISTKEY": DistKeyProperty,
3231        "DISTRIBUTED_BY": DistributedByProperty,
3232        "DISTSTYLE": DistStyleProperty,
3233        "ENGINE": EngineProperty,
3234        "EXECUTE AS": ExecuteAsProperty,
3235        "FORMAT": FileFormatProperty,
3236        "LANGUAGE": LanguageProperty,
3237        "LOCATION": LocationProperty,
3238        "LOCK": LockProperty,
3239        "PARTITIONED_BY": PartitionedByProperty,
3240        "RETURNS": ReturnsProperty,
3241        "ROW_FORMAT": RowFormatProperty,
3242        "SORTKEY": SortKeyProperty,
3243        "ENCODE": EncodeProperty,
3244        "INCLUDE": IncludeProperty,
3245    }
3246
3247    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3248
3249    # CREATE property locations
3250    # Form: schema specified
3251    #   create [POST_CREATE]
3252    #     table a [POST_NAME]
3253    #     (b int) [POST_SCHEMA]
3254    #     with ([POST_WITH])
3255    #     index (b) [POST_INDEX]
3256    #
3257    # Form: alias selection
3258    #   create [POST_CREATE]
3259    #     table a [POST_NAME]
3260    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3261    #     index (c) [POST_INDEX]
3262    class Location(AutoName):
3263        POST_CREATE = auto()
3264        POST_NAME = auto()
3265        POST_SCHEMA = auto()
3266        POST_WITH = auto()
3267        POST_ALIAS = auto()
3268        POST_EXPRESSION = auto()
3269        POST_INDEX = auto()
3270        UNSUPPORTED = auto()
3271
3272    @classmethod
3273    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3274        expressions = []
3275        for key, value in properties_dict.items():
3276            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3277            if property_cls:
3278                expressions.append(property_cls(this=convert(value)))
3279            else:
3280                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3281
3282        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'CREDENTIALS': <class 'CredentialsProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>, 'ENCODE': <class 'EncodeProperty'>, 'INCLUDE': <class 'IncludeProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'CredentialsProperty'>: 'CREDENTIALS', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistributedByProperty'>: 'DISTRIBUTED_BY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY', <class 'EncodeProperty'>: 'ENCODE', <class 'IncludeProperty'>: 'INCLUDE'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3272    @classmethod
3273    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3274        expressions = []
3275        for key, value in properties_dict.items():
3276            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3277            if property_cls:
3278                expressions.append(property_cls(this=convert(value)))
3279            else:
3280                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3281
3282        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3262    class Location(AutoName):
3263        POST_CREATE = auto()
3264        POST_NAME = auto()
3265        POST_SCHEMA = auto()
3266        POST_WITH = auto()
3267        POST_ALIAS = auto()
3268        POST_EXPRESSION = auto()
3269        POST_INDEX = auto()
3270        UNSUPPORTED = auto()

An enumeration.

POST_CREATE = <Location.POST_CREATE: 'POST_CREATE'>
POST_NAME = <Location.POST_NAME: 'POST_NAME'>
POST_SCHEMA = <Location.POST_SCHEMA: 'POST_SCHEMA'>
POST_WITH = <Location.POST_WITH: 'POST_WITH'>
POST_ALIAS = <Location.POST_ALIAS: 'POST_ALIAS'>
POST_EXPRESSION = <Location.POST_EXPRESSION: 'POST_EXPRESSION'>
POST_INDEX = <Location.POST_INDEX: 'POST_INDEX'>
UNSUPPORTED = <Location.UNSUPPORTED: 'UNSUPPORTED'>
class Qualify(Expression):
3285class Qualify(Expression):
3286    pass
key = 'qualify'
class InputOutputFormat(Expression):
3289class InputOutputFormat(Expression):
3290    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3294class Return(Expression):
3295    pass
key = 'return'
class Reference(Expression):
3298class Reference(Expression):
3299    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3302class Tuple(Expression):
3303    arg_types = {"expressions": False}
3304
3305    def isin(
3306        self,
3307        *expressions: t.Any,
3308        query: t.Optional[ExpOrStr] = None,
3309        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3310        copy: bool = True,
3311        **opts,
3312    ) -> In:
3313        return In(
3314            this=maybe_copy(self, copy),
3315            expressions=[convert(e, copy=copy) for e in expressions],
3316            query=maybe_parse(query, copy=copy, **opts) if query else None,
3317            unnest=(
3318                Unnest(
3319                    expressions=[
3320                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3321                        for e in ensure_list(unnest)
3322                    ]
3323                )
3324                if unnest
3325                else None
3326            ),
3327        )
arg_types = {'expressions': False}
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
3305    def isin(
3306        self,
3307        *expressions: t.Any,
3308        query: t.Optional[ExpOrStr] = None,
3309        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3310        copy: bool = True,
3311        **opts,
3312    ) -> In:
3313        return In(
3314            this=maybe_copy(self, copy),
3315            expressions=[convert(e, copy=copy) for e in expressions],
3316            query=maybe_parse(query, copy=copy, **opts) if query else None,
3317            unnest=(
3318                Unnest(
3319                    expressions=[
3320                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3321                        for e in ensure_list(unnest)
3322                    ]
3323                )
3324                if unnest
3325                else None
3326            ),
3327        )
key = 'tuple'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
class QueryOption(Expression):
3358class QueryOption(Expression):
3359    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3363class WithTableHint(Expression):
3364    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3368class IndexTableHint(Expression):
3369    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3373class HistoricalData(Expression):
3374    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3378class Put(Expression):
3379    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3383class Get(Expression):
3384    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3387class Table(Expression):
3388    arg_types = {
3389        "this": False,
3390        "alias": False,
3391        "db": False,
3392        "catalog": False,
3393        "laterals": False,
3394        "joins": False,
3395        "pivots": False,
3396        "hints": False,
3397        "system_time": False,
3398        "version": False,
3399        "format": False,
3400        "pattern": False,
3401        "ordinality": False,
3402        "when": False,
3403        "only": False,
3404        "partition": False,
3405        "changes": False,
3406        "rows_from": False,
3407        "sample": False,
3408    }
3409
3410    @property
3411    def name(self) -> str:
3412        if not self.this or isinstance(self.this, Func):
3413            return ""
3414        return self.this.name
3415
3416    @property
3417    def db(self) -> str:
3418        return self.text("db")
3419
3420    @property
3421    def catalog(self) -> str:
3422        return self.text("catalog")
3423
3424    @property
3425    def selects(self) -> t.List[Expression]:
3426        return []
3427
3428    @property
3429    def named_selects(self) -> t.List[str]:
3430        return []
3431
3432    @property
3433    def parts(self) -> t.List[Expression]:
3434        """Return the parts of a table in order catalog, db, table."""
3435        parts: t.List[Expression] = []
3436
3437        for arg in ("catalog", "db", "this"):
3438            part = self.args.get(arg)
3439
3440            if isinstance(part, Dot):
3441                parts.extend(part.flatten())
3442            elif isinstance(part, Expression):
3443                parts.append(part)
3444
3445        return parts
3446
3447    def to_column(self, copy: bool = True) -> Expression:
3448        parts = self.parts
3449        last_part = parts[-1]
3450
3451        if isinstance(last_part, Identifier):
3452            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3453        else:
3454            # This branch will be reached if a function or array is wrapped in a `Table`
3455            col = last_part
3456
3457        alias = self.args.get("alias")
3458        if alias:
3459            col = alias_(col, alias.this, copy=copy)
3460
3461        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False, 'partition': False, 'changes': False, 'rows_from': False, 'sample': False}
name: str
3410    @property
3411    def name(self) -> str:
3412        if not self.this or isinstance(self.this, Func):
3413            return ""
3414        return self.this.name
db: str
3416    @property
3417    def db(self) -> str:
3418        return self.text("db")
catalog: str
3420    @property
3421    def catalog(self) -> str:
3422        return self.text("catalog")
selects: List[Expression]
3424    @property
3425    def selects(self) -> t.List[Expression]:
3426        return []
named_selects: List[str]
3428    @property
3429    def named_selects(self) -> t.List[str]:
3430        return []
parts: List[Expression]
3432    @property
3433    def parts(self) -> t.List[Expression]:
3434        """Return the parts of a table in order catalog, db, table."""
3435        parts: t.List[Expression] = []
3436
3437        for arg in ("catalog", "db", "this"):
3438            part = self.args.get(arg)
3439
3440            if isinstance(part, Dot):
3441                parts.extend(part.flatten())
3442            elif isinstance(part, Expression):
3443                parts.append(part)
3444
3445        return parts

Return the parts of a table in order catalog, db, table.

def to_column(self, copy: bool = True) -> Expression:
3447    def to_column(self, copy: bool = True) -> Expression:
3448        parts = self.parts
3449        last_part = parts[-1]
3450
3451        if isinstance(last_part, Identifier):
3452            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3453        else:
3454            # This branch will be reached if a function or array is wrapped in a `Table`
3455            col = last_part
3456
3457        alias = self.args.get("alias")
3458        if alias:
3459            col = alias_(col, alias.this, copy=copy)
3460
3461        return col
key = 'table'
class SetOperation(Query):
3464class SetOperation(Query):
3465    arg_types = {
3466        "with": False,
3467        "this": True,
3468        "expression": True,
3469        "distinct": False,
3470        "by_name": False,
3471        "side": False,
3472        "kind": False,
3473        "on": False,
3474        **QUERY_MODIFIERS,
3475    }
3476
3477    def select(
3478        self: S,
3479        *expressions: t.Optional[ExpOrStr],
3480        append: bool = True,
3481        dialect: DialectType = None,
3482        copy: bool = True,
3483        **opts,
3484    ) -> S:
3485        this = maybe_copy(self, copy)
3486        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3487        this.expression.unnest().select(
3488            *expressions, append=append, dialect=dialect, copy=False, **opts
3489        )
3490        return this
3491
3492    @property
3493    def named_selects(self) -> t.List[str]:
3494        return self.this.unnest().named_selects
3495
3496    @property
3497    def is_star(self) -> bool:
3498        return self.this.is_star or self.expression.is_star
3499
3500    @property
3501    def selects(self) -> t.List[Expression]:
3502        return self.this.unnest().selects
3503
3504    @property
3505    def left(self) -> Query:
3506        return self.this
3507
3508    @property
3509    def right(self) -> Query:
3510        return self.expression
3511
3512    @property
3513    def kind(self) -> str:
3514        return self.text("kind").upper()
3515
3516    @property
3517    def side(self) -> str:
3518        return self.text("side").upper()
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3477    def select(
3478        self: S,
3479        *expressions: t.Optional[ExpOrStr],
3480        append: bool = True,
3481        dialect: DialectType = None,
3482        copy: bool = True,
3483        **opts,
3484    ) -> S:
3485        this = maybe_copy(self, copy)
3486        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3487        this.expression.unnest().select(
3488            *expressions, append=append, dialect=dialect, copy=False, **opts
3489        )
3490        return this

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

named_selects: List[str]
3492    @property
3493    def named_selects(self) -> t.List[str]:
3494        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3496    @property
3497    def is_star(self) -> bool:
3498        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3500    @property
3501    def selects(self) -> t.List[Expression]:
3502        return self.this.unnest().selects

Returns the query's projections.

left: Query
3504    @property
3505    def left(self) -> Query:
3506        return self.this
right: Query
3508    @property
3509    def right(self) -> Query:
3510        return self.expression
kind: str
3512    @property
3513    def kind(self) -> str:
3514        return self.text("kind").upper()
side: str
3516    @property
3517    def side(self) -> str:
3518        return self.text("side").upper()
key = 'setoperation'
class Union(SetOperation):
3521class Union(SetOperation):
3522    pass
key = 'union'
class Except(SetOperation):
3525class Except(SetOperation):
3526    pass
key = 'except'
class Intersect(SetOperation):
3529class Intersect(SetOperation):
3530    pass
key = 'intersect'
class Update(DML):
3533class Update(DML):
3534    arg_types = {
3535        "with": False,
3536        "this": False,
3537        "expressions": True,
3538        "from": False,
3539        "where": False,
3540        "returning": False,
3541        "order": False,
3542        "limit": False,
3543    }
3544
3545    def table(
3546        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3547    ) -> Update:
3548        """
3549        Set the table to update.
3550
3551        Example:
3552            >>> Update().table("my_table").set_("x = 1").sql()
3553            'UPDATE my_table SET x = 1'
3554
3555        Args:
3556            expression : the SQL code strings to parse.
3557                If a `Table` instance is passed, this is used as-is.
3558                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3559            dialect: the dialect used to parse the input expression.
3560            copy: if `False`, modify this expression instance in-place.
3561            opts: other options to use to parse the input expressions.
3562
3563        Returns:
3564            The modified Update expression.
3565        """
3566        return _apply_builder(
3567            expression=expression,
3568            instance=self,
3569            arg="this",
3570            into=Table,
3571            prefix=None,
3572            dialect=dialect,
3573            copy=copy,
3574            **opts,
3575        )
3576
3577    def set_(
3578        self,
3579        *expressions: ExpOrStr,
3580        append: bool = True,
3581        dialect: DialectType = None,
3582        copy: bool = True,
3583        **opts,
3584    ) -> Update:
3585        """
3586        Append to or set the SET expressions.
3587
3588        Example:
3589            >>> Update().table("my_table").set_("x = 1").sql()
3590            'UPDATE my_table SET x = 1'
3591
3592        Args:
3593            *expressions: the SQL code strings to parse.
3594                If `Expression` instance(s) are passed, they will be used as-is.
3595                Multiple expressions are combined with a comma.
3596            append: if `True`, add the new expressions to any existing SET expressions.
3597                Otherwise, this resets the expressions.
3598            dialect: the dialect used to parse the input expressions.
3599            copy: if `False`, modify this expression instance in-place.
3600            opts: other options to use to parse the input expressions.
3601        """
3602        return _apply_list_builder(
3603            *expressions,
3604            instance=self,
3605            arg="expressions",
3606            append=append,
3607            into=Expression,
3608            prefix=None,
3609            dialect=dialect,
3610            copy=copy,
3611            **opts,
3612        )
3613
3614    def where(
3615        self,
3616        *expressions: t.Optional[ExpOrStr],
3617        append: bool = True,
3618        dialect: DialectType = None,
3619        copy: bool = True,
3620        **opts,
3621    ) -> Select:
3622        """
3623        Append to or set the WHERE expressions.
3624
3625        Example:
3626            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3627            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3628
3629        Args:
3630            *expressions: the SQL code strings to parse.
3631                If an `Expression` instance is passed, it will be used as-is.
3632                Multiple expressions are combined with an AND operator.
3633            append: if `True`, AND the new expressions to any existing expression.
3634                Otherwise, this resets the expression.
3635            dialect: the dialect used to parse the input expressions.
3636            copy: if `False`, modify this expression instance in-place.
3637            opts: other options to use to parse the input expressions.
3638
3639        Returns:
3640            Select: the modified expression.
3641        """
3642        return _apply_conjunction_builder(
3643            *expressions,
3644            instance=self,
3645            arg="where",
3646            append=append,
3647            into=Where,
3648            dialect=dialect,
3649            copy=copy,
3650            **opts,
3651        )
3652
3653    def from_(
3654        self,
3655        expression: t.Optional[ExpOrStr] = None,
3656        dialect: DialectType = None,
3657        copy: bool = True,
3658        **opts,
3659    ) -> Update:
3660        """
3661        Set the FROM expression.
3662
3663        Example:
3664            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3665            'UPDATE my_table SET x = 1 FROM baz'
3666
3667        Args:
3668            expression : the SQL code strings to parse.
3669                If a `From` instance is passed, this is used as-is.
3670                If another `Expression` instance is passed, it will be wrapped in a `From`.
3671                If nothing is passed in then a from is not applied to the expression
3672            dialect: the dialect used to parse the input expression.
3673            copy: if `False`, modify this expression instance in-place.
3674            opts: other options to use to parse the input expressions.
3675
3676        Returns:
3677            The modified Update expression.
3678        """
3679        if not expression:
3680            return maybe_copy(self, copy)
3681
3682        return _apply_builder(
3683            expression=expression,
3684            instance=self,
3685            arg="from",
3686            into=From,
3687            prefix="FROM",
3688            dialect=dialect,
3689            copy=copy,
3690            **opts,
3691        )
3692
3693    def with_(
3694        self,
3695        alias: ExpOrStr,
3696        as_: ExpOrStr,
3697        recursive: t.Optional[bool] = None,
3698        materialized: t.Optional[bool] = None,
3699        append: bool = True,
3700        dialect: DialectType = None,
3701        copy: bool = True,
3702        **opts,
3703    ) -> Update:
3704        """
3705        Append to or set the common table expressions.
3706
3707        Example:
3708            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3709            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3710
3711        Args:
3712            alias: the SQL code string to parse as the table name.
3713                If an `Expression` instance is passed, this is used as-is.
3714            as_: the SQL code string to parse as the table expression.
3715                If an `Expression` instance is passed, it will be used as-is.
3716            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3717            materialized: set the MATERIALIZED part of the expression.
3718            append: if `True`, add to any existing expressions.
3719                Otherwise, this resets the expressions.
3720            dialect: the dialect used to parse the input expression.
3721            copy: if `False`, modify this expression instance in-place.
3722            opts: other options to use to parse the input expressions.
3723
3724        Returns:
3725            The modified expression.
3726        """
3727        return _apply_cte_builder(
3728            self,
3729            alias,
3730            as_,
3731            recursive=recursive,
3732            materialized=materialized,
3733            append=append,
3734            dialect=dialect,
3735            copy=copy,
3736            **opts,
3737        )
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
def table( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3545    def table(
3546        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3547    ) -> Update:
3548        """
3549        Set the table to update.
3550
3551        Example:
3552            >>> Update().table("my_table").set_("x = 1").sql()
3553            'UPDATE my_table SET x = 1'
3554
3555        Args:
3556            expression : the SQL code strings to parse.
3557                If a `Table` instance is passed, this is used as-is.
3558                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3559            dialect: the dialect used to parse the input expression.
3560            copy: if `False`, modify this expression instance in-place.
3561            opts: other options to use to parse the input expressions.
3562
3563        Returns:
3564            The modified Update expression.
3565        """
3566        return _apply_builder(
3567            expression=expression,
3568            instance=self,
3569            arg="this",
3570            into=Table,
3571            prefix=None,
3572            dialect=dialect,
3573            copy=copy,
3574            **opts,
3575        )

Set the table to update.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • expression : the SQL code strings to parse. If a Table instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Table.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3577    def set_(
3578        self,
3579        *expressions: ExpOrStr,
3580        append: bool = True,
3581        dialect: DialectType = None,
3582        copy: bool = True,
3583        **opts,
3584    ) -> Update:
3585        """
3586        Append to or set the SET expressions.
3587
3588        Example:
3589            >>> Update().table("my_table").set_("x = 1").sql()
3590            'UPDATE my_table SET x = 1'
3591
3592        Args:
3593            *expressions: the SQL code strings to parse.
3594                If `Expression` instance(s) are passed, they will be used as-is.
3595                Multiple expressions are combined with a comma.
3596            append: if `True`, add the new expressions to any existing SET expressions.
3597                Otherwise, this resets the expressions.
3598            dialect: the dialect used to parse the input expressions.
3599            copy: if `False`, modify this expression instance in-place.
3600            opts: other options to use to parse the input expressions.
3601        """
3602        return _apply_list_builder(
3603            *expressions,
3604            instance=self,
3605            arg="expressions",
3606            append=append,
3607            into=Expression,
3608            prefix=None,
3609            dialect=dialect,
3610            copy=copy,
3611            **opts,
3612        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3614    def where(
3615        self,
3616        *expressions: t.Optional[ExpOrStr],
3617        append: bool = True,
3618        dialect: DialectType = None,
3619        copy: bool = True,
3620        **opts,
3621    ) -> Select:
3622        """
3623        Append to or set the WHERE expressions.
3624
3625        Example:
3626            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3627            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3628
3629        Args:
3630            *expressions: the SQL code strings to parse.
3631                If an `Expression` instance is passed, it will be used as-is.
3632                Multiple expressions are combined with an AND operator.
3633            append: if `True`, AND the new expressions to any existing expression.
3634                Otherwise, this resets the expression.
3635            dialect: the dialect used to parse the input expressions.
3636            copy: if `False`, modify this expression instance in-place.
3637            opts: other options to use to parse the input expressions.
3638
3639        Returns:
3640            Select: the modified expression.
3641        """
3642        return _apply_conjunction_builder(
3643            *expressions,
3644            instance=self,
3645            arg="where",
3646            append=append,
3647            into=Where,
3648            dialect=dialect,
3649            copy=copy,
3650            **opts,
3651        )

Append to or set the WHERE expressions.

Example:
>>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
"UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3653    def from_(
3654        self,
3655        expression: t.Optional[ExpOrStr] = None,
3656        dialect: DialectType = None,
3657        copy: bool = True,
3658        **opts,
3659    ) -> Update:
3660        """
3661        Set the FROM expression.
3662
3663        Example:
3664            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3665            'UPDATE my_table SET x = 1 FROM baz'
3666
3667        Args:
3668            expression : the SQL code strings to parse.
3669                If a `From` instance is passed, this is used as-is.
3670                If another `Expression` instance is passed, it will be wrapped in a `From`.
3671                If nothing is passed in then a from is not applied to the expression
3672            dialect: the dialect used to parse the input expression.
3673            copy: if `False`, modify this expression instance in-place.
3674            opts: other options to use to parse the input expressions.
3675
3676        Returns:
3677            The modified Update expression.
3678        """
3679        if not expression:
3680            return maybe_copy(self, copy)
3681
3682        return _apply_builder(
3683            expression=expression,
3684            instance=self,
3685            arg="from",
3686            into=From,
3687            prefix="FROM",
3688            dialect=dialect,
3689            copy=copy,
3690            **opts,
3691        )

Set the FROM expression.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").sql()
'UPDATE my_table SET x = 1 FROM baz'
Arguments:
  • expression : the SQL code strings to parse. If a From instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a From. If nothing is passed in then a from is not applied to the expression
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3693    def with_(
3694        self,
3695        alias: ExpOrStr,
3696        as_: ExpOrStr,
3697        recursive: t.Optional[bool] = None,
3698        materialized: t.Optional[bool] = None,
3699        append: bool = True,
3700        dialect: DialectType = None,
3701        copy: bool = True,
3702        **opts,
3703    ) -> Update:
3704        """
3705        Append to or set the common table expressions.
3706
3707        Example:
3708            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3709            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3710
3711        Args:
3712            alias: the SQL code string to parse as the table name.
3713                If an `Expression` instance is passed, this is used as-is.
3714            as_: the SQL code string to parse as the table expression.
3715                If an `Expression` instance is passed, it will be used as-is.
3716            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3717            materialized: set the MATERIALIZED part of the expression.
3718            append: if `True`, add to any existing expressions.
3719                Otherwise, this resets the expressions.
3720            dialect: the dialect used to parse the input expression.
3721            copy: if `False`, modify this expression instance in-place.
3722            opts: other options to use to parse the input expressions.
3723
3724        Returns:
3725            The modified expression.
3726        """
3727        return _apply_cte_builder(
3728            self,
3729            alias,
3730            as_,
3731            recursive=recursive,
3732            materialized=materialized,
3733            append=append,
3734            dialect=dialect,
3735            copy=copy,
3736            **opts,
3737        )

Append to or set the common table expressions.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • materialized: set the MATERIALIZED part of the expression.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

key = 'update'
class Values(UDTF):
3740class Values(UDTF):
3741    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3744class Var(Expression):
3745    pass
key = 'var'
class Version(Expression):
3748class Version(Expression):
3749    """
3750    Time travel, iceberg, bigquery etc
3751    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3752    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3753    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3754    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3755    this is either TIMESTAMP or VERSION
3756    kind is ("AS OF", "BETWEEN")
3757    """
3758
3759    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3762class Schema(Expression):
3763    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3768class Lock(Expression):
3769    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3772class Select(Query):
3773    arg_types = {
3774        "with": False,
3775        "kind": False,
3776        "expressions": False,
3777        "hint": False,
3778        "distinct": False,
3779        "into": False,
3780        "from": False,
3781        "operation_modifiers": False,
3782        **QUERY_MODIFIERS,
3783    }
3784
3785    def from_(
3786        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3787    ) -> Select:
3788        """
3789        Set the FROM expression.
3790
3791        Example:
3792            >>> Select().from_("tbl").select("x").sql()
3793            'SELECT x FROM tbl'
3794
3795        Args:
3796            expression : the SQL code strings to parse.
3797                If a `From` instance is passed, this is used as-is.
3798                If another `Expression` instance is passed, it will be wrapped in a `From`.
3799            dialect: the dialect used to parse the input expression.
3800            copy: if `False`, modify this expression instance in-place.
3801            opts: other options to use to parse the input expressions.
3802
3803        Returns:
3804            The modified Select expression.
3805        """
3806        return _apply_builder(
3807            expression=expression,
3808            instance=self,
3809            arg="from",
3810            into=From,
3811            prefix="FROM",
3812            dialect=dialect,
3813            copy=copy,
3814            **opts,
3815        )
3816
3817    def group_by(
3818        self,
3819        *expressions: t.Optional[ExpOrStr],
3820        append: bool = True,
3821        dialect: DialectType = None,
3822        copy: bool = True,
3823        **opts,
3824    ) -> Select:
3825        """
3826        Set the GROUP BY expression.
3827
3828        Example:
3829            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3830            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3831
3832        Args:
3833            *expressions: the SQL code strings to parse.
3834                If a `Group` instance is passed, this is used as-is.
3835                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3836                If nothing is passed in then a group by is not applied to the expression
3837            append: if `True`, add to any existing expressions.
3838                Otherwise, this flattens all the `Group` expression into a single expression.
3839            dialect: the dialect used to parse the input expression.
3840            copy: if `False`, modify this expression instance in-place.
3841            opts: other options to use to parse the input expressions.
3842
3843        Returns:
3844            The modified Select expression.
3845        """
3846        if not expressions:
3847            return self if not copy else self.copy()
3848
3849        return _apply_child_list_builder(
3850            *expressions,
3851            instance=self,
3852            arg="group",
3853            append=append,
3854            copy=copy,
3855            prefix="GROUP BY",
3856            into=Group,
3857            dialect=dialect,
3858            **opts,
3859        )
3860
3861    def sort_by(
3862        self,
3863        *expressions: t.Optional[ExpOrStr],
3864        append: bool = True,
3865        dialect: DialectType = None,
3866        copy: bool = True,
3867        **opts,
3868    ) -> Select:
3869        """
3870        Set the SORT BY expression.
3871
3872        Example:
3873            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3874            'SELECT x FROM tbl SORT BY x DESC'
3875
3876        Args:
3877            *expressions: the SQL code strings to parse.
3878                If a `Group` instance is passed, this is used as-is.
3879                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3880            append: if `True`, add to any existing expressions.
3881                Otherwise, this flattens all the `Order` expression into a single expression.
3882            dialect: the dialect used to parse the input expression.
3883            copy: if `False`, modify this expression instance in-place.
3884            opts: other options to use to parse the input expressions.
3885
3886        Returns:
3887            The modified Select expression.
3888        """
3889        return _apply_child_list_builder(
3890            *expressions,
3891            instance=self,
3892            arg="sort",
3893            append=append,
3894            copy=copy,
3895            prefix="SORT BY",
3896            into=Sort,
3897            dialect=dialect,
3898            **opts,
3899        )
3900
3901    def cluster_by(
3902        self,
3903        *expressions: t.Optional[ExpOrStr],
3904        append: bool = True,
3905        dialect: DialectType = None,
3906        copy: bool = True,
3907        **opts,
3908    ) -> Select:
3909        """
3910        Set the CLUSTER BY expression.
3911
3912        Example:
3913            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3914            'SELECT x FROM tbl CLUSTER BY x DESC'
3915
3916        Args:
3917            *expressions: the SQL code strings to parse.
3918                If a `Group` instance is passed, this is used as-is.
3919                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3920            append: if `True`, add to any existing expressions.
3921                Otherwise, this flattens all the `Order` expression into a single expression.
3922            dialect: the dialect used to parse the input expression.
3923            copy: if `False`, modify this expression instance in-place.
3924            opts: other options to use to parse the input expressions.
3925
3926        Returns:
3927            The modified Select expression.
3928        """
3929        return _apply_child_list_builder(
3930            *expressions,
3931            instance=self,
3932            arg="cluster",
3933            append=append,
3934            copy=copy,
3935            prefix="CLUSTER BY",
3936            into=Cluster,
3937            dialect=dialect,
3938            **opts,
3939        )
3940
3941    def select(
3942        self,
3943        *expressions: t.Optional[ExpOrStr],
3944        append: bool = True,
3945        dialect: DialectType = None,
3946        copy: bool = True,
3947        **opts,
3948    ) -> Select:
3949        return _apply_list_builder(
3950            *expressions,
3951            instance=self,
3952            arg="expressions",
3953            append=append,
3954            dialect=dialect,
3955            into=Expression,
3956            copy=copy,
3957            **opts,
3958        )
3959
3960    def lateral(
3961        self,
3962        *expressions: t.Optional[ExpOrStr],
3963        append: bool = True,
3964        dialect: DialectType = None,
3965        copy: bool = True,
3966        **opts,
3967    ) -> Select:
3968        """
3969        Append to or set the LATERAL expressions.
3970
3971        Example:
3972            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3973            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3974
3975        Args:
3976            *expressions: the SQL code strings to parse.
3977                If an `Expression` instance is passed, it will be used as-is.
3978            append: if `True`, add to any existing expressions.
3979                Otherwise, this resets the expressions.
3980            dialect: the dialect used to parse the input expressions.
3981            copy: if `False`, modify this expression instance in-place.
3982            opts: other options to use to parse the input expressions.
3983
3984        Returns:
3985            The modified Select expression.
3986        """
3987        return _apply_list_builder(
3988            *expressions,
3989            instance=self,
3990            arg="laterals",
3991            append=append,
3992            into=Lateral,
3993            prefix="LATERAL VIEW",
3994            dialect=dialect,
3995            copy=copy,
3996            **opts,
3997        )
3998
3999    def join(
4000        self,
4001        expression: ExpOrStr,
4002        on: t.Optional[ExpOrStr] = None,
4003        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4004        append: bool = True,
4005        join_type: t.Optional[str] = None,
4006        join_alias: t.Optional[Identifier | str] = None,
4007        dialect: DialectType = None,
4008        copy: bool = True,
4009        **opts,
4010    ) -> Select:
4011        """
4012        Append to or set the JOIN expressions.
4013
4014        Example:
4015            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4016            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4017
4018            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4019            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4020
4021            Use `join_type` to change the type of join:
4022
4023            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4024            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4025
4026        Args:
4027            expression: the SQL code string to parse.
4028                If an `Expression` instance is passed, it will be used as-is.
4029            on: optionally specify the join "on" criteria as a SQL string.
4030                If an `Expression` instance is passed, it will be used as-is.
4031            using: optionally specify the join "using" criteria as a SQL string.
4032                If an `Expression` instance is passed, it will be used as-is.
4033            append: if `True`, add to any existing expressions.
4034                Otherwise, this resets the expressions.
4035            join_type: if set, alter the parsed join type.
4036            join_alias: an optional alias for the joined source.
4037            dialect: the dialect used to parse the input expressions.
4038            copy: if `False`, modify this expression instance in-place.
4039            opts: other options to use to parse the input expressions.
4040
4041        Returns:
4042            Select: the modified expression.
4043        """
4044        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4045
4046        try:
4047            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4048        except ParseError:
4049            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4050
4051        join = expression if isinstance(expression, Join) else Join(this=expression)
4052
4053        if isinstance(join.this, Select):
4054            join.this.replace(join.this.subquery())
4055
4056        if join_type:
4057            method: t.Optional[Token]
4058            side: t.Optional[Token]
4059            kind: t.Optional[Token]
4060
4061            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4062
4063            if method:
4064                join.set("method", method.text)
4065            if side:
4066                join.set("side", side.text)
4067            if kind:
4068                join.set("kind", kind.text)
4069
4070        if on:
4071            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4072            join.set("on", on)
4073
4074        if using:
4075            join = _apply_list_builder(
4076                *ensure_list(using),
4077                instance=join,
4078                arg="using",
4079                append=append,
4080                copy=copy,
4081                into=Identifier,
4082                **opts,
4083            )
4084
4085        if join_alias:
4086            join.set("this", alias_(join.this, join_alias, table=True))
4087
4088        return _apply_list_builder(
4089            join,
4090            instance=self,
4091            arg="joins",
4092            append=append,
4093            copy=copy,
4094            **opts,
4095        )
4096
4097    def having(
4098        self,
4099        *expressions: t.Optional[ExpOrStr],
4100        append: bool = True,
4101        dialect: DialectType = None,
4102        copy: bool = True,
4103        **opts,
4104    ) -> Select:
4105        """
4106        Append to or set the HAVING expressions.
4107
4108        Example:
4109            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4110            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4111
4112        Args:
4113            *expressions: the SQL code strings to parse.
4114                If an `Expression` instance is passed, it will be used as-is.
4115                Multiple expressions are combined with an AND operator.
4116            append: if `True`, AND the new expressions to any existing expression.
4117                Otherwise, this resets the expression.
4118            dialect: the dialect used to parse the input expressions.
4119            copy: if `False`, modify this expression instance in-place.
4120            opts: other options to use to parse the input expressions.
4121
4122        Returns:
4123            The modified Select expression.
4124        """
4125        return _apply_conjunction_builder(
4126            *expressions,
4127            instance=self,
4128            arg="having",
4129            append=append,
4130            into=Having,
4131            dialect=dialect,
4132            copy=copy,
4133            **opts,
4134        )
4135
4136    def window(
4137        self,
4138        *expressions: t.Optional[ExpOrStr],
4139        append: bool = True,
4140        dialect: DialectType = None,
4141        copy: bool = True,
4142        **opts,
4143    ) -> Select:
4144        return _apply_list_builder(
4145            *expressions,
4146            instance=self,
4147            arg="windows",
4148            append=append,
4149            into=Window,
4150            dialect=dialect,
4151            copy=copy,
4152            **opts,
4153        )
4154
4155    def qualify(
4156        self,
4157        *expressions: t.Optional[ExpOrStr],
4158        append: bool = True,
4159        dialect: DialectType = None,
4160        copy: bool = True,
4161        **opts,
4162    ) -> Select:
4163        return _apply_conjunction_builder(
4164            *expressions,
4165            instance=self,
4166            arg="qualify",
4167            append=append,
4168            into=Qualify,
4169            dialect=dialect,
4170            copy=copy,
4171            **opts,
4172        )
4173
4174    def distinct(
4175        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4176    ) -> Select:
4177        """
4178        Set the OFFSET expression.
4179
4180        Example:
4181            >>> Select().from_("tbl").select("x").distinct().sql()
4182            'SELECT DISTINCT x FROM tbl'
4183
4184        Args:
4185            ons: the expressions to distinct on
4186            distinct: whether the Select should be distinct
4187            copy: if `False`, modify this expression instance in-place.
4188
4189        Returns:
4190            Select: the modified expression.
4191        """
4192        instance = maybe_copy(self, copy)
4193        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4194        instance.set("distinct", Distinct(on=on) if distinct else None)
4195        return instance
4196
4197    def ctas(
4198        self,
4199        table: ExpOrStr,
4200        properties: t.Optional[t.Dict] = None,
4201        dialect: DialectType = None,
4202        copy: bool = True,
4203        **opts,
4204    ) -> Create:
4205        """
4206        Convert this expression to a CREATE TABLE AS statement.
4207
4208        Example:
4209            >>> Select().select("*").from_("tbl").ctas("x").sql()
4210            'CREATE TABLE x AS SELECT * FROM tbl'
4211
4212        Args:
4213            table: the SQL code string to parse as the table name.
4214                If another `Expression` instance is passed, it will be used as-is.
4215            properties: an optional mapping of table properties
4216            dialect: the dialect used to parse the input table.
4217            copy: if `False`, modify this expression instance in-place.
4218            opts: other options to use to parse the input table.
4219
4220        Returns:
4221            The new Create expression.
4222        """
4223        instance = maybe_copy(self, copy)
4224        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4225
4226        properties_expression = None
4227        if properties:
4228            properties_expression = Properties.from_dict(properties)
4229
4230        return Create(
4231            this=table_expression,
4232            kind="TABLE",
4233            expression=instance,
4234            properties=properties_expression,
4235        )
4236
4237    def lock(self, update: bool = True, copy: bool = True) -> Select:
4238        """
4239        Set the locking read mode for this expression.
4240
4241        Examples:
4242            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4243            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4244
4245            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4246            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4247
4248        Args:
4249            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4250            copy: if `False`, modify this expression instance in-place.
4251
4252        Returns:
4253            The modified expression.
4254        """
4255        inst = maybe_copy(self, copy)
4256        inst.set("locks", [Lock(update=update)])
4257
4258        return inst
4259
4260    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4261        """
4262        Set hints for this expression.
4263
4264        Examples:
4265            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4266            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4267
4268        Args:
4269            hints: The SQL code strings to parse as the hints.
4270                If an `Expression` instance is passed, it will be used as-is.
4271            dialect: The dialect used to parse the hints.
4272            copy: If `False`, modify this expression instance in-place.
4273
4274        Returns:
4275            The modified expression.
4276        """
4277        inst = maybe_copy(self, copy)
4278        inst.set(
4279            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4280        )
4281
4282        return inst
4283
4284    @property
4285    def named_selects(self) -> t.List[str]:
4286        return [e.output_name for e in self.expressions if e.alias_or_name]
4287
4288    @property
4289    def is_star(self) -> bool:
4290        return any(expression.is_star for expression in self.expressions)
4291
4292    @property
4293    def selects(self) -> t.List[Expression]:
4294        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': False, 'operation_modifiers': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def from_( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3785    def from_(
3786        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3787    ) -> Select:
3788        """
3789        Set the FROM expression.
3790
3791        Example:
3792            >>> Select().from_("tbl").select("x").sql()
3793            'SELECT x FROM tbl'
3794
3795        Args:
3796            expression : the SQL code strings to parse.
3797                If a `From` instance is passed, this is used as-is.
3798                If another `Expression` instance is passed, it will be wrapped in a `From`.
3799            dialect: the dialect used to parse the input expression.
3800            copy: if `False`, modify this expression instance in-place.
3801            opts: other options to use to parse the input expressions.
3802
3803        Returns:
3804            The modified Select expression.
3805        """
3806        return _apply_builder(
3807            expression=expression,
3808            instance=self,
3809            arg="from",
3810            into=From,
3811            prefix="FROM",
3812            dialect=dialect,
3813            copy=copy,
3814            **opts,
3815        )

Set the FROM expression.

Example:
>>> Select().from_("tbl").select("x").sql()
'SELECT x FROM tbl'
Arguments:
  • expression : the SQL code strings to parse. If a From instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a From.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3817    def group_by(
3818        self,
3819        *expressions: t.Optional[ExpOrStr],
3820        append: bool = True,
3821        dialect: DialectType = None,
3822        copy: bool = True,
3823        **opts,
3824    ) -> Select:
3825        """
3826        Set the GROUP BY expression.
3827
3828        Example:
3829            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3830            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3831
3832        Args:
3833            *expressions: the SQL code strings to parse.
3834                If a `Group` instance is passed, this is used as-is.
3835                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3836                If nothing is passed in then a group by is not applied to the expression
3837            append: if `True`, add to any existing expressions.
3838                Otherwise, this flattens all the `Group` expression into a single expression.
3839            dialect: the dialect used to parse the input expression.
3840            copy: if `False`, modify this expression instance in-place.
3841            opts: other options to use to parse the input expressions.
3842
3843        Returns:
3844            The modified Select expression.
3845        """
3846        if not expressions:
3847            return self if not copy else self.copy()
3848
3849        return _apply_child_list_builder(
3850            *expressions,
3851            instance=self,
3852            arg="group",
3853            append=append,
3854            copy=copy,
3855            prefix="GROUP BY",
3856            into=Group,
3857            dialect=dialect,
3858            **opts,
3859        )

Set the GROUP BY expression.

Example:
>>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
'SELECT x, COUNT(1) FROM tbl GROUP BY x'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Group. If nothing is passed in then a group by is not applied to the expression
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Group expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3861    def sort_by(
3862        self,
3863        *expressions: t.Optional[ExpOrStr],
3864        append: bool = True,
3865        dialect: DialectType = None,
3866        copy: bool = True,
3867        **opts,
3868    ) -> Select:
3869        """
3870        Set the SORT BY expression.
3871
3872        Example:
3873            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3874            'SELECT x FROM tbl SORT BY x DESC'
3875
3876        Args:
3877            *expressions: the SQL code strings to parse.
3878                If a `Group` instance is passed, this is used as-is.
3879                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3880            append: if `True`, add to any existing expressions.
3881                Otherwise, this flattens all the `Order` expression into a single expression.
3882            dialect: the dialect used to parse the input expression.
3883            copy: if `False`, modify this expression instance in-place.
3884            opts: other options to use to parse the input expressions.
3885
3886        Returns:
3887            The modified Select expression.
3888        """
3889        return _apply_child_list_builder(
3890            *expressions,
3891            instance=self,
3892            arg="sort",
3893            append=append,
3894            copy=copy,
3895            prefix="SORT BY",
3896            into=Sort,
3897            dialect=dialect,
3898            **opts,
3899        )

Set the SORT BY expression.

Example:
>>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl SORT BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a SORT.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def cluster_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3901    def cluster_by(
3902        self,
3903        *expressions: t.Optional[ExpOrStr],
3904        append: bool = True,
3905        dialect: DialectType = None,
3906        copy: bool = True,
3907        **opts,
3908    ) -> Select:
3909        """
3910        Set the CLUSTER BY expression.
3911
3912        Example:
3913            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3914            'SELECT x FROM tbl CLUSTER BY x DESC'
3915
3916        Args:
3917            *expressions: the SQL code strings to parse.
3918                If a `Group` instance is passed, this is used as-is.
3919                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3920            append: if `True`, add to any existing expressions.
3921                Otherwise, this flattens all the `Order` expression into a single expression.
3922            dialect: the dialect used to parse the input expression.
3923            copy: if `False`, modify this expression instance in-place.
3924            opts: other options to use to parse the input expressions.
3925
3926        Returns:
3927            The modified Select expression.
3928        """
3929        return _apply_child_list_builder(
3930            *expressions,
3931            instance=self,
3932            arg="cluster",
3933            append=append,
3934            copy=copy,
3935            prefix="CLUSTER BY",
3936            into=Cluster,
3937            dialect=dialect,
3938            **opts,
3939        )

Set the CLUSTER BY expression.

Example:
>>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl CLUSTER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Cluster.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3941    def select(
3942        self,
3943        *expressions: t.Optional[ExpOrStr],
3944        append: bool = True,
3945        dialect: DialectType = None,
3946        copy: bool = True,
3947        **opts,
3948    ) -> Select:
3949        return _apply_list_builder(
3950            *expressions,
3951            instance=self,
3952            arg="expressions",
3953            append=append,
3954            dialect=dialect,
3955            into=Expression,
3956            copy=copy,
3957            **opts,
3958        )

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3960    def lateral(
3961        self,
3962        *expressions: t.Optional[ExpOrStr],
3963        append: bool = True,
3964        dialect: DialectType = None,
3965        copy: bool = True,
3966        **opts,
3967    ) -> Select:
3968        """
3969        Append to or set the LATERAL expressions.
3970
3971        Example:
3972            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3973            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3974
3975        Args:
3976            *expressions: the SQL code strings to parse.
3977                If an `Expression` instance is passed, it will be used as-is.
3978            append: if `True`, add to any existing expressions.
3979                Otherwise, this resets the expressions.
3980            dialect: the dialect used to parse the input expressions.
3981            copy: if `False`, modify this expression instance in-place.
3982            opts: other options to use to parse the input expressions.
3983
3984        Returns:
3985            The modified Select expression.
3986        """
3987        return _apply_list_builder(
3988            *expressions,
3989            instance=self,
3990            arg="laterals",
3991            append=append,
3992            into=Lateral,
3993            prefix="LATERAL VIEW",
3994            dialect=dialect,
3995            copy=copy,
3996            **opts,
3997        )

Append to or set the LATERAL expressions.

Example:
>>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3999    def join(
4000        self,
4001        expression: ExpOrStr,
4002        on: t.Optional[ExpOrStr] = None,
4003        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4004        append: bool = True,
4005        join_type: t.Optional[str] = None,
4006        join_alias: t.Optional[Identifier | str] = None,
4007        dialect: DialectType = None,
4008        copy: bool = True,
4009        **opts,
4010    ) -> Select:
4011        """
4012        Append to or set the JOIN expressions.
4013
4014        Example:
4015            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4016            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4017
4018            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4019            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4020
4021            Use `join_type` to change the type of join:
4022
4023            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4024            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4025
4026        Args:
4027            expression: the SQL code string to parse.
4028                If an `Expression` instance is passed, it will be used as-is.
4029            on: optionally specify the join "on" criteria as a SQL string.
4030                If an `Expression` instance is passed, it will be used as-is.
4031            using: optionally specify the join "using" criteria as a SQL string.
4032                If an `Expression` instance is passed, it will be used as-is.
4033            append: if `True`, add to any existing expressions.
4034                Otherwise, this resets the expressions.
4035            join_type: if set, alter the parsed join type.
4036            join_alias: an optional alias for the joined source.
4037            dialect: the dialect used to parse the input expressions.
4038            copy: if `False`, modify this expression instance in-place.
4039            opts: other options to use to parse the input expressions.
4040
4041        Returns:
4042            Select: the modified expression.
4043        """
4044        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4045
4046        try:
4047            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4048        except ParseError:
4049            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4050
4051        join = expression if isinstance(expression, Join) else Join(this=expression)
4052
4053        if isinstance(join.this, Select):
4054            join.this.replace(join.this.subquery())
4055
4056        if join_type:
4057            method: t.Optional[Token]
4058            side: t.Optional[Token]
4059            kind: t.Optional[Token]
4060
4061            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4062
4063            if method:
4064                join.set("method", method.text)
4065            if side:
4066                join.set("side", side.text)
4067            if kind:
4068                join.set("kind", kind.text)
4069
4070        if on:
4071            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4072            join.set("on", on)
4073
4074        if using:
4075            join = _apply_list_builder(
4076                *ensure_list(using),
4077                instance=join,
4078                arg="using",
4079                append=append,
4080                copy=copy,
4081                into=Identifier,
4082                **opts,
4083            )
4084
4085        if join_alias:
4086            join.set("this", alias_(join.this, join_alias, table=True))
4087
4088        return _apply_list_builder(
4089            join,
4090            instance=self,
4091            arg="joins",
4092            append=append,
4093            copy=copy,
4094            **opts,
4095        )

Append to or set the JOIN expressions.

Example:
>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
>>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
'SELECT 1 FROM a JOIN b USING (x, y, z)'

Use join_type to change the type of join:

>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • join_type: if set, alter the parsed join type.
  • join_alias: an optional alias for the joined source.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4097    def having(
4098        self,
4099        *expressions: t.Optional[ExpOrStr],
4100        append: bool = True,
4101        dialect: DialectType = None,
4102        copy: bool = True,
4103        **opts,
4104    ) -> Select:
4105        """
4106        Append to or set the HAVING expressions.
4107
4108        Example:
4109            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4110            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4111
4112        Args:
4113            *expressions: the SQL code strings to parse.
4114                If an `Expression` instance is passed, it will be used as-is.
4115                Multiple expressions are combined with an AND operator.
4116            append: if `True`, AND the new expressions to any existing expression.
4117                Otherwise, this resets the expression.
4118            dialect: the dialect used to parse the input expressions.
4119            copy: if `False`, modify this expression instance in-place.
4120            opts: other options to use to parse the input expressions.
4121
4122        Returns:
4123            The modified Select expression.
4124        """
4125        return _apply_conjunction_builder(
4126            *expressions,
4127            instance=self,
4128            arg="having",
4129            append=append,
4130            into=Having,
4131            dialect=dialect,
4132            copy=copy,
4133            **opts,
4134        )

Append to or set the HAVING expressions.

Example:
>>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4136    def window(
4137        self,
4138        *expressions: t.Optional[ExpOrStr],
4139        append: bool = True,
4140        dialect: DialectType = None,
4141        copy: bool = True,
4142        **opts,
4143    ) -> Select:
4144        return _apply_list_builder(
4145            *expressions,
4146            instance=self,
4147            arg="windows",
4148            append=append,
4149            into=Window,
4150            dialect=dialect,
4151            copy=copy,
4152            **opts,
4153        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4155    def qualify(
4156        self,
4157        *expressions: t.Optional[ExpOrStr],
4158        append: bool = True,
4159        dialect: DialectType = None,
4160        copy: bool = True,
4161        **opts,
4162    ) -> Select:
4163        return _apply_conjunction_builder(
4164            *expressions,
4165            instance=self,
4166            arg="qualify",
4167            append=append,
4168            into=Qualify,
4169            dialect=dialect,
4170            copy=copy,
4171            **opts,
4172        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4174    def distinct(
4175        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4176    ) -> Select:
4177        """
4178        Set the OFFSET expression.
4179
4180        Example:
4181            >>> Select().from_("tbl").select("x").distinct().sql()
4182            'SELECT DISTINCT x FROM tbl'
4183
4184        Args:
4185            ons: the expressions to distinct on
4186            distinct: whether the Select should be distinct
4187            copy: if `False`, modify this expression instance in-place.
4188
4189        Returns:
4190            Select: the modified expression.
4191        """
4192        instance = maybe_copy(self, copy)
4193        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4194        instance.set("distinct", Distinct(on=on) if distinct else None)
4195        return instance

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").distinct().sql()
'SELECT DISTINCT x FROM tbl'
Arguments:
  • ons: the expressions to distinct on
  • distinct: whether the Select should be distinct
  • copy: if False, modify this expression instance in-place.
Returns:

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4197    def ctas(
4198        self,
4199        table: ExpOrStr,
4200        properties: t.Optional[t.Dict] = None,
4201        dialect: DialectType = None,
4202        copy: bool = True,
4203        **opts,
4204    ) -> Create:
4205        """
4206        Convert this expression to a CREATE TABLE AS statement.
4207
4208        Example:
4209            >>> Select().select("*").from_("tbl").ctas("x").sql()
4210            'CREATE TABLE x AS SELECT * FROM tbl'
4211
4212        Args:
4213            table: the SQL code string to parse as the table name.
4214                If another `Expression` instance is passed, it will be used as-is.
4215            properties: an optional mapping of table properties
4216            dialect: the dialect used to parse the input table.
4217            copy: if `False`, modify this expression instance in-place.
4218            opts: other options to use to parse the input table.
4219
4220        Returns:
4221            The new Create expression.
4222        """
4223        instance = maybe_copy(self, copy)
4224        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4225
4226        properties_expression = None
4227        if properties:
4228            properties_expression = Properties.from_dict(properties)
4229
4230        return Create(
4231            this=table_expression,
4232            kind="TABLE",
4233            expression=instance,
4234            properties=properties_expression,
4235        )

Convert this expression to a CREATE TABLE AS statement.

Example:
>>> Select().select("*").from_("tbl").ctas("x").sql()
'CREATE TABLE x AS SELECT * FROM tbl'
Arguments:
  • table: the SQL code string to parse as the table name. If another Expression instance is passed, it will be used as-is.
  • properties: an optional mapping of table properties
  • dialect: the dialect used to parse the input table.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input table.
Returns:

The new Create expression.

def lock( self, update: bool = True, copy: bool = True) -> Select:
4237    def lock(self, update: bool = True, copy: bool = True) -> Select:
4238        """
4239        Set the locking read mode for this expression.
4240
4241        Examples:
4242            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4243            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4244
4245            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4246            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4247
4248        Args:
4249            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4250            copy: if `False`, modify this expression instance in-place.
4251
4252        Returns:
4253            The modified expression.
4254        """
4255        inst = maybe_copy(self, copy)
4256        inst.set("locks", [Lock(update=update)])
4257
4258        return inst

Set the locking read mode for this expression.

Examples:
>>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
>>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
Arguments:
  • update: if True, the locking type will be FOR UPDATE, else it will be FOR SHARE.
  • copy: if False, modify this expression instance in-place.
Returns:

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Select:
4260    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4261        """
4262        Set hints for this expression.
4263
4264        Examples:
4265            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4266            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4267
4268        Args:
4269            hints: The SQL code strings to parse as the hints.
4270                If an `Expression` instance is passed, it will be used as-is.
4271            dialect: The dialect used to parse the hints.
4272            copy: If `False`, modify this expression instance in-place.
4273
4274        Returns:
4275            The modified expression.
4276        """
4277        inst = maybe_copy(self, copy)
4278        inst.set(
4279            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4280        )
4281
4282        return inst

Set hints for this expression.

Examples:
>>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
'SELECT /*+ BROADCAST(y) */ x FROM tbl'
Arguments:
  • hints: The SQL code strings to parse as the hints. If an Expression instance is passed, it will be used as-is.
  • dialect: The dialect used to parse the hints.
  • copy: If False, modify this expression instance in-place.
Returns:

The modified expression.

named_selects: List[str]
4284    @property
4285    def named_selects(self) -> t.List[str]:
4286        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
4288    @property
4289    def is_star(self) -> bool:
4290        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4292    @property
4293    def selects(self) -> t.List[Expression]:
4294        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4300class Subquery(DerivedTable, Query):
4301    arg_types = {
4302        "this": True,
4303        "alias": False,
4304        "with": False,
4305        **QUERY_MODIFIERS,
4306    }
4307
4308    def unnest(self):
4309        """Returns the first non subquery."""
4310        expression = self
4311        while isinstance(expression, Subquery):
4312            expression = expression.this
4313        return expression
4314
4315    def unwrap(self) -> Subquery:
4316        expression = self
4317        while expression.same_parent and expression.is_wrapper:
4318            expression = t.cast(Subquery, expression.parent)
4319        return expression
4320
4321    def select(
4322        self,
4323        *expressions: t.Optional[ExpOrStr],
4324        append: bool = True,
4325        dialect: DialectType = None,
4326        copy: bool = True,
4327        **opts,
4328    ) -> Subquery:
4329        this = maybe_copy(self, copy)
4330        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4331        return this
4332
4333    @property
4334    def is_wrapper(self) -> bool:
4335        """
4336        Whether this Subquery acts as a simple wrapper around another expression.
4337
4338        SELECT * FROM (((SELECT * FROM t)))
4339                      ^
4340                      This corresponds to a "wrapper" Subquery node
4341        """
4342        return all(v is None for k, v in self.args.items() if k != "this")
4343
4344    @property
4345    def is_star(self) -> bool:
4346        return self.this.is_star
4347
4348    @property
4349    def output_name(self) -> str:
4350        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def unnest(self):
4308    def unnest(self):
4309        """Returns the first non subquery."""
4310        expression = self
4311        while isinstance(expression, Subquery):
4312            expression = expression.this
4313        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4315    def unwrap(self) -> Subquery:
4316        expression = self
4317        while expression.same_parent and expression.is_wrapper:
4318            expression = t.cast(Subquery, expression.parent)
4319        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4321    def select(
4322        self,
4323        *expressions: t.Optional[ExpOrStr],
4324        append: bool = True,
4325        dialect: DialectType = None,
4326        copy: bool = True,
4327        **opts,
4328    ) -> Subquery:
4329        this = maybe_copy(self, copy)
4330        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4331        return this

Append to or set the SELECT expressions.

Example:
>>> Select().select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

is_wrapper: bool
4333    @property
4334    def is_wrapper(self) -> bool:
4335        """
4336        Whether this Subquery acts as a simple wrapper around another expression.
4337
4338        SELECT * FROM (((SELECT * FROM t)))
4339                      ^
4340                      This corresponds to a "wrapper" Subquery node
4341        """
4342        return all(v is None for k, v in self.args.items() if k != "this")

Whether this Subquery acts as a simple wrapper around another expression.

SELECT * FROM (((SELECT * FROM t))) ^ This corresponds to a "wrapper" Subquery node

is_star: bool
4344    @property
4345    def is_star(self) -> bool:
4346        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4348    @property
4349    def output_name(self) -> str:
4350        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'subquery'
class TableSample(Expression):
4353class TableSample(Expression):
4354    arg_types = {
4355        "expressions": False,
4356        "method": False,
4357        "bucket_numerator": False,
4358        "bucket_denominator": False,
4359        "bucket_field": False,
4360        "percent": False,
4361        "rows": False,
4362        "size": False,
4363        "seed": False,
4364    }
arg_types = {'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
4367class Tag(Expression):
4368    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4369
4370    arg_types = {
4371        "this": False,
4372        "prefix": False,
4373        "postfix": False,
4374    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4379class Pivot(Expression):
4380    arg_types = {
4381        "this": False,
4382        "alias": False,
4383        "expressions": False,
4384        "fields": False,
4385        "unpivot": False,
4386        "using": False,
4387        "group": False,
4388        "columns": False,
4389        "include_nulls": False,
4390        "default_on_null": False,
4391        "into": False,
4392    }
4393
4394    @property
4395    def unpivot(self) -> bool:
4396        return bool(self.args.get("unpivot"))
4397
4398    @property
4399    def fields(self) -> t.List[Expression]:
4400        return self.args.get("fields", [])
arg_types = {'this': False, 'alias': False, 'expressions': False, 'fields': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4394    @property
4395    def unpivot(self) -> bool:
4396        return bool(self.args.get("unpivot"))
fields: List[Expression]
4398    @property
4399    def fields(self) -> t.List[Expression]:
4400        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4405class UnpivotColumns(Expression):
4406    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4409class Window(Condition):
4410    arg_types = {
4411        "this": True,
4412        "partition_by": False,
4413        "order": False,
4414        "spec": False,
4415        "alias": False,
4416        "over": False,
4417        "first": False,
4418    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4421class WindowSpec(Expression):
4422    arg_types = {
4423        "kind": False,
4424        "start": False,
4425        "start_side": False,
4426        "end": False,
4427        "end_side": False,
4428        "exclude": False,
4429    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4432class PreWhere(Expression):
4433    pass
key = 'prewhere'
class Where(Expression):
4436class Where(Expression):
4437    pass
key = 'where'
class Star(Expression):
4440class Star(Expression):
4441    arg_types = {"except": False, "replace": False, "rename": False}
4442
4443    @property
4444    def name(self) -> str:
4445        return "*"
4446
4447    @property
4448    def output_name(self) -> str:
4449        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4443    @property
4444    def name(self) -> str:
4445        return "*"
output_name: str
4447    @property
4448    def output_name(self) -> str:
4449        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'star'
class Parameter(Condition):
4452class Parameter(Condition):
4453    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4456class SessionParameter(Condition):
4457    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4460class Placeholder(Condition):
4461    arg_types = {"this": False, "kind": False}
4462
4463    @property
4464    def name(self) -> str:
4465        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4463    @property
4464    def name(self) -> str:
4465        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4468class Null(Condition):
4469    arg_types: t.Dict[str, t.Any] = {}
4470
4471    @property
4472    def name(self) -> str:
4473        return "NULL"
4474
4475    def to_py(self) -> Lit[None]:
4476        return None
arg_types: Dict[str, Any] = {}
name: str
4471    @property
4472    def name(self) -> str:
4473        return "NULL"
def to_py(self) -> Literal[None]:
4475    def to_py(self) -> Lit[None]:
4476        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4479class Boolean(Condition):
4480    def to_py(self) -> bool:
4481        return self.this
def to_py(self) -> bool:
4480    def to_py(self) -> bool:
4481        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4484class DataTypeParam(Expression):
4485    arg_types = {"this": True, "expression": False}
4486
4487    @property
4488    def name(self) -> str:
4489        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4487    @property
4488    def name(self) -> str:
4489        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4494class DataType(Expression):
4495    arg_types = {
4496        "this": True,
4497        "expressions": False,
4498        "nested": False,
4499        "values": False,
4500        "prefix": False,
4501        "kind": False,
4502        "nullable": False,
4503    }
4504
4505    class Type(AutoName):
4506        ARRAY = auto()
4507        AGGREGATEFUNCTION = auto()
4508        SIMPLEAGGREGATEFUNCTION = auto()
4509        BIGDECIMAL = auto()
4510        BIGINT = auto()
4511        BIGSERIAL = auto()
4512        BINARY = auto()
4513        BIT = auto()
4514        BLOB = auto()
4515        BOOLEAN = auto()
4516        BPCHAR = auto()
4517        CHAR = auto()
4518        DATE = auto()
4519        DATE32 = auto()
4520        DATEMULTIRANGE = auto()
4521        DATERANGE = auto()
4522        DATETIME = auto()
4523        DATETIME2 = auto()
4524        DATETIME64 = auto()
4525        DECIMAL = auto()
4526        DECIMAL32 = auto()
4527        DECIMAL64 = auto()
4528        DECIMAL128 = auto()
4529        DECIMAL256 = auto()
4530        DOUBLE = auto()
4531        DYNAMIC = auto()
4532        ENUM = auto()
4533        ENUM8 = auto()
4534        ENUM16 = auto()
4535        FIXEDSTRING = auto()
4536        FLOAT = auto()
4537        GEOGRAPHY = auto()
4538        GEOMETRY = auto()
4539        POINT = auto()
4540        RING = auto()
4541        LINESTRING = auto()
4542        MULTILINESTRING = auto()
4543        POLYGON = auto()
4544        MULTIPOLYGON = auto()
4545        HLLSKETCH = auto()
4546        HSTORE = auto()
4547        IMAGE = auto()
4548        INET = auto()
4549        INT = auto()
4550        INT128 = auto()
4551        INT256 = auto()
4552        INT4MULTIRANGE = auto()
4553        INT4RANGE = auto()
4554        INT8MULTIRANGE = auto()
4555        INT8RANGE = auto()
4556        INTERVAL = auto()
4557        IPADDRESS = auto()
4558        IPPREFIX = auto()
4559        IPV4 = auto()
4560        IPV6 = auto()
4561        JSON = auto()
4562        JSONB = auto()
4563        LIST = auto()
4564        LONGBLOB = auto()
4565        LONGTEXT = auto()
4566        LOWCARDINALITY = auto()
4567        MAP = auto()
4568        MEDIUMBLOB = auto()
4569        MEDIUMINT = auto()
4570        MEDIUMTEXT = auto()
4571        MONEY = auto()
4572        NAME = auto()
4573        NCHAR = auto()
4574        NESTED = auto()
4575        NOTHING = auto()
4576        NULL = auto()
4577        NUMMULTIRANGE = auto()
4578        NUMRANGE = auto()
4579        NVARCHAR = auto()
4580        OBJECT = auto()
4581        RANGE = auto()
4582        ROWVERSION = auto()
4583        SERIAL = auto()
4584        SET = auto()
4585        SMALLDATETIME = auto()
4586        SMALLINT = auto()
4587        SMALLMONEY = auto()
4588        SMALLSERIAL = auto()
4589        STRUCT = auto()
4590        SUPER = auto()
4591        TEXT = auto()
4592        TINYBLOB = auto()
4593        TINYTEXT = auto()
4594        TIME = auto()
4595        TIMETZ = auto()
4596        TIMESTAMP = auto()
4597        TIMESTAMPNTZ = auto()
4598        TIMESTAMPLTZ = auto()
4599        TIMESTAMPTZ = auto()
4600        TIMESTAMP_S = auto()
4601        TIMESTAMP_MS = auto()
4602        TIMESTAMP_NS = auto()
4603        TINYINT = auto()
4604        TSMULTIRANGE = auto()
4605        TSRANGE = auto()
4606        TSTZMULTIRANGE = auto()
4607        TSTZRANGE = auto()
4608        UBIGINT = auto()
4609        UINT = auto()
4610        UINT128 = auto()
4611        UINT256 = auto()
4612        UMEDIUMINT = auto()
4613        UDECIMAL = auto()
4614        UDOUBLE = auto()
4615        UNION = auto()
4616        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4617        USERDEFINED = "USER-DEFINED"
4618        USMALLINT = auto()
4619        UTINYINT = auto()
4620        UUID = auto()
4621        VARBINARY = auto()
4622        VARCHAR = auto()
4623        VARIANT = auto()
4624        VECTOR = auto()
4625        XML = auto()
4626        YEAR = auto()
4627        TDIGEST = auto()
4628
4629    STRUCT_TYPES = {
4630        Type.NESTED,
4631        Type.OBJECT,
4632        Type.STRUCT,
4633        Type.UNION,
4634    }
4635
4636    ARRAY_TYPES = {
4637        Type.ARRAY,
4638        Type.LIST,
4639    }
4640
4641    NESTED_TYPES = {
4642        *STRUCT_TYPES,
4643        *ARRAY_TYPES,
4644        Type.MAP,
4645    }
4646
4647    TEXT_TYPES = {
4648        Type.CHAR,
4649        Type.NCHAR,
4650        Type.NVARCHAR,
4651        Type.TEXT,
4652        Type.VARCHAR,
4653        Type.NAME,
4654    }
4655
4656    SIGNED_INTEGER_TYPES = {
4657        Type.BIGINT,
4658        Type.INT,
4659        Type.INT128,
4660        Type.INT256,
4661        Type.MEDIUMINT,
4662        Type.SMALLINT,
4663        Type.TINYINT,
4664    }
4665
4666    UNSIGNED_INTEGER_TYPES = {
4667        Type.UBIGINT,
4668        Type.UINT,
4669        Type.UINT128,
4670        Type.UINT256,
4671        Type.UMEDIUMINT,
4672        Type.USMALLINT,
4673        Type.UTINYINT,
4674    }
4675
4676    INTEGER_TYPES = {
4677        *SIGNED_INTEGER_TYPES,
4678        *UNSIGNED_INTEGER_TYPES,
4679        Type.BIT,
4680    }
4681
4682    FLOAT_TYPES = {
4683        Type.DOUBLE,
4684        Type.FLOAT,
4685    }
4686
4687    REAL_TYPES = {
4688        *FLOAT_TYPES,
4689        Type.BIGDECIMAL,
4690        Type.DECIMAL,
4691        Type.DECIMAL32,
4692        Type.DECIMAL64,
4693        Type.DECIMAL128,
4694        Type.DECIMAL256,
4695        Type.MONEY,
4696        Type.SMALLMONEY,
4697        Type.UDECIMAL,
4698        Type.UDOUBLE,
4699    }
4700
4701    NUMERIC_TYPES = {
4702        *INTEGER_TYPES,
4703        *REAL_TYPES,
4704    }
4705
4706    TEMPORAL_TYPES = {
4707        Type.DATE,
4708        Type.DATE32,
4709        Type.DATETIME,
4710        Type.DATETIME2,
4711        Type.DATETIME64,
4712        Type.SMALLDATETIME,
4713        Type.TIME,
4714        Type.TIMESTAMP,
4715        Type.TIMESTAMPNTZ,
4716        Type.TIMESTAMPLTZ,
4717        Type.TIMESTAMPTZ,
4718        Type.TIMESTAMP_MS,
4719        Type.TIMESTAMP_NS,
4720        Type.TIMESTAMP_S,
4721        Type.TIMETZ,
4722    }
4723
4724    @classmethod
4725    def build(
4726        cls,
4727        dtype: DATA_TYPE,
4728        dialect: DialectType = None,
4729        udt: bool = False,
4730        copy: bool = True,
4731        **kwargs,
4732    ) -> DataType:
4733        """
4734        Constructs a DataType object.
4735
4736        Args:
4737            dtype: the data type of interest.
4738            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4739            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4740                DataType, thus creating a user-defined type.
4741            copy: whether to copy the data type.
4742            kwargs: additional arguments to pass in the constructor of DataType.
4743
4744        Returns:
4745            The constructed DataType object.
4746        """
4747        from sqlglot import parse_one
4748
4749        if isinstance(dtype, str):
4750            if dtype.upper() == "UNKNOWN":
4751                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4752
4753            try:
4754                data_type_exp = parse_one(
4755                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4756                )
4757            except ParseError:
4758                if udt:
4759                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4760                raise
4761        elif isinstance(dtype, DataType.Type):
4762            data_type_exp = DataType(this=dtype)
4763        elif isinstance(dtype, DataType):
4764            return maybe_copy(dtype, copy)
4765        else:
4766            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4767
4768        return DataType(**{**data_type_exp.args, **kwargs})
4769
4770    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4771        """
4772        Checks whether this DataType matches one of the provided data types. Nested types or precision
4773        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4774
4775        Args:
4776            dtypes: the data types to compare this DataType to.
4777            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4778                If false, it means that NULLABLE<INT> is equivalent to INT.
4779
4780        Returns:
4781            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4782        """
4783        self_is_nullable = self.args.get("nullable")
4784        for dtype in dtypes:
4785            other_type = DataType.build(dtype, copy=False, udt=True)
4786            other_is_nullable = other_type.args.get("nullable")
4787            if (
4788                other_type.expressions
4789                or (check_nullable and (self_is_nullable or other_is_nullable))
4790                or self.this == DataType.Type.USERDEFINED
4791                or other_type.this == DataType.Type.USERDEFINED
4792            ):
4793                matches = self == other_type
4794            else:
4795                matches = self.this == other_type.this
4796
4797            if matches:
4798                return True
4799        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.UNION: 'UNION'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>}
ARRAY_TYPES = {<Type.LIST: 'LIST'>, <Type.ARRAY: 'ARRAY'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.STRUCT: 'STRUCT'>, <Type.LIST: 'LIST'>, <Type.UNION: 'UNION'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.ARRAY: 'ARRAY'>}
TEXT_TYPES = {<Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>}
INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT: 'INT'>, <Type.UINT256: 'UINT256'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL32: 'DECIMAL32'>}
NUMERIC_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.INT: 'INT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.INT256: 'INT256'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.MONEY: 'MONEY'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.BIGINT: 'BIGINT'>}
TEMPORAL_TYPES = {<Type.DATETIME2: 'DATETIME2'>, <Type.TIME: 'TIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4724    @classmethod
4725    def build(
4726        cls,
4727        dtype: DATA_TYPE,
4728        dialect: DialectType = None,
4729        udt: bool = False,
4730        copy: bool = True,
4731        **kwargs,
4732    ) -> DataType:
4733        """
4734        Constructs a DataType object.
4735
4736        Args:
4737            dtype: the data type of interest.
4738            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4739            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4740                DataType, thus creating a user-defined type.
4741            copy: whether to copy the data type.
4742            kwargs: additional arguments to pass in the constructor of DataType.
4743
4744        Returns:
4745            The constructed DataType object.
4746        """
4747        from sqlglot import parse_one
4748
4749        if isinstance(dtype, str):
4750            if dtype.upper() == "UNKNOWN":
4751                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4752
4753            try:
4754                data_type_exp = parse_one(
4755                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4756                )
4757            except ParseError:
4758                if udt:
4759                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4760                raise
4761        elif isinstance(dtype, DataType.Type):
4762            data_type_exp = DataType(this=dtype)
4763        elif isinstance(dtype, DataType):
4764            return maybe_copy(dtype, copy)
4765        else:
4766            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4767
4768        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4770    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4771        """
4772        Checks whether this DataType matches one of the provided data types. Nested types or precision
4773        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4774
4775        Args:
4776            dtypes: the data types to compare this DataType to.
4777            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4778                If false, it means that NULLABLE<INT> is equivalent to INT.
4779
4780        Returns:
4781            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4782        """
4783        self_is_nullable = self.args.get("nullable")
4784        for dtype in dtypes:
4785            other_type = DataType.build(dtype, copy=False, udt=True)
4786            other_is_nullable = other_type.args.get("nullable")
4787            if (
4788                other_type.expressions
4789                or (check_nullable and (self_is_nullable or other_is_nullable))
4790                or self.this == DataType.Type.USERDEFINED
4791                or other_type.this == DataType.Type.USERDEFINED
4792            ):
4793                matches = self == other_type
4794            else:
4795                matches = self.this == other_type.this
4796
4797            if matches:
4798                return True
4799        return False

Checks whether this DataType matches one of the provided data types. Nested types or precision will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this DataType to.
  • check_nullable: whether to take the NULLABLE type constructor into account for the comparison. If false, it means that NULLABLE is equivalent to INT.
Returns:

True, if and only if there is a type in dtypes which is equal to this DataType.

key = 'datatype'
class DataType.Type(sqlglot.helper.AutoName):
4505    class Type(AutoName):
4506        ARRAY = auto()
4507        AGGREGATEFUNCTION = auto()
4508        SIMPLEAGGREGATEFUNCTION = auto()
4509        BIGDECIMAL = auto()
4510        BIGINT = auto()
4511        BIGSERIAL = auto()
4512        BINARY = auto()
4513        BIT = auto()
4514        BLOB = auto()
4515        BOOLEAN = auto()
4516        BPCHAR = auto()
4517        CHAR = auto()
4518        DATE = auto()
4519        DATE32 = auto()
4520        DATEMULTIRANGE = auto()
4521        DATERANGE = auto()
4522        DATETIME = auto()
4523        DATETIME2 = auto()
4524        DATETIME64 = auto()
4525        DECIMAL = auto()
4526        DECIMAL32 = auto()
4527        DECIMAL64 = auto()
4528        DECIMAL128 = auto()
4529        DECIMAL256 = auto()
4530        DOUBLE = auto()
4531        DYNAMIC = auto()
4532        ENUM = auto()
4533        ENUM8 = auto()
4534        ENUM16 = auto()
4535        FIXEDSTRING = auto()
4536        FLOAT = auto()
4537        GEOGRAPHY = auto()
4538        GEOMETRY = auto()
4539        POINT = auto()
4540        RING = auto()
4541        LINESTRING = auto()
4542        MULTILINESTRING = auto()
4543        POLYGON = auto()
4544        MULTIPOLYGON = auto()
4545        HLLSKETCH = auto()
4546        HSTORE = auto()
4547        IMAGE = auto()
4548        INET = auto()
4549        INT = auto()
4550        INT128 = auto()
4551        INT256 = auto()
4552        INT4MULTIRANGE = auto()
4553        INT4RANGE = auto()
4554        INT8MULTIRANGE = auto()
4555        INT8RANGE = auto()
4556        INTERVAL = auto()
4557        IPADDRESS = auto()
4558        IPPREFIX = auto()
4559        IPV4 = auto()
4560        IPV6 = auto()
4561        JSON = auto()
4562        JSONB = auto()
4563        LIST = auto()
4564        LONGBLOB = auto()
4565        LONGTEXT = auto()
4566        LOWCARDINALITY = auto()
4567        MAP = auto()
4568        MEDIUMBLOB = auto()
4569        MEDIUMINT = auto()
4570        MEDIUMTEXT = auto()
4571        MONEY = auto()
4572        NAME = auto()
4573        NCHAR = auto()
4574        NESTED = auto()
4575        NOTHING = auto()
4576        NULL = auto()
4577        NUMMULTIRANGE = auto()
4578        NUMRANGE = auto()
4579        NVARCHAR = auto()
4580        OBJECT = auto()
4581        RANGE = auto()
4582        ROWVERSION = auto()
4583        SERIAL = auto()
4584        SET = auto()
4585        SMALLDATETIME = auto()
4586        SMALLINT = auto()
4587        SMALLMONEY = auto()
4588        SMALLSERIAL = auto()
4589        STRUCT = auto()
4590        SUPER = auto()
4591        TEXT = auto()
4592        TINYBLOB = auto()
4593        TINYTEXT = auto()
4594        TIME = auto()
4595        TIMETZ = auto()
4596        TIMESTAMP = auto()
4597        TIMESTAMPNTZ = auto()
4598        TIMESTAMPLTZ = auto()
4599        TIMESTAMPTZ = auto()
4600        TIMESTAMP_S = auto()
4601        TIMESTAMP_MS = auto()
4602        TIMESTAMP_NS = auto()
4603        TINYINT = auto()
4604        TSMULTIRANGE = auto()
4605        TSRANGE = auto()
4606        TSTZMULTIRANGE = auto()
4607        TSTZRANGE = auto()
4608        UBIGINT = auto()
4609        UINT = auto()
4610        UINT128 = auto()
4611        UINT256 = auto()
4612        UMEDIUMINT = auto()
4613        UDECIMAL = auto()
4614        UDOUBLE = auto()
4615        UNION = auto()
4616        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4617        USERDEFINED = "USER-DEFINED"
4618        USMALLINT = auto()
4619        UTINYINT = auto()
4620        UUID = auto()
4621        VARBINARY = auto()
4622        VARCHAR = auto()
4623        VARIANT = auto()
4624        VECTOR = auto()
4625        XML = auto()
4626        YEAR = auto()
4627        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BLOB = <Type.BLOB: 'BLOB'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME2 = <Type.DATETIME2: 'DATETIME2'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
DYNAMIC = <Type.DYNAMIC: 'DYNAMIC'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NOTHING = <Type.NOTHING: 'NOTHING'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4806class PseudoType(DataType):
4807    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4811class ObjectIdentifier(DataType):
4812    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4816class SubqueryPredicate(Predicate):
4817    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4820class All(SubqueryPredicate):
4821    pass
key = 'all'
class Any(SubqueryPredicate):
4824class Any(SubqueryPredicate):
4825    pass
key = 'any'
class Command(Expression):
4830class Command(Expression):
4831    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4834class Transaction(Expression):
4835    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4838class Commit(Expression):
4839    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4842class Rollback(Expression):
4843    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4846class Alter(Expression):
4847    arg_types = {
4848        "this": True,
4849        "kind": True,
4850        "actions": True,
4851        "exists": False,
4852        "only": False,
4853        "options": False,
4854        "cluster": False,
4855        "not_valid": False,
4856    }
4857
4858    @property
4859    def kind(self) -> t.Optional[str]:
4860        kind = self.args.get("kind")
4861        return kind and kind.upper()
4862
4863    @property
4864    def actions(self) -> t.List[Expression]:
4865        return self.args.get("actions") or []
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False}
kind: Optional[str]
4858    @property
4859    def kind(self) -> t.Optional[str]:
4860        kind = self.args.get("kind")
4861        return kind and kind.upper()
actions: List[Expression]
4863    @property
4864    def actions(self) -> t.List[Expression]:
4865        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4868class Analyze(Expression):
4869    arg_types = {
4870        "kind": False,
4871        "this": False,
4872        "options": False,
4873        "mode": False,
4874        "partition": False,
4875        "expression": False,
4876        "properties": False,
4877    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4880class AnalyzeStatistics(Expression):
4881    arg_types = {
4882        "kind": True,
4883        "option": False,
4884        "this": False,
4885        "expressions": False,
4886    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4889class AnalyzeHistogram(Expression):
4890    arg_types = {
4891        "this": True,
4892        "expressions": True,
4893        "expression": False,
4894        "update_options": False,
4895    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4898class AnalyzeSample(Expression):
4899    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4902class AnalyzeListChainedRows(Expression):
4903    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4906class AnalyzeDelete(Expression):
4907    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4910class AnalyzeWith(Expression):
4911    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4914class AnalyzeValidate(Expression):
4915    arg_types = {
4916        "kind": True,
4917        "this": False,
4918        "expression": False,
4919    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4922class AnalyzeColumns(Expression):
4923    pass
key = 'analyzecolumns'
class UsingData(Expression):
4926class UsingData(Expression):
4927    pass
key = 'usingdata'
class AddConstraint(Expression):
4930class AddConstraint(Expression):
4931    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4934class AttachOption(Expression):
4935    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4938class DropPartition(Expression):
4939    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4943class ReplacePartition(Expression):
4944    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4948class Binary(Condition):
4949    arg_types = {"this": True, "expression": True}
4950
4951    @property
4952    def left(self) -> Expression:
4953        return self.this
4954
4955    @property
4956    def right(self) -> Expression:
4957        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4951    @property
4952    def left(self) -> Expression:
4953        return self.this
right: Expression
4955    @property
4956    def right(self) -> Expression:
4957        return self.expression
key = 'binary'
class Add(Binary):
4960class Add(Binary):
4961    pass
key = 'add'
class Connector(Binary):
4964class Connector(Binary):
4965    pass
key = 'connector'
class BitwiseAnd(Binary):
4968class BitwiseAnd(Binary):
4969    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4972class BitwiseLeftShift(Binary):
4973    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4976class BitwiseOr(Binary):
4977    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4980class BitwiseRightShift(Binary):
4981    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4984class BitwiseXor(Binary):
4985    pass
key = 'bitwisexor'
class Div(Binary):
4988class Div(Binary):
4989    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
arg_types = {'this': True, 'expression': True, 'typed': False, 'safe': False}
key = 'div'
class Overlaps(Binary):
4992class Overlaps(Binary):
4993    pass
key = 'overlaps'
class Dot(Binary):
4996class Dot(Binary):
4997    @property
4998    def is_star(self) -> bool:
4999        return self.expression.is_star
5000
5001    @property
5002    def name(self) -> str:
5003        return self.expression.name
5004
5005    @property
5006    def output_name(self) -> str:
5007        return self.name
5008
5009    @classmethod
5010    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5011        """Build a Dot object with a sequence of expressions."""
5012        if len(expressions) < 2:
5013            raise ValueError("Dot requires >= 2 expressions.")
5014
5015        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5016
5017    @property
5018    def parts(self) -> t.List[Expression]:
5019        """Return the parts of a table / column in order catalog, db, table."""
5020        this, *parts = self.flatten()
5021
5022        parts.reverse()
5023
5024        for arg in COLUMN_PARTS:
5025            part = this.args.get(arg)
5026
5027            if isinstance(part, Expression):
5028                parts.append(part)
5029
5030        parts.reverse()
5031        return parts
is_star: bool
4997    @property
4998    def is_star(self) -> bool:
4999        return self.expression.is_star

Checks whether an expression is a star.

name: str
5001    @property
5002    def name(self) -> str:
5003        return self.expression.name
output_name: str
5005    @property
5006    def output_name(self) -> str:
5007        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
@classmethod
def build( self, expressions: Sequence[Expression]) -> Dot:
5009    @classmethod
5010    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5011        """Build a Dot object with a sequence of expressions."""
5012        if len(expressions) < 2:
5013            raise ValueError("Dot requires >= 2 expressions.")
5014
5015        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
5017    @property
5018    def parts(self) -> t.List[Expression]:
5019        """Return the parts of a table / column in order catalog, db, table."""
5020        this, *parts = self.flatten()
5021
5022        parts.reverse()
5023
5024        for arg in COLUMN_PARTS:
5025            part = this.args.get(arg)
5026
5027            if isinstance(part, Expression):
5028                parts.append(part)
5029
5030        parts.reverse()
5031        return parts

Return the parts of a table / column in order catalog, db, table.

key = 'dot'
class DPipe(Binary):
5034class DPipe(Binary):
5035    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5038class EQ(Binary, Predicate):
5039    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5042class NullSafeEQ(Binary, Predicate):
5043    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5046class NullSafeNEQ(Binary, Predicate):
5047    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5051class PropertyEQ(Binary):
5052    pass
key = 'propertyeq'
class Distance(Binary):
5055class Distance(Binary):
5056    pass
key = 'distance'
class Escape(Binary):
5059class Escape(Binary):
5060    pass
key = 'escape'
class Glob(Binary, Predicate):
5063class Glob(Binary, Predicate):
5064    pass
key = 'glob'
class GT(Binary, Predicate):
5067class GT(Binary, Predicate):
5068    pass
key = 'gt'
class GTE(Binary, Predicate):
5071class GTE(Binary, Predicate):
5072    pass
key = 'gte'
class ILike(Binary, Predicate):
5075class ILike(Binary, Predicate):
5076    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5079class ILikeAny(Binary, Predicate):
5080    pass
key = 'ilikeany'
class IntDiv(Binary):
5083class IntDiv(Binary):
5084    pass
key = 'intdiv'
class Is(Binary, Predicate):
5087class Is(Binary, Predicate):
5088    pass
key = 'is'
class Kwarg(Binary):
5091class Kwarg(Binary):
5092    """Kwarg in special functions like func(kwarg => y)."""

Kwarg in special functions like func(kwarg => y).

key = 'kwarg'
class Like(Binary, Predicate):
5095class Like(Binary, Predicate):
5096    pass
key = 'like'
class LikeAny(Binary, Predicate):
5099class LikeAny(Binary, Predicate):
5100    pass
key = 'likeany'
class LT(Binary, Predicate):
5103class LT(Binary, Predicate):
5104    pass
key = 'lt'
class LTE(Binary, Predicate):
5107class LTE(Binary, Predicate):
5108    pass
key = 'lte'
class Mod(Binary):
5111class Mod(Binary):
5112    pass
key = 'mod'
class Mul(Binary):
5115class Mul(Binary):
5116    pass
key = 'mul'
class NEQ(Binary, Predicate):
5119class NEQ(Binary, Predicate):
5120    pass
key = 'neq'
class Operator(Binary):
5124class Operator(Binary):
5125    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5128class SimilarTo(Binary, Predicate):
5129    pass
key = 'similarto'
class Slice(Binary):
5132class Slice(Binary):
5133    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5136class Sub(Binary):
5137    pass
key = 'sub'
class Unary(Condition):
5142class Unary(Condition):
5143    pass
key = 'unary'
class BitwiseNot(Unary):
5146class BitwiseNot(Unary):
5147    pass
key = 'bitwisenot'
class Not(Unary):
5150class Not(Unary):
5151    pass
key = 'not'
class Paren(Unary):
5154class Paren(Unary):
5155    @property
5156    def output_name(self) -> str:
5157        return self.this.name
output_name: str
5155    @property
5156    def output_name(self) -> str:
5157        return self.this.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'paren'
class Neg(Unary):
5160class Neg(Unary):
5161    def to_py(self) -> int | Decimal:
5162        if self.is_number:
5163            return self.this.to_py() * -1
5164        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5161    def to_py(self) -> int | Decimal:
5162        if self.is_number:
5163            return self.this.to_py() * -1
5164        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5167class Alias(Expression):
5168    arg_types = {"this": True, "alias": False}
5169
5170    @property
5171    def output_name(self) -> str:
5172        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5170    @property
5171    def output_name(self) -> str:
5172        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'alias'
class PivotAlias(Alias):
5177class PivotAlias(Alias):
5178    pass
key = 'pivotalias'
class PivotAny(Expression):
5183class PivotAny(Expression):
5184    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5187class Aliases(Expression):
5188    arg_types = {"this": True, "expressions": True}
5189
5190    @property
5191    def aliases(self):
5192        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5190    @property
5191    def aliases(self):
5192        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5196class AtIndex(Expression):
5197    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5200class AtTimeZone(Expression):
5201    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5204class FromTimeZone(Expression):
5205    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5208class Between(Predicate):
5209    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5212class Bracket(Condition):
5213    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5214    arg_types = {
5215        "this": True,
5216        "expressions": True,
5217        "offset": False,
5218        "safe": False,
5219        "returns_list_for_maps": False,
5220    }
5221
5222    @property
5223    def output_name(self) -> str:
5224        if len(self.expressions) == 1:
5225            return self.expressions[0].output_name
5226
5227        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5222    @property
5223    def output_name(self) -> str:
5224        if len(self.expressions) == 1:
5225            return self.expressions[0].output_name
5226
5227        return super().output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'bracket'
class Distinct(Expression):
5230class Distinct(Expression):
5231    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5234class In(Predicate):
5235    arg_types = {
5236        "this": True,
5237        "expressions": False,
5238        "query": False,
5239        "unnest": False,
5240        "field": False,
5241        "is_global": False,
5242    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5246class ForIn(Expression):
5247    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5250class TimeUnit(Expression):
5251    """Automatically converts unit arg into a var."""
5252
5253    arg_types = {"unit": False}
5254
5255    UNABBREVIATED_UNIT_NAME = {
5256        "D": "DAY",
5257        "H": "HOUR",
5258        "M": "MINUTE",
5259        "MS": "MILLISECOND",
5260        "NS": "NANOSECOND",
5261        "Q": "QUARTER",
5262        "S": "SECOND",
5263        "US": "MICROSECOND",
5264        "W": "WEEK",
5265        "Y": "YEAR",
5266    }
5267
5268    VAR_LIKE = (Column, Literal, Var)
5269
5270    def __init__(self, **args):
5271        unit = args.get("unit")
5272        if isinstance(unit, self.VAR_LIKE):
5273            args["unit"] = Var(
5274                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5275            )
5276        elif isinstance(unit, Week):
5277            unit.set("this", Var(this=unit.this.name.upper()))
5278
5279        super().__init__(**args)
5280
5281    @property
5282    def unit(self) -> t.Optional[Var | IntervalSpan]:
5283        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5270    def __init__(self, **args):
5271        unit = args.get("unit")
5272        if isinstance(unit, self.VAR_LIKE):
5273            args["unit"] = Var(
5274                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5275            )
5276        elif isinstance(unit, Week):
5277            unit.set("this", Var(this=unit.this.name.upper()))
5278
5279        super().__init__(**args)
arg_types = {'unit': False}
UNABBREVIATED_UNIT_NAME = {'D': 'DAY', 'H': 'HOUR', 'M': 'MINUTE', 'MS': 'MILLISECOND', 'NS': 'NANOSECOND', 'Q': 'QUARTER', 'S': 'SECOND', 'US': 'MICROSECOND', 'W': 'WEEK', 'Y': 'YEAR'}
VAR_LIKE = (<class 'Column'>, <class 'Literal'>, <class 'Var'>)
unit: Union[Var, IntervalSpan, NoneType]
5281    @property
5282    def unit(self) -> t.Optional[Var | IntervalSpan]:
5283        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5286class IntervalOp(TimeUnit):
5287    arg_types = {"unit": False, "expression": True}
5288
5289    def interval(self):
5290        return Interval(
5291            this=self.expression.copy(),
5292            unit=self.unit.copy() if self.unit else None,
5293        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5289    def interval(self):
5290        return Interval(
5291            this=self.expression.copy(),
5292            unit=self.unit.copy() if self.unit else None,
5293        )
key = 'intervalop'
class IntervalSpan(DataType):
5299class IntervalSpan(DataType):
5300    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5303class Interval(TimeUnit):
5304    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5307class IgnoreNulls(Expression):
5308    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5311class RespectNulls(Expression):
5312    pass
key = 'respectnulls'
class HavingMax(Expression):
5316class HavingMax(Expression):
5317    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5321class Func(Condition):
5322    """
5323    The base class for all function expressions.
5324
5325    Attributes:
5326        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5327            treated as a variable length argument and the argument's value will be stored as a list.
5328        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5329            function expression. These values are used to map this node to a name during parsing as
5330            well as to provide the function's name during SQL string generation. By default the SQL
5331            name is set to the expression's class name transformed to snake case.
5332    """
5333
5334    is_var_len_args = False
5335
5336    @classmethod
5337    def from_arg_list(cls, args):
5338        if cls.is_var_len_args:
5339            all_arg_keys = list(cls.arg_types)
5340            # If this function supports variable length argument treat the last argument as such.
5341            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5342            num_non_var = len(non_var_len_arg_keys)
5343
5344            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5345            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5346        else:
5347            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5348
5349        return cls(**args_dict)
5350
5351    @classmethod
5352    def sql_names(cls):
5353        if cls is Func:
5354            raise NotImplementedError(
5355                "SQL name is only supported by concrete function implementations"
5356            )
5357        if "_sql_names" not in cls.__dict__:
5358            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5359        return cls._sql_names
5360
5361    @classmethod
5362    def sql_name(cls):
5363        return cls.sql_names()[0]
5364
5365    @classmethod
5366    def default_parser_mappings(cls):
5367        return {name: cls.from_arg_list for name in cls.sql_names()}

The base class for all function expressions.

Attributes:
  • is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
  • _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
is_var_len_args = False
@classmethod
def from_arg_list(cls, args):
5336    @classmethod
5337    def from_arg_list(cls, args):
5338        if cls.is_var_len_args:
5339            all_arg_keys = list(cls.arg_types)
5340            # If this function supports variable length argument treat the last argument as such.
5341            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5342            num_non_var = len(non_var_len_arg_keys)
5343
5344            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5345            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5346        else:
5347            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5348
5349        return cls(**args_dict)
@classmethod
def sql_names(cls):
5351    @classmethod
5352    def sql_names(cls):
5353        if cls is Func:
5354            raise NotImplementedError(
5355                "SQL name is only supported by concrete function implementations"
5356            )
5357        if "_sql_names" not in cls.__dict__:
5358            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5359        return cls._sql_names
@classmethod
def sql_name(cls):
5361    @classmethod
5362    def sql_name(cls):
5363        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5365    @classmethod
5366    def default_parser_mappings(cls):
5367        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5370class AggFunc(Func):
5371    pass
key = 'aggfunc'
class ArrayRemove(Func):
5374class ArrayRemove(Func):
5375    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5378class ParameterizedAgg(AggFunc):
5379    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5382class Abs(Func):
5383    pass
key = 'abs'
class ArgMax(AggFunc):
5386class ArgMax(AggFunc):
5387    arg_types = {"this": True, "expression": True, "count": False}
5388    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5391class ArgMin(AggFunc):
5392    arg_types = {"this": True, "expression": True, "count": False}
5393    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5396class ApproxTopK(AggFunc):
5397    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5400class Flatten(Func):
5401    pass
key = 'flatten'
class Transform(Func):
5405class Transform(Func):
5406    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5409class Anonymous(Func):
5410    arg_types = {"this": True, "expressions": False}
5411    is_var_len_args = True
5412
5413    @property
5414    def name(self) -> str:
5415        return self.this if isinstance(self.this, str) else self.this.name
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
5413    @property
5414    def name(self) -> str:
5415        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5418class AnonymousAggFunc(AggFunc):
5419    arg_types = {"this": True, "expressions": False}
5420    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5424class CombinedAggFunc(AnonymousAggFunc):
5425    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5428class CombinedParameterizedAgg(ParameterizedAgg):
5429    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5434class Hll(AggFunc):
5435    arg_types = {"this": True, "expressions": False}
5436    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5439class ApproxDistinct(AggFunc):
5440    arg_types = {"this": True, "accuracy": False}
5441    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5444class Apply(Func):
5445    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5448class Array(Func):
5449    arg_types = {"expressions": False, "bracket_notation": False}
5450    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5454class ToArray(Func):
5455    pass
key = 'toarray'
class List(Func):
5459class List(Func):
5460    arg_types = {"expressions": False}
5461    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5465class Pad(Func):
5466    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
arg_types = {'this': True, 'expression': True, 'fill_pattern': False, 'is_left': True}
key = 'pad'
class ToChar(Func):
5471class ToChar(Func):
5472    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5477class ToNumber(Func):
5478    arg_types = {
5479        "this": True,
5480        "format": False,
5481        "nlsparam": False,
5482        "precision": False,
5483        "scale": False,
5484    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5488class ToDouble(Func):
5489    arg_types = {
5490        "this": True,
5491        "format": False,
5492    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5495class Columns(Func):
5496    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5500class Convert(Func):
5501    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5505class ConvertToCharset(Func):
5506    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5509class ConvertTimezone(Func):
5510    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
5513class GenerateSeries(Func):
5514    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ExplodingGenerateSeries(GenerateSeries):
5520class ExplodingGenerateSeries(GenerateSeries):
5521    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5524class ArrayAgg(AggFunc):
5525    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5528class ArrayUniqueAgg(AggFunc):
5529    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5532class ArrayAll(Func):
5533    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5537class ArrayAny(Func):
5538    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5541class ArrayConcat(Func):
5542    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5543    arg_types = {"this": True, "expressions": False}
5544    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5547class ArrayConcatAgg(AggFunc):
5548    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5551class ArrayConstructCompact(Func):
5552    arg_types = {"expressions": True}
5553    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5556class ArrayContains(Binary, Func):
5557    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5560class ArrayContainsAll(Binary, Func):
5561    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5564class ArrayFilter(Func):
5565    arg_types = {"this": True, "expression": True}
5566    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5569class ArrayToString(Func):
5570    arg_types = {"this": True, "expression": True, "null": False}
5571    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5575class String(Func):
5576    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5579class StringToArray(Func):
5580    arg_types = {"this": True, "expression": True, "null": False}
5581    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5584class ArrayOverlaps(Binary, Func):
5585    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5588class ArraySize(Func):
5589    arg_types = {"this": True, "expression": False}
5590    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5593class ArraySort(Func):
5594    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5597class ArraySum(Func):
5598    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5601class ArrayUnionAgg(AggFunc):
5602    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5605class Avg(AggFunc):
5606    pass
key = 'avg'
class AnyValue(AggFunc):
5609class AnyValue(AggFunc):
5610    pass
key = 'anyvalue'
class Lag(AggFunc):
5613class Lag(AggFunc):
5614    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5617class Lead(AggFunc):
5618    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5623class First(AggFunc):
5624    pass
key = 'first'
class Last(AggFunc):
5627class Last(AggFunc):
5628    pass
key = 'last'
class FirstValue(AggFunc):
5631class FirstValue(AggFunc):
5632    pass
key = 'firstvalue'
class LastValue(AggFunc):
5635class LastValue(AggFunc):
5636    pass
key = 'lastvalue'
class NthValue(AggFunc):
5639class NthValue(AggFunc):
5640    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5643class Case(Func):
5644    arg_types = {"this": False, "ifs": True, "default": False}
5645
5646    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5647        instance = maybe_copy(self, copy)
5648        instance.append(
5649            "ifs",
5650            If(
5651                this=maybe_parse(condition, copy=copy, **opts),
5652                true=maybe_parse(then, copy=copy, **opts),
5653            ),
5654        )
5655        return instance
5656
5657    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5658        instance = maybe_copy(self, copy)
5659        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5660        return instance
arg_types = {'this': False, 'ifs': True, 'default': False}
def when( self, condition: Union[str, Expression], then: Union[str, Expression], copy: bool = True, **opts) -> Case:
5646    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5647        instance = maybe_copy(self, copy)
5648        instance.append(
5649            "ifs",
5650            If(
5651                this=maybe_parse(condition, copy=copy, **opts),
5652                true=maybe_parse(then, copy=copy, **opts),
5653            ),
5654        )
5655        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5657    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5658        instance = maybe_copy(self, copy)
5659        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5660        return instance
key = 'case'
class Cast(Func):
5663class Cast(Func):
5664    arg_types = {
5665        "this": True,
5666        "to": True,
5667        "format": False,
5668        "safe": False,
5669        "action": False,
5670        "default": False,
5671    }
5672
5673    @property
5674    def name(self) -> str:
5675        return self.this.name
5676
5677    @property
5678    def to(self) -> DataType:
5679        return self.args["to"]
5680
5681    @property
5682    def output_name(self) -> str:
5683        return self.name
5684
5685    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5686        """
5687        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5688        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5689        array<int> != array<float>.
5690
5691        Args:
5692            dtypes: the data types to compare this Cast's DataType to.
5693
5694        Returns:
5695            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5696        """
5697        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5673    @property
5674    def name(self) -> str:
5675        return self.this.name
to: DataType
5677    @property
5678    def to(self) -> DataType:
5679        return self.args["to"]
output_name: str
5681    @property
5682    def output_name(self) -> str:
5683        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
5685    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5686        """
5687        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5688        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5689        array<int> != array<float>.
5690
5691        Args:
5692            dtypes: the data types to compare this Cast's DataType to.
5693
5694        Returns:
5695            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5696        """
5697        return self.to.is_type(*dtypes)

Checks whether this Cast's DataType matches one of the provided data types. Nested types like arrays or structs will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this Cast's DataType to.
Returns:

True, if and only if there is a type in dtypes which is equal to this Cast's DataType.

key = 'cast'
class TryCast(Cast):
5700class TryCast(Cast):
5701    pass
key = 'trycast'
class JSONCast(Cast):
5705class JSONCast(Cast):
5706    pass
key = 'jsoncast'
class Try(Func):
5709class Try(Func):
5710    pass
key = 'try'
class CastToStrType(Func):
5713class CastToStrType(Func):
5714    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5718class TranslateCharacters(Expression):
5719    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5722class Collate(Binary, Func):
5723    pass
key = 'collate'
class Ceil(Func):
5726class Ceil(Func):
5727    arg_types = {"this": True, "decimals": False, "to": False}
5728    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5731class Coalesce(Func):
5732    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5733    is_var_len_args = True
5734    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False, 'is_null': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5737class Chr(Func):
5738    arg_types = {"expressions": True, "charset": False}
5739    is_var_len_args = True
5740    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5743class Concat(Func):
5744    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5745    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5748class ConcatWs(Concat):
5749    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5752class Contains(Func):
5753    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5757class ConnectByRoot(Func):
5758    pass
key = 'connectbyroot'
class Count(AggFunc):
5761class Count(AggFunc):
5762    arg_types = {"this": False, "expressions": False, "big_int": False}
5763    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5766class CountIf(AggFunc):
5767    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5771class Cbrt(Func):
5772    pass
key = 'cbrt'
class CurrentDate(Func):
5775class CurrentDate(Func):
5776    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5779class CurrentDatetime(Func):
5780    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5783class CurrentTime(Func):
5784    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5787class CurrentTimestamp(Func):
5788    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5791class CurrentSchema(Func):
5792    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5795class CurrentUser(Func):
5796    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5799class DateAdd(Func, IntervalOp):
5800    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5803class DateBin(Func, IntervalOp):
5804    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
5807class DateSub(Func, IntervalOp):
5808    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5811class DateDiff(Func, TimeUnit):
5812    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5813    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datediff'
class DateTrunc(Func):
5816class DateTrunc(Func):
5817    arg_types = {"unit": True, "this": True, "zone": False}
5818
5819    def __init__(self, **args):
5820        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5821        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5822        unabbreviate = args.pop("unabbreviate", True)
5823
5824        unit = args.get("unit")
5825        if isinstance(unit, TimeUnit.VAR_LIKE):
5826            unit_name = unit.name.upper()
5827            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5828                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5829
5830            args["unit"] = Literal.string(unit_name)
5831        elif isinstance(unit, Week):
5832            unit.set("this", Literal.string(unit.this.name.upper()))
5833
5834        super().__init__(**args)
5835
5836    @property
5837    def unit(self) -> Expression:
5838        return self.args["unit"]
DateTrunc(**args)
5819    def __init__(self, **args):
5820        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5821        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5822        unabbreviate = args.pop("unabbreviate", True)
5823
5824        unit = args.get("unit")
5825        if isinstance(unit, TimeUnit.VAR_LIKE):
5826            unit_name = unit.name.upper()
5827            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5828                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5829
5830            args["unit"] = Literal.string(unit_name)
5831        elif isinstance(unit, Week):
5832            unit.set("this", Literal.string(unit.this.name.upper()))
5833
5834        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5836    @property
5837    def unit(self) -> Expression:
5838        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5843class Datetime(Func):
5844    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5847class DatetimeAdd(Func, IntervalOp):
5848    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5851class DatetimeSub(Func, IntervalOp):
5852    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5855class DatetimeDiff(Func, TimeUnit):
5856    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5859class DatetimeTrunc(Func, TimeUnit):
5860    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5863class DayOfWeek(Func):
5864    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5869class DayOfWeekIso(Func):
5870    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5873class DayOfMonth(Func):
5874    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5877class DayOfYear(Func):
5878    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5881class ToDays(Func):
5882    pass
key = 'todays'
class WeekOfYear(Func):
5885class WeekOfYear(Func):
5886    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5889class MonthsBetween(Func):
5890    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5893class MakeInterval(Func):
5894    arg_types = {
5895        "year": False,
5896        "month": False,
5897        "day": False,
5898        "hour": False,
5899        "minute": False,
5900        "second": False,
5901    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5904class LastDay(Func, TimeUnit):
5905    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5906    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5909class Extract(Func):
5910    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5913class Exists(Func, SubqueryPredicate):
5914    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5917class Timestamp(Func):
5918    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5921class TimestampAdd(Func, TimeUnit):
5922    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5925class TimestampSub(Func, TimeUnit):
5926    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5929class TimestampDiff(Func, TimeUnit):
5930    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5931    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5934class TimestampTrunc(Func, TimeUnit):
5935    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5938class TimeAdd(Func, TimeUnit):
5939    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5942class TimeSub(Func, TimeUnit):
5943    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5946class TimeDiff(Func, TimeUnit):
5947    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5950class TimeTrunc(Func, TimeUnit):
5951    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5954class DateFromParts(Func):
5955    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5956    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5959class TimeFromParts(Func):
5960    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5961    arg_types = {
5962        "hour": True,
5963        "min": True,
5964        "sec": True,
5965        "nano": False,
5966        "fractions": False,
5967        "precision": False,
5968    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5971class DateStrToDate(Func):
5972    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5975class DateToDateStr(Func):
5976    pass
key = 'datetodatestr'
class DateToDi(Func):
5979class DateToDi(Func):
5980    pass
key = 'datetodi'
class Date(Func):
5984class Date(Func):
5985    arg_types = {"this": False, "zone": False, "expressions": False}
5986    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5989class Day(Func):
5990    pass
key = 'day'
class Decode(Func):
5993class Decode(Func):
5994    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5997class DiToDate(Func):
5998    pass
key = 'ditodate'
class Encode(Func):
6001class Encode(Func):
6002    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6005class Exp(Func):
6006    pass
key = 'exp'
class Explode(Func, UDTF):
6010class Explode(Func, UDTF):
6011    arg_types = {"this": True, "expressions": False}
6012    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6016class Inline(Func):
6017    pass
key = 'inline'
class ExplodeOuter(Explode):
6020class ExplodeOuter(Explode):
6021    pass
key = 'explodeouter'
class Posexplode(Explode):
6024class Posexplode(Explode):
6025    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6028class PosexplodeOuter(Posexplode, ExplodeOuter):
6029    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
6032class Unnest(Func, UDTF):
6033    arg_types = {
6034        "expressions": True,
6035        "alias": False,
6036        "offset": False,
6037        "explode_array": False,
6038    }
6039
6040    @property
6041    def selects(self) -> t.List[Expression]:
6042        columns = super().selects
6043        offset = self.args.get("offset")
6044        if offset:
6045            columns = columns + [to_identifier("offset") if offset is True else offset]
6046        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6040    @property
6041    def selects(self) -> t.List[Expression]:
6042        columns = super().selects
6043        offset = self.args.get("offset")
6044        if offset:
6045            columns = columns + [to_identifier("offset") if offset is True else offset]
6046        return columns
key = 'unnest'
class Floor(Func):
6049class Floor(Func):
6050    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6053class FromBase64(Func):
6054    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6057class FeaturesAtTime(Func):
6058    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
arg_types = {'this': True, 'time': False, 'num_rows': False, 'ignore_feature_nulls': False}
key = 'featuresattime'
class ToBase64(Func):
6061class ToBase64(Func):
6062    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6066class FromISO8601Timestamp(Func):
6067    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6070class GapFill(Func):
6071    arg_types = {
6072        "this": True,
6073        "ts_column": True,
6074        "bucket_width": True,
6075        "partitioning_columns": False,
6076        "value_columns": False,
6077        "origin": False,
6078        "ignore_nulls": False,
6079    }
arg_types = {'this': True, 'ts_column': True, 'bucket_width': True, 'partitioning_columns': False, 'value_columns': False, 'origin': False, 'ignore_nulls': False}
key = 'gapfill'
class GenerateDateArray(Func):
6083class GenerateDateArray(Func):
6084    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6088class GenerateTimestampArray(Func):
6089    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6092class Greatest(Func):
6093    arg_types = {"this": True, "expressions": False}
6094    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6099class OverflowTruncateBehavior(Expression):
6100    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6103class GroupConcat(AggFunc):
6104    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6107class Hex(Func):
6108    pass
key = 'hex'
class LowerHex(Hex):
6111class LowerHex(Hex):
6112    pass
key = 'lowerhex'
class And(Connector, Func):
6115class And(Connector, Func):
6116    pass
key = 'and'
class Or(Connector, Func):
6119class Or(Connector, Func):
6120    pass
key = 'or'
class Xor(Connector, Func):
6123class Xor(Connector, Func):
6124    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6127class If(Func):
6128    arg_types = {"this": True, "true": True, "false": False}
6129    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6132class Nullif(Func):
6133    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6136class Initcap(Func):
6137    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6140class IsAscii(Func):
6141    pass
key = 'isascii'
class IsNan(Func):
6144class IsNan(Func):
6145    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6149class Int64(Func):
6150    pass
key = 'int64'
class IsInf(Func):
6153class IsInf(Func):
6154    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6158class JSON(Expression):
6159    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6162class JSONPath(Expression):
6163    arg_types = {"expressions": True, "escape": False}
6164
6165    @property
6166    def output_name(self) -> str:
6167        last_segment = self.expressions[-1].this
6168        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6165    @property
6166    def output_name(self) -> str:
6167        last_segment = self.expressions[-1].this
6168        return last_segment if isinstance(last_segment, str) else ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonpath'
class JSONPathPart(Expression):
6171class JSONPathPart(Expression):
6172    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6175class JSONPathFilter(JSONPathPart):
6176    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6179class JSONPathKey(JSONPathPart):
6180    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6183class JSONPathRecursive(JSONPathPart):
6184    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6187class JSONPathRoot(JSONPathPart):
6188    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6191class JSONPathScript(JSONPathPart):
6192    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6195class JSONPathSlice(JSONPathPart):
6196    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6199class JSONPathSelector(JSONPathPart):
6200    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6203class JSONPathSubscript(JSONPathPart):
6204    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6207class JSONPathUnion(JSONPathPart):
6208    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6211class JSONPathWildcard(JSONPathPart):
6212    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6215class FormatJson(Expression):
6216    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6219class JSONKeyValue(Expression):
6220    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6223class JSONObject(Func):
6224    arg_types = {
6225        "expressions": False,
6226        "null_handling": False,
6227        "unique_keys": False,
6228        "return_type": False,
6229        "encoding": False,
6230    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6233class JSONObjectAgg(AggFunc):
6234    arg_types = {
6235        "expressions": False,
6236        "null_handling": False,
6237        "unique_keys": False,
6238        "return_type": False,
6239        "encoding": False,
6240    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6244class JSONBObjectAgg(AggFunc):
6245    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6249class JSONArray(Func):
6250    arg_types = {
6251        "expressions": True,
6252        "null_handling": False,
6253        "return_type": False,
6254        "strict": False,
6255    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6259class JSONArrayAgg(Func):
6260    arg_types = {
6261        "this": True,
6262        "order": False,
6263        "null_handling": False,
6264        "return_type": False,
6265        "strict": False,
6266    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6269class JSONExists(Func):
6270    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
arg_types = {'this': True, 'path': True, 'passing': False, 'on_condition': False}
key = 'jsonexists'
class JSONColumnDef(Expression):
6275class JSONColumnDef(Expression):
6276    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False}
key = 'jsoncolumndef'
class JSONSchema(Expression):
6279class JSONSchema(Expression):
6280    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6284class JSONValue(Expression):
6285    arg_types = {
6286        "this": True,
6287        "path": True,
6288        "returning": False,
6289        "on_condition": False,
6290    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6293class JSONValueArray(Func):
6294    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6298class JSONTable(Func):
6299    arg_types = {
6300        "this": True,
6301        "schema": True,
6302        "path": False,
6303        "error_handling": False,
6304        "empty_handling": False,
6305    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6309class ObjectInsert(Func):
6310    arg_types = {
6311        "this": True,
6312        "key": True,
6313        "value": True,
6314        "update_flag": False,
6315    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6318class OpenJSONColumnDef(Expression):
6319    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
arg_types = {'this': True, 'kind': True, 'path': False, 'as_json': False}
key = 'openjsoncolumndef'
class OpenJSON(Func):
6322class OpenJSON(Func):
6323    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6326class JSONBContains(Binary, Func):
6327    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6330class JSONBExists(Func):
6331    arg_types = {"this": True, "path": True}
6332    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6335class JSONExtract(Binary, Func):
6336    arg_types = {
6337        "this": True,
6338        "expression": True,
6339        "only_json_types": False,
6340        "expressions": False,
6341        "variant_extract": False,
6342        "json_query": False,
6343        "option": False,
6344        "quote": False,
6345        "on_condition": False,
6346    }
6347    _sql_names = ["JSON_EXTRACT"]
6348    is_var_len_args = True
6349
6350    @property
6351    def output_name(self) -> str:
6352        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False, 'json_query': False, 'option': False, 'quote': False, 'on_condition': False}
is_var_len_args = True
output_name: str
6350    @property
6351    def output_name(self) -> str:
6352        return self.expression.output_name if not self.expressions else ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextract'
class JSONExtractQuote(Expression):
6356class JSONExtractQuote(Expression):
6357    arg_types = {
6358        "option": True,
6359        "scalar": False,
6360    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6363class JSONExtractArray(Func):
6364    arg_types = {"this": True, "expression": False}
6365    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6368class JSONExtractScalar(Binary, Func):
6369    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6370    _sql_names = ["JSON_EXTRACT_SCALAR"]
6371    is_var_len_args = True
6372
6373    @property
6374    def output_name(self) -> str:
6375        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
6373    @property
6374    def output_name(self) -> str:
6375        return self.expression.output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextractscalar'
class JSONBExtract(Binary, Func):
6378class JSONBExtract(Binary, Func):
6379    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6382class JSONBExtractScalar(Binary, Func):
6383    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6386class JSONFormat(Func):
6387    arg_types = {"this": False, "options": False, "is_json": False}
6388    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6392class JSONArrayContains(Binary, Predicate, Func):
6393    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6396class ParseJSON(Func):
6397    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6398    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6399    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6400    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6403class Least(Func):
6404    arg_types = {"this": True, "expressions": False}
6405    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6408class Left(Func):
6409    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6416class Length(Func):
6417    arg_types = {"this": True, "binary": False, "encoding": False}
6418    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6421class Levenshtein(Func):
6422    arg_types = {
6423        "this": True,
6424        "expression": False,
6425        "ins_cost": False,
6426        "del_cost": False,
6427        "sub_cost": False,
6428        "max_dist": False,
6429    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6432class Ln(Func):
6433    pass
key = 'ln'
class Log(Func):
6436class Log(Func):
6437    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6440class LogicalOr(AggFunc):
6441    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6444class LogicalAnd(AggFunc):
6445    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6448class Lower(Func):
6449    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6452class Map(Func):
6453    arg_types = {"keys": False, "values": False}
6454
6455    @property
6456    def keys(self) -> t.List[Expression]:
6457        keys = self.args.get("keys")
6458        return keys.expressions if keys else []
6459
6460    @property
6461    def values(self) -> t.List[Expression]:
6462        values = self.args.get("values")
6463        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6455    @property
6456    def keys(self) -> t.List[Expression]:
6457        keys = self.args.get("keys")
6458        return keys.expressions if keys else []
values: List[Expression]
6460    @property
6461    def values(self) -> t.List[Expression]:
6462        values = self.args.get("values")
6463        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6467class ToMap(Func):
6468    pass
key = 'tomap'
class MapFromEntries(Func):
6471class MapFromEntries(Func):
6472    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6476class ScopeResolution(Expression):
6477    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6480class Stream(Expression):
6481    pass
key = 'stream'
class StarMap(Func):
6484class StarMap(Func):
6485    pass
key = 'starmap'
class VarMap(Func):
6488class VarMap(Func):
6489    arg_types = {"keys": True, "values": True}
6490    is_var_len_args = True
6491
6492    @property
6493    def keys(self) -> t.List[Expression]:
6494        return self.args["keys"].expressions
6495
6496    @property
6497    def values(self) -> t.List[Expression]:
6498        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6492    @property
6493    def keys(self) -> t.List[Expression]:
6494        return self.args["keys"].expressions
values: List[Expression]
6496    @property
6497    def values(self) -> t.List[Expression]:
6498        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6502class MatchAgainst(Func):
6503    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6506class Max(AggFunc):
6507    arg_types = {"this": True, "expressions": False}
6508    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6511class MD5(Func):
6512    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6516class MD5Digest(Func):
6517    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6520class Median(AggFunc):
6521    pass
key = 'median'
class Min(AggFunc):
6524class Min(AggFunc):
6525    arg_types = {"this": True, "expressions": False}
6526    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6529class Month(Func):
6530    pass
key = 'month'
class AddMonths(Func):
6533class AddMonths(Func):
6534    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6537class Nvl2(Func):
6538    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6541class Normalize(Func):
6542    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6545class Overlay(Func):
6546    arg_types = {"this": True, "expression": True, "from": True, "for": False}
arg_types = {'this': True, 'expression': True, 'from': True, 'for': False}
key = 'overlay'
class Predict(Func):
6550class Predict(Func):
6551    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6554class Pow(Binary, Func):
6555    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6558class PercentileCont(AggFunc):
6559    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6562class PercentileDisc(AggFunc):
6563    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6566class Quantile(AggFunc):
6567    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6570class ApproxQuantile(Quantile):
6571    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
6574class Quarter(Func):
6575    pass
key = 'quarter'
class Rand(Func):
6580class Rand(Func):
6581    _sql_names = ["RAND", "RANDOM"]
6582    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6585class Randn(Func):
6586    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6589class RangeN(Func):
6590    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6593class ReadCSV(Func):
6594    _sql_names = ["READ_CSV"]
6595    is_var_len_args = True
6596    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6599class Reduce(Func):
6600    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
arg_types = {'this': True, 'initial': True, 'merge': True, 'finish': False}
key = 'reduce'
class RegexpExtract(Func):
6603class RegexpExtract(Func):
6604    arg_types = {
6605        "this": True,
6606        "expression": True,
6607        "position": False,
6608        "occurrence": False,
6609        "parameters": False,
6610        "group": False,
6611    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6614class RegexpExtractAll(Func):
6615    arg_types = {
6616        "this": True,
6617        "expression": True,
6618        "position": False,
6619        "occurrence": False,
6620        "parameters": False,
6621        "group": False,
6622    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6625class RegexpReplace(Func):
6626    arg_types = {
6627        "this": True,
6628        "expression": True,
6629        "replacement": False,
6630        "position": False,
6631        "occurrence": False,
6632        "modifiers": False,
6633    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6636class RegexpLike(Binary, Func):
6637    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6640class RegexpILike(Binary, Func):
6641    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6646class RegexpSplit(Func):
6647    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6650class Repeat(Func):
6651    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6656class Round(Func):
6657    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6660class RowNumber(Func):
6661    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6664class SafeDivide(Func):
6665    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6668class SHA(Func):
6669    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6672class SHA2(Func):
6673    _sql_names = ["SHA2"]
6674    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6677class Sign(Func):
6678    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6681class SortArray(Func):
6682    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6685class Split(Func):
6686    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6690class SplitPart(Func):
6691    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6696class Substring(Func):
6697    _sql_names = ["SUBSTRING", "SUBSTR"]
6698    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6701class StandardHash(Func):
6702    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6705class StartsWith(Func):
6706    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6707    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6710class StrPosition(Func):
6711    arg_types = {
6712        "this": True,
6713        "substr": True,
6714        "position": False,
6715        "occurrence": False,
6716    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6719class StrToDate(Func):
6720    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6723class StrToTime(Func):
6724    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
arg_types = {'this': True, 'format': True, 'zone': False, 'safe': False}
key = 'strtotime'
class StrToUnix(Func):
6729class StrToUnix(Func):
6730    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6735class StrToMap(Func):
6736    arg_types = {
6737        "this": True,
6738        "pair_delim": False,
6739        "key_value_delim": False,
6740        "duplicate_resolution_callback": False,
6741    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6744class NumberToStr(Func):
6745    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6748class FromBase(Func):
6749    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6752class Struct(Func):
6753    arg_types = {"expressions": False}
6754    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6757class StructExtract(Func):
6758    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6763class Stuff(Func):
6764    _sql_names = ["STUFF", "INSERT"]
6765    arg_types = {"this": True, "start": True, "length": True, "expression": True}
arg_types = {'this': True, 'start': True, 'length': True, 'expression': True}
key = 'stuff'
class Sum(AggFunc):
6768class Sum(AggFunc):
6769    pass
key = 'sum'
class Sqrt(Func):
6772class Sqrt(Func):
6773    pass
key = 'sqrt'
class Stddev(AggFunc):
6776class Stddev(AggFunc):
6777    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6780class StddevPop(AggFunc):
6781    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6784class StddevSamp(AggFunc):
6785    pass
key = 'stddevsamp'
class Time(Func):
6789class Time(Func):
6790    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6793class TimeToStr(Func):
6794    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'zone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
6797class TimeToTimeStr(Func):
6798    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6801class TimeToUnix(Func):
6802    pass
key = 'timetounix'
class TimeStrToDate(Func):
6805class TimeStrToDate(Func):
6806    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6809class TimeStrToTime(Func):
6810    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6813class TimeStrToUnix(Func):
6814    pass
key = 'timestrtounix'
class Trim(Func):
6817class Trim(Func):
6818    arg_types = {
6819        "this": True,
6820        "expression": False,
6821        "position": False,
6822        "collation": False,
6823    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6826class TsOrDsAdd(Func, TimeUnit):
6827    # return_type is used to correctly cast the arguments of this expression when transpiling it
6828    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6829
6830    @property
6831    def return_type(self) -> DataType:
6832        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
arg_types = {'this': True, 'expression': True, 'unit': False, 'return_type': False}
return_type: DataType
6830    @property
6831    def return_type(self) -> DataType:
6832        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6835class TsOrDsDiff(Func, TimeUnit):
6836    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6839class TsOrDsToDateStr(Func):
6840    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6843class TsOrDsToDate(Func):
6844    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6847class TsOrDsToDatetime(Func):
6848    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6851class TsOrDsToTime(Func):
6852    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6855class TsOrDsToTimestamp(Func):
6856    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6859class TsOrDiToDi(Func):
6860    pass
key = 'tsorditodi'
class Unhex(Func):
6863class Unhex(Func):
6864    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6867class Unicode(Func):
6868    pass
key = 'unicode'
class UnixDate(Func):
6872class UnixDate(Func):
6873    pass
key = 'unixdate'
class UnixToStr(Func):
6876class UnixToStr(Func):
6877    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6882class UnixToTime(Func):
6883    arg_types = {
6884        "this": True,
6885        "scale": False,
6886        "zone": False,
6887        "hours": False,
6888        "minutes": False,
6889        "format": False,
6890    }
6891
6892    SECONDS = Literal.number(0)
6893    DECIS = Literal.number(1)
6894    CENTIS = Literal.number(2)
6895    MILLIS = Literal.number(3)
6896    DECIMILLIS = Literal.number(4)
6897    CENTIMILLIS = Literal.number(5)
6898    MICROS = Literal.number(6)
6899    DECIMICROS = Literal.number(7)
6900    CENTIMICROS = Literal.number(8)
6901    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False, 'format': False}
SECONDS = Literal(this=0, is_string=False)
DECIS = Literal(this=1, is_string=False)
CENTIS = Literal(this=2, is_string=False)
MILLIS = Literal(this=3, is_string=False)
DECIMILLIS = Literal(this=4, is_string=False)
CENTIMILLIS = Literal(this=5, is_string=False)
MICROS = Literal(this=6, is_string=False)
DECIMICROS = Literal(this=7, is_string=False)
CENTIMICROS = Literal(this=8, is_string=False)
NANOS = Literal(this=9, is_string=False)
key = 'unixtotime'
class UnixToTimeStr(Func):
6904class UnixToTimeStr(Func):
6905    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6908class UnixSeconds(Func):
6909    pass
key = 'unixseconds'
class Uuid(Func):
6912class Uuid(Func):
6913    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6914
6915    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6918class TimestampFromParts(Func):
6919    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6920    arg_types = {
6921        "year": True,
6922        "month": True,
6923        "day": True,
6924        "hour": True,
6925        "min": True,
6926        "sec": True,
6927        "nano": False,
6928        "zone": False,
6929        "milli": False,
6930    }
arg_types = {'year': True, 'month': True, 'day': True, 'hour': True, 'min': True, 'sec': True, 'nano': False, 'zone': False, 'milli': False}
key = 'timestampfromparts'
class Upper(Func):
6933class Upper(Func):
6934    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6937class Corr(Binary, AggFunc):
6938    pass
key = 'corr'
class Variance(AggFunc):
6941class Variance(AggFunc):
6942    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6945class VariancePop(AggFunc):
6946    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6949class CovarSamp(Binary, AggFunc):
6950    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6953class CovarPop(Binary, AggFunc):
6954    pass
key = 'covarpop'
class Week(Func):
6957class Week(Func):
6958    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6961class XMLElement(Func):
6962    _sql_names = ["XMLELEMENT"]
6963    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6966class XMLTable(Func):
6967    arg_types = {
6968        "this": True,
6969        "namespaces": False,
6970        "passing": False,
6971        "columns": False,
6972        "by_ref": False,
6973    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6976class XMLNamespace(Expression):
6977    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
6981class XMLKeyValueOption(Expression):
6982    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
6985class Year(Func):
6986    pass
key = 'year'
class Use(Expression):
6989class Use(Expression):
6990    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6993class Merge(DML):
6994    arg_types = {
6995        "this": True,
6996        "using": True,
6997        "on": True,
6998        "whens": True,
6999        "with": False,
7000        "returning": False,
7001    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7004class When(Expression):
7005    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class Whens(Expression):
7008class Whens(Expression):
7009    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7010
7011    arg_types = {"expressions": True}

Wraps around one or more WHEN [NOT] MATCHED [...] clauses.

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7016class NextValueFor(Func):
7017    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7022class Semicolon(Expression):
7023    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConcatAgg'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArrayRemove'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONCAT_AGG': <class 'ArrayConcatAgg'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_REMOVE': <class 'ArrayRemove'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CONVERT_TO_CHARSET': <class 'ConvertToCharset'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_ASCII': <class 'IsAscii'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'CHAR_LENGTH': <class 'Length'>, 'CHARACTER_LENGTH': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OR': <class 'Or'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRTOK_TO_ARRAY': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_SECONDS': <class 'UnixSeconds'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'UUID': <class 'Uuid'>, 'GEN_RANDOM_UUID': <class 'Uuid'>, 'GENERATE_UUID': <class 'Uuid'>, 'UUID_STRING': <class 'Uuid'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'XMLELEMENT': <class 'XMLElement'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
7063def maybe_parse(
7064    sql_or_expression: ExpOrStr,
7065    *,
7066    into: t.Optional[IntoType] = None,
7067    dialect: DialectType = None,
7068    prefix: t.Optional[str] = None,
7069    copy: bool = False,
7070    **opts,
7071) -> Expression:
7072    """Gracefully handle a possible string or expression.
7073
7074    Example:
7075        >>> maybe_parse("1")
7076        Literal(this=1, is_string=False)
7077        >>> maybe_parse(to_identifier("x"))
7078        Identifier(this=x, quoted=False)
7079
7080    Args:
7081        sql_or_expression: the SQL code string or an expression
7082        into: the SQLGlot Expression to parse into
7083        dialect: the dialect used to parse the input expressions (in the case that an
7084            input expression is a SQL string).
7085        prefix: a string to prefix the sql with before it gets parsed
7086            (automatically includes a space)
7087        copy: whether to copy the expression.
7088        **opts: other options to use to parse the input expressions (again, in the case
7089            that an input expression is a SQL string).
7090
7091    Returns:
7092        Expression: the parsed or given expression.
7093    """
7094    if isinstance(sql_or_expression, Expression):
7095        if copy:
7096            return sql_or_expression.copy()
7097        return sql_or_expression
7098
7099    if sql_or_expression is None:
7100        raise ParseError("SQL cannot be None")
7101
7102    import sqlglot
7103
7104    sql = str(sql_or_expression)
7105    if prefix:
7106        sql = f"{prefix} {sql}"
7107
7108    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 Expression 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:

Expression: the parsed or given expression.

def maybe_copy(instance, copy=True):
7119def maybe_copy(instance, copy=True):
7120    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7375def union(
7376    *expressions: ExpOrStr,
7377    distinct: bool = True,
7378    dialect: DialectType = None,
7379    copy: bool = True,
7380    **opts,
7381) -> Union:
7382    """
7383    Initializes a syntax tree for the `UNION` operation.
7384
7385    Example:
7386        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7387        'SELECT * FROM foo UNION SELECT * FROM bla'
7388
7389    Args:
7390        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7391            If `Expression` instances are passed, they will be used as-is.
7392        distinct: set the DISTINCT flag if and only if this is true.
7393        dialect: the dialect used to parse the input expression.
7394        copy: whether to copy the expression.
7395        opts: other options to use to parse the input expressions.
7396
7397    Returns:
7398        The new Union instance.
7399    """
7400    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7401    return _apply_set_operation(
7402        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7403    )

Initializes a syntax tree for the UNION operation.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the UNION's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • 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:

The new Union instance.

def intersect( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7406def intersect(
7407    *expressions: ExpOrStr,
7408    distinct: bool = True,
7409    dialect: DialectType = None,
7410    copy: bool = True,
7411    **opts,
7412) -> Intersect:
7413    """
7414    Initializes a syntax tree for the `INTERSECT` operation.
7415
7416    Example:
7417        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7418        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7419
7420    Args:
7421        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7422            If `Expression` instances are passed, they will be used as-is.
7423        distinct: set the DISTINCT flag if and only if this is true.
7424        dialect: the dialect used to parse the input expression.
7425        copy: whether to copy the expression.
7426        opts: other options to use to parse the input expressions.
7427
7428    Returns:
7429        The new Intersect instance.
7430    """
7431    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7432    return _apply_set_operation(
7433        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7434    )

Initializes a syntax tree for the INTERSECT operation.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the INTERSECT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • 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:

The new Intersect instance.

def except_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7437def except_(
7438    *expressions: ExpOrStr,
7439    distinct: bool = True,
7440    dialect: DialectType = None,
7441    copy: bool = True,
7442    **opts,
7443) -> Except:
7444    """
7445    Initializes a syntax tree for the `EXCEPT` operation.
7446
7447    Example:
7448        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7449        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7450
7451    Args:
7452        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7453            If `Expression` instances are passed, they will be used as-is.
7454        distinct: set the DISTINCT flag if and only if this is true.
7455        dialect: the dialect used to parse the input expression.
7456        copy: whether to copy the expression.
7457        opts: other options to use to parse the input expressions.
7458
7459    Returns:
7460        The new Except instance.
7461    """
7462    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7463    return _apply_set_operation(
7464        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7465    )

Initializes a syntax tree for the EXCEPT operation.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the EXCEPT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • 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:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7468def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7469    """
7470    Initializes a syntax tree from one or multiple SELECT expressions.
7471
7472    Example:
7473        >>> select("col1", "col2").from_("tbl").sql()
7474        'SELECT col1, col2 FROM tbl'
7475
7476    Args:
7477        *expressions: the SQL code string to parse as the expressions of a
7478            SELECT statement. If an Expression instance is passed, this is used as-is.
7479        dialect: the dialect used to parse the input expressions (in the case that an
7480            input expression is a SQL string).
7481        **opts: other options to use to parse the input expressions (again, in the case
7482            that an input expression is a SQL string).
7483
7484    Returns:
7485        Select: the syntax tree for the SELECT statement.
7486    """
7487    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

Example:
>>> select("col1", "col2").from_("tbl").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expressions: the SQL code string to parse as the expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7490def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7491    """
7492    Initializes a syntax tree from a FROM expression.
7493
7494    Example:
7495        >>> from_("tbl").select("col1", "col2").sql()
7496        'SELECT col1, col2 FROM tbl'
7497
7498    Args:
7499        *expression: the SQL code string to parse as the FROM expressions of a
7500            SELECT statement. If an Expression instance is passed, this is used as-is.
7501        dialect: the dialect used to parse the input expression (in the case that the
7502            input expression is a SQL string).
7503        **opts: other options to use to parse the input expressions (again, in the case
7504            that the input expression is a SQL string).
7505
7506    Returns:
7507        Select: the syntax tree for the SELECT statement.
7508    """
7509    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

Example:
>>> from_("tbl").select("col1", "col2").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expression: the SQL code string to parse as the FROM expressions of a SELECT statement. If an Expression 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).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Update:
7512def update(
7513    table: str | Table,
7514    properties: t.Optional[dict] = None,
7515    where: t.Optional[ExpOrStr] = None,
7516    from_: t.Optional[ExpOrStr] = None,
7517    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7518    dialect: DialectType = None,
7519    **opts,
7520) -> Update:
7521    """
7522    Creates an update statement.
7523
7524    Example:
7525        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
7526        "WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
7527
7528    Args:
7529        properties: dictionary of properties to SET which are
7530            auto converted to sql objects eg None -> NULL
7531        where: sql conditional parsed into a WHERE statement
7532        from_: sql statement parsed into a FROM statement
7533        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7534        dialect: the dialect used to parse the input expressions.
7535        **opts: other options to use to parse the input expressions.
7536
7537    Returns:
7538        Update: the syntax tree for the UPDATE statement.
7539    """
7540    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7541    if properties:
7542        update_expr.set(
7543            "expressions",
7544            [
7545                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7546                for k, v in properties.items()
7547            ],
7548        )
7549    if from_:
7550        update_expr.set(
7551            "from",
7552            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7553        )
7554    if isinstance(where, Condition):
7555        where = Where(this=where)
7556    if where:
7557        update_expr.set(
7558            "where",
7559            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7560        )
7561    if with_:
7562        cte_list = [
7563            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7564            for alias, qry in with_.items()
7565        ]
7566        update_expr.set(
7567            "with",
7568            With(expressions=cte_list),
7569        )
7570    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
"WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
Arguments:
  • properties: dictionary of properties to SET which are auto converted to sql objects eg None -> NULL
  • where: sql conditional parsed into a WHERE statement
  • from_: sql statement parsed into a FROM statement
  • with_: dictionary of CTE aliases / select statements to include in a WITH clause.
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Delete:
7573def delete(
7574    table: ExpOrStr,
7575    where: t.Optional[ExpOrStr] = None,
7576    returning: t.Optional[ExpOrStr] = None,
7577    dialect: DialectType = None,
7578    **opts,
7579) -> Delete:
7580    """
7581    Builds a delete statement.
7582
7583    Example:
7584        >>> delete("my_table", where="id > 1").sql()
7585        'DELETE FROM my_table WHERE id > 1'
7586
7587    Args:
7588        where: sql conditional parsed into a WHERE statement
7589        returning: sql conditional parsed into a RETURNING statement
7590        dialect: the dialect used to parse the input expressions.
7591        **opts: other options to use to parse the input expressions.
7592
7593    Returns:
7594        Delete: the syntax tree for the DELETE statement.
7595    """
7596    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7597    if where:
7598        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7599    if returning:
7600        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7601    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7604def insert(
7605    expression: ExpOrStr,
7606    into: ExpOrStr,
7607    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7608    overwrite: t.Optional[bool] = None,
7609    returning: t.Optional[ExpOrStr] = None,
7610    dialect: DialectType = None,
7611    copy: bool = True,
7612    **opts,
7613) -> Insert:
7614    """
7615    Builds an INSERT statement.
7616
7617    Example:
7618        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7619        'INSERT INTO tbl VALUES (1, 2, 3)'
7620
7621    Args:
7622        expression: the sql string or expression of the INSERT statement
7623        into: the tbl to insert data to.
7624        columns: optionally the table's column names.
7625        overwrite: whether to INSERT OVERWRITE or not.
7626        returning: sql conditional parsed into a RETURNING statement
7627        dialect: the dialect used to parse the input expressions.
7628        copy: whether to copy the expression.
7629        **opts: other options to use to parse the input expressions.
7630
7631    Returns:
7632        Insert: the syntax tree for the INSERT statement.
7633    """
7634    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7635    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7636
7637    if columns:
7638        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7639
7640    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7641
7642    if returning:
7643        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7644
7645    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7648def merge(
7649    *when_exprs: ExpOrStr,
7650    into: ExpOrStr,
7651    using: ExpOrStr,
7652    on: ExpOrStr,
7653    returning: t.Optional[ExpOrStr] = None,
7654    dialect: DialectType = None,
7655    copy: bool = True,
7656    **opts,
7657) -> Merge:
7658    """
7659    Builds a MERGE statement.
7660
7661    Example:
7662        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7663        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7664        ...       into="my_table",
7665        ...       using="source_table",
7666        ...       on="my_table.id = source_table.id").sql()
7667        'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
7668
7669    Args:
7670        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7671        into: The target table to merge data into.
7672        using: The source table to merge data from.
7673        on: The join condition for the merge.
7674        returning: The columns to return from the merge.
7675        dialect: The dialect used to parse the input expressions.
7676        copy: Whether to copy the expression.
7677        **opts: Other options to use to parse the input expressions.
7678
7679    Returns:
7680        Merge: The syntax tree for the MERGE statement.
7681    """
7682    expressions: t.List[Expression] = []
7683    for when_expr in when_exprs:
7684        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7685        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7686
7687    merge = Merge(
7688        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7689        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7690        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7691        whens=Whens(expressions=expressions),
7692    )
7693    if returning:
7694        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7695
7696    return merge

Builds a MERGE statement.

Example:
>>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
...       into="my_table",
...       using="source_table",
...       on="my_table.id = source_table.id").sql()
'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
Arguments:
  • *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
  • into: The target table to merge data into.
  • using: The source table to merge data from.
  • on: The join condition for the merge.
  • returning: The columns to return from the merge.
  • dialect: The dialect used to parse the input expressions.
  • copy: Whether to copy the expression.
  • **opts: Other options to use to parse the input expressions.
Returns:

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7699def condition(
7700    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7701) -> Condition:
7702    """
7703    Initialize a logical condition expression.
7704
7705    Example:
7706        >>> condition("x=1").sql()
7707        'x = 1'
7708
7709        This is helpful for composing larger logical syntax trees:
7710        >>> where = condition("x=1")
7711        >>> where = where.and_("y=1")
7712        >>> Select().from_("tbl").select("*").where(where).sql()
7713        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7714
7715    Args:
7716        *expression: the SQL code string to parse.
7717            If an Expression instance is passed, this is used as-is.
7718        dialect: the dialect used to parse the input expression (in the case that the
7719            input expression is a SQL string).
7720        copy: Whether to copy `expression` (only applies to expressions).
7721        **opts: other options to use to parse the input expressions (again, in the case
7722            that the input expression is a SQL string).
7723
7724    Returns:
7725        The new Condition instance
7726    """
7727    return maybe_parse(
7728        expression,
7729        into=Condition,
7730        dialect=dialect,
7731        copy=copy,
7732        **opts,
7733    )

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")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression 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

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7736def and_(
7737    *expressions: t.Optional[ExpOrStr],
7738    dialect: DialectType = None,
7739    copy: bool = True,
7740    wrap: bool = True,
7741    **opts,
7742) -> Condition:
7743    """
7744    Combine multiple conditions with an AND logical operator.
7745
7746    Example:
7747        >>> and_("x=1", and_("y=1", "z=1")).sql()
7748        'x = 1 AND (y = 1 AND z = 1)'
7749
7750    Args:
7751        *expressions: the SQL code strings to parse.
7752            If an Expression instance is passed, this is used as-is.
7753        dialect: the dialect used to parse the input expression.
7754        copy: whether to copy `expressions` (only applies to Expressions).
7755        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7756            precedence issues, but can be turned off when the produced AST is too deep and
7757            causes recursion-related issues.
7758        **opts: other options to use to parse the input expressions.
7759
7760    Returns:
7761        The new condition
7762    """
7763    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 Expression 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 Expressions).
  • 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

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7766def or_(
7767    *expressions: t.Optional[ExpOrStr],
7768    dialect: DialectType = None,
7769    copy: bool = True,
7770    wrap: bool = True,
7771    **opts,
7772) -> Condition:
7773    """
7774    Combine multiple conditions with an OR logical operator.
7775
7776    Example:
7777        >>> or_("x=1", or_("y=1", "z=1")).sql()
7778        'x = 1 OR (y = 1 OR z = 1)'
7779
7780    Args:
7781        *expressions: the SQL code strings to parse.
7782            If an Expression instance is passed, this is used as-is.
7783        dialect: the dialect used to parse the input expression.
7784        copy: whether to copy `expressions` (only applies to Expressions).
7785        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7786            precedence issues, but can be turned off when the produced AST is too deep and
7787            causes recursion-related issues.
7788        **opts: other options to use to parse the input expressions.
7789
7790    Returns:
7791        The new condition
7792    """
7793    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 Expression 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 Expressions).
  • 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

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7796def xor(
7797    *expressions: t.Optional[ExpOrStr],
7798    dialect: DialectType = None,
7799    copy: bool = True,
7800    wrap: bool = True,
7801    **opts,
7802) -> Condition:
7803    """
7804    Combine multiple conditions with an XOR logical operator.
7805
7806    Example:
7807        >>> xor("x=1", xor("y=1", "z=1")).sql()
7808        'x = 1 XOR (y = 1 XOR z = 1)'
7809
7810    Args:
7811        *expressions: the SQL code strings to parse.
7812            If an Expression instance is passed, this is used as-is.
7813        dialect: the dialect used to parse the input expression.
7814        copy: whether to copy `expressions` (only applies to Expressions).
7815        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7816            precedence issues, but can be turned off when the produced AST is too deep and
7817            causes recursion-related issues.
7818        **opts: other options to use to parse the input expressions.
7819
7820    Returns:
7821        The new condition
7822    """
7823    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 Expression 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 Expressions).
  • 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

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7826def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7827    """
7828    Wrap a condition with a NOT operator.
7829
7830    Example:
7831        >>> not_("this_suit='black'").sql()
7832        "NOT this_suit = 'black'"
7833
7834    Args:
7835        expression: the SQL code string to parse.
7836            If an Expression instance is passed, this is used as-is.
7837        dialect: the dialect used to parse the input expression.
7838        copy: whether to copy the expression or not.
7839        **opts: other options to use to parse the input expressions.
7840
7841    Returns:
7842        The new condition.
7843    """
7844    this = condition(
7845        expression,
7846        dialect=dialect,
7847        copy=copy,
7848        **opts,
7849    )
7850    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 Expression 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.

def paren( expression: Union[str, Expression], copy: bool = True) -> Paren:
7853def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7854    """
7855    Wrap an expression in parentheses.
7856
7857    Example:
7858        >>> paren("5 + 3").sql()
7859        '(5 + 3)'
7860
7861    Args:
7862        expression: the SQL code string to parse.
7863            If an Expression instance is passed, this is used as-is.
7864        copy: whether to copy the expression or not.
7865
7866    Returns:
7867        The wrapped expression.
7868    """
7869    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 Expression instance is passed, this is used as-is.
  • copy: whether to copy the expression or not.
Returns:

The wrapped expression.

SAFE_IDENTIFIER_RE: Pattern[str] = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
7885def to_identifier(name, quoted=None, copy=True):
7886    """Builds an identifier.
7887
7888    Args:
7889        name: The name to turn into an identifier.
7890        quoted: Whether to force quote the identifier.
7891        copy: Whether to copy name if it's an Identifier.
7892
7893    Returns:
7894        The identifier ast node.
7895    """
7896
7897    if name is None:
7898        return None
7899
7900    if isinstance(name, Identifier):
7901        identifier = maybe_copy(name, copy)
7902    elif isinstance(name, str):
7903        identifier = Identifier(
7904            this=name,
7905            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7906        )
7907    else:
7908        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7909    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.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Identifier:
7912def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7913    """
7914    Parses a given string into an identifier.
7915
7916    Args:
7917        name: The name to parse into an identifier.
7918        dialect: The dialect to parse against.
7919
7920    Returns:
7921        The identifier ast node.
7922    """
7923    try:
7924        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7925    except (ParseError, TokenError):
7926        expression = to_identifier(name)
7927
7928    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*(-?[0-9]+(?:\\.[0-9]+)?)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
7934def to_interval(interval: str | Literal) -> Interval:
7935    """Builds an interval expression from a string like '1 day' or '5 months'."""
7936    if isinstance(interval, Literal):
7937        if not interval.is_string:
7938            raise ValueError("Invalid interval string.")
7939
7940        interval = interval.this
7941
7942    interval = maybe_parse(f"INTERVAL {interval}")
7943    assert isinstance(interval, Interval)
7944    return interval

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
7947def to_table(
7948    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7949) -> Table:
7950    """
7951    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7952    If a table is passed in then that table is returned.
7953
7954    Args:
7955        sql_path: a `[catalog].[schema].[table]` string.
7956        dialect: the source dialect according to which the table name will be parsed.
7957        copy: Whether to copy a table if it is passed in.
7958        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7959
7960    Returns:
7961        A table expression.
7962    """
7963    if isinstance(sql_path, Table):
7964        return maybe_copy(sql_path, copy=copy)
7965
7966    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7967
7968    for k, v in kwargs.items():
7969        table.set(k, v)
7970
7971    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
7974def to_column(
7975    sql_path: str | Column,
7976    quoted: t.Optional[bool] = None,
7977    dialect: DialectType = None,
7978    copy: bool = True,
7979    **kwargs,
7980) -> Column:
7981    """
7982    Create a column from a `[table].[column]` sql path. Table is optional.
7983    If a column is passed in then that column is returned.
7984
7985    Args:
7986        sql_path: a `[table].[column]` string.
7987        quoted: Whether or not to force quote identifiers.
7988        dialect: the source dialect according to which the column name will be parsed.
7989        copy: Whether to copy a column if it is passed in.
7990        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7991
7992    Returns:
7993        A column expression.
7994    """
7995    if isinstance(sql_path, Column):
7996        return maybe_copy(sql_path, copy=copy)
7997
7998    try:
7999        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8000    except ParseError:
8001        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8002
8003    for k, v in kwargs.items():
8004        col.set(k, v)
8005
8006    if quoted:
8007        for i in col.find_all(Identifier):
8008            i.set("quoted", True)
8009
8010    return col

Create a column from a [table].[column] sql path. Table is optional. If a column is passed in then that column is returned.

Arguments:
  • sql_path: a [table].[column] string.
  • quoted: Whether or not to force quote identifiers.
  • dialect: the source dialect according to which the column name will be parsed.
  • copy: Whether to copy a column if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Column expression with.
Returns:

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts):
8013def alias_(
8014    expression: ExpOrStr,
8015    alias: t.Optional[str | Identifier],
8016    table: bool | t.Sequence[str | Identifier] = False,
8017    quoted: t.Optional[bool] = None,
8018    dialect: DialectType = None,
8019    copy: bool = True,
8020    **opts,
8021):
8022    """Create an Alias expression.
8023
8024    Example:
8025        >>> alias_('foo', 'bar').sql()
8026        'foo AS bar'
8027
8028        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8029        '(SELECT 1, 2) AS bar(a, b)'
8030
8031    Args:
8032        expression: the SQL code strings to parse.
8033            If an Expression instance is passed, this is used as-is.
8034        alias: the alias name to use. If the name has
8035            special characters it is quoted.
8036        table: Whether to create a table alias, can also be a list of columns.
8037        quoted: whether to quote the alias
8038        dialect: the dialect used to parse the input expression.
8039        copy: Whether to copy the expression.
8040        **opts: other options to use to parse the input expressions.
8041
8042    Returns:
8043        Alias: the aliased expression
8044    """
8045    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8046    alias = to_identifier(alias, quoted=quoted)
8047
8048    if table:
8049        table_alias = TableAlias(this=alias)
8050        exp.set("alias", table_alias)
8051
8052        if not isinstance(table, bool):
8053            for column in table:
8054                table_alias.append("columns", to_identifier(column, quoted=quoted))
8055
8056        return exp
8057
8058    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8059    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8060    # for the complete Window expression.
8061    #
8062    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8063
8064    if "alias" in exp.arg_types and not isinstance(exp, Window):
8065        exp.set("alias", alias)
8066        return exp
8067    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 Expression 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

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8070def subquery(
8071    expression: ExpOrStr,
8072    alias: t.Optional[Identifier | str] = None,
8073    dialect: DialectType = None,
8074    **opts,
8075) -> Select:
8076    """
8077    Build a subquery expression that's selected from.
8078
8079    Example:
8080        >>> subquery('select x from tbl', 'bar').select('x').sql()
8081        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8082
8083    Args:
8084        expression: the SQL code strings to parse.
8085            If an Expression instance is passed, this is used as-is.
8086        alias: the alias name to use.
8087        dialect: the dialect used to parse the input expression.
8088        **opts: other options to use to parse the input expressions.
8089
8090    Returns:
8091        A new Select instance with the subquery expression included.
8092    """
8093
8094    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8095    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression that's selected from.

Example:
>>> subquery('select x from tbl', 'bar').select('x').sql()
'SELECT x FROM (SELECT x FROM tbl) AS bar'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use.
  • dialect: the dialect used to parse the input expression.
  • **opts: other options to use to parse the input expressions.
Returns:

A new Select instance with the subquery expression included.

def column( col, table=None, db=None, catalog=None, *, fields=None, quoted=None, copy=True):
8126def column(
8127    col,
8128    table=None,
8129    db=None,
8130    catalog=None,
8131    *,
8132    fields=None,
8133    quoted=None,
8134    copy=True,
8135):
8136    """
8137    Build a Column.
8138
8139    Args:
8140        col: Column name.
8141        table: Table name.
8142        db: Database name.
8143        catalog: Catalog name.
8144        fields: Additional fields using dots.
8145        quoted: Whether to force quotes on the column's identifiers.
8146        copy: Whether to copy identifiers if passed in.
8147
8148    Returns:
8149        The new Column instance.
8150    """
8151    this = Column(
8152        this=to_identifier(col, quoted=quoted, copy=copy),
8153        table=to_identifier(table, quoted=quoted, copy=copy),
8154        db=to_identifier(db, quoted=quoted, copy=copy),
8155        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8156    )
8157
8158    if fields:
8159        this = Dot.build(
8160            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8161        )
8162    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8165def cast(
8166    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8167) -> Cast:
8168    """Cast an expression to a data type.
8169
8170    Example:
8171        >>> cast('x + 1', 'int').sql()
8172        'CAST(x + 1 AS INT)'
8173
8174    Args:
8175        expression: The expression to cast.
8176        to: The datatype to cast to.
8177        copy: Whether to copy the supplied expressions.
8178        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8179            - The expression to be cast is already a exp.Cast expression
8180            - The existing cast is to a type that is logically equivalent to new type
8181
8182            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8183            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8184            and instead just return the original expression `CAST(x as DATETIME)`.
8185
8186            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8187            mapping is applied in the target dialect generator.
8188
8189    Returns:
8190        The new Cast instance.
8191    """
8192    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8193    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8194
8195    # dont re-cast if the expression is already a cast to the correct type
8196    if isinstance(expr, Cast):
8197        from sqlglot.dialects.dialect import Dialect
8198
8199        target_dialect = Dialect.get_or_raise(dialect)
8200        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8201
8202        existing_cast_type: DataType.Type = expr.to.this
8203        new_cast_type: DataType.Type = data_type.this
8204        types_are_equivalent = type_mapping.get(
8205            existing_cast_type, existing_cast_type.value
8206        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8207
8208        if expr.is_type(data_type) or types_are_equivalent:
8209            return expr
8210
8211    expr = Cast(this=expr, to=data_type)
8212    expr.type = data_type
8213
8214    return expr

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
  • copy: Whether to copy the supplied expressions.
  • dialect: The target dialect. This is used to prevent a re-cast in the following scenario:

    • The expression to be cast is already a exp.Cast expression
    • The existing cast is to a type that is logically equivalent to new type

    For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP, but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return CAST(x (as DATETIME) as TIMESTAMP) and instead just return the original expression CAST(x as DATETIME).

    This is to prevent it being output as a double cast CAST(x (as TIMESTAMP) as TIMESTAMP) once the DATETIME -> TIMESTAMP mapping is applied in the target dialect generator.

Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
8217def table_(
8218    table: Identifier | str,
8219    db: t.Optional[Identifier | str] = None,
8220    catalog: t.Optional[Identifier | str] = None,
8221    quoted: t.Optional[bool] = None,
8222    alias: t.Optional[Identifier | str] = None,
8223) -> Table:
8224    """Build a Table.
8225
8226    Args:
8227        table: Table name.
8228        db: Database name.
8229        catalog: Catalog name.
8230        quote: Whether to force quotes on the table's identifiers.
8231        alias: Table's alias.
8232
8233    Returns:
8234        The new Table instance.
8235    """
8236    return Table(
8237        this=to_identifier(table, quoted=quoted) if table else None,
8238        db=to_identifier(db, quoted=quoted) if db else None,
8239        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8240        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8241    )

Build a Table.

Arguments:
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • quote: Whether to force quotes on the table's identifiers.
  • alias: Table's alias.
Returns:

The new Table instance.

def values( values: Iterable[Tuple[Any, ...]], alias: Optional[str] = None, columns: Union[Iterable[str], Dict[str, DataType], NoneType] = None) -> Values:
8244def values(
8245    values: t.Iterable[t.Tuple[t.Any, ...]],
8246    alias: t.Optional[str] = None,
8247    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8248) -> Values:
8249    """Build VALUES statement.
8250
8251    Example:
8252        >>> values([(1, '2')]).sql()
8253        "VALUES (1, '2')"
8254
8255    Args:
8256        values: values statements that will be converted to SQL
8257        alias: optional alias
8258        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8259         If either are provided then an alias is also required.
8260
8261    Returns:
8262        Values: the Values expression object
8263    """
8264    if columns and not alias:
8265        raise ValueError("Alias is required when providing columns")
8266
8267    return Values(
8268        expressions=[convert(tup) for tup in values],
8269        alias=(
8270            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8271            if columns
8272            else (TableAlias(this=to_identifier(alias)) if alias else None)
8273        ),
8274    )

Build VALUES statement.

Example:
>>> values([(1, '2')]).sql()
"VALUES (1, '2')"
Arguments:
  • values: values statements that will be converted to SQL
  • alias: optional alias
  • columns: Optional list of ordered column names or ordered dictionary of column names to types. If either are provided then an alias is also required.
Returns:

Values: the Values expression object

def var( name: Union[str, Expression, NoneType]) -> Var:
8277def var(name: t.Optional[ExpOrStr]) -> Var:
8278    """Build a SQL variable.
8279
8280    Example:
8281        >>> repr(var('x'))
8282        'Var(this=x)'
8283
8284        >>> repr(var(column('x', table='y')))
8285        'Var(this=x)'
8286
8287    Args:
8288        name: The name of the var or an expression who's name will become the var.
8289
8290    Returns:
8291        The new variable node.
8292    """
8293    if not name:
8294        raise ValueError("Cannot convert empty name into var.")
8295
8296    if isinstance(name, Expression):
8297        name = name.name
8298    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8301def rename_table(
8302    old_name: str | Table,
8303    new_name: str | Table,
8304    dialect: DialectType = None,
8305) -> Alter:
8306    """Build ALTER TABLE... RENAME... expression
8307
8308    Args:
8309        old_name: The old name of the table
8310        new_name: The new name of the table
8311        dialect: The dialect to parse the table.
8312
8313    Returns:
8314        Alter table expression
8315    """
8316    old_table = to_table(old_name, dialect=dialect)
8317    new_table = to_table(new_name, dialect=dialect)
8318    return Alter(
8319        this=old_table,
8320        kind="TABLE",
8321        actions=[
8322            AlterRename(this=new_table),
8323        ],
8324    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse the table.
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8327def rename_column(
8328    table_name: str | Table,
8329    old_column_name: str | Column,
8330    new_column_name: str | Column,
8331    exists: t.Optional[bool] = None,
8332    dialect: DialectType = None,
8333) -> Alter:
8334    """Build ALTER TABLE... RENAME COLUMN... expression
8335
8336    Args:
8337        table_name: Name of the table
8338        old_column: The old name of the column
8339        new_column: The new name of the column
8340        exists: Whether to add the `IF EXISTS` clause
8341        dialect: The dialect to parse the table/column.
8342
8343    Returns:
8344        Alter table expression
8345    """
8346    table = to_table(table_name, dialect=dialect)
8347    old_column = to_column(old_column_name, dialect=dialect)
8348    new_column = to_column(new_column_name, dialect=dialect)
8349    return Alter(
8350        this=table,
8351        kind="TABLE",
8352        actions=[
8353            RenameColumn(this=old_column, to=new_column, exists=exists),
8354        ],
8355    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether to add the IF EXISTS clause
  • dialect: The dialect to parse the table/column.
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
8358def convert(value: t.Any, copy: bool = False) -> Expression:
8359    """Convert a python value into an expression object.
8360
8361    Raises an error if a conversion is not possible.
8362
8363    Args:
8364        value: A python object.
8365        copy: Whether to copy `value` (only applies to Expressions and collections).
8366
8367    Returns:
8368        The equivalent expression object.
8369    """
8370    if isinstance(value, Expression):
8371        return maybe_copy(value, copy)
8372    if isinstance(value, str):
8373        return Literal.string(value)
8374    if isinstance(value, bool):
8375        return Boolean(this=value)
8376    if value is None or (isinstance(value, float) and math.isnan(value)):
8377        return null()
8378    if isinstance(value, numbers.Number):
8379        return Literal.number(value)
8380    if isinstance(value, bytes):
8381        return HexString(this=value.hex())
8382    if isinstance(value, datetime.datetime):
8383        datetime_literal = Literal.string(value.isoformat(sep=" "))
8384
8385        tz = None
8386        if value.tzinfo:
8387            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8388            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8389            tz = Literal.string(str(value.tzinfo))
8390
8391        return TimeStrToTime(this=datetime_literal, zone=tz)
8392    if isinstance(value, datetime.date):
8393        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8394        return DateStrToDate(this=date_literal)
8395    if isinstance(value, tuple):
8396        if hasattr(value, "_fields"):
8397            return Struct(
8398                expressions=[
8399                    PropertyEQ(
8400                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8401                    )
8402                    for k in value._fields
8403                ]
8404            )
8405        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8406    if isinstance(value, list):
8407        return Array(expressions=[convert(v, copy=copy) for v in value])
8408    if isinstance(value, dict):
8409        return Map(
8410            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8411            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8412        )
8413    if hasattr(value, "__dict__"):
8414        return Struct(
8415            expressions=[
8416                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8417                for k, v in value.__dict__.items()
8418            ]
8419        )
8420    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 Expressions and collections).
Returns:

The equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
8423def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8424    """
8425    Replace children of an expression with the result of a lambda fun(child) -> exp.
8426    """
8427    for k, v in tuple(expression.args.items()):
8428        is_list_arg = type(v) is list
8429
8430        child_nodes = v if is_list_arg else [v]
8431        new_child_nodes = []
8432
8433        for cn in child_nodes:
8434            if isinstance(cn, Expression):
8435                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8436                    new_child_nodes.append(child_node)
8437            else:
8438                new_child_nodes.append(cn)
8439
8440        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))

Replace children of an expression with the result of a lambda fun(child) -> exp.

def replace_tree( expression: Expression, fun: Callable, prune: Optional[Callable[[Expression], bool]] = None) -> Expression:
8443def replace_tree(
8444    expression: Expression,
8445    fun: t.Callable,
8446    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8447) -> Expression:
8448    """
8449    Replace an entire tree with the result of function calls on each node.
8450
8451    This will be traversed in reverse dfs, so leaves first.
8452    If new nodes are created as a result of function calls, they will also be traversed.
8453    """
8454    stack = list(expression.dfs(prune=prune))
8455
8456    while stack:
8457        node = stack.pop()
8458        new_node = fun(node)
8459
8460        if new_node is not node:
8461            node.replace(new_node)
8462
8463            if isinstance(new_node, Expression):
8464                stack.append(new_node)
8465
8466    return new_node

Replace an entire tree with the result of function calls on each node.

This will be traversed in reverse dfs, so leaves first. If new nodes are created as a result of function calls, they will also be traversed.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
8469def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8470    """
8471    Return all table names referenced through columns in an expression.
8472
8473    Example:
8474        >>> import sqlglot
8475        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8476        ['a', 'c']
8477
8478    Args:
8479        expression: expression to find table names.
8480        exclude: a table name to exclude
8481
8482    Returns:
8483        A list of unique names.
8484    """
8485    return {
8486        table
8487        for table in (column.table for column in expression.find_all(Column))
8488        if table and table != exclude
8489    }

Return all table names referenced through columns in an expression.

Example:
>>> import sqlglot
>>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
['a', 'c']
Arguments:
  • expression: expression to find table names.
  • exclude: a table name to exclude
Returns:

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, identify: bool = False) -> str:
8492def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8493    """Get the full name of a table as a string.
8494
8495    Args:
8496        table: Table expression node or string.
8497        dialect: The dialect to generate the table name for.
8498        identify: Determines when an identifier should be quoted. Possible values are:
8499            False (default): Never quote, except in cases where it's mandatory by the dialect.
8500            True: Always quote.
8501
8502    Examples:
8503        >>> from sqlglot import exp, parse_one
8504        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8505        'a.b.c'
8506
8507    Returns:
8508        The table name.
8509    """
8510
8511    table = maybe_parse(table, into=Table, dialect=dialect)
8512
8513    if not table:
8514        raise ValueError(f"Cannot parse {table}")
8515
8516    return ".".join(
8517        (
8518            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8519            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8520            else part.name
8521        )
8522        for part in table.parts
8523    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> str:
8526def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8527    """Returns a case normalized table name without quotes.
8528
8529    Args:
8530        table: the table to normalize
8531        dialect: the dialect to use for normalization rules
8532        copy: whether to copy the expression.
8533
8534    Examples:
8535        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8536        'A-B.c'
8537    """
8538    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8539
8540    return ".".join(
8541        p.name
8542        for p in normalize_identifiers(
8543            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8544        ).parts
8545    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8548def replace_tables(
8549    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8550) -> E:
8551    """Replace all tables in expression according to the mapping.
8552
8553    Args:
8554        expression: expression node to be transformed and replaced.
8555        mapping: mapping of table names.
8556        dialect: the dialect of the mapping table
8557        copy: whether to copy the expression.
8558
8559    Examples:
8560        >>> from sqlglot import exp, parse_one
8561        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8562        'SELECT * FROM c /* a.b */'
8563
8564    Returns:
8565        The mapped expression.
8566    """
8567
8568    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8569
8570    def _replace_tables(node: Expression) -> Expression:
8571        if isinstance(node, Table) and node.meta.get("replace") is not False:
8572            original = normalize_table_name(node, dialect=dialect)
8573            new_name = mapping.get(original)
8574
8575            if new_name:
8576                table = to_table(
8577                    new_name,
8578                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8579                    dialect=dialect,
8580                )
8581                table.add_comments([original])
8582                return table
8583        return node
8584
8585    return expression.transform(_replace_tables, copy=copy)  # type: ignore

Replace all tables in expression according to the mapping.

Arguments:
  • expression: expression node to be transformed and replaced.
  • mapping: mapping of table names.
  • dialect: the dialect of the mapping table
  • copy: whether to copy the expression.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
'SELECT * FROM c /* a.b */'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
8588def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8589    """Replace placeholders in an expression.
8590
8591    Args:
8592        expression: expression node to be transformed and replaced.
8593        args: positional names that will substitute unnamed placeholders in the given order.
8594        kwargs: keyword arguments that will substitute named placeholders.
8595
8596    Examples:
8597        >>> from sqlglot import exp, parse_one
8598        >>> replace_placeholders(
8599        ...     parse_one("select * from :tbl where ? = ?"),
8600        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8601        ... ).sql()
8602        "SELECT * FROM foo WHERE str_col = 'b'"
8603
8604    Returns:
8605        The mapped expression.
8606    """
8607
8608    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8609        if isinstance(node, Placeholder):
8610            if node.this:
8611                new_name = kwargs.get(node.this)
8612                if new_name is not None:
8613                    return convert(new_name)
8614            else:
8615                try:
8616                    return convert(next(args))
8617                except StopIteration:
8618                    pass
8619        return node
8620
8621    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Union[Query, Callable[[], Query]]], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8624def expand(
8625    expression: Expression,
8626    sources: t.Dict[str, Query | t.Callable[[], Query]],
8627    dialect: DialectType = None,
8628    copy: bool = True,
8629) -> Expression:
8630    """Transforms an expression by expanding all referenced sources into subqueries.
8631
8632    Examples:
8633        >>> from sqlglot import parse_one
8634        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8635        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8636
8637        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8638        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8639
8640    Args:
8641        expression: The expression to expand.
8642        sources: A dict of name to query or a callable that provides a query on demand.
8643        dialect: The dialect of the sources dict or the callable.
8644        copy: Whether to copy the expression during transformation. Defaults to True.
8645
8646    Returns:
8647        The transformed expression.
8648    """
8649    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8650
8651    def _expand(node: Expression):
8652        if isinstance(node, Table):
8653            name = normalize_table_name(node, dialect=dialect)
8654            source = normalized_sources.get(name)
8655
8656            if source:
8657                # Create a subquery with the same alias (or table name if no alias)
8658                parsed_source = source() if callable(source) else source
8659                subquery = parsed_source.subquery(node.alias or name)
8660                subquery.comments = [f"source: {name}"]
8661
8662                # Continue expanding within the subquery
8663                return subquery.transform(_expand, copy=False)
8664
8665        return node
8666
8667    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dict of name to query or a callable that provides a query on demand.
  • dialect: The dialect of the sources dict or the callable.
  • copy: Whether to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Func:
8670def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8671    """
8672    Returns a Func expression.
8673
8674    Examples:
8675        >>> func("abs", 5).sql()
8676        'ABS(5)'
8677
8678        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8679        'CAST(5 AS DOUBLE)'
8680
8681    Args:
8682        name: the name of the function to build.
8683        args: the args used to instantiate the function of interest.
8684        copy: whether to copy the argument expressions.
8685        dialect: the source dialect.
8686        kwargs: the kwargs used to instantiate the function of interest.
8687
8688    Note:
8689        The arguments `args` and `kwargs` are mutually exclusive.
8690
8691    Returns:
8692        An instance of the function of interest, or an anonymous function, if `name` doesn't
8693        correspond to an existing `sqlglot.expressions.Func` class.
8694    """
8695    if args and kwargs:
8696        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8697
8698    from sqlglot.dialects.dialect import Dialect
8699
8700    dialect = Dialect.get_or_raise(dialect)
8701
8702    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8703    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8704
8705    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8706    if constructor:
8707        if converted:
8708            if "dialect" in constructor.__code__.co_varnames:
8709                function = constructor(converted, dialect=dialect)
8710            else:
8711                function = constructor(converted)
8712        elif constructor.__name__ == "from_arg_list":
8713            function = constructor.__self__(**kwargs)  # type: ignore
8714        else:
8715            constructor = FUNCTION_BY_NAME.get(name.upper())
8716            if constructor:
8717                function = constructor(**kwargs)
8718            else:
8719                raise ValueError(
8720                    f"Unable to convert '{name}' into a Func. Either manually construct "
8721                    "the Func expression of interest or parse the function call."
8722                )
8723    else:
8724        kwargs = kwargs or {"expressions": converted}
8725        function = Anonymous(this=name, **kwargs)
8726
8727    for error_message in function.error_messages(converted):
8728        raise ValueError(error_message)
8729
8730    return function

Returns a Func expression.

Examples:
>>> func("abs", 5).sql()
'ABS(5)'
>>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
'CAST(5 AS DOUBLE)'
Arguments:
  • name: the name of the function to build.
  • args: the args used to instantiate the function of interest.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Note:

The arguments args and kwargs are mutually exclusive.

Returns:

An instance of the function of interest, or an anonymous function, if name doesn't correspond to an existing sqlglot.expressions.Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
8733def case(
8734    expression: t.Optional[ExpOrStr] = None,
8735    **opts,
8736) -> Case:
8737    """
8738    Initialize a CASE statement.
8739
8740    Example:
8741        case().when("a = 1", "foo").else_("bar")
8742
8743    Args:
8744        expression: Optionally, the input expression (not all dialects support this)
8745        **opts: Extra keyword arguments for parsing `expression`
8746    """
8747    if expression is not None:
8748        this = maybe_parse(expression, **opts)
8749    else:
8750        this = None
8751    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Array:
8754def array(
8755    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8756) -> Array:
8757    """
8758    Returns an array.
8759
8760    Examples:
8761        >>> array(1, 'x').sql()
8762        'ARRAY(1, x)'
8763
8764    Args:
8765        expressions: the expressions to add to the array.
8766        copy: whether to copy the argument expressions.
8767        dialect: the source dialect.
8768        kwargs: the kwargs used to instantiate the function of interest.
8769
8770    Returns:
8771        An array expression.
8772    """
8773    return Array(
8774        expressions=[
8775            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8776            for expression in expressions
8777        ]
8778    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Tuple:
8781def tuple_(
8782    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8783) -> Tuple:
8784    """
8785    Returns an tuple.
8786
8787    Examples:
8788        >>> tuple_(1, 'x').sql()
8789        '(1, x)'
8790
8791    Args:
8792        expressions: the expressions to add to the tuple.
8793        copy: whether to copy the argument expressions.
8794        dialect: the source dialect.
8795        kwargs: the kwargs used to instantiate the function of interest.
8796
8797    Returns:
8798        A tuple expression.
8799    """
8800    return Tuple(
8801        expressions=[
8802            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8803            for expression in expressions
8804        ]
8805    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

A tuple expression.

def true() -> Boolean:
8808def true() -> Boolean:
8809    """
8810    Returns a true Boolean expression.
8811    """
8812    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8815def false() -> Boolean:
8816    """
8817    Returns a false Boolean expression.
8818    """
8819    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8822def null() -> Null:
8823    """
8824    Returns a Null expression.
8825    """
8826    return Null()

Returns a Null expression.

NONNULL_CONSTANTS = (<class 'Literal'>, <class 'Boolean'>)
CONSTANTS = (<class 'Literal'>, <class 'Boolean'>, <class 'Null'>)