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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
159    def text(self, key) -> str:
160        """
161        Returns a textual representation of the argument corresponding to "key". This can only be used
162        for args that are strings or leaf Expression instances, such as identifiers and literals.
163        """
164        field = self.args.get(key)
165        if isinstance(field, str):
166            return field
167        if isinstance(field, (Identifier, Literal, Var)):
168            return field.this
169        if isinstance(field, (Star, Null)):
170            return field.name
171        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
173    @property
174    def is_string(self) -> bool:
175        """
176        Checks whether a Literal expression is a string.
177        """
178        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
216    @property
217    def alias_column_names(self) -> t.List[str]:
218        table_alias = self.args.get("alias")
219        if not table_alias:
220            return []
221        return [c.name for c in table_alias.args.get("columns") or []]
name: str
223    @property
224    def name(self) -> str:
225        return self.text("this")
alias_or_name: str
227    @property
228    def alias_or_name(self) -> str:
229        return self.alias or self.name
output_name: str
231    @property
232    def output_name(self) -> str:
233        """
234        Name of the output column if this expression is a selection.
235
236        If the Expression has no output name, an empty string is returned.
237
238        Example:
239            >>> from sqlglot import parse_one
240            >>> parse_one("SELECT a").expressions[0].output_name
241            'a'
242            >>> parse_one("SELECT b AS c").expressions[0].output_name
243            'c'
244            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
245            ''
246        """
247        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]
249    @property
250    def type(self) -> t.Optional[DataType]:
251        return self._type
def is_type(self, *dtypes) -> bool:
259    def is_type(self, *dtypes) -> bool:
260        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
262    def is_leaf(self) -> bool:
263        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
265    @property
266    def meta(self) -> t.Dict[str, t.Any]:
267        if self._meta is None:
268            self._meta = {}
269        return self._meta
def copy(self) -> typing_extensions.Self:
305    def copy(self) -> Self:
306        """
307        Returns a deep copy of the expression.
308        """
309        return deepcopy(self)

Returns a deep copy of the expression.

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

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
416    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
417        """Yields the key and expression for all arguments, exploding list args."""
418        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
419            if type(vs) is list:
420                for v in reversed(vs) if reverse else vs:  # type: ignore
421                    if hasattr(v, "parent"):
422                        yield v
423            else:
424                if hasattr(vs, "parent"):
425                    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]:
427    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
428        """
429        Returns the first node in this tree which matches at least one of
430        the specified types.
431
432        Args:
433            expression_types: the expression type(s) to match.
434            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
435
436        Returns:
437            The node which matches the criteria or None if no such node was found.
438        """
439        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]:
441    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
442        """
443        Returns a generator object which visits all nodes in this tree and only
444        yields those that match at least one of the specified expression types.
445
446        Args:
447            expression_types: the expression type(s) to match.
448            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
449
450        Returns:
451            The generator object.
452        """
453        for expression in self.walk(bfs=bfs):
454            if isinstance(expression, expression_types):
455                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]:
457    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
458        """
459        Returns a nearest parent matching expression_types.
460
461        Args:
462            expression_types: the expression type(s) to match.
463
464        Returns:
465            The parent node.
466        """
467        ancestor = self.parent
468        while ancestor and not isinstance(ancestor, expression_types):
469            ancestor = ancestor.parent
470        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]
472    @property
473    def parent_select(self) -> t.Optional[Select]:
474        """
475        Returns the parent select statement.
476        """
477        return self.find_ancestor(Select)

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
493    def walk(
494        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
495    ) -> t.Iterator[Expression]:
496        """
497        Returns a generator object which visits all nodes in this tree.
498
499        Args:
500            bfs: if set to True the BFS traversal order will be applied,
501                otherwise the DFS traversal will be used instead.
502            prune: callable that returns True if the generator should stop traversing
503                this branch of the tree.
504
505        Returns:
506            the generator object.
507        """
508        if bfs:
509            yield from self.bfs(prune=prune)
510        else:
511            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]:
513    def dfs(
514        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
515    ) -> t.Iterator[Expression]:
516        """
517        Returns a generator object which visits all nodes in this tree in
518        the DFS (Depth-first) order.
519
520        Returns:
521            The generator object.
522        """
523        stack = [self]
524
525        while stack:
526            node = stack.pop()
527
528            yield node
529
530            if prune and prune(node):
531                continue
532
533            for v in node.iter_expressions(reverse=True):
534                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]:
536    def bfs(
537        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
538    ) -> t.Iterator[Expression]:
539        """
540        Returns a generator object which visits all nodes in this tree in
541        the BFS (Breadth-first) order.
542
543        Returns:
544            The generator object.
545        """
546        queue = deque([self])
547
548        while queue:
549            node = queue.popleft()
550
551            yield node
552
553            if prune and prune(node):
554                continue
555
556            for v in node.iter_expressions():
557                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):
559    def unnest(self):
560        """
561        Returns the first non parenthesis child or self.
562        """
563        expression = self
564        while type(expression) is Paren:
565            expression = expression.this
566        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
582    def flatten(self, unnest=True):
583        """
584        Returns a generator which yields child nodes whose parents are the same class.
585
586        A AND B AND C -> [A, B, C]
587        """
588        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
589            if type(node) is not self.__class__:
590                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:
598    def to_s(self) -> str:
599        """
600        Same as __repr__, but includes additional information which can be useful
601        for debugging, like empty or missing args and the AST nodes' object IDs.
602        """
603        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:
605    def sql(self, dialect: DialectType = None, **opts) -> str:
606        """
607        Returns SQL string representation of this tree.
608
609        Args:
610            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
611            opts: other `sqlglot.generator.Generator` options.
612
613        Returns:
614            The SQL string.
615        """
616        from sqlglot.dialects import Dialect
617
618        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:
620    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
621        """
622        Visits all tree nodes (excluding already transformed ones)
623        and applies the given transformation function to each node.
624
625        Args:
626            fun: a function which takes a node as an argument and returns a
627                new transformed node or the same node without modifications. If the function
628                returns None, then the corresponding node will be removed from the syntax tree.
629            copy: if set to True a new tree instance is constructed, otherwise the tree is
630                modified in place.
631
632        Returns:
633            The transformed tree.
634        """
635        root = None
636        new_node = None
637
638        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
639            parent, arg_key, index = node.parent, node.arg_key, node.index
640            new_node = fun(node, *args, **kwargs)
641
642            if not root:
643                root = new_node
644            elif parent and arg_key and new_node is not node:
645                parent.set(arg_key, new_node, index)
646
647        assert root
648        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):
656    def replace(self, expression):
657        """
658        Swap out this expression with a new expression.
659
660        For example::
661
662            >>> tree = Select().select("x").from_("tbl")
663            >>> tree.find(Column).replace(column("y"))
664            Column(
665              this=Identifier(this=y, quoted=False))
666            >>> tree.sql()
667            'SELECT y FROM tbl'
668
669        Args:
670            expression: new node
671
672        Returns:
673            The new expression or expressions.
674        """
675        parent = self.parent
676
677        if not parent or parent is expression:
678            return expression
679
680        key = self.arg_key
681        value = parent.args.get(key)
682
683        if type(expression) is list and isinstance(value, Expression):
684            # We are trying to replace an Expression with a list, so it's assumed that
685            # the intention was to really replace the parent of this expression.
686            value.parent.replace(expression)
687        else:
688            parent.set(key, expression, self.index)
689
690        if expression is not self:
691            self.parent = None
692            self.arg_key = None
693            self.index = None
694
695        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:
697    def pop(self: E) -> E:
698        """
699        Remove this expression from its AST.
700
701        Returns:
702            The popped expression.
703        """
704        self.replace(None)
705        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
707    def assert_is(self, type_: t.Type[E]) -> E:
708        """
709        Assert that this `Expression` is an instance of `type_`.
710
711        If it is NOT an instance of `type_`, this raises an assertion error.
712        Otherwise, this returns this expression.
713
714        Examples:
715            This is useful for type security in chained expressions:
716
717            >>> import sqlglot
718            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
719            'SELECT x, z FROM y'
720        """
721        if not isinstance(self, type_):
722            raise AssertionError(f"{self} is not {type_}.")
723        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]:
725    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
726        """
727        Checks if this expression is valid (e.g. all mandatory args are set).
728
729        Args:
730            args: a sequence of values that were used to instantiate a Func expression. This is used
731                to check that the provided arguments don't exceed the function argument limit.
732
733        Returns:
734            A list of error messages for all possible errors that were found.
735        """
736        errors: t.List[str] = []
737
738        for k in self.args:
739            if k not in self.arg_types:
740                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
741        for k, mandatory in self.arg_types.items():
742            v = self.args.get(k)
743            if mandatory and (v is None or (isinstance(v, list) and not v)):
744                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
745
746        if (
747            args
748            and isinstance(self, Func)
749            and len(args) > len(self.arg_types)
750            and not self.is_var_len_args
751        ):
752            errors.append(
753                f"The number of provided arguments ({len(args)}) is greater than "
754                f"the maximum number of supported arguments ({len(self.arg_types)})"
755            )
756
757        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):
759    def dump(self):
760        """
761        Dump this Expression to a JSON-serializable dict.
762        """
763        from sqlglot.serde import dump
764
765        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
767    @classmethod
768    def load(cls, obj):
769        """
770        Load a dict (as returned by `Expression.dump`) into an Expression instance.
771        """
772        from sqlglot.serde import load
773
774        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:
776    def and_(
777        self,
778        *expressions: t.Optional[ExpOrStr],
779        dialect: DialectType = None,
780        copy: bool = True,
781        wrap: bool = True,
782        **opts,
783    ) -> Condition:
784        """
785        AND this condition with one or multiple expressions.
786
787        Example:
788            >>> condition("x=1").and_("y=1").sql()
789            'x = 1 AND y = 1'
790
791        Args:
792            *expressions: the SQL code strings to parse.
793                If an `Expression` instance is passed, it will be used as-is.
794            dialect: the dialect used to parse the input expression.
795            copy: whether to copy the involved expressions (only applies to Expressions).
796            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
797                precedence issues, but can be turned off when the produced AST is too deep and
798                causes recursion-related issues.
799            opts: other options to use to parse the input expressions.
800
801        Returns:
802            The new And condition.
803        """
804        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:
806    def or_(
807        self,
808        *expressions: t.Optional[ExpOrStr],
809        dialect: DialectType = None,
810        copy: bool = True,
811        wrap: bool = True,
812        **opts,
813    ) -> Condition:
814        """
815        OR this condition with one or multiple expressions.
816
817        Example:
818            >>> condition("x=1").or_("y=1").sql()
819            'x = 1 OR y = 1'
820
821        Args:
822            *expressions: the SQL code strings to parse.
823                If an `Expression` instance is passed, it will be used as-is.
824            dialect: the dialect used to parse the input expression.
825            copy: whether to copy the involved expressions (only applies to Expressions).
826            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
827                precedence issues, but can be turned off when the produced AST is too deep and
828                causes recursion-related issues.
829            opts: other options to use to parse the input expressions.
830
831        Returns:
832            The new Or condition.
833        """
834        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):
836    def not_(self, copy: bool = True):
837        """
838        Wrap this condition with NOT.
839
840        Example:
841            >>> condition("x=1").not_().sql()
842            'NOT x = 1'
843
844        Args:
845            copy: whether to copy this object.
846
847        Returns:
848            The new Not instance.
849        """
850        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:
852    def update_positions(
853        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
854    ) -> E:
855        """
856        Update this expression with positions from a token or other expression.
857
858        Args:
859            other: a token or expression to update this expression with.
860
861        Returns:
862            The updated expression.
863        """
864        if isinstance(other, Expression):
865            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
866        elif other is not None:
867            self.meta.update(
868                {
869                    "line": other.line,
870                    "col": other.col,
871                    "start": other.start,
872                    "end": other.end,
873                }
874            )
875        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
876        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:
878    def as_(
879        self,
880        alias: str | Identifier,
881        quoted: t.Optional[bool] = None,
882        dialect: DialectType = None,
883        copy: bool = True,
884        **opts,
885    ) -> Alias:
886        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:
911    def isin(
912        self,
913        *expressions: t.Any,
914        query: t.Optional[ExpOrStr] = None,
915        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
916        copy: bool = True,
917        **opts,
918    ) -> In:
919        subquery = maybe_parse(query, copy=copy, **opts) if query else None
920        if subquery and not isinstance(subquery, Subquery):
921            subquery = subquery.subquery(copy=False)
922
923        return In(
924            this=maybe_copy(self, copy),
925            expressions=[convert(e, copy=copy) for e in expressions],
926            query=subquery,
927            unnest=(
928                Unnest(
929                    expressions=[
930                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
931                        for e in ensure_list(unnest)
932                    ]
933                )
934                if unnest
935                else None
936            ),
937        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
939    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
940        return Between(
941            this=maybe_copy(self, copy),
942            low=convert(low, copy=copy, **opts),
943            high=convert(high, copy=copy, **opts),
944        )
def is_( self, other: Union[str, Expression]) -> Is:
946    def is_(self, other: ExpOrStr) -> Is:
947        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
949    def like(self, other: ExpOrStr) -> Like:
950        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
952    def ilike(self, other: ExpOrStr) -> ILike:
953        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
955    def eq(self, other: t.Any) -> EQ:
956        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
958    def neq(self, other: t.Any) -> NEQ:
959        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
961    def rlike(self, other: ExpOrStr) -> RegexpLike:
962        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
964    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
965        div = self._binop(Div, other)
966        div.args["typed"] = typed
967        div.args["safe"] = safe
968        return div
def asc(self, nulls_first: bool = True) -> Ordered:
970    def asc(self, nulls_first: bool = True) -> Ordered:
971        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
973    def desc(self, nulls_first: bool = False) -> Ordered:
974        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):
1057class Condition(Expression):
1058    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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

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

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

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

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

Returns the query's projections.

named_selects: List[str]
1214    @property
1215    def named_selects(self) -> t.List[str]:
1216        """Returns the output names of the query's projections."""
1217        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:
1219    def select(
1220        self: Q,
1221        *expressions: t.Optional[ExpOrStr],
1222        append: bool = True,
1223        dialect: DialectType = None,
1224        copy: bool = True,
1225        **opts,
1226    ) -> Q:
1227        """
1228        Append to or set the SELECT expressions.
1229
1230        Example:
1231            >>> Select().select("x", "y").sql()
1232            'SELECT x, y'
1233
1234        Args:
1235            *expressions: the SQL code strings to parse.
1236                If an `Expression` instance is passed, it will be used as-is.
1237            append: if `True`, add to any existing expressions.
1238                Otherwise, this resets the expressions.
1239            dialect: the dialect used to parse the input expressions.
1240            copy: if `False`, modify this expression instance in-place.
1241            opts: other options to use to parse the input expressions.
1242
1243        Returns:
1244            The modified Query expression.
1245        """
1246        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:
1248    def where(
1249        self: Q,
1250        *expressions: t.Optional[ExpOrStr],
1251        append: bool = True,
1252        dialect: DialectType = None,
1253        copy: bool = True,
1254        **opts,
1255    ) -> Q:
1256        """
1257        Append to or set the WHERE expressions.
1258
1259        Examples:
1260            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1261            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1262
1263        Args:
1264            *expressions: the SQL code strings to parse.
1265                If an `Expression` instance is passed, it will be used as-is.
1266                Multiple expressions are combined with an AND operator.
1267            append: if `True`, AND the new expressions to any existing expression.
1268                Otherwise, this resets the expression.
1269            dialect: the dialect used to parse the input expressions.
1270            copy: if `False`, modify this expression instance in-place.
1271            opts: other options to use to parse the input expressions.
1272
1273        Returns:
1274            The modified expression.
1275        """
1276        return _apply_conjunction_builder(
1277            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1278            instance=self,
1279            arg="where",
1280            append=append,
1281            into=Where,
1282            dialect=dialect,
1283            copy=copy,
1284            **opts,
1285        )

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

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:
1336    def union(
1337        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1338    ) -> Union:
1339        """
1340        Builds a UNION expression.
1341
1342        Example:
1343            >>> import sqlglot
1344            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1345            'SELECT * FROM foo UNION SELECT * FROM bla'
1346
1347        Args:
1348            expressions: the SQL code strings.
1349                If `Expression` instances are passed, they will be used as-is.
1350            distinct: set the DISTINCT flag if and only if this is true.
1351            dialect: the dialect used to parse the input expression.
1352            opts: other options to use to parse the input expressions.
1353
1354        Returns:
1355            The new Union expression.
1356        """
1357        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:
1359    def intersect(
1360        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1361    ) -> Intersect:
1362        """
1363        Builds an INTERSECT expression.
1364
1365        Example:
1366            >>> import sqlglot
1367            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1368            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1369
1370        Args:
1371            expressions: the SQL code strings.
1372                If `Expression` instances are passed, they will be used as-is.
1373            distinct: set the DISTINCT flag if and only if this is true.
1374            dialect: the dialect used to parse the input expression.
1375            opts: other options to use to parse the input expressions.
1376
1377        Returns:
1378            The new Intersect expression.
1379        """
1380        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:
1382    def except_(
1383        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1384    ) -> Except:
1385        """
1386        Builds an EXCEPT expression.
1387
1388        Example:
1389            >>> import sqlglot
1390            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1391            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1392
1393        Args:
1394            expressions: the SQL code strings.
1395                If `Expression` instance are passed, they will be used as-is.
1396            distinct: set the DISTINCT flag if and only if this is true.
1397            dialect: the dialect used to parse the input expression.
1398            opts: other options to use to parse the input expressions.
1399
1400        Returns:
1401            The new Except expression.
1402        """
1403        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):
1406class UDTF(DerivedTable):
1407    @property
1408    def selects(self) -> t.List[Expression]:
1409        alias = self.args.get("alias")
1410        return alias.columns if alias else []
selects: List[Expression]
1407    @property
1408    def selects(self) -> t.List[Expression]:
1409        alias = self.args.get("alias")
1410        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1413class Cache(Expression):
1414    arg_types = {
1415        "this": True,
1416        "lazy": False,
1417        "options": False,
1418        "expression": False,
1419    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1422class Uncache(Expression):
1423    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1426class Refresh(Expression):
1427    pass
key = 'refresh'
class DDL(Expression):
1430class DDL(Expression):
1431    @property
1432    def ctes(self) -> t.List[CTE]:
1433        """Returns a list of all the CTEs attached to this statement."""
1434        with_ = self.args.get("with")
1435        return with_.expressions if with_ else []
1436
1437    @property
1438    def selects(self) -> t.List[Expression]:
1439        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1440        return self.expression.selects if isinstance(self.expression, Query) else []
1441
1442    @property
1443    def named_selects(self) -> t.List[str]:
1444        """
1445        If this statement contains a query (e.g. a CTAS), this returns the output
1446        names of the query's projections.
1447        """
1448        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1431    @property
1432    def ctes(self) -> t.List[CTE]:
1433        """Returns a list of all the CTEs attached to this statement."""
1434        with_ = self.args.get("with")
1435        return with_.expressions if with_ else []

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

selects: List[Expression]
1437    @property
1438    def selects(self) -> t.List[Expression]:
1439        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1440        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]
1442    @property
1443    def named_selects(self) -> t.List[str]:
1444        """
1445        If this statement contains a query (e.g. a CTAS), this returns the output
1446        names of the query's projections.
1447        """
1448        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):
1451class DML(Expression):
1452    def returning(
1453        self,
1454        expression: ExpOrStr,
1455        dialect: DialectType = None,
1456        copy: bool = True,
1457        **opts,
1458    ) -> "Self":
1459        """
1460        Set the RETURNING expression. Not supported by all dialects.
1461
1462        Example:
1463            >>> delete("tbl").returning("*", dialect="postgres").sql()
1464            'DELETE FROM tbl RETURNING *'
1465
1466        Args:
1467            expression: the SQL code strings to parse.
1468                If an `Expression` instance is passed, it will be used as-is.
1469            dialect: the dialect used to parse the input expressions.
1470            copy: if `False`, modify this expression instance in-place.
1471            opts: other options to use to parse the input expressions.
1472
1473        Returns:
1474            Delete: the modified expression.
1475        """
1476        return _apply_builder(
1477            expression=expression,
1478            instance=self,
1479            arg="returning",
1480            prefix="RETURNING",
1481            dialect=dialect,
1482            copy=copy,
1483            into=Returning,
1484            **opts,
1485        )
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:
1452    def returning(
1453        self,
1454        expression: ExpOrStr,
1455        dialect: DialectType = None,
1456        copy: bool = True,
1457        **opts,
1458    ) -> "Self":
1459        """
1460        Set the RETURNING expression. Not supported by all dialects.
1461
1462        Example:
1463            >>> delete("tbl").returning("*", dialect="postgres").sql()
1464            'DELETE FROM tbl RETURNING *'
1465
1466        Args:
1467            expression: the SQL code strings to parse.
1468                If an `Expression` instance is passed, it will be used as-is.
1469            dialect: the dialect used to parse the input expressions.
1470            copy: if `False`, modify this expression instance in-place.
1471            opts: other options to use to parse the input expressions.
1472
1473        Returns:
1474            Delete: the modified expression.
1475        """
1476        return _apply_builder(
1477            expression=expression,
1478            instance=self,
1479            arg="returning",
1480            prefix="RETURNING",
1481            dialect=dialect,
1482            copy=copy,
1483            into=Returning,
1484            **opts,
1485        )

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

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

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

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1741class ColumnPosition(Expression):
1742    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1745class ColumnDef(Expression):
1746    arg_types = {
1747        "this": True,
1748        "kind": False,
1749        "constraints": False,
1750        "exists": False,
1751        "position": False,
1752        "default": False,
1753        "output": False,
1754    }
1755
1756    @property
1757    def constraints(self) -> t.List[ColumnConstraint]:
1758        return self.args.get("constraints") or []
1759
1760    @property
1761    def kind(self) -> t.Optional[DataType]:
1762        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1756    @property
1757    def constraints(self) -> t.List[ColumnConstraint]:
1758        return self.args.get("constraints") or []
kind: Optional[DataType]
1760    @property
1761    def kind(self) -> t.Optional[DataType]:
1762        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1765class AlterColumn(Expression):
1766    arg_types = {
1767        "this": True,
1768        "dtype": False,
1769        "collate": False,
1770        "using": False,
1771        "default": False,
1772        "drop": False,
1773        "comment": False,
1774        "allow_null": False,
1775        "visible": False,
1776    }
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):
1780class AlterIndex(Expression):
1781    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1785class AlterDistStyle(Expression):
1786    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1789class AlterSortKey(Expression):
1790    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1793class AlterSet(Expression):
1794    arg_types = {
1795        "expressions": False,
1796        "option": False,
1797        "tablespace": False,
1798        "access_method": False,
1799        "file_format": False,
1800        "copy_options": False,
1801        "tag": False,
1802        "location": False,
1803        "serde": False,
1804    }
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):
1807class RenameColumn(Expression):
1808    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1811class AlterRename(Expression):
1812    pass
key = 'alterrename'
class SwapTable(Expression):
1815class SwapTable(Expression):
1816    pass
key = 'swaptable'
class Comment(Expression):
1819class Comment(Expression):
1820    arg_types = {
1821        "this": True,
1822        "kind": True,
1823        "expression": True,
1824        "exists": False,
1825        "materialized": False,
1826    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1829class Comprehension(Expression):
1830    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):
1834class MergeTreeTTLAction(Expression):
1835    arg_types = {
1836        "this": True,
1837        "delete": False,
1838        "recompress": False,
1839        "to_disk": False,
1840        "to_volume": False,
1841    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1845class MergeTreeTTL(Expression):
1846    arg_types = {
1847        "expressions": True,
1848        "where": False,
1849        "group": False,
1850        "aggregates": False,
1851    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1855class IndexConstraintOption(Expression):
1856    arg_types = {
1857        "key_block_size": False,
1858        "using": False,
1859        "parser": False,
1860        "comment": False,
1861        "visible": False,
1862        "engine_attr": False,
1863        "secondary_engine_attr": False,
1864    }
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):
1867class ColumnConstraint(Expression):
1868    arg_types = {"this": False, "kind": True}
1869
1870    @property
1871    def kind(self) -> ColumnConstraintKind:
1872        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1870    @property
1871    def kind(self) -> ColumnConstraintKind:
1872        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1875class ColumnConstraintKind(Expression):
1876    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1879class AutoIncrementColumnConstraint(ColumnConstraintKind):
1880    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1883class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1884    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1887class CaseSpecificColumnConstraint(ColumnConstraintKind):
1888    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1891class CharacterSetColumnConstraint(ColumnConstraintKind):
1892    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1895class CheckColumnConstraint(ColumnConstraintKind):
1896    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1899class ClusteredColumnConstraint(ColumnConstraintKind):
1900    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1903class CollateColumnConstraint(ColumnConstraintKind):
1904    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1907class CommentColumnConstraint(ColumnConstraintKind):
1908    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1911class CompressColumnConstraint(ColumnConstraintKind):
1912    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1915class DateFormatColumnConstraint(ColumnConstraintKind):
1916    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1919class DefaultColumnConstraint(ColumnConstraintKind):
1920    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1923class EncodeColumnConstraint(ColumnConstraintKind):
1924    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1928class ExcludeColumnConstraint(ColumnConstraintKind):
1929    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1932class EphemeralColumnConstraint(ColumnConstraintKind):
1933    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1936class WithOperator(Expression):
1937    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1940class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1941    # this: True -> ALWAYS, this: False -> BY DEFAULT
1942    arg_types = {
1943        "this": False,
1944        "expression": False,
1945        "on_null": False,
1946        "start": False,
1947        "increment": False,
1948        "minvalue": False,
1949        "maxvalue": False,
1950        "cycle": False,
1951        "order": False,
1952    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False, 'order': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1955class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1956    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1961class IndexColumnConstraint(ColumnConstraintKind):
1962    arg_types = {
1963        "this": False,
1964        "expressions": False,
1965        "kind": False,
1966        "index_type": False,
1967        "options": False,
1968        "expression": False,  # Clickhouse
1969        "granularity": False,
1970    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1973class InlineLengthColumnConstraint(ColumnConstraintKind):
1974    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1977class NonClusteredColumnConstraint(ColumnConstraintKind):
1978    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1981class NotForReplicationColumnConstraint(ColumnConstraintKind):
1982    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1986class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1987    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1990class NotNullColumnConstraint(ColumnConstraintKind):
1991    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1995class OnUpdateColumnConstraint(ColumnConstraintKind):
1996    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1999class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2000    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2003class TitleColumnConstraint(ColumnConstraintKind):
2004    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2007class UniqueColumnConstraint(ColumnConstraintKind):
2008    arg_types = {
2009        "this": False,
2010        "index_type": False,
2011        "on_conflict": False,
2012        "nulls": False,
2013        "options": False,
2014    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2017class UppercaseColumnConstraint(ColumnConstraintKind):
2018    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2022class WatermarkColumnConstraint(Expression):
2023    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2026class PathColumnConstraint(ColumnConstraintKind):
2027    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2031class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2032    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2037class ComputedColumnConstraint(ColumnConstraintKind):
2038    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2041class Constraint(Expression):
2042    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2045class Delete(DML):
2046    arg_types = {
2047        "with": False,
2048        "this": False,
2049        "using": False,
2050        "where": False,
2051        "returning": False,
2052        "limit": False,
2053        "tables": False,  # Multiple-Table Syntax (MySQL)
2054        "cluster": False,  # Clickhouse
2055    }
2056
2057    def delete(
2058        self,
2059        table: ExpOrStr,
2060        dialect: DialectType = None,
2061        copy: bool = True,
2062        **opts,
2063    ) -> Delete:
2064        """
2065        Create a DELETE expression or replace the table on an existing DELETE expression.
2066
2067        Example:
2068            >>> delete("tbl").sql()
2069            'DELETE FROM tbl'
2070
2071        Args:
2072            table: the table from which to delete.
2073            dialect: the dialect used to parse the input expression.
2074            copy: if `False`, modify this expression instance in-place.
2075            opts: other options to use to parse the input expressions.
2076
2077        Returns:
2078            Delete: the modified expression.
2079        """
2080        return _apply_builder(
2081            expression=table,
2082            instance=self,
2083            arg="this",
2084            dialect=dialect,
2085            into=Table,
2086            copy=copy,
2087            **opts,
2088        )
2089
2090    def where(
2091        self,
2092        *expressions: t.Optional[ExpOrStr],
2093        append: bool = True,
2094        dialect: DialectType = None,
2095        copy: bool = True,
2096        **opts,
2097    ) -> Delete:
2098        """
2099        Append to or set the WHERE expressions.
2100
2101        Example:
2102            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2103            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2104
2105        Args:
2106            *expressions: the SQL code strings to parse.
2107                If an `Expression` instance is passed, it will be used as-is.
2108                Multiple expressions are combined with an AND operator.
2109            append: if `True`, AND the new expressions to any existing expression.
2110                Otherwise, this resets the expression.
2111            dialect: the dialect used to parse the input expressions.
2112            copy: if `False`, modify this expression instance in-place.
2113            opts: other options to use to parse the input expressions.
2114
2115        Returns:
2116            Delete: the modified expression.
2117        """
2118        return _apply_conjunction_builder(
2119            *expressions,
2120            instance=self,
2121            arg="where",
2122            append=append,
2123            into=Where,
2124            dialect=dialect,
2125            copy=copy,
2126            **opts,
2127        )
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:
2057    def delete(
2058        self,
2059        table: ExpOrStr,
2060        dialect: DialectType = None,
2061        copy: bool = True,
2062        **opts,
2063    ) -> Delete:
2064        """
2065        Create a DELETE expression or replace the table on an existing DELETE expression.
2066
2067        Example:
2068            >>> delete("tbl").sql()
2069            'DELETE FROM tbl'
2070
2071        Args:
2072            table: the table from which to delete.
2073            dialect: the dialect used to parse the input expression.
2074            copy: if `False`, modify this expression instance in-place.
2075            opts: other options to use to parse the input expressions.
2076
2077        Returns:
2078            Delete: the modified expression.
2079        """
2080        return _apply_builder(
2081            expression=table,
2082            instance=self,
2083            arg="this",
2084            dialect=dialect,
2085            into=Table,
2086            copy=copy,
2087            **opts,
2088        )

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

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):
2130class Drop(Expression):
2131    arg_types = {
2132        "this": False,
2133        "kind": False,
2134        "expressions": False,
2135        "exists": False,
2136        "temporary": False,
2137        "materialized": False,
2138        "cascade": False,
2139        "constraints": False,
2140        "purge": False,
2141        "cluster": False,
2142        "concurrently": False,
2143    }
2144
2145    @property
2146    def kind(self) -> t.Optional[str]:
2147        kind = self.args.get("kind")
2148        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]
2145    @property
2146    def kind(self) -> t.Optional[str]:
2147        kind = self.args.get("kind")
2148        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2152class Export(Expression):
2153    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2156class Filter(Expression):
2157    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2160class Check(Expression):
2161    pass
key = 'check'
class Changes(Expression):
2164class Changes(Expression):
2165    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2169class Connect(Expression):
2170    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2173class CopyParameter(Expression):
2174    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2177class Copy(DML):
2178    arg_types = {
2179        "this": True,
2180        "kind": True,
2181        "files": True,
2182        "credentials": False,
2183        "format": False,
2184        "params": False,
2185    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2188class Credentials(Expression):
2189    arg_types = {
2190        "credentials": False,
2191        "encryption": False,
2192        "storage": False,
2193        "iam_role": False,
2194        "region": False,
2195    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2198class Prior(Expression):
2199    pass
key = 'prior'
class Directory(Expression):
2202class Directory(Expression):
2203    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2204    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2207class ForeignKey(Expression):
2208    arg_types = {
2209        "expressions": False,
2210        "reference": False,
2211        "delete": False,
2212        "update": False,
2213        "options": False,
2214    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2217class ColumnPrefix(Expression):
2218    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2221class PrimaryKey(Expression):
2222    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2227class Into(Expression):
2228    arg_types = {
2229        "this": False,
2230        "temporary": False,
2231        "unlogged": False,
2232        "bulk_collect": False,
2233        "expressions": False,
2234    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2237class From(Expression):
2238    @property
2239    def name(self) -> str:
2240        return self.this.name
2241
2242    @property
2243    def alias_or_name(self) -> str:
2244        return self.this.alias_or_name
name: str
2238    @property
2239    def name(self) -> str:
2240        return self.this.name
alias_or_name: str
2242    @property
2243    def alias_or_name(self) -> str:
2244        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2247class Having(Expression):
2248    pass
key = 'having'
class Hint(Expression):
2251class Hint(Expression):
2252    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2255class JoinHint(Expression):
2256    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2259class Identifier(Expression):
2260    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2261
2262    @property
2263    def quoted(self) -> bool:
2264        return bool(self.args.get("quoted"))
2265
2266    @property
2267    def hashable_args(self) -> t.Any:
2268        return (self.this, self.quoted)
2269
2270    @property
2271    def output_name(self) -> str:
2272        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2262    @property
2263    def quoted(self) -> bool:
2264        return bool(self.args.get("quoted"))
hashable_args: Any
2266    @property
2267    def hashable_args(self) -> t.Any:
2268        return (self.this, self.quoted)
output_name: str
2270    @property
2271    def output_name(self) -> str:
2272        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):
2276class Opclass(Expression):
2277    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2280class Index(Expression):
2281    arg_types = {
2282        "this": False,
2283        "table": False,
2284        "unique": False,
2285        "primary": False,
2286        "amp": False,  # teradata
2287        "params": False,
2288    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2291class IndexParameters(Expression):
2292    arg_types = {
2293        "using": False,
2294        "include": False,
2295        "columns": False,
2296        "with_storage": False,
2297        "partition_by": False,
2298        "tablespace": False,
2299        "where": False,
2300        "on": False,
2301    }
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):
2304class Insert(DDL, DML):
2305    arg_types = {
2306        "hint": False,
2307        "with": False,
2308        "is_function": False,
2309        "this": False,
2310        "expression": False,
2311        "conflict": False,
2312        "returning": False,
2313        "overwrite": False,
2314        "exists": False,
2315        "alternative": False,
2316        "where": False,
2317        "ignore": False,
2318        "by_name": False,
2319        "stored": False,
2320        "partition": False,
2321        "settings": False,
2322        "source": False,
2323    }
2324
2325    def with_(
2326        self,
2327        alias: ExpOrStr,
2328        as_: ExpOrStr,
2329        recursive: t.Optional[bool] = None,
2330        materialized: t.Optional[bool] = None,
2331        append: bool = True,
2332        dialect: DialectType = None,
2333        copy: bool = True,
2334        **opts,
2335    ) -> Insert:
2336        """
2337        Append to or set the common table expressions.
2338
2339        Example:
2340            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2341            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2342
2343        Args:
2344            alias: the SQL code string to parse as the table name.
2345                If an `Expression` instance is passed, this is used as-is.
2346            as_: the SQL code string to parse as the table expression.
2347                If an `Expression` instance is passed, it will be used as-is.
2348            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2349            materialized: set the MATERIALIZED part of the expression.
2350            append: if `True`, add to any existing expressions.
2351                Otherwise, this resets the expressions.
2352            dialect: the dialect used to parse the input expression.
2353            copy: if `False`, modify this expression instance in-place.
2354            opts: other options to use to parse the input expressions.
2355
2356        Returns:
2357            The modified expression.
2358        """
2359        return _apply_cte_builder(
2360            self,
2361            alias,
2362            as_,
2363            recursive=recursive,
2364            materialized=materialized,
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )
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:
2325    def with_(
2326        self,
2327        alias: ExpOrStr,
2328        as_: ExpOrStr,
2329        recursive: t.Optional[bool] = None,
2330        materialized: t.Optional[bool] = None,
2331        append: bool = True,
2332        dialect: DialectType = None,
2333        copy: bool = True,
2334        **opts,
2335    ) -> Insert:
2336        """
2337        Append to or set the common table expressions.
2338
2339        Example:
2340            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2341            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2342
2343        Args:
2344            alias: the SQL code string to parse as the table name.
2345                If an `Expression` instance is passed, this is used as-is.
2346            as_: the SQL code string to parse as the table expression.
2347                If an `Expression` instance is passed, it will be used as-is.
2348            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2349            materialized: set the MATERIALIZED part of the expression.
2350            append: if `True`, add to any existing expressions.
2351                Otherwise, this resets the expressions.
2352            dialect: the dialect used to parse the input expression.
2353            copy: if `False`, modify this expression instance in-place.
2354            opts: other options to use to parse the input expressions.
2355
2356        Returns:
2357            The modified expression.
2358        """
2359        return _apply_cte_builder(
2360            self,
2361            alias,
2362            as_,
2363            recursive=recursive,
2364            materialized=materialized,
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )

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):
2372class ConditionalInsert(Expression):
2373    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2376class MultitableInserts(Expression):
2377    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2380class OnConflict(Expression):
2381    arg_types = {
2382        "duplicate": False,
2383        "expressions": False,
2384        "action": False,
2385        "conflict_keys": False,
2386        "constraint": False,
2387        "where": False,
2388    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2391class OnCondition(Expression):
2392    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2395class Returning(Expression):
2396    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2400class Introducer(Expression):
2401    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2405class National(Expression):
2406    pass
key = 'national'
class LoadData(Expression):
2409class LoadData(Expression):
2410    arg_types = {
2411        "this": True,
2412        "local": False,
2413        "overwrite": False,
2414        "inpath": True,
2415        "partition": False,
2416        "input_format": False,
2417        "serde": False,
2418    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2421class Partition(Expression):
2422    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2425class PartitionRange(Expression):
2426    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2430class PartitionId(Expression):
2431    pass
key = 'partitionid'
class Fetch(Expression):
2434class Fetch(Expression):
2435    arg_types = {
2436        "direction": False,
2437        "count": False,
2438        "limit_options": False,
2439    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2442class Grant(Expression):
2443    arg_types = {
2444        "privileges": True,
2445        "kind": False,
2446        "securable": True,
2447        "principals": True,
2448        "grant_option": False,
2449    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2452class Group(Expression):
2453    arg_types = {
2454        "expressions": False,
2455        "grouping_sets": False,
2456        "cube": False,
2457        "rollup": False,
2458        "totals": False,
2459        "all": False,
2460    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2463class Cube(Expression):
2464    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2467class Rollup(Expression):
2468    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2471class GroupingSets(Expression):
2472    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2475class Lambda(Expression):
2476    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2479class Limit(Expression):
2480    arg_types = {
2481        "this": False,
2482        "expression": True,
2483        "offset": False,
2484        "limit_options": False,
2485        "expressions": False,
2486    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2489class LimitOptions(Expression):
2490    arg_types = {
2491        "percent": False,
2492        "rows": False,
2493        "with_ties": False,
2494    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2497class Literal(Condition):
2498    arg_types = {"this": True, "is_string": True}
2499
2500    @property
2501    def hashable_args(self) -> t.Any:
2502        return (self.this, self.args.get("is_string"))
2503
2504    @classmethod
2505    def number(cls, number) -> Literal:
2506        return cls(this=str(number), is_string=False)
2507
2508    @classmethod
2509    def string(cls, string) -> Literal:
2510        return cls(this=str(string), is_string=True)
2511
2512    @property
2513    def output_name(self) -> str:
2514        return self.name
2515
2516    def to_py(self) -> int | str | Decimal:
2517        if self.is_number:
2518            try:
2519                return int(self.this)
2520            except ValueError:
2521                return Decimal(self.this)
2522        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2500    @property
2501    def hashable_args(self) -> t.Any:
2502        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2504    @classmethod
2505    def number(cls, number) -> Literal:
2506        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2508    @classmethod
2509    def string(cls, string) -> Literal:
2510        return cls(this=str(string), is_string=True)
output_name: str
2512    @property
2513    def output_name(self) -> str:
2514        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:
2516    def to_py(self) -> int | str | Decimal:
2517        if self.is_number:
2518            try:
2519                return int(self.this)
2520            except ValueError:
2521                return Decimal(self.this)
2522        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2525class Join(Expression):
2526    arg_types = {
2527        "this": True,
2528        "on": False,
2529        "side": False,
2530        "kind": False,
2531        "using": False,
2532        "method": False,
2533        "global": False,
2534        "hint": False,
2535        "match_condition": False,  # Snowflake
2536        "expressions": False,
2537        "pivots": False,
2538    }
2539
2540    @property
2541    def method(self) -> str:
2542        return self.text("method").upper()
2543
2544    @property
2545    def kind(self) -> str:
2546        return self.text("kind").upper()
2547
2548    @property
2549    def side(self) -> str:
2550        return self.text("side").upper()
2551
2552    @property
2553    def hint(self) -> str:
2554        return self.text("hint").upper()
2555
2556    @property
2557    def alias_or_name(self) -> str:
2558        return self.this.alias_or_name
2559
2560    @property
2561    def is_semi_or_anti_join(self) -> bool:
2562        return self.kind in ("SEMI", "ANTI")
2563
2564    def on(
2565        self,
2566        *expressions: t.Optional[ExpOrStr],
2567        append: bool = True,
2568        dialect: DialectType = None,
2569        copy: bool = True,
2570        **opts,
2571    ) -> Join:
2572        """
2573        Append to or set the ON expressions.
2574
2575        Example:
2576            >>> import sqlglot
2577            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2578            'JOIN x ON y = 1'
2579
2580        Args:
2581            *expressions: the SQL code strings to parse.
2582                If an `Expression` instance is passed, it will be used as-is.
2583                Multiple expressions are combined with an AND operator.
2584            append: if `True`, AND the new expressions to any existing expression.
2585                Otherwise, this resets the expression.
2586            dialect: the dialect used to parse the input expressions.
2587            copy: if `False`, modify this expression instance in-place.
2588            opts: other options to use to parse the input expressions.
2589
2590        Returns:
2591            The modified Join expression.
2592        """
2593        join = _apply_conjunction_builder(
2594            *expressions,
2595            instance=self,
2596            arg="on",
2597            append=append,
2598            dialect=dialect,
2599            copy=copy,
2600            **opts,
2601        )
2602
2603        if join.kind == "CROSS":
2604            join.set("kind", None)
2605
2606        return join
2607
2608    def using(
2609        self,
2610        *expressions: t.Optional[ExpOrStr],
2611        append: bool = True,
2612        dialect: DialectType = None,
2613        copy: bool = True,
2614        **opts,
2615    ) -> Join:
2616        """
2617        Append to or set the USING expressions.
2618
2619        Example:
2620            >>> import sqlglot
2621            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2622            'JOIN x USING (foo, bla)'
2623
2624        Args:
2625            *expressions: the SQL code strings to parse.
2626                If an `Expression` instance is passed, it will be used as-is.
2627            append: if `True`, concatenate the new expressions to the existing "using" list.
2628                Otherwise, this resets the expression.
2629            dialect: the dialect used to parse the input expressions.
2630            copy: if `False`, modify this expression instance in-place.
2631            opts: other options to use to parse the input expressions.
2632
2633        Returns:
2634            The modified Join expression.
2635        """
2636        join = _apply_list_builder(
2637            *expressions,
2638            instance=self,
2639            arg="using",
2640            append=append,
2641            dialect=dialect,
2642            copy=copy,
2643            **opts,
2644        )
2645
2646        if join.kind == "CROSS":
2647            join.set("kind", None)
2648
2649        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
2540    @property
2541    def method(self) -> str:
2542        return self.text("method").upper()
kind: str
2544    @property
2545    def kind(self) -> str:
2546        return self.text("kind").upper()
side: str
2548    @property
2549    def side(self) -> str:
2550        return self.text("side").upper()
hint: str
2552    @property
2553    def hint(self) -> str:
2554        return self.text("hint").upper()
alias_or_name: str
2556    @property
2557    def alias_or_name(self) -> str:
2558        return self.this.alias_or_name
is_semi_or_anti_join: bool
2560    @property
2561    def is_semi_or_anti_join(self) -> bool:
2562        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:
2564    def on(
2565        self,
2566        *expressions: t.Optional[ExpOrStr],
2567        append: bool = True,
2568        dialect: DialectType = None,
2569        copy: bool = True,
2570        **opts,
2571    ) -> Join:
2572        """
2573        Append to or set the ON expressions.
2574
2575        Example:
2576            >>> import sqlglot
2577            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2578            'JOIN x ON y = 1'
2579
2580        Args:
2581            *expressions: the SQL code strings to parse.
2582                If an `Expression` instance is passed, it will be used as-is.
2583                Multiple expressions are combined with an AND operator.
2584            append: if `True`, AND the new expressions to any existing expression.
2585                Otherwise, this resets the expression.
2586            dialect: the dialect used to parse the input expressions.
2587            copy: if `False`, modify this expression instance in-place.
2588            opts: other options to use to parse the input expressions.
2589
2590        Returns:
2591            The modified Join expression.
2592        """
2593        join = _apply_conjunction_builder(
2594            *expressions,
2595            instance=self,
2596            arg="on",
2597            append=append,
2598            dialect=dialect,
2599            copy=copy,
2600            **opts,
2601        )
2602
2603        if join.kind == "CROSS":
2604            join.set("kind", None)
2605
2606        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:
2608    def using(
2609        self,
2610        *expressions: t.Optional[ExpOrStr],
2611        append: bool = True,
2612        dialect: DialectType = None,
2613        copy: bool = True,
2614        **opts,
2615    ) -> Join:
2616        """
2617        Append to or set the USING expressions.
2618
2619        Example:
2620            >>> import sqlglot
2621            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2622            'JOIN x USING (foo, bla)'
2623
2624        Args:
2625            *expressions: the SQL code strings to parse.
2626                If an `Expression` instance is passed, it will be used as-is.
2627            append: if `True`, concatenate the new expressions to the existing "using" list.
2628                Otherwise, this resets the expression.
2629            dialect: the dialect used to parse the input expressions.
2630            copy: if `False`, modify this expression instance in-place.
2631            opts: other options to use to parse the input expressions.
2632
2633        Returns:
2634            The modified Join expression.
2635        """
2636        join = _apply_list_builder(
2637            *expressions,
2638            instance=self,
2639            arg="using",
2640            append=append,
2641            dialect=dialect,
2642            copy=copy,
2643            **opts,
2644        )
2645
2646        if join.kind == "CROSS":
2647            join.set("kind", None)
2648
2649        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):
2652class Lateral(UDTF):
2653    arg_types = {
2654        "this": True,
2655        "view": False,
2656        "outer": False,
2657        "alias": False,
2658        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2659        "ordinality": False,
2660    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2665class TableFromRows(UDTF):
2666    arg_types = {
2667        "this": True,
2668        "alias": False,
2669        "joins": False,
2670        "pivots": False,
2671        "sample": False,
2672    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2675class MatchRecognizeMeasure(Expression):
2676    arg_types = {
2677        "this": True,
2678        "window_frame": False,
2679    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2682class MatchRecognize(Expression):
2683    arg_types = {
2684        "partition_by": False,
2685        "order": False,
2686        "measures": False,
2687        "rows": False,
2688        "after": False,
2689        "pattern": False,
2690        "define": False,
2691        "alias": False,
2692    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2697class Final(Expression):
2698    pass
key = 'final'
class Offset(Expression):
2701class Offset(Expression):
2702    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2705class Order(Expression):
2706    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2710class WithFill(Expression):
2711    arg_types = {
2712        "from": False,
2713        "to": False,
2714        "step": False,
2715        "interpolate": False,
2716    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2721class Cluster(Order):
2722    pass
key = 'cluster'
class Distribute(Order):
2725class Distribute(Order):
2726    pass
key = 'distribute'
class Sort(Order):
2729class Sort(Order):
2730    pass
key = 'sort'
class Ordered(Expression):
2733class Ordered(Expression):
2734    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2735
2736    @property
2737    def name(self) -> str:
2738        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2736    @property
2737    def name(self) -> str:
2738        return self.this.name
key = 'ordered'
class Property(Expression):
2741class Property(Expression):
2742    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2745class GrantPrivilege(Expression):
2746    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2749class GrantPrincipal(Expression):
2750    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2753class AllowedValuesProperty(Expression):
2754    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2757class AlgorithmProperty(Property):
2758    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2761class AutoIncrementProperty(Property):
2762    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2766class AutoRefreshProperty(Property):
2767    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2770class BackupProperty(Property):
2771    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2774class BlockCompressionProperty(Property):
2775    arg_types = {
2776        "autotemp": False,
2777        "always": False,
2778        "default": False,
2779        "manual": False,
2780        "never": False,
2781    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2784class CharacterSetProperty(Property):
2785    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2788class ChecksumProperty(Property):
2789    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2792class CollateProperty(Property):
2793    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2796class CopyGrantsProperty(Property):
2797    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2800class DataBlocksizeProperty(Property):
2801    arg_types = {
2802        "size": False,
2803        "units": False,
2804        "minimum": False,
2805        "maximum": False,
2806        "default": False,
2807    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2810class DataDeletionProperty(Property):
2811    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):
2814class DefinerProperty(Property):
2815    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2818class DistKeyProperty(Property):
2819    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2824class DistributedByProperty(Property):
2825    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):
2828class DistStyleProperty(Property):
2829    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2832class DuplicateKeyProperty(Property):
2833    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2836class EngineProperty(Property):
2837    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2840class HeapProperty(Property):
2841    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2844class ToTableProperty(Property):
2845    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2848class ExecuteAsProperty(Property):
2849    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2852class ExternalProperty(Property):
2853    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2856class FallbackProperty(Property):
2857    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2860class FileFormatProperty(Property):
2861    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2864class CredentialsProperty(Property):
2865    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2868class FreespaceProperty(Property):
2869    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2872class GlobalProperty(Property):
2873    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2876class IcebergProperty(Property):
2877    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2880class InheritsProperty(Property):
2881    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2884class InputModelProperty(Property):
2885    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2888class OutputModelProperty(Property):
2889    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2892class IsolatedLoadingProperty(Property):
2893    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2896class JournalProperty(Property):
2897    arg_types = {
2898        "no": False,
2899        "dual": False,
2900        "before": False,
2901        "local": False,
2902        "after": False,
2903    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2906class LanguageProperty(Property):
2907    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2910class EnviromentProperty(Property):
2911    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2915class ClusteredByProperty(Property):
2916    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2919class DictProperty(Property):
2920    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2923class DictSubProperty(Property):
2924    pass
key = 'dictsubproperty'
class DictRange(Property):
2927class DictRange(Property):
2928    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2931class DynamicProperty(Property):
2932    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2937class OnCluster(Property):
2938    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2942class EmptyProperty(Property):
2943    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2946class LikeProperty(Property):
2947    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2950class LocationProperty(Property):
2951    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2954class LockProperty(Property):
2955    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2958class LockingProperty(Property):
2959    arg_types = {
2960        "this": False,
2961        "kind": True,
2962        "for_or_in": False,
2963        "lock_type": True,
2964        "override": False,
2965    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2968class LogProperty(Property):
2969    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2972class MaterializedProperty(Property):
2973    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2976class MergeBlockRatioProperty(Property):
2977    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):
2980class NoPrimaryIndexProperty(Property):
2981    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2984class OnProperty(Property):
2985    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2988class OnCommitProperty(Property):
2989    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2992class PartitionedByProperty(Property):
2993    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
2996class PartitionedByBucket(Property):
2997    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3000class PartitionByTruncate(Property):
3001    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3005class PartitionByRangeProperty(Property):
3006    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3010class PartitionByRangePropertyDynamic(Expression):
3011    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):
3015class UniqueKeyProperty(Property):
3016    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3020class PartitionBoundSpec(Expression):
3021    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3022    arg_types = {
3023        "this": False,
3024        "expression": False,
3025        "from_expressions": False,
3026        "to_expressions": False,
3027    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3030class PartitionedOfProperty(Property):
3031    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3032    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3035class StreamingTableProperty(Property):
3036    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3039class RemoteWithConnectionModelProperty(Property):
3040    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3043class ReturnsProperty(Property):
3044    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):
3047class StrictProperty(Property):
3048    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3051class RowFormatProperty(Property):
3052    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3055class RowFormatDelimitedProperty(Property):
3056    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3057    arg_types = {
3058        "fields": False,
3059        "escaped": False,
3060        "collection_items": False,
3061        "map_keys": False,
3062        "lines": False,
3063        "null": False,
3064        "serde": False,
3065    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3068class RowFormatSerdeProperty(Property):
3069    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3073class QueryTransform(Expression):
3074    arg_types = {
3075        "expressions": True,
3076        "command_script": True,
3077        "schema": False,
3078        "row_format_before": False,
3079        "record_writer": False,
3080        "row_format_after": False,
3081        "record_reader": False,
3082    }
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):
3085class SampleProperty(Property):
3086    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3090class SecurityProperty(Property):
3091    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3094class SchemaCommentProperty(Property):
3095    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
3098class SerdeProperties(Property):
3099    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3102class SetProperty(Property):
3103    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3106class SharingProperty(Property):
3107    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3110class SetConfigProperty(Property):
3111    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3114class SettingsProperty(Property):
3115    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3118class SortKeyProperty(Property):
3119    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3122class SqlReadWriteProperty(Property):
3123    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3126class SqlSecurityProperty(Property):
3127    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3130class StabilityProperty(Property):
3131    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3134class StorageHandlerProperty(Property):
3135    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3138class TemporaryProperty(Property):
3139    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3142class SecureProperty(Property):
3143    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3147class Tags(ColumnConstraintKind, Property):
3148    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3151class TransformModelProperty(Property):
3152    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3155class TransientProperty(Property):
3156    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3159class UnloggedProperty(Property):
3160    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3164class UsingTemplateProperty(Property):
3165    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3169class ViewAttributeProperty(Property):
3170    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3173class VolatileProperty(Property):
3174    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3177class WithDataProperty(Property):
3178    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3181class WithJournalTableProperty(Property):
3182    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3185class WithSchemaBindingProperty(Property):
3186    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3189class WithSystemVersioningProperty(Property):
3190    arg_types = {
3191        "on": False,
3192        "this": False,
3193        "data_consistency": False,
3194        "retention_period": False,
3195        "with": True,
3196    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3199class WithProcedureOptions(Property):
3200    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3203class EncodeProperty(Property):
3204    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3207class IncludeProperty(Property):
3208    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3211class ForceProperty(Property):
3212    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3215class Properties(Expression):
3216    arg_types = {"expressions": True}
3217
3218    NAME_TO_PROPERTY = {
3219        "ALGORITHM": AlgorithmProperty,
3220        "AUTO_INCREMENT": AutoIncrementProperty,
3221        "CHARACTER SET": CharacterSetProperty,
3222        "CLUSTERED_BY": ClusteredByProperty,
3223        "COLLATE": CollateProperty,
3224        "COMMENT": SchemaCommentProperty,
3225        "CREDENTIALS": CredentialsProperty,
3226        "DEFINER": DefinerProperty,
3227        "DISTKEY": DistKeyProperty,
3228        "DISTRIBUTED_BY": DistributedByProperty,
3229        "DISTSTYLE": DistStyleProperty,
3230        "ENGINE": EngineProperty,
3231        "EXECUTE AS": ExecuteAsProperty,
3232        "FORMAT": FileFormatProperty,
3233        "LANGUAGE": LanguageProperty,
3234        "LOCATION": LocationProperty,
3235        "LOCK": LockProperty,
3236        "PARTITIONED_BY": PartitionedByProperty,
3237        "RETURNS": ReturnsProperty,
3238        "ROW_FORMAT": RowFormatProperty,
3239        "SORTKEY": SortKeyProperty,
3240        "ENCODE": EncodeProperty,
3241        "INCLUDE": IncludeProperty,
3242    }
3243
3244    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3245
3246    # CREATE property locations
3247    # Form: schema specified
3248    #   create [POST_CREATE]
3249    #     table a [POST_NAME]
3250    #     (b int) [POST_SCHEMA]
3251    #     with ([POST_WITH])
3252    #     index (b) [POST_INDEX]
3253    #
3254    # Form: alias selection
3255    #   create [POST_CREATE]
3256    #     table a [POST_NAME]
3257    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3258    #     index (c) [POST_INDEX]
3259    class Location(AutoName):
3260        POST_CREATE = auto()
3261        POST_NAME = auto()
3262        POST_SCHEMA = auto()
3263        POST_WITH = auto()
3264        POST_ALIAS = auto()
3265        POST_EXPRESSION = auto()
3266        POST_INDEX = auto()
3267        UNSUPPORTED = auto()
3268
3269    @classmethod
3270    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3271        expressions = []
3272        for key, value in properties_dict.items():
3273            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3274            if property_cls:
3275                expressions.append(property_cls(this=convert(value)))
3276            else:
3277                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3278
3279        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:
3269    @classmethod
3270    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3271        expressions = []
3272        for key, value in properties_dict.items():
3273            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3274            if property_cls:
3275                expressions.append(property_cls(this=convert(value)))
3276            else:
3277                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3278
3279        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3259    class Location(AutoName):
3260        POST_CREATE = auto()
3261        POST_NAME = auto()
3262        POST_SCHEMA = auto()
3263        POST_WITH = auto()
3264        POST_ALIAS = auto()
3265        POST_EXPRESSION = auto()
3266        POST_INDEX = auto()
3267        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):
3282class Qualify(Expression):
3283    pass
key = 'qualify'
class InputOutputFormat(Expression):
3286class InputOutputFormat(Expression):
3287    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3291class Return(Expression):
3292    pass
key = 'return'
class Reference(Expression):
3295class Reference(Expression):
3296    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3299class Tuple(Expression):
3300    arg_types = {"expressions": False}
3301
3302    def isin(
3303        self,
3304        *expressions: t.Any,
3305        query: t.Optional[ExpOrStr] = None,
3306        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3307        copy: bool = True,
3308        **opts,
3309    ) -> In:
3310        return In(
3311            this=maybe_copy(self, copy),
3312            expressions=[convert(e, copy=copy) for e in expressions],
3313            query=maybe_parse(query, copy=copy, **opts) if query else None,
3314            unnest=(
3315                Unnest(
3316                    expressions=[
3317                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3318                        for e in ensure_list(unnest)
3319                    ]
3320                )
3321                if unnest
3322                else None
3323            ),
3324        )
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:
3302    def isin(
3303        self,
3304        *expressions: t.Any,
3305        query: t.Optional[ExpOrStr] = None,
3306        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3307        copy: bool = True,
3308        **opts,
3309    ) -> In:
3310        return In(
3311            this=maybe_copy(self, copy),
3312            expressions=[convert(e, copy=copy) for e in expressions],
3313            query=maybe_parse(query, copy=copy, **opts) if query else None,
3314            unnest=(
3315                Unnest(
3316                    expressions=[
3317                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3318                        for e in ensure_list(unnest)
3319                    ]
3320                )
3321                if unnest
3322                else None
3323            ),
3324        )
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):
3355class QueryOption(Expression):
3356    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3360class WithTableHint(Expression):
3361    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3365class IndexTableHint(Expression):
3366    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3370class HistoricalData(Expression):
3371    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3375class Put(Expression):
3376    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3380class Get(Expression):
3381    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3384class Table(Expression):
3385    arg_types = {
3386        "this": False,
3387        "alias": False,
3388        "db": False,
3389        "catalog": False,
3390        "laterals": False,
3391        "joins": False,
3392        "pivots": False,
3393        "hints": False,
3394        "system_time": False,
3395        "version": False,
3396        "format": False,
3397        "pattern": False,
3398        "ordinality": False,
3399        "when": False,
3400        "only": False,
3401        "partition": False,
3402        "changes": False,
3403        "rows_from": False,
3404        "sample": False,
3405    }
3406
3407    @property
3408    def name(self) -> str:
3409        if not self.this or isinstance(self.this, Func):
3410            return ""
3411        return self.this.name
3412
3413    @property
3414    def db(self) -> str:
3415        return self.text("db")
3416
3417    @property
3418    def catalog(self) -> str:
3419        return self.text("catalog")
3420
3421    @property
3422    def selects(self) -> t.List[Expression]:
3423        return []
3424
3425    @property
3426    def named_selects(self) -> t.List[str]:
3427        return []
3428
3429    @property
3430    def parts(self) -> t.List[Expression]:
3431        """Return the parts of a table in order catalog, db, table."""
3432        parts: t.List[Expression] = []
3433
3434        for arg in ("catalog", "db", "this"):
3435            part = self.args.get(arg)
3436
3437            if isinstance(part, Dot):
3438                parts.extend(part.flatten())
3439            elif isinstance(part, Expression):
3440                parts.append(part)
3441
3442        return parts
3443
3444    def to_column(self, copy: bool = True) -> Expression:
3445        parts = self.parts
3446        last_part = parts[-1]
3447
3448        if isinstance(last_part, Identifier):
3449            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3450        else:
3451            # This branch will be reached if a function or array is wrapped in a `Table`
3452            col = last_part
3453
3454        alias = self.args.get("alias")
3455        if alias:
3456            col = alias_(col, alias.this, copy=copy)
3457
3458        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
3407    @property
3408    def name(self) -> str:
3409        if not self.this or isinstance(self.this, Func):
3410            return ""
3411        return self.this.name
db: str
3413    @property
3414    def db(self) -> str:
3415        return self.text("db")
catalog: str
3417    @property
3418    def catalog(self) -> str:
3419        return self.text("catalog")
selects: List[Expression]
3421    @property
3422    def selects(self) -> t.List[Expression]:
3423        return []
named_selects: List[str]
3425    @property
3426    def named_selects(self) -> t.List[str]:
3427        return []
parts: List[Expression]
3429    @property
3430    def parts(self) -> t.List[Expression]:
3431        """Return the parts of a table in order catalog, db, table."""
3432        parts: t.List[Expression] = []
3433
3434        for arg in ("catalog", "db", "this"):
3435            part = self.args.get(arg)
3436
3437            if isinstance(part, Dot):
3438                parts.extend(part.flatten())
3439            elif isinstance(part, Expression):
3440                parts.append(part)
3441
3442        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3444    def to_column(self, copy: bool = True) -> Expression:
3445        parts = self.parts
3446        last_part = parts[-1]
3447
3448        if isinstance(last_part, Identifier):
3449            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3450        else:
3451            # This branch will be reached if a function or array is wrapped in a `Table`
3452            col = last_part
3453
3454        alias = self.args.get("alias")
3455        if alias:
3456            col = alias_(col, alias.this, copy=copy)
3457
3458        return col
key = 'table'
class SetOperation(Query):
3461class SetOperation(Query):
3462    arg_types = {
3463        "with": False,
3464        "this": True,
3465        "expression": True,
3466        "distinct": False,
3467        "by_name": False,
3468        "side": False,
3469        "kind": False,
3470        "on": False,
3471        **QUERY_MODIFIERS,
3472    }
3473
3474    def select(
3475        self: S,
3476        *expressions: t.Optional[ExpOrStr],
3477        append: bool = True,
3478        dialect: DialectType = None,
3479        copy: bool = True,
3480        **opts,
3481    ) -> S:
3482        this = maybe_copy(self, copy)
3483        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3484        this.expression.unnest().select(
3485            *expressions, append=append, dialect=dialect, copy=False, **opts
3486        )
3487        return this
3488
3489    @property
3490    def named_selects(self) -> t.List[str]:
3491        return self.this.unnest().named_selects
3492
3493    @property
3494    def is_star(self) -> bool:
3495        return self.this.is_star or self.expression.is_star
3496
3497    @property
3498    def selects(self) -> t.List[Expression]:
3499        return self.this.unnest().selects
3500
3501    @property
3502    def left(self) -> Query:
3503        return self.this
3504
3505    @property
3506    def right(self) -> Query:
3507        return self.expression
3508
3509    @property
3510    def kind(self) -> str:
3511        return self.text("kind").upper()
3512
3513    @property
3514    def side(self) -> str:
3515        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:
3474    def select(
3475        self: S,
3476        *expressions: t.Optional[ExpOrStr],
3477        append: bool = True,
3478        dialect: DialectType = None,
3479        copy: bool = True,
3480        **opts,
3481    ) -> S:
3482        this = maybe_copy(self, copy)
3483        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3484        this.expression.unnest().select(
3485            *expressions, append=append, dialect=dialect, copy=False, **opts
3486        )
3487        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]
3489    @property
3490    def named_selects(self) -> t.List[str]:
3491        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3493    @property
3494    def is_star(self) -> bool:
3495        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3497    @property
3498    def selects(self) -> t.List[Expression]:
3499        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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:
3938    def select(
3939        self,
3940        *expressions: t.Optional[ExpOrStr],
3941        append: bool = True,
3942        dialect: DialectType = None,
3943        copy: bool = True,
3944        **opts,
3945    ) -> Select:
3946        return _apply_list_builder(
3947            *expressions,
3948            instance=self,
3949            arg="expressions",
3950            append=append,
3951            dialect=dialect,
3952            into=Expression,
3953            copy=copy,
3954            **opts,
3955        )

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

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

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

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:
4133    def window(
4134        self,
4135        *expressions: t.Optional[ExpOrStr],
4136        append: bool = True,
4137        dialect: DialectType = None,
4138        copy: bool = True,
4139        **opts,
4140    ) -> Select:
4141        return _apply_list_builder(
4142            *expressions,
4143            instance=self,
4144            arg="windows",
4145            append=append,
4146            into=Window,
4147            dialect=dialect,
4148            copy=copy,
4149            **opts,
4150        )
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:
4152    def qualify(
4153        self,
4154        *expressions: t.Optional[ExpOrStr],
4155        append: bool = True,
4156        dialect: DialectType = None,
4157        copy: bool = True,
4158        **opts,
4159    ) -> Select:
4160        return _apply_conjunction_builder(
4161            *expressions,
4162            instance=self,
4163            arg="qualify",
4164            append=append,
4165            into=Qualify,
4166            dialect=dialect,
4167            copy=copy,
4168            **opts,
4169        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4171    def distinct(
4172        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4173    ) -> Select:
4174        """
4175        Set the OFFSET expression.
4176
4177        Example:
4178            >>> Select().from_("tbl").select("x").distinct().sql()
4179            'SELECT DISTINCT x FROM tbl'
4180
4181        Args:
4182            ons: the expressions to distinct on
4183            distinct: whether the Select should be distinct
4184            copy: if `False`, modify this expression instance in-place.
4185
4186        Returns:
4187            Select: the modified expression.
4188        """
4189        instance = maybe_copy(self, copy)
4190        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4191        instance.set("distinct", Distinct(on=on) if distinct else None)
4192        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:
4194    def ctas(
4195        self,
4196        table: ExpOrStr,
4197        properties: t.Optional[t.Dict] = None,
4198        dialect: DialectType = None,
4199        copy: bool = True,
4200        **opts,
4201    ) -> Create:
4202        """
4203        Convert this expression to a CREATE TABLE AS statement.
4204
4205        Example:
4206            >>> Select().select("*").from_("tbl").ctas("x").sql()
4207            'CREATE TABLE x AS SELECT * FROM tbl'
4208
4209        Args:
4210            table: the SQL code string to parse as the table name.
4211                If another `Expression` instance is passed, it will be used as-is.
4212            properties: an optional mapping of table properties
4213            dialect: the dialect used to parse the input table.
4214            copy: if `False`, modify this expression instance in-place.
4215            opts: other options to use to parse the input table.
4216
4217        Returns:
4218            The new Create expression.
4219        """
4220        instance = maybe_copy(self, copy)
4221        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4222
4223        properties_expression = None
4224        if properties:
4225            properties_expression = Properties.from_dict(properties)
4226
4227        return Create(
4228            this=table_expression,
4229            kind="TABLE",
4230            expression=instance,
4231            properties=properties_expression,
4232        )

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:
4234    def lock(self, update: bool = True, copy: bool = True) -> Select:
4235        """
4236        Set the locking read mode for this expression.
4237
4238        Examples:
4239            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4240            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4241
4242            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4243            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4244
4245        Args:
4246            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4247            copy: if `False`, modify this expression instance in-place.
4248
4249        Returns:
4250            The modified expression.
4251        """
4252        inst = maybe_copy(self, copy)
4253        inst.set("locks", [Lock(update=update)])
4254
4255        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:
4257    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4258        """
4259        Set hints for this expression.
4260
4261        Examples:
4262            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4263            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4264
4265        Args:
4266            hints: The SQL code strings to parse as the hints.
4267                If an `Expression` instance is passed, it will be used as-is.
4268            dialect: The dialect used to parse the hints.
4269            copy: If `False`, modify this expression instance in-place.
4270
4271        Returns:
4272            The modified expression.
4273        """
4274        inst = maybe_copy(self, copy)
4275        inst.set(
4276            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4277        )
4278
4279        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]
4281    @property
4282    def named_selects(self) -> t.List[str]:
4283        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
4285    @property
4286    def is_star(self) -> bool:
4287        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4289    @property
4290    def selects(self) -> t.List[Expression]:
4291        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
4312    def unwrap(self) -> Subquery:
4313        expression = self
4314        while expression.same_parent and expression.is_wrapper:
4315            expression = t.cast(Subquery, expression.parent)
4316        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:
4318    def select(
4319        self,
4320        *expressions: t.Optional[ExpOrStr],
4321        append: bool = True,
4322        dialect: DialectType = None,
4323        copy: bool = True,
4324        **opts,
4325    ) -> Subquery:
4326        this = maybe_copy(self, copy)
4327        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4328        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
4330    @property
4331    def is_wrapper(self) -> bool:
4332        """
4333        Whether this Subquery acts as a simple wrapper around another expression.
4334
4335        SELECT * FROM (((SELECT * FROM t)))
4336                      ^
4337                      This corresponds to a "wrapper" Subquery node
4338        """
4339        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
4341    @property
4342    def is_star(self) -> bool:
4343        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4345    @property
4346    def output_name(self) -> str:
4347        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):
4350class TableSample(Expression):
4351    arg_types = {
4352        "expressions": False,
4353        "method": False,
4354        "bucket_numerator": False,
4355        "bucket_denominator": False,
4356        "bucket_field": False,
4357        "percent": False,
4358        "rows": False,
4359        "size": False,
4360        "seed": False,
4361    }
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):
4364class Tag(Expression):
4365    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4366
4367    arg_types = {
4368        "this": False,
4369        "prefix": False,
4370        "postfix": False,
4371    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4376class Pivot(Expression):
4377    arg_types = {
4378        "this": False,
4379        "alias": False,
4380        "expressions": False,
4381        "fields": False,
4382        "unpivot": False,
4383        "using": False,
4384        "group": False,
4385        "columns": False,
4386        "include_nulls": False,
4387        "default_on_null": False,
4388        "into": False,
4389    }
4390
4391    @property
4392    def unpivot(self) -> bool:
4393        return bool(self.args.get("unpivot"))
4394
4395    @property
4396    def fields(self) -> t.List[Expression]:
4397        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
4391    @property
4392    def unpivot(self) -> bool:
4393        return bool(self.args.get("unpivot"))
fields: List[Expression]
4395    @property
4396    def fields(self) -> t.List[Expression]:
4397        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4402class UnpivotColumns(Expression):
4403    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4406class Window(Condition):
4407    arg_types = {
4408        "this": True,
4409        "partition_by": False,
4410        "order": False,
4411        "spec": False,
4412        "alias": False,
4413        "over": False,
4414        "first": False,
4415    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4418class WindowSpec(Expression):
4419    arg_types = {
4420        "kind": False,
4421        "start": False,
4422        "start_side": False,
4423        "end": False,
4424        "end_side": False,
4425        "exclude": False,
4426    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4429class PreWhere(Expression):
4430    pass
key = 'prewhere'
class Where(Expression):
4433class Where(Expression):
4434    pass
key = 'where'
class Star(Expression):
4437class Star(Expression):
4438    arg_types = {"except": False, "replace": False, "rename": False}
4439
4440    @property
4441    def name(self) -> str:
4442        return "*"
4443
4444    @property
4445    def output_name(self) -> str:
4446        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4440    @property
4441    def name(self) -> str:
4442        return "*"
output_name: str
4444    @property
4445    def output_name(self) -> str:
4446        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):
4449class Parameter(Condition):
4450    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4453class SessionParameter(Condition):
4454    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4458class Placeholder(Condition):
4459    arg_types = {"this": False, "kind": False, "widget": False}
4460
4461    @property
4462    def name(self) -> str:
4463        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False}
name: str
4461    @property
4462    def name(self) -> str:
4463        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4466class Null(Condition):
4467    arg_types: t.Dict[str, t.Any] = {}
4468
4469    @property
4470    def name(self) -> str:
4471        return "NULL"
4472
4473    def to_py(self) -> Lit[None]:
4474        return None
arg_types: Dict[str, Any] = {}
name: str
4469    @property
4470    def name(self) -> str:
4471        return "NULL"
def to_py(self) -> Literal[None]:
4473    def to_py(self) -> Lit[None]:
4474        return None

Returns a Python object equivalent of the SQL node.

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

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4482class DataTypeParam(Expression):
4483    arg_types = {"this": True, "expression": False}
4484
4485    @property
4486    def name(self) -> str:
4487        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4485    @property
4486    def name(self) -> str:
4487        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4492class DataType(Expression):
4493    arg_types = {
4494        "this": True,
4495        "expressions": False,
4496        "nested": False,
4497        "values": False,
4498        "prefix": False,
4499        "kind": False,
4500        "nullable": False,
4501    }
4502
4503    class Type(AutoName):
4504        ARRAY = auto()
4505        AGGREGATEFUNCTION = auto()
4506        SIMPLEAGGREGATEFUNCTION = auto()
4507        BIGDECIMAL = auto()
4508        BIGINT = auto()
4509        BIGSERIAL = auto()
4510        BINARY = auto()
4511        BIT = auto()
4512        BLOB = auto()
4513        BOOLEAN = auto()
4514        BPCHAR = auto()
4515        CHAR = auto()
4516        DATE = auto()
4517        DATE32 = auto()
4518        DATEMULTIRANGE = auto()
4519        DATERANGE = auto()
4520        DATETIME = auto()
4521        DATETIME2 = auto()
4522        DATETIME64 = auto()
4523        DECIMAL = auto()
4524        DECIMAL32 = auto()
4525        DECIMAL64 = auto()
4526        DECIMAL128 = auto()
4527        DECIMAL256 = auto()
4528        DOUBLE = auto()
4529        DYNAMIC = auto()
4530        ENUM = auto()
4531        ENUM8 = auto()
4532        ENUM16 = auto()
4533        FIXEDSTRING = auto()
4534        FLOAT = auto()
4535        GEOGRAPHY = auto()
4536        GEOMETRY = auto()
4537        POINT = auto()
4538        RING = auto()
4539        LINESTRING = auto()
4540        MULTILINESTRING = auto()
4541        POLYGON = auto()
4542        MULTIPOLYGON = auto()
4543        HLLSKETCH = auto()
4544        HSTORE = auto()
4545        IMAGE = auto()
4546        INET = auto()
4547        INT = auto()
4548        INT128 = auto()
4549        INT256 = auto()
4550        INT4MULTIRANGE = auto()
4551        INT4RANGE = auto()
4552        INT8MULTIRANGE = auto()
4553        INT8RANGE = auto()
4554        INTERVAL = auto()
4555        IPADDRESS = auto()
4556        IPPREFIX = auto()
4557        IPV4 = auto()
4558        IPV6 = auto()
4559        JSON = auto()
4560        JSONB = auto()
4561        LIST = auto()
4562        LONGBLOB = auto()
4563        LONGTEXT = auto()
4564        LOWCARDINALITY = auto()
4565        MAP = auto()
4566        MEDIUMBLOB = auto()
4567        MEDIUMINT = auto()
4568        MEDIUMTEXT = auto()
4569        MONEY = auto()
4570        NAME = auto()
4571        NCHAR = auto()
4572        NESTED = auto()
4573        NOTHING = auto()
4574        NULL = auto()
4575        NUMMULTIRANGE = auto()
4576        NUMRANGE = auto()
4577        NVARCHAR = auto()
4578        OBJECT = auto()
4579        RANGE = auto()
4580        ROWVERSION = auto()
4581        SERIAL = auto()
4582        SET = auto()
4583        SMALLDATETIME = auto()
4584        SMALLINT = auto()
4585        SMALLMONEY = auto()
4586        SMALLSERIAL = auto()
4587        STRUCT = auto()
4588        SUPER = auto()
4589        TEXT = auto()
4590        TINYBLOB = auto()
4591        TINYTEXT = auto()
4592        TIME = auto()
4593        TIMETZ = auto()
4594        TIMESTAMP = auto()
4595        TIMESTAMPNTZ = auto()
4596        TIMESTAMPLTZ = auto()
4597        TIMESTAMPTZ = auto()
4598        TIMESTAMP_S = auto()
4599        TIMESTAMP_MS = auto()
4600        TIMESTAMP_NS = auto()
4601        TINYINT = auto()
4602        TSMULTIRANGE = auto()
4603        TSRANGE = auto()
4604        TSTZMULTIRANGE = auto()
4605        TSTZRANGE = auto()
4606        UBIGINT = auto()
4607        UINT = auto()
4608        UINT128 = auto()
4609        UINT256 = auto()
4610        UMEDIUMINT = auto()
4611        UDECIMAL = auto()
4612        UDOUBLE = auto()
4613        UNION = auto()
4614        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4615        USERDEFINED = "USER-DEFINED"
4616        USMALLINT = auto()
4617        UTINYINT = auto()
4618        UUID = auto()
4619        VARBINARY = auto()
4620        VARCHAR = auto()
4621        VARIANT = auto()
4622        VECTOR = auto()
4623        XML = auto()
4624        YEAR = auto()
4625        TDIGEST = auto()
4626
4627    STRUCT_TYPES = {
4628        Type.NESTED,
4629        Type.OBJECT,
4630        Type.STRUCT,
4631        Type.UNION,
4632    }
4633
4634    ARRAY_TYPES = {
4635        Type.ARRAY,
4636        Type.LIST,
4637    }
4638
4639    NESTED_TYPES = {
4640        *STRUCT_TYPES,
4641        *ARRAY_TYPES,
4642        Type.MAP,
4643    }
4644
4645    TEXT_TYPES = {
4646        Type.CHAR,
4647        Type.NCHAR,
4648        Type.NVARCHAR,
4649        Type.TEXT,
4650        Type.VARCHAR,
4651        Type.NAME,
4652    }
4653
4654    SIGNED_INTEGER_TYPES = {
4655        Type.BIGINT,
4656        Type.INT,
4657        Type.INT128,
4658        Type.INT256,
4659        Type.MEDIUMINT,
4660        Type.SMALLINT,
4661        Type.TINYINT,
4662    }
4663
4664    UNSIGNED_INTEGER_TYPES = {
4665        Type.UBIGINT,
4666        Type.UINT,
4667        Type.UINT128,
4668        Type.UINT256,
4669        Type.UMEDIUMINT,
4670        Type.USMALLINT,
4671        Type.UTINYINT,
4672    }
4673
4674    INTEGER_TYPES = {
4675        *SIGNED_INTEGER_TYPES,
4676        *UNSIGNED_INTEGER_TYPES,
4677        Type.BIT,
4678    }
4679
4680    FLOAT_TYPES = {
4681        Type.DOUBLE,
4682        Type.FLOAT,
4683    }
4684
4685    REAL_TYPES = {
4686        *FLOAT_TYPES,
4687        Type.BIGDECIMAL,
4688        Type.DECIMAL,
4689        Type.DECIMAL32,
4690        Type.DECIMAL64,
4691        Type.DECIMAL128,
4692        Type.DECIMAL256,
4693        Type.MONEY,
4694        Type.SMALLMONEY,
4695        Type.UDECIMAL,
4696        Type.UDOUBLE,
4697    }
4698
4699    NUMERIC_TYPES = {
4700        *INTEGER_TYPES,
4701        *REAL_TYPES,
4702    }
4703
4704    TEMPORAL_TYPES = {
4705        Type.DATE,
4706        Type.DATE32,
4707        Type.DATETIME,
4708        Type.DATETIME2,
4709        Type.DATETIME64,
4710        Type.SMALLDATETIME,
4711        Type.TIME,
4712        Type.TIMESTAMP,
4713        Type.TIMESTAMPNTZ,
4714        Type.TIMESTAMPLTZ,
4715        Type.TIMESTAMPTZ,
4716        Type.TIMESTAMP_MS,
4717        Type.TIMESTAMP_NS,
4718        Type.TIMESTAMP_S,
4719        Type.TIMETZ,
4720    }
4721
4722    @classmethod
4723    def build(
4724        cls,
4725        dtype: DATA_TYPE,
4726        dialect: DialectType = None,
4727        udt: bool = False,
4728        copy: bool = True,
4729        **kwargs,
4730    ) -> DataType:
4731        """
4732        Constructs a DataType object.
4733
4734        Args:
4735            dtype: the data type of interest.
4736            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4737            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4738                DataType, thus creating a user-defined type.
4739            copy: whether to copy the data type.
4740            kwargs: additional arguments to pass in the constructor of DataType.
4741
4742        Returns:
4743            The constructed DataType object.
4744        """
4745        from sqlglot import parse_one
4746
4747        if isinstance(dtype, str):
4748            if dtype.upper() == "UNKNOWN":
4749                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4750
4751            try:
4752                data_type_exp = parse_one(
4753                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4754                )
4755            except ParseError:
4756                if udt:
4757                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4758                raise
4759        elif isinstance(dtype, (Identifier, Dot)) and udt:
4760            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
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.NESTED: 'NESTED'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.MAP: 'MAP'>, <Type.LIST: 'LIST'>}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.TEXT: 'TEXT'>}
SIGNED_INTEGER_TYPES = {<Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT256: 'UINT256'>}
INTEGER_TYPES = {<Type.UINT128: 'UINT128'>, <Type.BIT: 'BIT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT256: 'UINT256'>, <Type.INT: 'INT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.MONEY: 'MONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL64: 'DECIMAL64'>}
NUMERIC_TYPES = {<Type.BIT: 'BIT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.MONEY: 'MONEY'>, <Type.INT128: 'INT128'>, <Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.INT: 'INT'>, <Type.UINT128: 'UINT128'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT256: 'UINT256'>}
TEMPORAL_TYPES = {<Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIME: 'TIME'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME: 'DATETIME'>}
@classmethod
def build( cls, dtype: Union[str, Identifier, Dot, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4722    @classmethod
4723    def build(
4724        cls,
4725        dtype: DATA_TYPE,
4726        dialect: DialectType = None,
4727        udt: bool = False,
4728        copy: bool = True,
4729        **kwargs,
4730    ) -> DataType:
4731        """
4732        Constructs a DataType object.
4733
4734        Args:
4735            dtype: the data type of interest.
4736            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4737            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4738                DataType, thus creating a user-defined type.
4739            copy: whether to copy the data type.
4740            kwargs: additional arguments to pass in the constructor of DataType.
4741
4742        Returns:
4743            The constructed DataType object.
4744        """
4745        from sqlglot import parse_one
4746
4747        if isinstance(dtype, str):
4748            if dtype.upper() == "UNKNOWN":
4749                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4750
4751            try:
4752                data_type_exp = parse_one(
4753                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4754                )
4755            except ParseError:
4756                if udt:
4757                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4758                raise
4759        elif isinstance(dtype, (Identifier, Dot)) and udt:
4760            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
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, Identifier, Dot, 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):
4503    class Type(AutoName):
4504        ARRAY = auto()
4505        AGGREGATEFUNCTION = auto()
4506        SIMPLEAGGREGATEFUNCTION = auto()
4507        BIGDECIMAL = auto()
4508        BIGINT = auto()
4509        BIGSERIAL = auto()
4510        BINARY = auto()
4511        BIT = auto()
4512        BLOB = auto()
4513        BOOLEAN = auto()
4514        BPCHAR = auto()
4515        CHAR = auto()
4516        DATE = auto()
4517        DATE32 = auto()
4518        DATEMULTIRANGE = auto()
4519        DATERANGE = auto()
4520        DATETIME = auto()
4521        DATETIME2 = auto()
4522        DATETIME64 = auto()
4523        DECIMAL = auto()
4524        DECIMAL32 = auto()
4525        DECIMAL64 = auto()
4526        DECIMAL128 = auto()
4527        DECIMAL256 = auto()
4528        DOUBLE = auto()
4529        DYNAMIC = auto()
4530        ENUM = auto()
4531        ENUM8 = auto()
4532        ENUM16 = auto()
4533        FIXEDSTRING = auto()
4534        FLOAT = auto()
4535        GEOGRAPHY = auto()
4536        GEOMETRY = auto()
4537        POINT = auto()
4538        RING = auto()
4539        LINESTRING = auto()
4540        MULTILINESTRING = auto()
4541        POLYGON = auto()
4542        MULTIPOLYGON = auto()
4543        HLLSKETCH = auto()
4544        HSTORE = auto()
4545        IMAGE = auto()
4546        INET = auto()
4547        INT = auto()
4548        INT128 = auto()
4549        INT256 = auto()
4550        INT4MULTIRANGE = auto()
4551        INT4RANGE = auto()
4552        INT8MULTIRANGE = auto()
4553        INT8RANGE = auto()
4554        INTERVAL = auto()
4555        IPADDRESS = auto()
4556        IPPREFIX = auto()
4557        IPV4 = auto()
4558        IPV6 = auto()
4559        JSON = auto()
4560        JSONB = auto()
4561        LIST = auto()
4562        LONGBLOB = auto()
4563        LONGTEXT = auto()
4564        LOWCARDINALITY = auto()
4565        MAP = auto()
4566        MEDIUMBLOB = auto()
4567        MEDIUMINT = auto()
4568        MEDIUMTEXT = auto()
4569        MONEY = auto()
4570        NAME = auto()
4571        NCHAR = auto()
4572        NESTED = auto()
4573        NOTHING = auto()
4574        NULL = auto()
4575        NUMMULTIRANGE = auto()
4576        NUMRANGE = auto()
4577        NVARCHAR = auto()
4578        OBJECT = auto()
4579        RANGE = auto()
4580        ROWVERSION = auto()
4581        SERIAL = auto()
4582        SET = auto()
4583        SMALLDATETIME = auto()
4584        SMALLINT = auto()
4585        SMALLMONEY = auto()
4586        SMALLSERIAL = auto()
4587        STRUCT = auto()
4588        SUPER = auto()
4589        TEXT = auto()
4590        TINYBLOB = auto()
4591        TINYTEXT = auto()
4592        TIME = auto()
4593        TIMETZ = auto()
4594        TIMESTAMP = auto()
4595        TIMESTAMPNTZ = auto()
4596        TIMESTAMPLTZ = auto()
4597        TIMESTAMPTZ = auto()
4598        TIMESTAMP_S = auto()
4599        TIMESTAMP_MS = auto()
4600        TIMESTAMP_NS = auto()
4601        TINYINT = auto()
4602        TSMULTIRANGE = auto()
4603        TSRANGE = auto()
4604        TSTZMULTIRANGE = auto()
4605        TSTZRANGE = auto()
4606        UBIGINT = auto()
4607        UINT = auto()
4608        UINT128 = auto()
4609        UINT256 = auto()
4610        UMEDIUMINT = auto()
4611        UDECIMAL = auto()
4612        UDOUBLE = auto()
4613        UNION = auto()
4614        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4615        USERDEFINED = "USER-DEFINED"
4616        USMALLINT = auto()
4617        UTINYINT = auto()
4618        UUID = auto()
4619        VARBINARY = auto()
4620        VARCHAR = auto()
4621        VARIANT = auto()
4622        VECTOR = auto()
4623        XML = auto()
4624        YEAR = auto()
4625        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'>
class PseudoType(DataType):
4803class PseudoType(DataType):
4804    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4808class ObjectIdentifier(DataType):
4809    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4813class SubqueryPredicate(Predicate):
4814    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4817class All(SubqueryPredicate):
4818    pass
key = 'all'
class Any(SubqueryPredicate):
4821class Any(SubqueryPredicate):
4822    pass
key = 'any'
class Command(Expression):
4827class Command(Expression):
4828    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4831class Transaction(Expression):
4832    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4835class Commit(Expression):
4836    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4839class Rollback(Expression):
4840    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4843class Alter(Expression):
4844    arg_types = {
4845        "this": True,
4846        "kind": True,
4847        "actions": True,
4848        "exists": False,
4849        "only": False,
4850        "options": False,
4851        "cluster": False,
4852        "not_valid": False,
4853    }
4854
4855    @property
4856    def kind(self) -> t.Optional[str]:
4857        kind = self.args.get("kind")
4858        return kind and kind.upper()
4859
4860    @property
4861    def actions(self) -> t.List[Expression]:
4862        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]
4855    @property
4856    def kind(self) -> t.Optional[str]:
4857        kind = self.args.get("kind")
4858        return kind and kind.upper()
actions: List[Expression]
4860    @property
4861    def actions(self) -> t.List[Expression]:
4862        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4865class Analyze(Expression):
4866    arg_types = {
4867        "kind": False,
4868        "this": False,
4869        "options": False,
4870        "mode": False,
4871        "partition": False,
4872        "expression": False,
4873        "properties": False,
4874    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4877class AnalyzeStatistics(Expression):
4878    arg_types = {
4879        "kind": True,
4880        "option": False,
4881        "this": False,
4882        "expressions": False,
4883    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4886class AnalyzeHistogram(Expression):
4887    arg_types = {
4888        "this": True,
4889        "expressions": True,
4890        "expression": False,
4891        "update_options": False,
4892    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4895class AnalyzeSample(Expression):
4896    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4899class AnalyzeListChainedRows(Expression):
4900    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4903class AnalyzeDelete(Expression):
4904    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4907class AnalyzeWith(Expression):
4908    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4911class AnalyzeValidate(Expression):
4912    arg_types = {
4913        "kind": True,
4914        "this": False,
4915        "expression": False,
4916    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4919class AnalyzeColumns(Expression):
4920    pass
key = 'analyzecolumns'
class UsingData(Expression):
4923class UsingData(Expression):
4924    pass
key = 'usingdata'
class AddConstraint(Expression):
4927class AddConstraint(Expression):
4928    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AddPartition(Expression):
4931class AddPartition(Expression):
4932    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'addpartition'
class AttachOption(Expression):
4935class AttachOption(Expression):
4936    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4939class DropPartition(Expression):
4940    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4944class ReplacePartition(Expression):
4945    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4949class Binary(Condition):
4950    arg_types = {"this": True, "expression": True}
4951
4952    @property
4953    def left(self) -> Expression:
4954        return self.this
4955
4956    @property
4957    def right(self) -> Expression:
4958        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4952    @property
4953    def left(self) -> Expression:
4954        return self.this
right: Expression
4956    @property
4957    def right(self) -> Expression:
4958        return self.expression
key = 'binary'
class Add(Binary):
4961class Add(Binary):
4962    pass
key = 'add'
class Connector(Binary):
4965class Connector(Binary):
4966    pass
key = 'connector'
class BitwiseAnd(Binary):
4969class BitwiseAnd(Binary):
4970    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4973class BitwiseLeftShift(Binary):
4974    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4977class BitwiseOr(Binary):
4978    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4981class BitwiseRightShift(Binary):
4982    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4985class BitwiseXor(Binary):
4986    pass
key = 'bitwisexor'
class Div(Binary):
4989class Div(Binary):
4990    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):
4993class Overlaps(Binary):
4994    pass
key = 'overlaps'
class Dot(Binary):
4997class Dot(Binary):
4998    @property
4999    def is_star(self) -> bool:
5000        return self.expression.is_star
5001
5002    @property
5003    def name(self) -> str:
5004        return self.expression.name
5005
5006    @property
5007    def output_name(self) -> str:
5008        return self.name
5009
5010    @classmethod
5011    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5012        """Build a Dot object with a sequence of expressions."""
5013        if len(expressions) < 2:
5014            raise ValueError("Dot requires >= 2 expressions.")
5015
5016        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5017
5018    @property
5019    def parts(self) -> t.List[Expression]:
5020        """Return the parts of a table / column in order catalog, db, table."""
5021        this, *parts = self.flatten()
5022
5023        parts.reverse()
5024
5025        for arg in COLUMN_PARTS:
5026            part = this.args.get(arg)
5027
5028            if isinstance(part, Expression):
5029                parts.append(part)
5030
5031        parts.reverse()
5032        return parts
is_star: bool
4998    @property
4999    def is_star(self) -> bool:
5000        return self.expression.is_star

Checks whether an expression is a star.

name: str
5002    @property
5003    def name(self) -> str:
5004        return self.expression.name
output_name: str
5006    @property
5007    def output_name(self) -> str:
5008        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:
5010    @classmethod
5011    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5012        """Build a Dot object with a sequence of expressions."""
5013        if len(expressions) < 2:
5014            raise ValueError("Dot requires >= 2 expressions.")
5015
5016        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]
5018    @property
5019    def parts(self) -> t.List[Expression]:
5020        """Return the parts of a table / column in order catalog, db, table."""
5021        this, *parts = self.flatten()
5022
5023        parts.reverse()
5024
5025        for arg in COLUMN_PARTS:
5026            part = this.args.get(arg)
5027
5028            if isinstance(part, Expression):
5029                parts.append(part)
5030
5031        parts.reverse()
5032        return parts

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

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

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

key = 'kwarg'
class Like(Binary, Predicate):
5099class Like(Binary, Predicate):
5100    pass
key = 'like'
class LikeAny(Binary, Predicate):
5103class LikeAny(Binary, Predicate):
5104    pass
key = 'likeany'
class LT(Binary, Predicate):
5107class LT(Binary, Predicate):
5108    pass
key = 'lt'
class LTE(Binary, Predicate):
5111class LTE(Binary, Predicate):
5112    pass
key = 'lte'
class Mod(Binary):
5115class Mod(Binary):
5116    pass
key = 'mod'
class Mul(Binary):
5119class Mul(Binary):
5120    pass
key = 'mul'
class NEQ(Binary, Predicate):
5123class NEQ(Binary, Predicate):
5124    pass
key = 'neq'
class Operator(Binary):
5128class Operator(Binary):
5129    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5132class SimilarTo(Binary, Predicate):
5133    pass
key = 'similarto'
class Slice(Binary):
5136class Slice(Binary):
5137    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5140class Sub(Binary):
5141    pass
key = 'sub'
class Unary(Condition):
5146class Unary(Condition):
5147    pass
key = 'unary'
class BitwiseNot(Unary):
5150class BitwiseNot(Unary):
5151    pass
key = 'bitwisenot'
class Not(Unary):
5154class Not(Unary):
5155    pass
key = 'not'
class Paren(Unary):
5158class Paren(Unary):
5159    @property
5160    def output_name(self) -> str:
5161        return self.this.name
output_name: str
5159    @property
5160    def output_name(self) -> str:
5161        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):
5164class Neg(Unary):
5165    def to_py(self) -> int | Decimal:
5166        if self.is_number:
5167            return self.this.to_py() * -1
5168        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5165    def to_py(self) -> int | Decimal:
5166        if self.is_number:
5167            return self.this.to_py() * -1
5168        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5171class Alias(Expression):
5172    arg_types = {"this": True, "alias": False}
5173
5174    @property
5175    def output_name(self) -> str:
5176        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5174    @property
5175    def output_name(self) -> str:
5176        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):
5181class PivotAlias(Alias):
5182    pass
key = 'pivotalias'
class PivotAny(Expression):
5187class PivotAny(Expression):
5188    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5191class Aliases(Expression):
5192    arg_types = {"this": True, "expressions": True}
5193
5194    @property
5195    def aliases(self):
5196        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5194    @property
5195    def aliases(self):
5196        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5200class AtIndex(Expression):
5201    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5204class AtTimeZone(Expression):
5205    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5208class FromTimeZone(Expression):
5209    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5212class Between(Predicate):
5213    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5216class Bracket(Condition):
5217    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5218    arg_types = {
5219        "this": True,
5220        "expressions": True,
5221        "offset": False,
5222        "safe": False,
5223        "returns_list_for_maps": False,
5224    }
5225
5226    @property
5227    def output_name(self) -> str:
5228        if len(self.expressions) == 1:
5229            return self.expressions[0].output_name
5230
5231        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5226    @property
5227    def output_name(self) -> str:
5228        if len(self.expressions) == 1:
5229            return self.expressions[0].output_name
5230
5231        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):
5234class Distinct(Expression):
5235    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5238class In(Predicate):
5239    arg_types = {
5240        "this": True,
5241        "expressions": False,
5242        "query": False,
5243        "unnest": False,
5244        "field": False,
5245        "is_global": False,
5246    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5250class ForIn(Expression):
5251    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5254class TimeUnit(Expression):
5255    """Automatically converts unit arg into a var."""
5256
5257    arg_types = {"unit": False}
5258
5259    UNABBREVIATED_UNIT_NAME = {
5260        "D": "DAY",
5261        "H": "HOUR",
5262        "M": "MINUTE",
5263        "MS": "MILLISECOND",
5264        "NS": "NANOSECOND",
5265        "Q": "QUARTER",
5266        "S": "SECOND",
5267        "US": "MICROSECOND",
5268        "W": "WEEK",
5269        "Y": "YEAR",
5270    }
5271
5272    VAR_LIKE = (Column, Literal, Var)
5273
5274    def __init__(self, **args):
5275        unit = args.get("unit")
5276        if isinstance(unit, self.VAR_LIKE):
5277            args["unit"] = Var(
5278                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5279            )
5280        elif isinstance(unit, Week):
5281            unit.set("this", Var(this=unit.this.name.upper()))
5282
5283        super().__init__(**args)
5284
5285    @property
5286    def unit(self) -> t.Optional[Var | IntervalSpan]:
5287        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5274    def __init__(self, **args):
5275        unit = args.get("unit")
5276        if isinstance(unit, self.VAR_LIKE):
5277            args["unit"] = Var(
5278                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5279            )
5280        elif isinstance(unit, Week):
5281            unit.set("this", Var(this=unit.this.name.upper()))
5282
5283        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]
5285    @property
5286    def unit(self) -> t.Optional[Var | IntervalSpan]:
5287        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5290class IntervalOp(TimeUnit):
5291    arg_types = {"unit": False, "expression": True}
5292
5293    def interval(self):
5294        return Interval(
5295            this=self.expression.copy(),
5296            unit=self.unit.copy() if self.unit else None,
5297        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5293    def interval(self):
5294        return Interval(
5295            this=self.expression.copy(),
5296            unit=self.unit.copy() if self.unit else None,
5297        )
key = 'intervalop'
class IntervalSpan(DataType):
5303class IntervalSpan(DataType):
5304    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5307class Interval(TimeUnit):
5308    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5311class IgnoreNulls(Expression):
5312    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5315class RespectNulls(Expression):
5316    pass
key = 'respectnulls'
class HavingMax(Expression):
5320class HavingMax(Expression):
5321    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5325class Func(Condition):
5326    """
5327    The base class for all function expressions.
5328
5329    Attributes:
5330        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5331            treated as a variable length argument and the argument's value will be stored as a list.
5332        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5333            function expression. These values are used to map this node to a name during parsing as
5334            well as to provide the function's name during SQL string generation. By default the SQL
5335            name is set to the expression's class name transformed to snake case.
5336    """
5337
5338    is_var_len_args = False
5339
5340    @classmethod
5341    def from_arg_list(cls, args):
5342        if cls.is_var_len_args:
5343            all_arg_keys = list(cls.arg_types)
5344            # If this function supports variable length argument treat the last argument as such.
5345            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5346            num_non_var = len(non_var_len_arg_keys)
5347
5348            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5349            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5350        else:
5351            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5352
5353        return cls(**args_dict)
5354
5355    @classmethod
5356    def sql_names(cls):
5357        if cls is Func:
5358            raise NotImplementedError(
5359                "SQL name is only supported by concrete function implementations"
5360            )
5361        if "_sql_names" not in cls.__dict__:
5362            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5363        return cls._sql_names
5364
5365    @classmethod
5366    def sql_name(cls):
5367        return cls.sql_names()[0]
5368
5369    @classmethod
5370    def default_parser_mappings(cls):
5371        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):
5340    @classmethod
5341    def from_arg_list(cls, args):
5342        if cls.is_var_len_args:
5343            all_arg_keys = list(cls.arg_types)
5344            # If this function supports variable length argument treat the last argument as such.
5345            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5346            num_non_var = len(non_var_len_arg_keys)
5347
5348            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5349            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5350        else:
5351            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5352
5353        return cls(**args_dict)
@classmethod
def sql_names(cls):
5355    @classmethod
5356    def sql_names(cls):
5357        if cls is Func:
5358            raise NotImplementedError(
5359                "SQL name is only supported by concrete function implementations"
5360            )
5361        if "_sql_names" not in cls.__dict__:
5362            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5363        return cls._sql_names
@classmethod
def sql_name(cls):
5365    @classmethod
5366    def sql_name(cls):
5367        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5369    @classmethod
5370    def default_parser_mappings(cls):
5371        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5374class AggFunc(Func):
5375    pass
key = 'aggfunc'
class ArrayRemove(Func):
5378class ArrayRemove(Func):
5379    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5382class ParameterizedAgg(AggFunc):
5383    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5386class Abs(Func):
5387    pass
key = 'abs'
class ArgMax(AggFunc):
5390class ArgMax(AggFunc):
5391    arg_types = {"this": True, "expression": True, "count": False}
5392    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5395class ArgMin(AggFunc):
5396    arg_types = {"this": True, "expression": True, "count": False}
5397    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5400class ApproxTopK(AggFunc):
5401    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5404class Flatten(Func):
5405    pass
key = 'flatten'
class Transform(Func):
5409class Transform(Func):
5410    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5413class Anonymous(Func):
5414    arg_types = {"this": True, "expressions": False}
5415    is_var_len_args = True
5416
5417    @property
5418    def name(self) -> str:
5419        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
5417    @property
5418    def name(self) -> str:
5419        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5422class AnonymousAggFunc(AggFunc):
5423    arg_types = {"this": True, "expressions": False}
5424    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5428class CombinedAggFunc(AnonymousAggFunc):
5429    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5432class CombinedParameterizedAgg(ParameterizedAgg):
5433    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5438class Hll(AggFunc):
5439    arg_types = {"this": True, "expressions": False}
5440    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5443class ApproxDistinct(AggFunc):
5444    arg_types = {"this": True, "accuracy": False}
5445    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5448class Apply(Func):
5449    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5452class Array(Func):
5453    arg_types = {"expressions": False, "bracket_notation": False}
5454    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5458class ToArray(Func):
5459    pass
key = 'toarray'
class List(Func):
5463class List(Func):
5464    arg_types = {"expressions": False}
5465    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5469class Pad(Func):
5470    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):
5475class ToChar(Func):
5476    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5481class ToNumber(Func):
5482    arg_types = {
5483        "this": True,
5484        "format": False,
5485        "nlsparam": False,
5486        "precision": False,
5487        "scale": False,
5488    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5492class ToDouble(Func):
5493    arg_types = {
5494        "this": True,
5495        "format": False,
5496    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5499class Columns(Func):
5500    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5504class Convert(Func):
5505    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5509class ConvertToCharset(Func):
5510    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5513class ConvertTimezone(Func):
5514    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):
5517class GenerateSeries(Func):
5518    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):
5524class ExplodingGenerateSeries(GenerateSeries):
5525    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5528class ArrayAgg(AggFunc):
5529    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5532class ArrayUniqueAgg(AggFunc):
5533    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5536class ArrayAll(Func):
5537    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5541class ArrayAny(Func):
5542    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5545class ArrayConcat(Func):
5546    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5547    arg_types = {"this": True, "expressions": False}
5548    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5551class ArrayConcatAgg(AggFunc):
5552    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5555class ArrayConstructCompact(Func):
5556    arg_types = {"expressions": True}
5557    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5560class ArrayContains(Binary, Func):
5561    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5564class ArrayContainsAll(Binary, Func):
5565    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5568class ArrayFilter(Func):
5569    arg_types = {"this": True, "expression": True}
5570    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5573class ArrayToString(Func):
5574    arg_types = {"this": True, "expression": True, "null": False}
5575    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5578class ArrayIntersect(Func):
5579    arg_types = {"expressions": True}
5580    is_var_len_args = True
5581    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5584class StPoint(Func):
5585    arg_types = {"this": True, "expression": True, "null": False}
5586    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5589class StDistance(Func):
5590    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5594class String(Func):
5595    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5598class StringToArray(Func):
5599    arg_types = {"this": True, "expression": False, "null": False}
5600    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
arg_types = {'this': True, 'expression': False, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5603class ArrayOverlaps(Binary, Func):
5604    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5607class ArraySize(Func):
5608    arg_types = {"this": True, "expression": False}
5609    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5612class ArraySort(Func):
5613    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5616class ArraySum(Func):
5617    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5620class ArrayUnionAgg(AggFunc):
5621    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5624class Avg(AggFunc):
5625    pass
key = 'avg'
class AnyValue(AggFunc):
5628class AnyValue(AggFunc):
5629    pass
key = 'anyvalue'
class Lag(AggFunc):
5632class Lag(AggFunc):
5633    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5636class Lead(AggFunc):
5637    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5642class First(AggFunc):
5643    pass
key = 'first'
class Last(AggFunc):
5646class Last(AggFunc):
5647    pass
key = 'last'
class FirstValue(AggFunc):
5650class FirstValue(AggFunc):
5651    pass
key = 'firstvalue'
class LastValue(AggFunc):
5654class LastValue(AggFunc):
5655    pass
key = 'lastvalue'
class NthValue(AggFunc):
5658class NthValue(AggFunc):
5659    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5662class Case(Func):
5663    arg_types = {"this": False, "ifs": True, "default": False}
5664
5665    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5666        instance = maybe_copy(self, copy)
5667        instance.append(
5668            "ifs",
5669            If(
5670                this=maybe_parse(condition, copy=copy, **opts),
5671                true=maybe_parse(then, copy=copy, **opts),
5672            ),
5673        )
5674        return instance
5675
5676    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5677        instance = maybe_copy(self, copy)
5678        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5679        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:
5665    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5666        instance = maybe_copy(self, copy)
5667        instance.append(
5668            "ifs",
5669            If(
5670                this=maybe_parse(condition, copy=copy, **opts),
5671                true=maybe_parse(then, copy=copy, **opts),
5672            ),
5673        )
5674        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5676    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5677        instance = maybe_copy(self, copy)
5678        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5679        return instance
key = 'case'
class Cast(Func):
5682class Cast(Func):
5683    arg_types = {
5684        "this": True,
5685        "to": True,
5686        "format": False,
5687        "safe": False,
5688        "action": False,
5689        "default": False,
5690    }
5691
5692    @property
5693    def name(self) -> str:
5694        return self.this.name
5695
5696    @property
5697    def to(self) -> DataType:
5698        return self.args["to"]
5699
5700    @property
5701    def output_name(self) -> str:
5702        return self.name
5703
5704    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5705        """
5706        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5707        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5708        array<int> != array<float>.
5709
5710        Args:
5711            dtypes: the data types to compare this Cast's DataType to.
5712
5713        Returns:
5714            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5715        """
5716        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5692    @property
5693    def name(self) -> str:
5694        return self.this.name
to: DataType
5696    @property
5697    def to(self) -> DataType:
5698        return self.args["to"]
output_name: str
5700    @property
5701    def output_name(self) -> str:
5702        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, Identifier, Dot, DataType, DataType.Type]) -> bool:
5704    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5705        """
5706        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5707        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5708        array<int> != array<float>.
5709
5710        Args:
5711            dtypes: the data types to compare this Cast's DataType to.
5712
5713        Returns:
5714            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5715        """
5716        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):
5719class TryCast(Cast):
5720    pass
key = 'trycast'
class JSONCast(Cast):
5724class JSONCast(Cast):
5725    pass
key = 'jsoncast'
class Try(Func):
5728class Try(Func):
5729    pass
key = 'try'
class CastToStrType(Func):
5732class CastToStrType(Func):
5733    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5737class TranslateCharacters(Expression):
5738    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5741class Collate(Binary, Func):
5742    pass
key = 'collate'
class Ceil(Func):
5745class Ceil(Func):
5746    arg_types = {"this": True, "decimals": False, "to": False}
5747    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5750class Coalesce(Func):
5751    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5752    is_var_len_args = True
5753    _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):
5756class Chr(Func):
5757    arg_types = {"expressions": True, "charset": False}
5758    is_var_len_args = True
5759    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5762class Concat(Func):
5763    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5764    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5767class ConcatWs(Concat):
5768    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5771class Contains(Func):
5772    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5776class ConnectByRoot(Func):
5777    pass
key = 'connectbyroot'
class Count(AggFunc):
5780class Count(AggFunc):
5781    arg_types = {"this": False, "expressions": False, "big_int": False}
5782    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5785class CountIf(AggFunc):
5786    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5790class Cbrt(Func):
5791    pass
key = 'cbrt'
class CurrentDate(Func):
5794class CurrentDate(Func):
5795    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5798class CurrentDatetime(Func):
5799    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5802class CurrentTime(Func):
5803    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5806class CurrentTimestamp(Func):
5807    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5810class CurrentSchema(Func):
5811    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5814class CurrentUser(Func):
5815    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5818class DateAdd(Func, IntervalOp):
5819    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5822class DateBin(Func, IntervalOp):
5823    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):
5826class DateSub(Func, IntervalOp):
5827    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5830class DateDiff(Func, TimeUnit):
5831    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5832    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):
5835class DateTrunc(Func):
5836    arg_types = {"unit": True, "this": True, "zone": False}
5837
5838    def __init__(self, **args):
5839        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5840        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5841        unabbreviate = args.pop("unabbreviate", True)
5842
5843        unit = args.get("unit")
5844        if isinstance(unit, TimeUnit.VAR_LIKE):
5845            unit_name = unit.name.upper()
5846            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5847                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5848
5849            args["unit"] = Literal.string(unit_name)
5850        elif isinstance(unit, Week):
5851            unit.set("this", Literal.string(unit.this.name.upper()))
5852
5853        super().__init__(**args)
5854
5855    @property
5856    def unit(self) -> Expression:
5857        return self.args["unit"]
DateTrunc(**args)
5838    def __init__(self, **args):
5839        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5840        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5841        unabbreviate = args.pop("unabbreviate", True)
5842
5843        unit = args.get("unit")
5844        if isinstance(unit, TimeUnit.VAR_LIKE):
5845            unit_name = unit.name.upper()
5846            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5847                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5848
5849            args["unit"] = Literal.string(unit_name)
5850        elif isinstance(unit, Week):
5851            unit.set("this", Literal.string(unit.this.name.upper()))
5852
5853        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5855    @property
5856    def unit(self) -> Expression:
5857        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5862class Datetime(Func):
5863    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5866class DatetimeAdd(Func, IntervalOp):
5867    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5870class DatetimeSub(Func, IntervalOp):
5871    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5874class DatetimeDiff(Func, TimeUnit):
5875    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5878class DatetimeTrunc(Func, TimeUnit):
5879    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5882class DayOfWeek(Func):
5883    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5888class DayOfWeekIso(Func):
5889    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5892class DayOfMonth(Func):
5893    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5896class DayOfYear(Func):
5897    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5900class ToDays(Func):
5901    pass
key = 'todays'
class WeekOfYear(Func):
5904class WeekOfYear(Func):
5905    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5908class MonthsBetween(Func):
5909    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5912class MakeInterval(Func):
5913    arg_types = {
5914        "year": False,
5915        "month": False,
5916        "day": False,
5917        "hour": False,
5918        "minute": False,
5919        "second": False,
5920    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5923class LastDay(Func, TimeUnit):
5924    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5925    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5928class Extract(Func):
5929    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5932class Exists(Func, SubqueryPredicate):
5933    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5936class Timestamp(Func):
5937    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5940class TimestampAdd(Func, TimeUnit):
5941    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5944class TimestampSub(Func, TimeUnit):
5945    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5948class TimestampDiff(Func, TimeUnit):
5949    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5950    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5953class TimestampTrunc(Func, TimeUnit):
5954    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5957class TimeAdd(Func, TimeUnit):
5958    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5961class TimeSub(Func, TimeUnit):
5962    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5965class TimeDiff(Func, TimeUnit):
5966    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5969class TimeTrunc(Func, TimeUnit):
5970    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5973class DateFromParts(Func):
5974    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5975    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5978class TimeFromParts(Func):
5979    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5980    arg_types = {
5981        "hour": True,
5982        "min": True,
5983        "sec": True,
5984        "nano": False,
5985        "fractions": False,
5986        "precision": False,
5987    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5990class DateStrToDate(Func):
5991    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5994class DateToDateStr(Func):
5995    pass
key = 'datetodatestr'
class DateToDi(Func):
5998class DateToDi(Func):
5999    pass
key = 'datetodi'
class Date(Func):
6003class Date(Func):
6004    arg_types = {"this": False, "zone": False, "expressions": False}
6005    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6008class Day(Func):
6009    pass
key = 'day'
class Decode(Func):
6012class Decode(Func):
6013    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
6016class DiToDate(Func):
6017    pass
key = 'ditodate'
class Encode(Func):
6020class Encode(Func):
6021    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6024class Exp(Func):
6025    pass
key = 'exp'
class Explode(Func, UDTF):
6029class Explode(Func, UDTF):
6030    arg_types = {"this": True, "expressions": False}
6031    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6035class Inline(Func):
6036    pass
key = 'inline'
class ExplodeOuter(Explode):
6039class ExplodeOuter(Explode):
6040    pass
key = 'explodeouter'
class Posexplode(Explode):
6043class Posexplode(Explode):
6044    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6047class PosexplodeOuter(Posexplode, ExplodeOuter):
6048    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
6051class Unnest(Func, UDTF):
6052    arg_types = {
6053        "expressions": True,
6054        "alias": False,
6055        "offset": False,
6056        "explode_array": False,
6057    }
6058
6059    @property
6060    def selects(self) -> t.List[Expression]:
6061        columns = super().selects
6062        offset = self.args.get("offset")
6063        if offset:
6064            columns = columns + [to_identifier("offset") if offset is True else offset]
6065        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6059    @property
6060    def selects(self) -> t.List[Expression]:
6061        columns = super().selects
6062        offset = self.args.get("offset")
6063        if offset:
6064            columns = columns + [to_identifier("offset") if offset is True else offset]
6065        return columns
key = 'unnest'
class Floor(Func):
6068class Floor(Func):
6069    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6072class FromBase64(Func):
6073    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6076class FeaturesAtTime(Func):
6077    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):
6080class ToBase64(Func):
6081    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6085class FromISO8601Timestamp(Func):
6086    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6089class GapFill(Func):
6090    arg_types = {
6091        "this": True,
6092        "ts_column": True,
6093        "bucket_width": True,
6094        "partitioning_columns": False,
6095        "value_columns": False,
6096        "origin": False,
6097        "ignore_nulls": False,
6098    }
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):
6102class GenerateDateArray(Func):
6103    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6107class GenerateTimestampArray(Func):
6108    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6111class Greatest(Func):
6112    arg_types = {"this": True, "expressions": False}
6113    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6118class OverflowTruncateBehavior(Expression):
6119    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6122class GroupConcat(AggFunc):
6123    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6126class Hex(Func):
6127    pass
key = 'hex'
class LowerHex(Hex):
6130class LowerHex(Hex):
6131    pass
key = 'lowerhex'
class And(Connector, Func):
6134class And(Connector, Func):
6135    pass
key = 'and'
class Or(Connector, Func):
6138class Or(Connector, Func):
6139    pass
key = 'or'
class Xor(Connector, Func):
6142class Xor(Connector, Func):
6143    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6146class If(Func):
6147    arg_types = {"this": True, "true": True, "false": False}
6148    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6151class Nullif(Func):
6152    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6155class Initcap(Func):
6156    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6159class IsAscii(Func):
6160    pass
key = 'isascii'
class IsNan(Func):
6163class IsNan(Func):
6164    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6168class Int64(Func):
6169    pass
key = 'int64'
class IsInf(Func):
6172class IsInf(Func):
6173    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6177class JSON(Expression):
6178    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6181class JSONPath(Expression):
6182    arg_types = {"expressions": True, "escape": False}
6183
6184    @property
6185    def output_name(self) -> str:
6186        last_segment = self.expressions[-1].this
6187        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6184    @property
6185    def output_name(self) -> str:
6186        last_segment = self.expressions[-1].this
6187        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):
6190class JSONPathPart(Expression):
6191    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6194class JSONPathFilter(JSONPathPart):
6195    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6198class JSONPathKey(JSONPathPart):
6199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6202class JSONPathRecursive(JSONPathPart):
6203    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6206class JSONPathRoot(JSONPathPart):
6207    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6210class JSONPathScript(JSONPathPart):
6211    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6214class JSONPathSlice(JSONPathPart):
6215    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6218class JSONPathSelector(JSONPathPart):
6219    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6222class JSONPathSubscript(JSONPathPart):
6223    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6226class JSONPathUnion(JSONPathPart):
6227    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6230class JSONPathWildcard(JSONPathPart):
6231    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6234class FormatJson(Expression):
6235    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6238class JSONKeyValue(Expression):
6239    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6242class JSONObject(Func):
6243    arg_types = {
6244        "expressions": False,
6245        "null_handling": False,
6246        "unique_keys": False,
6247        "return_type": False,
6248        "encoding": False,
6249    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6252class JSONObjectAgg(AggFunc):
6253    arg_types = {
6254        "expressions": False,
6255        "null_handling": False,
6256        "unique_keys": False,
6257        "return_type": False,
6258        "encoding": False,
6259    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6263class JSONBObjectAgg(AggFunc):
6264    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6268class JSONArray(Func):
6269    arg_types = {
6270        "expressions": True,
6271        "null_handling": False,
6272        "return_type": False,
6273        "strict": False,
6274    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6278class JSONArrayAgg(Func):
6279    arg_types = {
6280        "this": True,
6281        "order": False,
6282        "null_handling": False,
6283        "return_type": False,
6284        "strict": False,
6285    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6288class JSONExists(Func):
6289    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):
6294class JSONColumnDef(Expression):
6295    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):
6298class JSONSchema(Expression):
6299    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6303class JSONValue(Expression):
6304    arg_types = {
6305        "this": True,
6306        "path": True,
6307        "returning": False,
6308        "on_condition": False,
6309    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6312class JSONValueArray(Func):
6313    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6317class JSONTable(Func):
6318    arg_types = {
6319        "this": True,
6320        "schema": True,
6321        "path": False,
6322        "error_handling": False,
6323        "empty_handling": False,
6324    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6328class ObjectInsert(Func):
6329    arg_types = {
6330        "this": True,
6331        "key": True,
6332        "value": True,
6333        "update_flag": False,
6334    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6337class OpenJSONColumnDef(Expression):
6338    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):
6341class OpenJSON(Func):
6342    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6345class JSONBContains(Binary, Func):
6346    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6349class JSONBExists(Func):
6350    arg_types = {"this": True, "path": True}
6351    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6354class JSONExtract(Binary, Func):
6355    arg_types = {
6356        "this": True,
6357        "expression": True,
6358        "only_json_types": False,
6359        "expressions": False,
6360        "variant_extract": False,
6361        "json_query": False,
6362        "option": False,
6363        "quote": False,
6364        "on_condition": False,
6365    }
6366    _sql_names = ["JSON_EXTRACT"]
6367    is_var_len_args = True
6368
6369    @property
6370    def output_name(self) -> str:
6371        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
6369    @property
6370    def output_name(self) -> str:
6371        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):
6375class JSONExtractQuote(Expression):
6376    arg_types = {
6377        "option": True,
6378        "scalar": False,
6379    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6382class JSONExtractArray(Func):
6383    arg_types = {"this": True, "expression": False}
6384    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6387class JSONExtractScalar(Binary, Func):
6388    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6389    _sql_names = ["JSON_EXTRACT_SCALAR"]
6390    is_var_len_args = True
6391
6392    @property
6393    def output_name(self) -> str:
6394        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
6392    @property
6393    def output_name(self) -> str:
6394        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):
6397class JSONBExtract(Binary, Func):
6398    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6401class JSONBExtractScalar(Binary, Func):
6402    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6405class JSONFormat(Func):
6406    arg_types = {"this": False, "options": False, "is_json": False}
6407    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6411class JSONArrayContains(Binary, Predicate, Func):
6412    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6415class ParseJSON(Func):
6416    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6417    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6418    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6419    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6422class Least(Func):
6423    arg_types = {"this": True, "expressions": False}
6424    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6427class Left(Func):
6428    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6435class Length(Func):
6436    arg_types = {"this": True, "binary": False, "encoding": False}
6437    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6440class Levenshtein(Func):
6441    arg_types = {
6442        "this": True,
6443        "expression": False,
6444        "ins_cost": False,
6445        "del_cost": False,
6446        "sub_cost": False,
6447        "max_dist": False,
6448    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6451class Ln(Func):
6452    pass
key = 'ln'
class Log(Func):
6455class Log(Func):
6456    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6459class LogicalOr(AggFunc):
6460    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6463class LogicalAnd(AggFunc):
6464    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6467class Lower(Func):
6468    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6471class Map(Func):
6472    arg_types = {"keys": False, "values": False}
6473
6474    @property
6475    def keys(self) -> t.List[Expression]:
6476        keys = self.args.get("keys")
6477        return keys.expressions if keys else []
6478
6479    @property
6480    def values(self) -> t.List[Expression]:
6481        values = self.args.get("values")
6482        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6474    @property
6475    def keys(self) -> t.List[Expression]:
6476        keys = self.args.get("keys")
6477        return keys.expressions if keys else []
values: List[Expression]
6479    @property
6480    def values(self) -> t.List[Expression]:
6481        values = self.args.get("values")
6482        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6486class ToMap(Func):
6487    pass
key = 'tomap'
class MapFromEntries(Func):
6490class MapFromEntries(Func):
6491    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6495class ScopeResolution(Expression):
6496    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6499class Stream(Expression):
6500    pass
key = 'stream'
class StarMap(Func):
6503class StarMap(Func):
6504    pass
key = 'starmap'
class VarMap(Func):
6507class VarMap(Func):
6508    arg_types = {"keys": True, "values": True}
6509    is_var_len_args = True
6510
6511    @property
6512    def keys(self) -> t.List[Expression]:
6513        return self.args["keys"].expressions
6514
6515    @property
6516    def values(self) -> t.List[Expression]:
6517        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6511    @property
6512    def keys(self) -> t.List[Expression]:
6513        return self.args["keys"].expressions
values: List[Expression]
6515    @property
6516    def values(self) -> t.List[Expression]:
6517        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6521class MatchAgainst(Func):
6522    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6525class Max(AggFunc):
6526    arg_types = {"this": True, "expressions": False}
6527    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6530class MD5(Func):
6531    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6535class MD5Digest(Func):
6536    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6539class Median(AggFunc):
6540    pass
key = 'median'
class Min(AggFunc):
6543class Min(AggFunc):
6544    arg_types = {"this": True, "expressions": False}
6545    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6548class Month(Func):
6549    pass
key = 'month'
class AddMonths(Func):
6552class AddMonths(Func):
6553    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6556class Nvl2(Func):
6557    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6560class Normalize(Func):
6561    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6564class Overlay(Func):
6565    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):
6569class Predict(Func):
6570    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6573class Pow(Binary, Func):
6574    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6577class PercentileCont(AggFunc):
6578    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6581class PercentileDisc(AggFunc):
6582    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6585class Quantile(AggFunc):
6586    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6589class ApproxQuantile(Quantile):
6590    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):
6593class Quarter(Func):
6594    pass
key = 'quarter'
class Rand(Func):
6599class Rand(Func):
6600    _sql_names = ["RAND", "RANDOM"]
6601    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6604class Randn(Func):
6605    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6608class RangeN(Func):
6609    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6612class ReadCSV(Func):
6613    _sql_names = ["READ_CSV"]
6614    is_var_len_args = True
6615    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6618class Reduce(Func):
6619    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):
6622class RegexpExtract(Func):
6623    arg_types = {
6624        "this": True,
6625        "expression": True,
6626        "position": False,
6627        "occurrence": False,
6628        "parameters": False,
6629        "group": False,
6630    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6633class RegexpExtractAll(Func):
6634    arg_types = {
6635        "this": True,
6636        "expression": True,
6637        "position": False,
6638        "occurrence": False,
6639        "parameters": False,
6640        "group": False,
6641    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6644class RegexpReplace(Func):
6645    arg_types = {
6646        "this": True,
6647        "expression": True,
6648        "replacement": False,
6649        "position": False,
6650        "occurrence": False,
6651        "modifiers": False,
6652    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6655class RegexpLike(Binary, Func):
6656    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6659class RegexpILike(Binary, Func):
6660    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6665class RegexpSplit(Func):
6666    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6669class Repeat(Func):
6670    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6675class Round(Func):
6676    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6679class RowNumber(Func):
6680    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6683class SafeDivide(Func):
6684    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6687class SHA(Func):
6688    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6691class SHA2(Func):
6692    _sql_names = ["SHA2"]
6693    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6696class Sign(Func):
6697    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6700class SortArray(Func):
6701    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6704class Split(Func):
6705    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6709class SplitPart(Func):
6710    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6715class Substring(Func):
6716    _sql_names = ["SUBSTRING", "SUBSTR"]
6717    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6720class StandardHash(Func):
6721    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6724class StartsWith(Func):
6725    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6726    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
6729class EndsWith(Func):
6730    _sql_names = ["ENDS_WITH", "ENDSWITH"]
6731    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
6734class StrPosition(Func):
6735    arg_types = {
6736        "this": True,
6737        "substr": True,
6738        "position": False,
6739        "occurrence": False,
6740    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6743class StrToDate(Func):
6744    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6747class StrToTime(Func):
6748    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):
6753class StrToUnix(Func):
6754    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6759class StrToMap(Func):
6760    arg_types = {
6761        "this": True,
6762        "pair_delim": False,
6763        "key_value_delim": False,
6764        "duplicate_resolution_callback": False,
6765    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6768class NumberToStr(Func):
6769    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6772class FromBase(Func):
6773    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6776class Struct(Func):
6777    arg_types = {"expressions": False}
6778    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6781class StructExtract(Func):
6782    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6787class Stuff(Func):
6788    _sql_names = ["STUFF", "INSERT"]
6789    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):
6792class Sum(AggFunc):
6793    pass
key = 'sum'
class Sqrt(Func):
6796class Sqrt(Func):
6797    pass
key = 'sqrt'
class Stddev(AggFunc):
6800class Stddev(AggFunc):
6801    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6804class StddevPop(AggFunc):
6805    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6808class StddevSamp(AggFunc):
6809    pass
key = 'stddevsamp'
class Time(Func):
6813class Time(Func):
6814    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6817class TimeToStr(Func):
6818    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):
6821class TimeToTimeStr(Func):
6822    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6825class TimeToUnix(Func):
6826    pass
key = 'timetounix'
class TimeStrToDate(Func):
6829class TimeStrToDate(Func):
6830    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6833class TimeStrToTime(Func):
6834    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6837class TimeStrToUnix(Func):
6838    pass
key = 'timestrtounix'
class Trim(Func):
6841class Trim(Func):
6842    arg_types = {
6843        "this": True,
6844        "expression": False,
6845        "position": False,
6846        "collation": False,
6847    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6850class TsOrDsAdd(Func, TimeUnit):
6851    # return_type is used to correctly cast the arguments of this expression when transpiling it
6852    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6853
6854    @property
6855    def return_type(self) -> DataType:
6856        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
6854    @property
6855    def return_type(self) -> DataType:
6856        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6859class TsOrDsDiff(Func, TimeUnit):
6860    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6863class TsOrDsToDateStr(Func):
6864    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6867class TsOrDsToDate(Func):
6868    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6871class TsOrDsToDatetime(Func):
6872    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6875class TsOrDsToTime(Func):
6876    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6879class TsOrDsToTimestamp(Func):
6880    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6883class TsOrDiToDi(Func):
6884    pass
key = 'tsorditodi'
class Unhex(Func):
6887class Unhex(Func):
6888    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6891class Unicode(Func):
6892    pass
key = 'unicode'
class UnixDate(Func):
6896class UnixDate(Func):
6897    pass
key = 'unixdate'
class UnixToStr(Func):
6900class UnixToStr(Func):
6901    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6906class UnixToTime(Func):
6907    arg_types = {
6908        "this": True,
6909        "scale": False,
6910        "zone": False,
6911        "hours": False,
6912        "minutes": False,
6913        "format": False,
6914    }
6915
6916    SECONDS = Literal.number(0)
6917    DECIS = Literal.number(1)
6918    CENTIS = Literal.number(2)
6919    MILLIS = Literal.number(3)
6920    DECIMILLIS = Literal.number(4)
6921    CENTIMILLIS = Literal.number(5)
6922    MICROS = Literal.number(6)
6923    DECIMICROS = Literal.number(7)
6924    CENTIMICROS = Literal.number(8)
6925    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):
6928class UnixToTimeStr(Func):
6929    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6932class UnixSeconds(Func):
6933    pass
key = 'unixseconds'
class Uuid(Func):
6936class Uuid(Func):
6937    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6938
6939    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6942class TimestampFromParts(Func):
6943    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6944    arg_types = {
6945        "year": True,
6946        "month": True,
6947        "day": True,
6948        "hour": True,
6949        "min": True,
6950        "sec": True,
6951        "nano": False,
6952        "zone": False,
6953        "milli": False,
6954    }
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):
6957class Upper(Func):
6958    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6961class Corr(Binary, AggFunc):
6962    pass
key = 'corr'
class Variance(AggFunc):
6965class Variance(AggFunc):
6966    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6969class VariancePop(AggFunc):
6970    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6973class CovarSamp(Binary, AggFunc):
6974    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6977class CovarPop(Binary, AggFunc):
6978    pass
key = 'covarpop'
class Week(Func):
6981class Week(Func):
6982    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6985class XMLElement(Func):
6986    _sql_names = ["XMLELEMENT"]
6987    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6990class XMLTable(Func):
6991    arg_types = {
6992        "this": True,
6993        "namespaces": False,
6994        "passing": False,
6995        "columns": False,
6996        "by_ref": False,
6997    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7000class XMLNamespace(Expression):
7001    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7005class XMLKeyValueOption(Expression):
7006    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7009class Year(Func):
7010    pass
key = 'year'
class Use(Expression):
7013class Use(Expression):
7014    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7017class Merge(DML):
7018    arg_types = {
7019        "this": True,
7020        "using": True,
7021        "on": True,
7022        "whens": True,
7023        "with": False,
7024        "returning": False,
7025    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7028class When(Expression):
7029    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):
7032class Whens(Expression):
7033    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7034
7035    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7040class NextValueFor(Func):
7041    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7046class Semicolon(Expression):
7047    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7052class TableColumn(Expression):
7053    pass
key = 'tablecolumn'
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 'ArrayIntersect'>, <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 'EndsWith'>, <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 'StDistance'>, <class 'StPoint'>, <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_INTERSECT': <class 'ArrayIntersect'>, 'ARRAY_INTERSECTION': <class 'ArrayIntersect'>, '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'>, 'ENDS_WITH': <class 'EndsWith'>, 'ENDSWITH': <class 'EndsWith'>, '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'>, 'ST_DISTANCE': <class 'StDistance'>, 'ST_POINT': <class 'StPoint'>, 'ST_MAKEPOINT': <class 'StPoint'>, '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:
7093def maybe_parse(
7094    sql_or_expression: ExpOrStr,
7095    *,
7096    into: t.Optional[IntoType] = None,
7097    dialect: DialectType = None,
7098    prefix: t.Optional[str] = None,
7099    copy: bool = False,
7100    **opts,
7101) -> Expression:
7102    """Gracefully handle a possible string or expression.
7103
7104    Example:
7105        >>> maybe_parse("1")
7106        Literal(this=1, is_string=False)
7107        >>> maybe_parse(to_identifier("x"))
7108        Identifier(this=x, quoted=False)
7109
7110    Args:
7111        sql_or_expression: the SQL code string or an expression
7112        into: the SQLGlot Expression to parse into
7113        dialect: the dialect used to parse the input expressions (in the case that an
7114            input expression is a SQL string).
7115        prefix: a string to prefix the sql with before it gets parsed
7116            (automatically includes a space)
7117        copy: whether to copy the expression.
7118        **opts: other options to use to parse the input expressions (again, in the case
7119            that an input expression is a SQL string).
7120
7121    Returns:
7122        Expression: the parsed or given expression.
7123    """
7124    if isinstance(sql_or_expression, Expression):
7125        if copy:
7126            return sql_or_expression.copy()
7127        return sql_or_expression
7128
7129    if sql_or_expression is None:
7130        raise ParseError("SQL cannot be None")
7131
7132    import sqlglot
7133
7134    sql = str(sql_or_expression)
7135    if prefix:
7136        sql = f"{prefix} {sql}"
7137
7138    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):
7149def maybe_copy(instance, copy=True):
7150    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:
7405def union(
7406    *expressions: ExpOrStr,
7407    distinct: bool = True,
7408    dialect: DialectType = None,
7409    copy: bool = True,
7410    **opts,
7411) -> Union:
7412    """
7413    Initializes a syntax tree for the `UNION` operation.
7414
7415    Example:
7416        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7417        'SELECT * FROM foo UNION SELECT * FROM bla'
7418
7419    Args:
7420        expressions: the SQL code strings, corresponding to the `UNION`'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 Union instance.
7429    """
7430    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7431    return _apply_set_operation(
7432        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7433    )

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:
7436def intersect(
7437    *expressions: ExpOrStr,
7438    distinct: bool = True,
7439    dialect: DialectType = None,
7440    copy: bool = True,
7441    **opts,
7442) -> Intersect:
7443    """
7444    Initializes a syntax tree for the `INTERSECT` operation.
7445
7446    Example:
7447        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7448        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7449
7450    Args:
7451        expressions: the SQL code strings, corresponding to the `INTERSECT`'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 Intersect instance.
7460    """
7461    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7462    return _apply_set_operation(
7463        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7464    )

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:
7467def except_(
7468    *expressions: ExpOrStr,
7469    distinct: bool = True,
7470    dialect: DialectType = None,
7471    copy: bool = True,
7472    **opts,
7473) -> Except:
7474    """
7475    Initializes a syntax tree for the `EXCEPT` operation.
7476
7477    Example:
7478        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7479        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7480
7481    Args:
7482        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7483            If `Expression` instances are passed, they will be used as-is.
7484        distinct: set the DISTINCT flag if and only if this is true.
7485        dialect: the dialect used to parse the input expression.
7486        copy: whether to copy the expression.
7487        opts: other options to use to parse the input expressions.
7488
7489    Returns:
7490        The new Except instance.
7491    """
7492    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7493    return _apply_set_operation(
7494        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7495    )

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:
7498def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7499    """
7500    Initializes a syntax tree from one or multiple SELECT expressions.
7501
7502    Example:
7503        >>> select("col1", "col2").from_("tbl").sql()
7504        'SELECT col1, col2 FROM tbl'
7505
7506    Args:
7507        *expressions: the SQL code string to parse as the expressions of a
7508            SELECT statement. If an Expression instance is passed, this is used as-is.
7509        dialect: the dialect used to parse the input expressions (in the case that an
7510            input expression is a SQL string).
7511        **opts: other options to use to parse the input expressions (again, in the case
7512            that an input expression is a SQL string).
7513
7514    Returns:
7515        Select: the syntax tree for the SELECT statement.
7516    """
7517    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:
7520def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7521    """
7522    Initializes a syntax tree from a FROM expression.
7523
7524    Example:
7525        >>> from_("tbl").select("col1", "col2").sql()
7526        'SELECT col1, col2 FROM tbl'
7527
7528    Args:
7529        *expression: the SQL code string to parse as the FROM expressions of a
7530            SELECT statement. If an Expression instance is passed, this is used as-is.
7531        dialect: the dialect used to parse the input expression (in the case that the
7532            input expression is a SQL string).
7533        **opts: other options to use to parse the input expressions (again, in the case
7534            that the input expression is a SQL string).
7535
7536    Returns:
7537        Select: the syntax tree for the SELECT statement.
7538    """
7539    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:
7542def update(
7543    table: str | Table,
7544    properties: t.Optional[dict] = None,
7545    where: t.Optional[ExpOrStr] = None,
7546    from_: t.Optional[ExpOrStr] = None,
7547    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7548    dialect: DialectType = None,
7549    **opts,
7550) -> Update:
7551    """
7552    Creates an update statement.
7553
7554    Example:
7555        >>> 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()
7556        "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"
7557
7558    Args:
7559        properties: dictionary of properties to SET which are
7560            auto converted to sql objects eg None -> NULL
7561        where: sql conditional parsed into a WHERE statement
7562        from_: sql statement parsed into a FROM statement
7563        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7564        dialect: the dialect used to parse the input expressions.
7565        **opts: other options to use to parse the input expressions.
7566
7567    Returns:
7568        Update: the syntax tree for the UPDATE statement.
7569    """
7570    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7571    if properties:
7572        update_expr.set(
7573            "expressions",
7574            [
7575                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7576                for k, v in properties.items()
7577            ],
7578        )
7579    if from_:
7580        update_expr.set(
7581            "from",
7582            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7583        )
7584    if isinstance(where, Condition):
7585        where = Where(this=where)
7586    if where:
7587        update_expr.set(
7588            "where",
7589            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7590        )
7591    if with_:
7592        cte_list = [
7593            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7594            for alias, qry in with_.items()
7595        ]
7596        update_expr.set(
7597            "with",
7598            With(expressions=cte_list),
7599        )
7600    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:
7603def delete(
7604    table: ExpOrStr,
7605    where: t.Optional[ExpOrStr] = None,
7606    returning: t.Optional[ExpOrStr] = None,
7607    dialect: DialectType = None,
7608    **opts,
7609) -> Delete:
7610    """
7611    Builds a delete statement.
7612
7613    Example:
7614        >>> delete("my_table", where="id > 1").sql()
7615        'DELETE FROM my_table WHERE id > 1'
7616
7617    Args:
7618        where: sql conditional parsed into a WHERE statement
7619        returning: sql conditional parsed into a RETURNING statement
7620        dialect: the dialect used to parse the input expressions.
7621        **opts: other options to use to parse the input expressions.
7622
7623    Returns:
7624        Delete: the syntax tree for the DELETE statement.
7625    """
7626    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7627    if where:
7628        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7629    if returning:
7630        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7631    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:
7634def insert(
7635    expression: ExpOrStr,
7636    into: ExpOrStr,
7637    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7638    overwrite: t.Optional[bool] = None,
7639    returning: t.Optional[ExpOrStr] = None,
7640    dialect: DialectType = None,
7641    copy: bool = True,
7642    **opts,
7643) -> Insert:
7644    """
7645    Builds an INSERT statement.
7646
7647    Example:
7648        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7649        'INSERT INTO tbl VALUES (1, 2, 3)'
7650
7651    Args:
7652        expression: the sql string or expression of the INSERT statement
7653        into: the tbl to insert data to.
7654        columns: optionally the table's column names.
7655        overwrite: whether to INSERT OVERWRITE or not.
7656        returning: sql conditional parsed into a RETURNING statement
7657        dialect: the dialect used to parse the input expressions.
7658        copy: whether to copy the expression.
7659        **opts: other options to use to parse the input expressions.
7660
7661    Returns:
7662        Insert: the syntax tree for the INSERT statement.
7663    """
7664    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7665    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7666
7667    if columns:
7668        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7669
7670    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7671
7672    if returning:
7673        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7674
7675    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:
7678def merge(
7679    *when_exprs: ExpOrStr,
7680    into: ExpOrStr,
7681    using: ExpOrStr,
7682    on: ExpOrStr,
7683    returning: t.Optional[ExpOrStr] = None,
7684    dialect: DialectType = None,
7685    copy: bool = True,
7686    **opts,
7687) -> Merge:
7688    """
7689    Builds a MERGE statement.
7690
7691    Example:
7692        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7693        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7694        ...       into="my_table",
7695        ...       using="source_table",
7696        ...       on="my_table.id = source_table.id").sql()
7697        '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)'
7698
7699    Args:
7700        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7701        into: The target table to merge data into.
7702        using: The source table to merge data from.
7703        on: The join condition for the merge.
7704        returning: The columns to return from the merge.
7705        dialect: The dialect used to parse the input expressions.
7706        copy: Whether to copy the expression.
7707        **opts: Other options to use to parse the input expressions.
7708
7709    Returns:
7710        Merge: The syntax tree for the MERGE statement.
7711    """
7712    expressions: t.List[Expression] = []
7713    for when_expr in when_exprs:
7714        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7715        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7716
7717    merge = Merge(
7718        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7719        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7720        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7721        whens=Whens(expressions=expressions),
7722    )
7723    if returning:
7724        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7725
7726    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:
7729def condition(
7730    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7731) -> Condition:
7732    """
7733    Initialize a logical condition expression.
7734
7735    Example:
7736        >>> condition("x=1").sql()
7737        'x = 1'
7738
7739        This is helpful for composing larger logical syntax trees:
7740        >>> where = condition("x=1")
7741        >>> where = where.and_("y=1")
7742        >>> Select().from_("tbl").select("*").where(where).sql()
7743        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7744
7745    Args:
7746        *expression: the SQL code string to parse.
7747            If an Expression instance is passed, this is used as-is.
7748        dialect: the dialect used to parse the input expression (in the case that the
7749            input expression is a SQL string).
7750        copy: Whether to copy `expression` (only applies to expressions).
7751        **opts: other options to use to parse the input expressions (again, in the case
7752            that the input expression is a SQL string).
7753
7754    Returns:
7755        The new Condition instance
7756    """
7757    return maybe_parse(
7758        expression,
7759        into=Condition,
7760        dialect=dialect,
7761        copy=copy,
7762        **opts,
7763    )

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:
7766def and_(
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 AND logical operator.
7775
7776    Example:
7777        >>> and_("x=1", and_("y=1", "z=1")).sql()
7778        'x = 1 AND (y = 1 AND 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, 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:
7796def or_(
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 OR logical operator.
7805
7806    Example:
7807        >>> or_("x=1", or_("y=1", "z=1")).sql()
7808        'x = 1 OR (y = 1 OR 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, 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:
7826def xor(
7827    *expressions: t.Optional[ExpOrStr],
7828    dialect: DialectType = None,
7829    copy: bool = True,
7830    wrap: bool = True,
7831    **opts,
7832) -> Condition:
7833    """
7834    Combine multiple conditions with an XOR logical operator.
7835
7836    Example:
7837        >>> xor("x=1", xor("y=1", "z=1")).sql()
7838        'x = 1 XOR (y = 1 XOR z = 1)'
7839
7840    Args:
7841        *expressions: the SQL code strings to parse.
7842            If an Expression instance is passed, this is used as-is.
7843        dialect: the dialect used to parse the input expression.
7844        copy: whether to copy `expressions` (only applies to Expressions).
7845        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7846            precedence issues, but can be turned off when the produced AST is too deep and
7847            causes recursion-related issues.
7848        **opts: other options to use to parse the input expressions.
7849
7850    Returns:
7851        The new condition
7852    """
7853    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:
7856def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7857    """
7858    Wrap a condition with a NOT operator.
7859
7860    Example:
7861        >>> not_("this_suit='black'").sql()
7862        "NOT this_suit = 'black'"
7863
7864    Args:
7865        expression: the SQL code string to parse.
7866            If an Expression instance is passed, this is used as-is.
7867        dialect: the dialect used to parse the input expression.
7868        copy: whether to copy the expression or not.
7869        **opts: other options to use to parse the input expressions.
7870
7871    Returns:
7872        The new condition.
7873    """
7874    this = condition(
7875        expression,
7876        dialect=dialect,
7877        copy=copy,
7878        **opts,
7879    )
7880    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:
7883def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7884    """
7885    Wrap an expression in parentheses.
7886
7887    Example:
7888        >>> paren("5 + 3").sql()
7889        '(5 + 3)'
7890
7891    Args:
7892        expression: the SQL code string to parse.
7893            If an Expression instance is passed, this is used as-is.
7894        copy: whether to copy the expression or not.
7895
7896    Returns:
7897        The wrapped expression.
7898    """
7899    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):
7915def to_identifier(name, quoted=None, copy=True):
7916    """Builds an identifier.
7917
7918    Args:
7919        name: The name to turn into an identifier.
7920        quoted: Whether to force quote the identifier.
7921        copy: Whether to copy name if it's an Identifier.
7922
7923    Returns:
7924        The identifier ast node.
7925    """
7926
7927    if name is None:
7928        return None
7929
7930    if isinstance(name, Identifier):
7931        identifier = maybe_copy(name, copy)
7932    elif isinstance(name, str):
7933        identifier = Identifier(
7934            this=name,
7935            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7936        )
7937    else:
7938        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7939    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:
7942def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7943    """
7944    Parses a given string into an identifier.
7945
7946    Args:
7947        name: The name to parse into an identifier.
7948        dialect: The dialect to parse against.
7949
7950    Returns:
7951        The identifier ast node.
7952    """
7953    try:
7954        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7955    except (ParseError, TokenError):
7956        expression = to_identifier(name)
7957
7958    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:
7964def to_interval(interval: str | Literal) -> Interval:
7965    """Builds an interval expression from a string like '1 day' or '5 months'."""
7966    if isinstance(interval, Literal):
7967        if not interval.is_string:
7968            raise ValueError("Invalid interval string.")
7969
7970        interval = interval.this
7971
7972    interval = maybe_parse(f"INTERVAL {interval}")
7973    assert isinstance(interval, Interval)
7974    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:
7977def to_table(
7978    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7979) -> Table:
7980    """
7981    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7982    If a table is passed in then that table is returned.
7983
7984    Args:
7985        sql_path: a `[catalog].[schema].[table]` string.
7986        dialect: the source dialect according to which the table name will be parsed.
7987        copy: Whether to copy a table if it is passed in.
7988        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7989
7990    Returns:
7991        A table expression.
7992    """
7993    if isinstance(sql_path, Table):
7994        return maybe_copy(sql_path, copy=copy)
7995
7996    try:
7997        table = maybe_parse(sql_path, into=Table, dialect=dialect)
7998    except ParseError:
7999        catalog, db, this = split_num_words(sql_path, ".", 3)
8000
8001        if not this:
8002            raise
8003
8004        table = table_(this, db=db, catalog=catalog)
8005
8006    for k, v in kwargs.items():
8007        table.set(k, v)
8008
8009    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:
8012def to_column(
8013    sql_path: str | Column,
8014    quoted: t.Optional[bool] = None,
8015    dialect: DialectType = None,
8016    copy: bool = True,
8017    **kwargs,
8018) -> Column:
8019    """
8020    Create a column from a `[table].[column]` sql path. Table is optional.
8021    If a column is passed in then that column is returned.
8022
8023    Args:
8024        sql_path: a `[table].[column]` string.
8025        quoted: Whether or not to force quote identifiers.
8026        dialect: the source dialect according to which the column name will be parsed.
8027        copy: Whether to copy a column if it is passed in.
8028        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8029
8030    Returns:
8031        A column expression.
8032    """
8033    if isinstance(sql_path, Column):
8034        return maybe_copy(sql_path, copy=copy)
8035
8036    try:
8037        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8038    except ParseError:
8039        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8040
8041    for k, v in kwargs.items():
8042        col.set(k, v)
8043
8044    if quoted:
8045        for i in col.find_all(Identifier):
8046            i.set("quoted", True)
8047
8048    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):
8051def alias_(
8052    expression: ExpOrStr,
8053    alias: t.Optional[str | Identifier],
8054    table: bool | t.Sequence[str | Identifier] = False,
8055    quoted: t.Optional[bool] = None,
8056    dialect: DialectType = None,
8057    copy: bool = True,
8058    **opts,
8059):
8060    """Create an Alias expression.
8061
8062    Example:
8063        >>> alias_('foo', 'bar').sql()
8064        'foo AS bar'
8065
8066        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8067        '(SELECT 1, 2) AS bar(a, b)'
8068
8069    Args:
8070        expression: the SQL code strings to parse.
8071            If an Expression instance is passed, this is used as-is.
8072        alias: the alias name to use. If the name has
8073            special characters it is quoted.
8074        table: Whether to create a table alias, can also be a list of columns.
8075        quoted: whether to quote the alias
8076        dialect: the dialect used to parse the input expression.
8077        copy: Whether to copy the expression.
8078        **opts: other options to use to parse the input expressions.
8079
8080    Returns:
8081        Alias: the aliased expression
8082    """
8083    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8084    alias = to_identifier(alias, quoted=quoted)
8085
8086    if table:
8087        table_alias = TableAlias(this=alias)
8088        exp.set("alias", table_alias)
8089
8090        if not isinstance(table, bool):
8091            for column in table:
8092                table_alias.append("columns", to_identifier(column, quoted=quoted))
8093
8094        return exp
8095
8096    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8097    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8098    # for the complete Window expression.
8099    #
8100    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8101
8102    if "alias" in exp.arg_types and not isinstance(exp, Window):
8103        exp.set("alias", alias)
8104        return exp
8105    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:
8108def subquery(
8109    expression: ExpOrStr,
8110    alias: t.Optional[Identifier | str] = None,
8111    dialect: DialectType = None,
8112    **opts,
8113) -> Select:
8114    """
8115    Build a subquery expression that's selected from.
8116
8117    Example:
8118        >>> subquery('select x from tbl', 'bar').select('x').sql()
8119        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8120
8121    Args:
8122        expression: the SQL code strings to parse.
8123            If an Expression instance is passed, this is used as-is.
8124        alias: the alias name to use.
8125        dialect: the dialect used to parse the input expression.
8126        **opts: other options to use to parse the input expressions.
8127
8128    Returns:
8129        A new Select instance with the subquery expression included.
8130    """
8131
8132    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8133    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):
8164def column(
8165    col,
8166    table=None,
8167    db=None,
8168    catalog=None,
8169    *,
8170    fields=None,
8171    quoted=None,
8172    copy=True,
8173):
8174    """
8175    Build a Column.
8176
8177    Args:
8178        col: Column name.
8179        table: Table name.
8180        db: Database name.
8181        catalog: Catalog name.
8182        fields: Additional fields using dots.
8183        quoted: Whether to force quotes on the column's identifiers.
8184        copy: Whether to copy identifiers if passed in.
8185
8186    Returns:
8187        The new Column instance.
8188    """
8189    if not isinstance(col, Star):
8190        col = to_identifier(col, quoted=quoted, copy=copy)
8191
8192    this = Column(
8193        this=col,
8194        table=to_identifier(table, quoted=quoted, copy=copy),
8195        db=to_identifier(db, quoted=quoted, copy=copy),
8196        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8197    )
8198
8199    if fields:
8200        this = Dot.build(
8201            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8202        )
8203    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, Identifier, Dot, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8206def cast(
8207    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8208) -> Cast:
8209    """Cast an expression to a data type.
8210
8211    Example:
8212        >>> cast('x + 1', 'int').sql()
8213        'CAST(x + 1 AS INT)'
8214
8215    Args:
8216        expression: The expression to cast.
8217        to: The datatype to cast to.
8218        copy: Whether to copy the supplied expressions.
8219        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8220            - The expression to be cast is already a exp.Cast expression
8221            - The existing cast is to a type that is logically equivalent to new type
8222
8223            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8224            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8225            and instead just return the original expression `CAST(x as DATETIME)`.
8226
8227            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8228            mapping is applied in the target dialect generator.
8229
8230    Returns:
8231        The new Cast instance.
8232    """
8233    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8234    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8235
8236    # dont re-cast if the expression is already a cast to the correct type
8237    if isinstance(expr, Cast):
8238        from sqlglot.dialects.dialect import Dialect
8239
8240        target_dialect = Dialect.get_or_raise(dialect)
8241        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8242
8243        existing_cast_type: DataType.Type = expr.to.this
8244        new_cast_type: DataType.Type = data_type.this
8245        types_are_equivalent = type_mapping.get(
8246            existing_cast_type, existing_cast_type.value
8247        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8248
8249        if expr.is_type(data_type) or types_are_equivalent:
8250            return expr
8251
8252    expr = Cast(this=expr, to=data_type)
8253    expr.type = data_type
8254
8255    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:
8258def table_(
8259    table: Identifier | str,
8260    db: t.Optional[Identifier | str] = None,
8261    catalog: t.Optional[Identifier | str] = None,
8262    quoted: t.Optional[bool] = None,
8263    alias: t.Optional[Identifier | str] = None,
8264) -> Table:
8265    """Build a Table.
8266
8267    Args:
8268        table: Table name.
8269        db: Database name.
8270        catalog: Catalog name.
8271        quote: Whether to force quotes on the table's identifiers.
8272        alias: Table's alias.
8273
8274    Returns:
8275        The new Table instance.
8276    """
8277    return Table(
8278        this=to_identifier(table, quoted=quoted) if table else None,
8279        db=to_identifier(db, quoted=quoted) if db else None,
8280        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8281        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8282    )

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:
8285def values(
8286    values: t.Iterable[t.Tuple[t.Any, ...]],
8287    alias: t.Optional[str] = None,
8288    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8289) -> Values:
8290    """Build VALUES statement.
8291
8292    Example:
8293        >>> values([(1, '2')]).sql()
8294        "VALUES (1, '2')"
8295
8296    Args:
8297        values: values statements that will be converted to SQL
8298        alias: optional alias
8299        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8300         If either are provided then an alias is also required.
8301
8302    Returns:
8303        Values: the Values expression object
8304    """
8305    if columns and not alias:
8306        raise ValueError("Alias is required when providing columns")
8307
8308    return Values(
8309        expressions=[convert(tup) for tup in values],
8310        alias=(
8311            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8312            if columns
8313            else (TableAlias(this=to_identifier(alias)) if alias else None)
8314        ),
8315    )

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:
8318def var(name: t.Optional[ExpOrStr]) -> Var:
8319    """Build a SQL variable.
8320
8321    Example:
8322        >>> repr(var('x'))
8323        'Var(this=x)'
8324
8325        >>> repr(var(column('x', table='y')))
8326        'Var(this=x)'
8327
8328    Args:
8329        name: The name of the var or an expression who's name will become the var.
8330
8331    Returns:
8332        The new variable node.
8333    """
8334    if not name:
8335        raise ValueError("Cannot convert empty name into var.")
8336
8337    if isinstance(name, Expression):
8338        name = name.name
8339    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:
8342def rename_table(
8343    old_name: str | Table,
8344    new_name: str | Table,
8345    dialect: DialectType = None,
8346) -> Alter:
8347    """Build ALTER TABLE... RENAME... expression
8348
8349    Args:
8350        old_name: The old name of the table
8351        new_name: The new name of the table
8352        dialect: The dialect to parse the table.
8353
8354    Returns:
8355        Alter table expression
8356    """
8357    old_table = to_table(old_name, dialect=dialect)
8358    new_table = to_table(new_name, dialect=dialect)
8359    return Alter(
8360        this=old_table,
8361        kind="TABLE",
8362        actions=[
8363            AlterRename(this=new_table),
8364        ],
8365    )

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:
8368def rename_column(
8369    table_name: str | Table,
8370    old_column_name: str | Column,
8371    new_column_name: str | Column,
8372    exists: t.Optional[bool] = None,
8373    dialect: DialectType = None,
8374) -> Alter:
8375    """Build ALTER TABLE... RENAME COLUMN... expression
8376
8377    Args:
8378        table_name: Name of the table
8379        old_column: The old name of the column
8380        new_column: The new name of the column
8381        exists: Whether to add the `IF EXISTS` clause
8382        dialect: The dialect to parse the table/column.
8383
8384    Returns:
8385        Alter table expression
8386    """
8387    table = to_table(table_name, dialect=dialect)
8388    old_column = to_column(old_column_name, dialect=dialect)
8389    new_column = to_column(new_column_name, dialect=dialect)
8390    return Alter(
8391        this=table,
8392        kind="TABLE",
8393        actions=[
8394            RenameColumn(this=old_column, to=new_column, exists=exists),
8395        ],
8396    )

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:
8399def convert(value: t.Any, copy: bool = False) -> Expression:
8400    """Convert a python value into an expression object.
8401
8402    Raises an error if a conversion is not possible.
8403
8404    Args:
8405        value: A python object.
8406        copy: Whether to copy `value` (only applies to Expressions and collections).
8407
8408    Returns:
8409        The equivalent expression object.
8410    """
8411    if isinstance(value, Expression):
8412        return maybe_copy(value, copy)
8413    if isinstance(value, str):
8414        return Literal.string(value)
8415    if isinstance(value, bool):
8416        return Boolean(this=value)
8417    if value is None or (isinstance(value, float) and math.isnan(value)):
8418        return null()
8419    if isinstance(value, numbers.Number):
8420        return Literal.number(value)
8421    if isinstance(value, bytes):
8422        return HexString(this=value.hex())
8423    if isinstance(value, datetime.datetime):
8424        datetime_literal = Literal.string(value.isoformat(sep=" "))
8425
8426        tz = None
8427        if value.tzinfo:
8428            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8429            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8430            tz = Literal.string(str(value.tzinfo))
8431
8432        return TimeStrToTime(this=datetime_literal, zone=tz)
8433    if isinstance(value, datetime.date):
8434        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8435        return DateStrToDate(this=date_literal)
8436    if isinstance(value, tuple):
8437        if hasattr(value, "_fields"):
8438            return Struct(
8439                expressions=[
8440                    PropertyEQ(
8441                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8442                    )
8443                    for k in value._fields
8444                ]
8445            )
8446        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8447    if isinstance(value, list):
8448        return Array(expressions=[convert(v, copy=copy) for v in value])
8449    if isinstance(value, dict):
8450        return Map(
8451            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8452            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8453        )
8454    if hasattr(value, "__dict__"):
8455        return Struct(
8456            expressions=[
8457                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8458                for k, v in value.__dict__.items()
8459            ]
8460        )
8461    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:
8464def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8465    """
8466    Replace children of an expression with the result of a lambda fun(child) -> exp.
8467    """
8468    for k, v in tuple(expression.args.items()):
8469        is_list_arg = type(v) is list
8470
8471        child_nodes = v if is_list_arg else [v]
8472        new_child_nodes = []
8473
8474        for cn in child_nodes:
8475            if isinstance(cn, Expression):
8476                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8477                    new_child_nodes.append(child_node)
8478            else:
8479                new_child_nodes.append(cn)
8480
8481        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:
8484def replace_tree(
8485    expression: Expression,
8486    fun: t.Callable,
8487    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8488) -> Expression:
8489    """
8490    Replace an entire tree with the result of function calls on each node.
8491
8492    This will be traversed in reverse dfs, so leaves first.
8493    If new nodes are created as a result of function calls, they will also be traversed.
8494    """
8495    stack = list(expression.dfs(prune=prune))
8496
8497    while stack:
8498        node = stack.pop()
8499        new_node = fun(node)
8500
8501        if new_node is not node:
8502            node.replace(new_node)
8503
8504            if isinstance(new_node, Expression):
8505                stack.append(new_node)
8506
8507    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]:
8510def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8511    """
8512    Return all table names referenced through columns in an expression.
8513
8514    Example:
8515        >>> import sqlglot
8516        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8517        ['a', 'c']
8518
8519    Args:
8520        expression: expression to find table names.
8521        exclude: a table name to exclude
8522
8523    Returns:
8524        A list of unique names.
8525    """
8526    return {
8527        table
8528        for table in (column.table for column in expression.find_all(Column))
8529        if table and table != exclude
8530    }

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:
8533def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8534    """Get the full name of a table as a string.
8535
8536    Args:
8537        table: Table expression node or string.
8538        dialect: The dialect to generate the table name for.
8539        identify: Determines when an identifier should be quoted. Possible values are:
8540            False (default): Never quote, except in cases where it's mandatory by the dialect.
8541            True: Always quote.
8542
8543    Examples:
8544        >>> from sqlglot import exp, parse_one
8545        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8546        'a.b.c'
8547
8548    Returns:
8549        The table name.
8550    """
8551
8552    table = maybe_parse(table, into=Table, dialect=dialect)
8553
8554    if not table:
8555        raise ValueError(f"Cannot parse {table}")
8556
8557    return ".".join(
8558        (
8559            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8560            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8561            else part.name
8562        )
8563        for part in table.parts
8564    )

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:
8567def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8568    """Returns a case normalized table name without quotes.
8569
8570    Args:
8571        table: the table to normalize
8572        dialect: the dialect to use for normalization rules
8573        copy: whether to copy the expression.
8574
8575    Examples:
8576        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8577        'A-B.c'
8578    """
8579    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8580
8581    return ".".join(
8582        p.name
8583        for p in normalize_identifiers(
8584            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8585        ).parts
8586    )

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:
8589def replace_tables(
8590    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8591) -> E:
8592    """Replace all tables in expression according to the mapping.
8593
8594    Args:
8595        expression: expression node to be transformed and replaced.
8596        mapping: mapping of table names.
8597        dialect: the dialect of the mapping table
8598        copy: whether to copy the expression.
8599
8600    Examples:
8601        >>> from sqlglot import exp, parse_one
8602        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8603        'SELECT * FROM c /* a.b */'
8604
8605    Returns:
8606        The mapped expression.
8607    """
8608
8609    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8610
8611    def _replace_tables(node: Expression) -> Expression:
8612        if isinstance(node, Table) and node.meta.get("replace") is not False:
8613            original = normalize_table_name(node, dialect=dialect)
8614            new_name = mapping.get(original)
8615
8616            if new_name:
8617                table = to_table(
8618                    new_name,
8619                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8620                    dialect=dialect,
8621                )
8622                table.add_comments([original])
8623                return table
8624        return node
8625
8626    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:
8629def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8630    """Replace placeholders in an expression.
8631
8632    Args:
8633        expression: expression node to be transformed and replaced.
8634        args: positional names that will substitute unnamed placeholders in the given order.
8635        kwargs: keyword arguments that will substitute named placeholders.
8636
8637    Examples:
8638        >>> from sqlglot import exp, parse_one
8639        >>> replace_placeholders(
8640        ...     parse_one("select * from :tbl where ? = ?"),
8641        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8642        ... ).sql()
8643        "SELECT * FROM foo WHERE str_col = 'b'"
8644
8645    Returns:
8646        The mapped expression.
8647    """
8648
8649    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8650        if isinstance(node, Placeholder):
8651            if node.this:
8652                new_name = kwargs.get(node.this)
8653                if new_name is not None:
8654                    return convert(new_name)
8655            else:
8656                try:
8657                    return convert(next(args))
8658                except StopIteration:
8659                    pass
8660        return node
8661
8662    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:
8665def expand(
8666    expression: Expression,
8667    sources: t.Dict[str, Query | t.Callable[[], Query]],
8668    dialect: DialectType = None,
8669    copy: bool = True,
8670) -> Expression:
8671    """Transforms an expression by expanding all referenced sources into subqueries.
8672
8673    Examples:
8674        >>> from sqlglot import parse_one
8675        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8676        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8677
8678        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8679        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8680
8681    Args:
8682        expression: The expression to expand.
8683        sources: A dict of name to query or a callable that provides a query on demand.
8684        dialect: The dialect of the sources dict or the callable.
8685        copy: Whether to copy the expression during transformation. Defaults to True.
8686
8687    Returns:
8688        The transformed expression.
8689    """
8690    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8691
8692    def _expand(node: Expression):
8693        if isinstance(node, Table):
8694            name = normalize_table_name(node, dialect=dialect)
8695            source = normalized_sources.get(name)
8696
8697            if source:
8698                # Create a subquery with the same alias (or table name if no alias)
8699                parsed_source = source() if callable(source) else source
8700                subquery = parsed_source.subquery(node.alias or name)
8701                subquery.comments = [f"source: {name}"]
8702
8703                # Continue expanding within the subquery
8704                return subquery.transform(_expand, copy=False)
8705
8706        return node
8707
8708    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:
8711def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8712    """
8713    Returns a Func expression.
8714
8715    Examples:
8716        >>> func("abs", 5).sql()
8717        'ABS(5)'
8718
8719        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8720        'CAST(5 AS DOUBLE)'
8721
8722    Args:
8723        name: the name of the function to build.
8724        args: the args used to instantiate the function of interest.
8725        copy: whether to copy the argument expressions.
8726        dialect: the source dialect.
8727        kwargs: the kwargs used to instantiate the function of interest.
8728
8729    Note:
8730        The arguments `args` and `kwargs` are mutually exclusive.
8731
8732    Returns:
8733        An instance of the function of interest, or an anonymous function, if `name` doesn't
8734        correspond to an existing `sqlglot.expressions.Func` class.
8735    """
8736    if args and kwargs:
8737        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8738
8739    from sqlglot.dialects.dialect import Dialect
8740
8741    dialect = Dialect.get_or_raise(dialect)
8742
8743    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8744    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8745
8746    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8747    if constructor:
8748        if converted:
8749            if "dialect" in constructor.__code__.co_varnames:
8750                function = constructor(converted, dialect=dialect)
8751            else:
8752                function = constructor(converted)
8753        elif constructor.__name__ == "from_arg_list":
8754            function = constructor.__self__(**kwargs)  # type: ignore
8755        else:
8756            constructor = FUNCTION_BY_NAME.get(name.upper())
8757            if constructor:
8758                function = constructor(**kwargs)
8759            else:
8760                raise ValueError(
8761                    f"Unable to convert '{name}' into a Func. Either manually construct "
8762                    "the Func expression of interest or parse the function call."
8763                )
8764    else:
8765        kwargs = kwargs or {"expressions": converted}
8766        function = Anonymous(this=name, **kwargs)
8767
8768    for error_message in function.error_messages(converted):
8769        raise ValueError(error_message)
8770
8771    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:
8774def case(
8775    expression: t.Optional[ExpOrStr] = None,
8776    **opts,
8777) -> Case:
8778    """
8779    Initialize a CASE statement.
8780
8781    Example:
8782        case().when("a = 1", "foo").else_("bar")
8783
8784    Args:
8785        expression: Optionally, the input expression (not all dialects support this)
8786        **opts: Extra keyword arguments for parsing `expression`
8787    """
8788    if expression is not None:
8789        this = maybe_parse(expression, **opts)
8790    else:
8791        this = None
8792    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:
8795def array(
8796    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8797) -> Array:
8798    """
8799    Returns an array.
8800
8801    Examples:
8802        >>> array(1, 'x').sql()
8803        'ARRAY(1, x)'
8804
8805    Args:
8806        expressions: the expressions to add to the array.
8807        copy: whether to copy the argument expressions.
8808        dialect: the source dialect.
8809        kwargs: the kwargs used to instantiate the function of interest.
8810
8811    Returns:
8812        An array expression.
8813    """
8814    return Array(
8815        expressions=[
8816            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8817            for expression in expressions
8818        ]
8819    )

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:
8822def tuple_(
8823    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8824) -> Tuple:
8825    """
8826    Returns an tuple.
8827
8828    Examples:
8829        >>> tuple_(1, 'x').sql()
8830        '(1, x)'
8831
8832    Args:
8833        expressions: the expressions to add to the tuple.
8834        copy: whether to copy the argument expressions.
8835        dialect: the source dialect.
8836        kwargs: the kwargs used to instantiate the function of interest.
8837
8838    Returns:
8839        A tuple expression.
8840    """
8841    return Tuple(
8842        expressions=[
8843            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8844            for expression in expressions
8845        ]
8846    )

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:
8849def true() -> Boolean:
8850    """
8851    Returns a true Boolean expression.
8852    """
8853    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8856def false() -> Boolean:
8857    """
8858    Returns a false Boolean expression.
8859    """
8860    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8863def null() -> Null:
8864    """
8865    Returns a Null expression.
8866    """
8867    return Null()

Returns a Null expression.

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