Edit on GitHub

Expressions

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

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


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

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • index: the index of an expression if it is inside of a list argument in its parent.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the sqlglot.expressions.DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

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

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

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

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

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

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

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
310    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
311        if self.comments is None:
312            self.comments = []
313
314        if comments:
315            for comment in comments:
316                _, *meta = comment.split(SQLGLOT_META)
317                if meta:
318                    for kv in "".join(meta).split(","):
319                        k, *v = kv.split("=")
320                        value = v[0].strip() if v else True
321                        self.meta[k.strip()] = to_bool(value)
322
323                if not prepend:
324                    self.comments.append(comment)
325
326            if prepend:
327                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
329    def pop_comments(self) -> t.List[str]:
330        comments = self.comments or []
331        self.comments = None
332        return comments
def append(self, arg_key: str, value: Any) -> None:
334    def append(self, arg_key: str, value: t.Any) -> None:
335        """
336        Appends value to arg_key if it's a list or sets it as a new list.
337
338        Args:
339            arg_key (str): name of the list expression arg
340            value (Any): value to append to the list
341        """
342        if type(self.args.get(arg_key)) is not list:
343            self.args[arg_key] = []
344        self._set_parent(arg_key, value)
345        values = self.args[arg_key]
346        if hasattr(value, "parent"):
347            value.index = len(values)
348        values.append(value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set( self, arg_key: str, value: Any, index: Optional[int] = None, overwrite: bool = True) -> None:
350    def set(
351        self,
352        arg_key: str,
353        value: t.Any,
354        index: t.Optional[int] = None,
355        overwrite: bool = True,
356    ) -> None:
357        """
358        Sets arg_key to value.
359
360        Args:
361            arg_key: name of the expression arg.
362            value: value to set the arg to.
363            index: if the arg is a list, this specifies what position to add the value in it.
364            overwrite: assuming an index is given, this determines whether to overwrite the
365                list entry instead of only inserting a new value (i.e., like list.insert).
366        """
367        if index is not None:
368            expressions = self.args.get(arg_key) or []
369
370            if seq_get(expressions, index) is None:
371                return
372            if value is None:
373                expressions.pop(index)
374                for v in expressions[index:]:
375                    v.index = v.index - 1
376                return
377
378            if isinstance(value, list):
379                expressions.pop(index)
380                expressions[index:index] = value
381            elif overwrite:
382                expressions[index] = value
383            else:
384                expressions.insert(index, value)
385
386            value = expressions
387        elif value is None:
388            self.args.pop(arg_key, None)
389            return
390
391        self.args[arg_key] = value
392        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
  • overwrite: assuming an index is given, this determines whether to overwrite the list entry instead of only inserting a new value (i.e., like list.insert).
depth: int
406    @property
407    def depth(self) -> int:
408        """
409        Returns the depth of this tree.
410        """
411        if self.parent:
412            return self.parent.depth + 1
413        return 0

Returns the depth of this tree.

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

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

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

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

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

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

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

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs: if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune: callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

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

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

Returns:

The generator object.

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

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

Returns:

The generator object.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

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

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

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

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

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

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

Returns SQL string representation of this tree.

Arguments:
  • dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
  • opts: other sqlglot.generator.Generator options.
Returns:

The SQL string.

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

Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun: a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy: if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

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

Swap out this expression with a new expression.

For example::

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

The new expression or expressions.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Assert that this Expression is an instance of type_.

If it is NOT an instance of type_, this raises an assertion error. Otherwise, this returns this expression.

Examples:

This is useful for type security in chained expressions:

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

Checks if this expression is valid (e.g. all mandatory args are set).

Arguments:
  • args: a sequence of values that were used to instantiate a Func expression. This is used to check that the provided arguments don't exceed the function argument limit.
Returns:

A list of error messages for all possible errors that were found.

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

Dump this Expression to a JSON-serializable dict.

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

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

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

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1").and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

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

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1").or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

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

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether to copy this object.
Returns:

The new Not instance.

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

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

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

The updated expression.

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

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

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

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

Set the ORDER BY expression.

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

The modified Select expression.

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

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

Append to or set the SELECT expressions.

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

The modified Query expression.

def 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:
1247    def with_(
1248        self: Q,
1249        alias: ExpOrStr,
1250        as_: ExpOrStr,
1251        recursive: t.Optional[bool] = None,
1252        materialized: t.Optional[bool] = None,
1253        append: bool = True,
1254        dialect: DialectType = None,
1255        copy: bool = True,
1256        scalar: bool = False,
1257        **opts,
1258    ) -> Q:
1259        """
1260        Append to or set the common table expressions.
1261
1262        Example:
1263            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1264            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1265
1266        Args:
1267            alias: the SQL code string to parse as the table name.
1268                If an `Expression` instance is passed, this is used as-is.
1269            as_: the SQL code string to parse as the table expression.
1270                If an `Expression` instance is passed, it will be used as-is.
1271            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1272            materialized: set the MATERIALIZED part of the expression.
1273            append: if `True`, add to any existing expressions.
1274                Otherwise, this resets the expressions.
1275            dialect: the dialect used to parse the input expression.
1276            copy: if `False`, modify this expression instance in-place.
1277            scalar: if `True`, this is a scalar common table expression.
1278            opts: other options to use to parse the input expressions.
1279
1280        Returns:
1281            The modified expression.
1282        """
1283        return _apply_cte_builder(
1284            self,
1285            alias,
1286            as_,
1287            recursive=recursive,
1288            materialized=materialized,
1289            append=append,
1290            dialect=dialect,
1291            copy=copy,
1292            scalar=scalar,
1293            **opts,
1294        )

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:
1296    def union(
1297        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1298    ) -> Union:
1299        """
1300        Builds a UNION expression.
1301
1302        Example:
1303            >>> import sqlglot
1304            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1305            'SELECT * FROM foo UNION SELECT * FROM bla'
1306
1307        Args:
1308            expressions: the SQL code strings.
1309                If `Expression` instances are passed, they will be used as-is.
1310            distinct: set the DISTINCT flag if and only if this is true.
1311            dialect: the dialect used to parse the input expression.
1312            opts: other options to use to parse the input expressions.
1313
1314        Returns:
1315            The new Union expression.
1316        """
1317        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:
1319    def intersect(
1320        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1321    ) -> Intersect:
1322        """
1323        Builds an INTERSECT expression.
1324
1325        Example:
1326            >>> import sqlglot
1327            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1328            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1329
1330        Args:
1331            expressions: the SQL code strings.
1332                If `Expression` instances are passed, they will be used as-is.
1333            distinct: set the DISTINCT flag if and only if this is true.
1334            dialect: the dialect used to parse the input expression.
1335            opts: other options to use to parse the input expressions.
1336
1337        Returns:
1338            The new Intersect expression.
1339        """
1340        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:
1342    def except_(
1343        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1344    ) -> Except:
1345        """
1346        Builds an EXCEPT expression.
1347
1348        Example:
1349            >>> import sqlglot
1350            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1351            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1352
1353        Args:
1354            expressions: the SQL code strings.
1355                If `Expression` instance are passed, they will be used as-is.
1356            distinct: set the DISTINCT flag if and only if this is true.
1357            dialect: the dialect used to parse the input expression.
1358            opts: other options to use to parse the input expressions.
1359
1360        Returns:
1361            The new Except expression.
1362        """
1363        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):
1366class UDTF(DerivedTable):
1367    @property
1368    def selects(self) -> t.List[Expression]:
1369        alias = self.args.get("alias")
1370        return alias.columns if alias else []
selects: List[Expression]
1367    @property
1368    def selects(self) -> t.List[Expression]:
1369        alias = self.args.get("alias")
1370        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1373class Cache(Expression):
1374    arg_types = {
1375        "this": True,
1376        "lazy": False,
1377        "options": False,
1378        "expression": False,
1379    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1382class Uncache(Expression):
1383    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1386class Refresh(Expression):
1387    pass
key = 'refresh'
class DDL(Expression):
1390class DDL(Expression):
1391    @property
1392    def ctes(self) -> t.List[CTE]:
1393        """Returns a list of all the CTEs attached to this statement."""
1394        with_ = self.args.get("with")
1395        return with_.expressions if with_ else []
1396
1397    @property
1398    def selects(self) -> t.List[Expression]:
1399        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1400        return self.expression.selects if isinstance(self.expression, Query) else []
1401
1402    @property
1403    def named_selects(self) -> t.List[str]:
1404        """
1405        If this statement contains a query (e.g. a CTAS), this returns the output
1406        names of the query's projections.
1407        """
1408        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1391    @property
1392    def ctes(self) -> t.List[CTE]:
1393        """Returns a list of all the CTEs attached to this statement."""
1394        with_ = self.args.get("with")
1395        return with_.expressions if with_ else []

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

selects: List[Expression]
1397    @property
1398    def selects(self) -> t.List[Expression]:
1399        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1400        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]
1402    @property
1403    def named_selects(self) -> t.List[str]:
1404        """
1405        If this statement contains a query (e.g. a CTAS), this returns the output
1406        names of the query's projections.
1407        """
1408        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):
1411class DML(Expression):
1412    def returning(
1413        self,
1414        expression: ExpOrStr,
1415        dialect: DialectType = None,
1416        copy: bool = True,
1417        **opts,
1418    ) -> "Self":
1419        """
1420        Set the RETURNING expression. Not supported by all dialects.
1421
1422        Example:
1423            >>> delete("tbl").returning("*", dialect="postgres").sql()
1424            'DELETE FROM tbl RETURNING *'
1425
1426        Args:
1427            expression: the SQL code strings to parse.
1428                If an `Expression` instance is passed, it will be used as-is.
1429            dialect: the dialect used to parse the input expressions.
1430            copy: if `False`, modify this expression instance in-place.
1431            opts: other options to use to parse the input expressions.
1432
1433        Returns:
1434            Delete: the modified expression.
1435        """
1436        return _apply_builder(
1437            expression=expression,
1438            instance=self,
1439            arg="returning",
1440            prefix="RETURNING",
1441            dialect=dialect,
1442            copy=copy,
1443            into=Returning,
1444            **opts,
1445        )
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:
1412    def returning(
1413        self,
1414        expression: ExpOrStr,
1415        dialect: DialectType = None,
1416        copy: bool = True,
1417        **opts,
1418    ) -> "Self":
1419        """
1420        Set the RETURNING expression. Not supported by all dialects.
1421
1422        Example:
1423            >>> delete("tbl").returning("*", dialect="postgres").sql()
1424            'DELETE FROM tbl RETURNING *'
1425
1426        Args:
1427            expression: the SQL code strings to parse.
1428                If an `Expression` instance is passed, it will be used as-is.
1429            dialect: the dialect used to parse the input expressions.
1430            copy: if `False`, modify this expression instance in-place.
1431            opts: other options to use to parse the input expressions.
1432
1433        Returns:
1434            Delete: the modified expression.
1435        """
1436        return _apply_builder(
1437            expression=expression,
1438            instance=self,
1439            arg="returning",
1440            prefix="RETURNING",
1441            dialect=dialect,
1442            copy=copy,
1443            into=Returning,
1444            **opts,
1445        )

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):
1448class Create(DDL):
1449    arg_types = {
1450        "with": False,
1451        "this": True,
1452        "kind": True,
1453        "expression": False,
1454        "exists": False,
1455        "properties": False,
1456        "replace": False,
1457        "refresh": False,
1458        "unique": False,
1459        "indexes": False,
1460        "no_schema_binding": False,
1461        "begin": False,
1462        "end": False,
1463        "clone": False,
1464        "concurrently": False,
1465        "clustered": False,
1466    }
1467
1468    @property
1469    def kind(self) -> t.Optional[str]:
1470        kind = self.args.get("kind")
1471        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]
1468    @property
1469    def kind(self) -> t.Optional[str]:
1470        kind = self.args.get("kind")
1471        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1474class SequenceProperties(Expression):
1475    arg_types = {
1476        "increment": False,
1477        "minvalue": False,
1478        "maxvalue": False,
1479        "cache": False,
1480        "start": False,
1481        "owned": False,
1482        "options": False,
1483    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1486class TruncateTable(Expression):
1487    arg_types = {
1488        "expressions": True,
1489        "is_database": False,
1490        "exists": False,
1491        "only": False,
1492        "cluster": False,
1493        "identity": False,
1494        "option": False,
1495        "partition": False,
1496    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1502class Clone(Expression):
1503    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1506class Describe(Expression):
1507    arg_types = {
1508        "this": True,
1509        "style": False,
1510        "kind": False,
1511        "expressions": False,
1512        "partition": False,
1513        "format": False,
1514    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1518class Attach(Expression):
1519    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1523class Detach(Expression):
1524    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1528class Summarize(Expression):
1529    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1532class Kill(Expression):
1533    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1536class Pragma(Expression):
1537    pass
key = 'pragma'
class Declare(Expression):
1540class Declare(Expression):
1541    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1544class DeclareItem(Expression):
1545    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1548class Set(Expression):
1549    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1552class Heredoc(Expression):
1553    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1556class SetItem(Expression):
1557    arg_types = {
1558        "this": False,
1559        "expressions": False,
1560        "kind": False,
1561        "collate": False,  # MySQL SET NAMES statement
1562        "global": False,
1563    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1566class Show(Expression):
1567    arg_types = {
1568        "this": True,
1569        "history": False,
1570        "terse": False,
1571        "target": False,
1572        "offset": False,
1573        "starts_with": False,
1574        "limit": False,
1575        "from": False,
1576        "like": False,
1577        "where": False,
1578        "db": False,
1579        "scope": False,
1580        "scope_kind": False,
1581        "full": False,
1582        "mutex": False,
1583        "query": False,
1584        "channel": False,
1585        "global": False,
1586        "log": False,
1587        "position": False,
1588        "types": False,
1589        "privileges": False,
1590    }
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):
1593class UserDefinedFunction(Expression):
1594    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1597class CharacterSet(Expression):
1598    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1601class RecursiveWithSearch(Expression):
1602    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):
1605class With(Expression):
1606    arg_types = {"expressions": True, "recursive": False, "search": False}
1607
1608    @property
1609    def recursive(self) -> bool:
1610        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1608    @property
1609    def recursive(self) -> bool:
1610        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1613class WithinGroup(Expression):
1614    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1619class CTE(DerivedTable):
1620    arg_types = {
1621        "this": True,
1622        "alias": True,
1623        "scalar": False,
1624        "materialized": False,
1625    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1628class ProjectionDef(Expression):
1629    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1632class TableAlias(Expression):
1633    arg_types = {"this": False, "columns": False}
1634
1635    @property
1636    def columns(self):
1637        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1635    @property
1636    def columns(self):
1637        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1640class BitString(Condition):
1641    pass
key = 'bitstring'
class HexString(Condition):
1644class HexString(Condition):
1645    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1648class ByteString(Condition):
1649    pass
key = 'bytestring'
class RawString(Condition):
1652class RawString(Condition):
1653    pass
key = 'rawstring'
class UnicodeString(Condition):
1656class UnicodeString(Condition):
1657    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1660class Column(Condition):
1661    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1662
1663    @property
1664    def table(self) -> str:
1665        return self.text("table")
1666
1667    @property
1668    def db(self) -> str:
1669        return self.text("db")
1670
1671    @property
1672    def catalog(self) -> str:
1673        return self.text("catalog")
1674
1675    @property
1676    def output_name(self) -> str:
1677        return self.name
1678
1679    @property
1680    def parts(self) -> t.List[Identifier]:
1681        """Return the parts of a column in order catalog, db, table, name."""
1682        return [
1683            t.cast(Identifier, self.args[part])
1684            for part in ("catalog", "db", "table", "this")
1685            if self.args.get(part)
1686        ]
1687
1688    def to_dot(self) -> Dot | Identifier:
1689        """Converts the column into a dot expression."""
1690        parts = self.parts
1691        parent = self.parent
1692
1693        while parent:
1694            if isinstance(parent, Dot):
1695                parts.append(parent.expression)
1696            parent = parent.parent
1697
1698        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
1663    @property
1664    def table(self) -> str:
1665        return self.text("table")
db: str
1667    @property
1668    def db(self) -> str:
1669        return self.text("db")
catalog: str
1671    @property
1672    def catalog(self) -> str:
1673        return self.text("catalog")
output_name: str
1675    @property
1676    def output_name(self) -> str:
1677        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]
1679    @property
1680    def parts(self) -> t.List[Identifier]:
1681        """Return the parts of a column in order catalog, db, table, name."""
1682        return [
1683            t.cast(Identifier, self.args[part])
1684            for part in ("catalog", "db", "table", "this")
1685            if self.args.get(part)
1686        ]

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

def to_dot(self) -> Dot | Identifier:
1688    def to_dot(self) -> Dot | Identifier:
1689        """Converts the column into a dot expression."""
1690        parts = self.parts
1691        parent = self.parent
1692
1693        while parent:
1694            if isinstance(parent, Dot):
1695                parts.append(parent.expression)
1696            parent = parent.parent
1697
1698        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1701class ColumnPosition(Expression):
1702    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1705class ColumnDef(Expression):
1706    arg_types = {
1707        "this": True,
1708        "kind": False,
1709        "constraints": False,
1710        "exists": False,
1711        "position": False,
1712        "default": False,
1713        "output": False,
1714    }
1715
1716    @property
1717    def constraints(self) -> t.List[ColumnConstraint]:
1718        return self.args.get("constraints") or []
1719
1720    @property
1721    def kind(self) -> t.Optional[DataType]:
1722        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1716    @property
1717    def constraints(self) -> t.List[ColumnConstraint]:
1718        return self.args.get("constraints") or []
kind: Optional[DataType]
1720    @property
1721    def kind(self) -> t.Optional[DataType]:
1722        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1725class AlterColumn(Expression):
1726    arg_types = {
1727        "this": True,
1728        "dtype": False,
1729        "collate": False,
1730        "using": False,
1731        "default": False,
1732        "drop": False,
1733        "comment": False,
1734        "allow_null": False,
1735        "visible": False,
1736    }
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):
1740class AlterIndex(Expression):
1741    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1745class AlterDistStyle(Expression):
1746    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1749class AlterSortKey(Expression):
1750    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1753class AlterSet(Expression):
1754    arg_types = {
1755        "expressions": False,
1756        "option": False,
1757        "tablespace": False,
1758        "access_method": False,
1759        "file_format": False,
1760        "copy_options": False,
1761        "tag": False,
1762        "location": False,
1763        "serde": False,
1764    }
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):
1767class RenameColumn(Expression):
1768    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1771class AlterRename(Expression):
1772    pass
key = 'alterrename'
class SwapTable(Expression):
1775class SwapTable(Expression):
1776    pass
key = 'swaptable'
class Comment(Expression):
1779class Comment(Expression):
1780    arg_types = {
1781        "this": True,
1782        "kind": True,
1783        "expression": True,
1784        "exists": False,
1785        "materialized": False,
1786    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1789class Comprehension(Expression):
1790    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):
1794class MergeTreeTTLAction(Expression):
1795    arg_types = {
1796        "this": True,
1797        "delete": False,
1798        "recompress": False,
1799        "to_disk": False,
1800        "to_volume": False,
1801    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1805class MergeTreeTTL(Expression):
1806    arg_types = {
1807        "expressions": True,
1808        "where": False,
1809        "group": False,
1810        "aggregates": False,
1811    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1815class IndexConstraintOption(Expression):
1816    arg_types = {
1817        "key_block_size": False,
1818        "using": False,
1819        "parser": False,
1820        "comment": False,
1821        "visible": False,
1822        "engine_attr": False,
1823        "secondary_engine_attr": False,
1824    }
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):
1827class ColumnConstraint(Expression):
1828    arg_types = {"this": False, "kind": True}
1829
1830    @property
1831    def kind(self) -> ColumnConstraintKind:
1832        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1830    @property
1831    def kind(self) -> ColumnConstraintKind:
1832        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1835class ColumnConstraintKind(Expression):
1836    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1839class AutoIncrementColumnConstraint(ColumnConstraintKind):
1840    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1843class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1844    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1847class CaseSpecificColumnConstraint(ColumnConstraintKind):
1848    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1851class CharacterSetColumnConstraint(ColumnConstraintKind):
1852    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1855class CheckColumnConstraint(ColumnConstraintKind):
1856    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1859class ClusteredColumnConstraint(ColumnConstraintKind):
1860    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1863class CollateColumnConstraint(ColumnConstraintKind):
1864    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1867class CommentColumnConstraint(ColumnConstraintKind):
1868    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1871class CompressColumnConstraint(ColumnConstraintKind):
1872    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1875class DateFormatColumnConstraint(ColumnConstraintKind):
1876    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1879class DefaultColumnConstraint(ColumnConstraintKind):
1880    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1883class EncodeColumnConstraint(ColumnConstraintKind):
1884    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1888class ExcludeColumnConstraint(ColumnConstraintKind):
1889    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1892class EphemeralColumnConstraint(ColumnConstraintKind):
1893    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1896class WithOperator(Expression):
1897    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1900class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1901    # this: True -> ALWAYS, this: False -> BY DEFAULT
1902    arg_types = {
1903        "this": False,
1904        "expression": False,
1905        "on_null": False,
1906        "start": False,
1907        "increment": False,
1908        "minvalue": False,
1909        "maxvalue": False,
1910        "cycle": False,
1911    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1914class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1915    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1920class IndexColumnConstraint(ColumnConstraintKind):
1921    arg_types = {
1922        "this": False,
1923        "expressions": False,
1924        "kind": False,
1925        "index_type": False,
1926        "options": False,
1927        "expression": False,  # Clickhouse
1928        "granularity": False,
1929    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1932class InlineLengthColumnConstraint(ColumnConstraintKind):
1933    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1936class NonClusteredColumnConstraint(ColumnConstraintKind):
1937    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1940class NotForReplicationColumnConstraint(ColumnConstraintKind):
1941    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1945class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1946    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1949class NotNullColumnConstraint(ColumnConstraintKind):
1950    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1954class OnUpdateColumnConstraint(ColumnConstraintKind):
1955    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1959class TransformColumnConstraint(ColumnConstraintKind):
1960    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1963class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1964    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1967class TitleColumnConstraint(ColumnConstraintKind):
1968    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1971class UniqueColumnConstraint(ColumnConstraintKind):
1972    arg_types = {
1973        "this": False,
1974        "index_type": False,
1975        "on_conflict": False,
1976        "nulls": False,
1977        "options": False,
1978    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1981class UppercaseColumnConstraint(ColumnConstraintKind):
1982    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1986class WatermarkColumnConstraint(Expression):
1987    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1990class PathColumnConstraint(ColumnConstraintKind):
1991    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1995class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1996    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2001class ComputedColumnConstraint(ColumnConstraintKind):
2002    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2005class Constraint(Expression):
2006    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2009class Delete(DML):
2010    arg_types = {
2011        "with": False,
2012        "this": False,
2013        "using": False,
2014        "where": False,
2015        "returning": False,
2016        "limit": False,
2017        "tables": False,  # Multiple-Table Syntax (MySQL)
2018        "cluster": False,  # Clickhouse
2019    }
2020
2021    def delete(
2022        self,
2023        table: ExpOrStr,
2024        dialect: DialectType = None,
2025        copy: bool = True,
2026        **opts,
2027    ) -> Delete:
2028        """
2029        Create a DELETE expression or replace the table on an existing DELETE expression.
2030
2031        Example:
2032            >>> delete("tbl").sql()
2033            'DELETE FROM tbl'
2034
2035        Args:
2036            table: the table from which to delete.
2037            dialect: the dialect used to parse the input expression.
2038            copy: if `False`, modify this expression instance in-place.
2039            opts: other options to use to parse the input expressions.
2040
2041        Returns:
2042            Delete: the modified expression.
2043        """
2044        return _apply_builder(
2045            expression=table,
2046            instance=self,
2047            arg="this",
2048            dialect=dialect,
2049            into=Table,
2050            copy=copy,
2051            **opts,
2052        )
2053
2054    def where(
2055        self,
2056        *expressions: t.Optional[ExpOrStr],
2057        append: bool = True,
2058        dialect: DialectType = None,
2059        copy: bool = True,
2060        **opts,
2061    ) -> Delete:
2062        """
2063        Append to or set the WHERE expressions.
2064
2065        Example:
2066            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2067            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2068
2069        Args:
2070            *expressions: the SQL code strings to parse.
2071                If an `Expression` instance is passed, it will be used as-is.
2072                Multiple expressions are combined with an AND operator.
2073            append: if `True`, AND the new expressions to any existing expression.
2074                Otherwise, this resets the expression.
2075            dialect: the dialect used to parse the input expressions.
2076            copy: if `False`, modify this expression instance in-place.
2077            opts: other options to use to parse the input expressions.
2078
2079        Returns:
2080            Delete: the modified expression.
2081        """
2082        return _apply_conjunction_builder(
2083            *expressions,
2084            instance=self,
2085            arg="where",
2086            append=append,
2087            into=Where,
2088            dialect=dialect,
2089            copy=copy,
2090            **opts,
2091        )
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:
2021    def delete(
2022        self,
2023        table: ExpOrStr,
2024        dialect: DialectType = None,
2025        copy: bool = True,
2026        **opts,
2027    ) -> Delete:
2028        """
2029        Create a DELETE expression or replace the table on an existing DELETE expression.
2030
2031        Example:
2032            >>> delete("tbl").sql()
2033            'DELETE FROM tbl'
2034
2035        Args:
2036            table: the table from which to delete.
2037            dialect: the dialect used to parse the input expression.
2038            copy: if `False`, modify this expression instance in-place.
2039            opts: other options to use to parse the input expressions.
2040
2041        Returns:
2042            Delete: the modified expression.
2043        """
2044        return _apply_builder(
2045            expression=table,
2046            instance=self,
2047            arg="this",
2048            dialect=dialect,
2049            into=Table,
2050            copy=copy,
2051            **opts,
2052        )

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:
2054    def where(
2055        self,
2056        *expressions: t.Optional[ExpOrStr],
2057        append: bool = True,
2058        dialect: DialectType = None,
2059        copy: bool = True,
2060        **opts,
2061    ) -> Delete:
2062        """
2063        Append to or set the WHERE expressions.
2064
2065        Example:
2066            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2067            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2068
2069        Args:
2070            *expressions: the SQL code strings to parse.
2071                If an `Expression` instance is passed, it will be used as-is.
2072                Multiple expressions are combined with an AND operator.
2073            append: if `True`, AND the new expressions to any existing expression.
2074                Otherwise, this resets the expression.
2075            dialect: the dialect used to parse the input expressions.
2076            copy: if `False`, modify this expression instance in-place.
2077            opts: other options to use to parse the input expressions.
2078
2079        Returns:
2080            Delete: the modified expression.
2081        """
2082        return _apply_conjunction_builder(
2083            *expressions,
2084            instance=self,
2085            arg="where",
2086            append=append,
2087            into=Where,
2088            dialect=dialect,
2089            copy=copy,
2090            **opts,
2091        )

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):
2094class Drop(Expression):
2095    arg_types = {
2096        "this": False,
2097        "kind": False,
2098        "expressions": False,
2099        "exists": False,
2100        "temporary": False,
2101        "materialized": False,
2102        "cascade": False,
2103        "constraints": False,
2104        "purge": False,
2105        "cluster": False,
2106        "concurrently": False,
2107    }
2108
2109    @property
2110    def kind(self) -> t.Optional[str]:
2111        kind = self.args.get("kind")
2112        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]
2109    @property
2110    def kind(self) -> t.Optional[str]:
2111        kind = self.args.get("kind")
2112        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2116class Export(Expression):
2117    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2120class Filter(Expression):
2121    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2124class Check(Expression):
2125    pass
key = 'check'
class Changes(Expression):
2128class Changes(Expression):
2129    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2133class Connect(Expression):
2134    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2137class CopyParameter(Expression):
2138    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2141class Copy(DML):
2142    arg_types = {
2143        "this": True,
2144        "kind": True,
2145        "files": True,
2146        "credentials": False,
2147        "format": False,
2148        "params": False,
2149    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2152class Credentials(Expression):
2153    arg_types = {
2154        "credentials": False,
2155        "encryption": False,
2156        "storage": False,
2157        "iam_role": False,
2158        "region": False,
2159    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2162class Prior(Expression):
2163    pass
key = 'prior'
class Directory(Expression):
2166class Directory(Expression):
2167    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2168    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2171class ForeignKey(Expression):
2172    arg_types = {
2173        "expressions": False,
2174        "reference": False,
2175        "delete": False,
2176        "update": False,
2177        "options": False,
2178    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2181class ColumnPrefix(Expression):
2182    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2185class PrimaryKey(Expression):
2186    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2191class Into(Expression):
2192    arg_types = {
2193        "this": False,
2194        "temporary": False,
2195        "unlogged": False,
2196        "bulk_collect": False,
2197        "expressions": False,
2198    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2201class From(Expression):
2202    @property
2203    def name(self) -> str:
2204        return self.this.name
2205
2206    @property
2207    def alias_or_name(self) -> str:
2208        return self.this.alias_or_name
name: str
2202    @property
2203    def name(self) -> str:
2204        return self.this.name
alias_or_name: str
2206    @property
2207    def alias_or_name(self) -> str:
2208        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2211class Having(Expression):
2212    pass
key = 'having'
class Hint(Expression):
2215class Hint(Expression):
2216    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2219class JoinHint(Expression):
2220    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2223class Identifier(Expression):
2224    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2225
2226    @property
2227    def quoted(self) -> bool:
2228        return bool(self.args.get("quoted"))
2229
2230    @property
2231    def hashable_args(self) -> t.Any:
2232        return (self.this, self.quoted)
2233
2234    @property
2235    def output_name(self) -> str:
2236        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2226    @property
2227    def quoted(self) -> bool:
2228        return bool(self.args.get("quoted"))
hashable_args: Any
2230    @property
2231    def hashable_args(self) -> t.Any:
2232        return (self.this, self.quoted)
output_name: str
2234    @property
2235    def output_name(self) -> str:
2236        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):
2240class Opclass(Expression):
2241    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2244class Index(Expression):
2245    arg_types = {
2246        "this": False,
2247        "table": False,
2248        "unique": False,
2249        "primary": False,
2250        "amp": False,  # teradata
2251        "params": False,
2252    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2255class IndexParameters(Expression):
2256    arg_types = {
2257        "using": False,
2258        "include": False,
2259        "columns": False,
2260        "with_storage": False,
2261        "partition_by": False,
2262        "tablespace": False,
2263        "where": False,
2264        "on": False,
2265    }
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):
2268class Insert(DDL, DML):
2269    arg_types = {
2270        "hint": False,
2271        "with": False,
2272        "is_function": False,
2273        "this": False,
2274        "expression": False,
2275        "conflict": False,
2276        "returning": False,
2277        "overwrite": False,
2278        "exists": False,
2279        "alternative": False,
2280        "where": False,
2281        "ignore": False,
2282        "by_name": False,
2283        "stored": False,
2284        "partition": False,
2285        "settings": False,
2286        "source": False,
2287    }
2288
2289    def with_(
2290        self,
2291        alias: ExpOrStr,
2292        as_: ExpOrStr,
2293        recursive: t.Optional[bool] = None,
2294        materialized: t.Optional[bool] = None,
2295        append: bool = True,
2296        dialect: DialectType = None,
2297        copy: bool = True,
2298        **opts,
2299    ) -> Insert:
2300        """
2301        Append to or set the common table expressions.
2302
2303        Example:
2304            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2305            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2306
2307        Args:
2308            alias: the SQL code string to parse as the table name.
2309                If an `Expression` instance is passed, this is used as-is.
2310            as_: the SQL code string to parse as the table expression.
2311                If an `Expression` instance is passed, it will be used as-is.
2312            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2313            materialized: set the MATERIALIZED part of the expression.
2314            append: if `True`, add to any existing expressions.
2315                Otherwise, this resets the expressions.
2316            dialect: the dialect used to parse the input expression.
2317            copy: if `False`, modify this expression instance in-place.
2318            opts: other options to use to parse the input expressions.
2319
2320        Returns:
2321            The modified expression.
2322        """
2323        return _apply_cte_builder(
2324            self,
2325            alias,
2326            as_,
2327            recursive=recursive,
2328            materialized=materialized,
2329            append=append,
2330            dialect=dialect,
2331            copy=copy,
2332            **opts,
2333        )
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:
2289    def with_(
2290        self,
2291        alias: ExpOrStr,
2292        as_: ExpOrStr,
2293        recursive: t.Optional[bool] = None,
2294        materialized: t.Optional[bool] = None,
2295        append: bool = True,
2296        dialect: DialectType = None,
2297        copy: bool = True,
2298        **opts,
2299    ) -> Insert:
2300        """
2301        Append to or set the common table expressions.
2302
2303        Example:
2304            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2305            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2306
2307        Args:
2308            alias: the SQL code string to parse as the table name.
2309                If an `Expression` instance is passed, this is used as-is.
2310            as_: the SQL code string to parse as the table expression.
2311                If an `Expression` instance is passed, it will be used as-is.
2312            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2313            materialized: set the MATERIALIZED part of the expression.
2314            append: if `True`, add to any existing expressions.
2315                Otherwise, this resets the expressions.
2316            dialect: the dialect used to parse the input expression.
2317            copy: if `False`, modify this expression instance in-place.
2318            opts: other options to use to parse the input expressions.
2319
2320        Returns:
2321            The modified expression.
2322        """
2323        return _apply_cte_builder(
2324            self,
2325            alias,
2326            as_,
2327            recursive=recursive,
2328            materialized=materialized,
2329            append=append,
2330            dialect=dialect,
2331            copy=copy,
2332            **opts,
2333        )

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):
2336class ConditionalInsert(Expression):
2337    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2340class MultitableInserts(Expression):
2341    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2344class OnConflict(Expression):
2345    arg_types = {
2346        "duplicate": False,
2347        "expressions": False,
2348        "action": False,
2349        "conflict_keys": False,
2350        "constraint": False,
2351        "where": False,
2352    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2355class OnCondition(Expression):
2356    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2359class Returning(Expression):
2360    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2364class Introducer(Expression):
2365    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2369class National(Expression):
2370    pass
key = 'national'
class LoadData(Expression):
2373class LoadData(Expression):
2374    arg_types = {
2375        "this": True,
2376        "local": False,
2377        "overwrite": False,
2378        "inpath": True,
2379        "partition": False,
2380        "input_format": False,
2381        "serde": False,
2382    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2385class Partition(Expression):
2386    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2389class PartitionRange(Expression):
2390    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2394class PartitionId(Expression):
2395    pass
key = 'partitionid'
class Fetch(Expression):
2398class Fetch(Expression):
2399    arg_types = {
2400        "direction": False,
2401        "count": False,
2402        "limit_options": False,
2403    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2406class Grant(Expression):
2407    arg_types = {
2408        "privileges": True,
2409        "kind": False,
2410        "securable": True,
2411        "principals": True,
2412        "grant_option": False,
2413    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2416class Group(Expression):
2417    arg_types = {
2418        "expressions": False,
2419        "grouping_sets": False,
2420        "cube": False,
2421        "rollup": False,
2422        "totals": False,
2423        "all": False,
2424    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2427class Cube(Expression):
2428    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2431class Rollup(Expression):
2432    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2435class GroupingSets(Expression):
2436    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2439class Lambda(Expression):
2440    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2443class Limit(Expression):
2444    arg_types = {
2445        "this": False,
2446        "expression": True,
2447        "offset": False,
2448        "limit_options": False,
2449        "expressions": False,
2450    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2453class LimitOptions(Expression):
2454    arg_types = {
2455        "percent": False,
2456        "rows": False,
2457        "with_ties": False,
2458    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2461class Literal(Condition):
2462    arg_types = {"this": True, "is_string": True}
2463
2464    @property
2465    def hashable_args(self) -> t.Any:
2466        return (self.this, self.args.get("is_string"))
2467
2468    @classmethod
2469    def number(cls, number) -> Literal:
2470        return cls(this=str(number), is_string=False)
2471
2472    @classmethod
2473    def string(cls, string) -> Literal:
2474        return cls(this=str(string), is_string=True)
2475
2476    @property
2477    def output_name(self) -> str:
2478        return self.name
2479
2480    def to_py(self) -> int | str | Decimal:
2481        if self.is_number:
2482            try:
2483                return int(self.this)
2484            except ValueError:
2485                return Decimal(self.this)
2486        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2464    @property
2465    def hashable_args(self) -> t.Any:
2466        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2468    @classmethod
2469    def number(cls, number) -> Literal:
2470        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2472    @classmethod
2473    def string(cls, string) -> Literal:
2474        return cls(this=str(string), is_string=True)
output_name: str
2476    @property
2477    def output_name(self) -> str:
2478        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:
2480    def to_py(self) -> int | str | Decimal:
2481        if self.is_number:
2482            try:
2483                return int(self.this)
2484            except ValueError:
2485                return Decimal(self.this)
2486        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2489class Join(Expression):
2490    arg_types = {
2491        "this": True,
2492        "on": False,
2493        "side": False,
2494        "kind": False,
2495        "using": False,
2496        "method": False,
2497        "global": False,
2498        "hint": False,
2499        "match_condition": False,  # Snowflake
2500        "expressions": False,
2501        "pivots": False,
2502    }
2503
2504    @property
2505    def method(self) -> str:
2506        return self.text("method").upper()
2507
2508    @property
2509    def kind(self) -> str:
2510        return self.text("kind").upper()
2511
2512    @property
2513    def side(self) -> str:
2514        return self.text("side").upper()
2515
2516    @property
2517    def hint(self) -> str:
2518        return self.text("hint").upper()
2519
2520    @property
2521    def alias_or_name(self) -> str:
2522        return self.this.alias_or_name
2523
2524    @property
2525    def is_semi_or_anti_join(self) -> bool:
2526        return self.kind in ("SEMI", "ANTI")
2527
2528    def on(
2529        self,
2530        *expressions: t.Optional[ExpOrStr],
2531        append: bool = True,
2532        dialect: DialectType = None,
2533        copy: bool = True,
2534        **opts,
2535    ) -> Join:
2536        """
2537        Append to or set the ON expressions.
2538
2539        Example:
2540            >>> import sqlglot
2541            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2542            'JOIN x ON y = 1'
2543
2544        Args:
2545            *expressions: the SQL code strings to parse.
2546                If an `Expression` instance is passed, it will be used as-is.
2547                Multiple expressions are combined with an AND operator.
2548            append: if `True`, AND the new expressions to any existing expression.
2549                Otherwise, this resets the expression.
2550            dialect: the dialect used to parse the input expressions.
2551            copy: if `False`, modify this expression instance in-place.
2552            opts: other options to use to parse the input expressions.
2553
2554        Returns:
2555            The modified Join expression.
2556        """
2557        join = _apply_conjunction_builder(
2558            *expressions,
2559            instance=self,
2560            arg="on",
2561            append=append,
2562            dialect=dialect,
2563            copy=copy,
2564            **opts,
2565        )
2566
2567        if join.kind == "CROSS":
2568            join.set("kind", None)
2569
2570        return join
2571
2572    def using(
2573        self,
2574        *expressions: t.Optional[ExpOrStr],
2575        append: bool = True,
2576        dialect: DialectType = None,
2577        copy: bool = True,
2578        **opts,
2579    ) -> Join:
2580        """
2581        Append to or set the USING expressions.
2582
2583        Example:
2584            >>> import sqlglot
2585            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2586            'JOIN x USING (foo, bla)'
2587
2588        Args:
2589            *expressions: the SQL code strings to parse.
2590                If an `Expression` instance is passed, it will be used as-is.
2591            append: if `True`, concatenate the new expressions to the existing "using" list.
2592                Otherwise, this resets the expression.
2593            dialect: the dialect used to parse the input expressions.
2594            copy: if `False`, modify this expression instance in-place.
2595            opts: other options to use to parse the input expressions.
2596
2597        Returns:
2598            The modified Join expression.
2599        """
2600        join = _apply_list_builder(
2601            *expressions,
2602            instance=self,
2603            arg="using",
2604            append=append,
2605            dialect=dialect,
2606            copy=copy,
2607            **opts,
2608        )
2609
2610        if join.kind == "CROSS":
2611            join.set("kind", None)
2612
2613        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
2504    @property
2505    def method(self) -> str:
2506        return self.text("method").upper()
kind: str
2508    @property
2509    def kind(self) -> str:
2510        return self.text("kind").upper()
side: str
2512    @property
2513    def side(self) -> str:
2514        return self.text("side").upper()
hint: str
2516    @property
2517    def hint(self) -> str:
2518        return self.text("hint").upper()
alias_or_name: str
2520    @property
2521    def alias_or_name(self) -> str:
2522        return self.this.alias_or_name
is_semi_or_anti_join: bool
2524    @property
2525    def is_semi_or_anti_join(self) -> bool:
2526        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:
2528    def on(
2529        self,
2530        *expressions: t.Optional[ExpOrStr],
2531        append: bool = True,
2532        dialect: DialectType = None,
2533        copy: bool = True,
2534        **opts,
2535    ) -> Join:
2536        """
2537        Append to or set the ON expressions.
2538
2539        Example:
2540            >>> import sqlglot
2541            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2542            'JOIN x ON y = 1'
2543
2544        Args:
2545            *expressions: the SQL code strings to parse.
2546                If an `Expression` instance is passed, it will be used as-is.
2547                Multiple expressions are combined with an AND operator.
2548            append: if `True`, AND the new expressions to any existing expression.
2549                Otherwise, this resets the expression.
2550            dialect: the dialect used to parse the input expressions.
2551            copy: if `False`, modify this expression instance in-place.
2552            opts: other options to use to parse the input expressions.
2553
2554        Returns:
2555            The modified Join expression.
2556        """
2557        join = _apply_conjunction_builder(
2558            *expressions,
2559            instance=self,
2560            arg="on",
2561            append=append,
2562            dialect=dialect,
2563            copy=copy,
2564            **opts,
2565        )
2566
2567        if join.kind == "CROSS":
2568            join.set("kind", None)
2569
2570        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:
2572    def using(
2573        self,
2574        *expressions: t.Optional[ExpOrStr],
2575        append: bool = True,
2576        dialect: DialectType = None,
2577        copy: bool = True,
2578        **opts,
2579    ) -> Join:
2580        """
2581        Append to or set the USING expressions.
2582
2583        Example:
2584            >>> import sqlglot
2585            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2586            'JOIN x USING (foo, bla)'
2587
2588        Args:
2589            *expressions: the SQL code strings to parse.
2590                If an `Expression` instance is passed, it will be used as-is.
2591            append: if `True`, concatenate the new expressions to the existing "using" list.
2592                Otherwise, this resets the expression.
2593            dialect: the dialect used to parse the input expressions.
2594            copy: if `False`, modify this expression instance in-place.
2595            opts: other options to use to parse the input expressions.
2596
2597        Returns:
2598            The modified Join expression.
2599        """
2600        join = _apply_list_builder(
2601            *expressions,
2602            instance=self,
2603            arg="using",
2604            append=append,
2605            dialect=dialect,
2606            copy=copy,
2607            **opts,
2608        )
2609
2610        if join.kind == "CROSS":
2611            join.set("kind", None)
2612
2613        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):
2616class Lateral(UDTF):
2617    arg_types = {
2618        "this": True,
2619        "view": False,
2620        "outer": False,
2621        "alias": False,
2622        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2623        "ordinality": False,
2624    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2629class TableFromRows(UDTF):
2630    arg_types = {
2631        "this": True,
2632        "alias": False,
2633        "joins": False,
2634        "pivots": False,
2635        "sample": False,
2636    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2639class MatchRecognizeMeasure(Expression):
2640    arg_types = {
2641        "this": True,
2642        "window_frame": False,
2643    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2646class MatchRecognize(Expression):
2647    arg_types = {
2648        "partition_by": False,
2649        "order": False,
2650        "measures": False,
2651        "rows": False,
2652        "after": False,
2653        "pattern": False,
2654        "define": False,
2655        "alias": False,
2656    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2661class Final(Expression):
2662    pass
key = 'final'
class Offset(Expression):
2665class Offset(Expression):
2666    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2669class Order(Expression):
2670    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2674class WithFill(Expression):
2675    arg_types = {
2676        "from": False,
2677        "to": False,
2678        "step": False,
2679        "interpolate": False,
2680    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2685class Cluster(Order):
2686    pass
key = 'cluster'
class Distribute(Order):
2689class Distribute(Order):
2690    pass
key = 'distribute'
class Sort(Order):
2693class Sort(Order):
2694    pass
key = 'sort'
class Ordered(Expression):
2697class Ordered(Expression):
2698    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2699
2700    @property
2701    def name(self) -> str:
2702        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2700    @property
2701    def name(self) -> str:
2702        return self.this.name
key = 'ordered'
class Property(Expression):
2705class Property(Expression):
2706    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2709class GrantPrivilege(Expression):
2710    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2713class GrantPrincipal(Expression):
2714    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2717class AllowedValuesProperty(Expression):
2718    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2721class AlgorithmProperty(Property):
2722    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2725class AutoIncrementProperty(Property):
2726    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2730class AutoRefreshProperty(Property):
2731    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2734class BackupProperty(Property):
2735    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2738class BlockCompressionProperty(Property):
2739    arg_types = {
2740        "autotemp": False,
2741        "always": False,
2742        "default": False,
2743        "manual": False,
2744        "never": False,
2745    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2748class CharacterSetProperty(Property):
2749    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2752class ChecksumProperty(Property):
2753    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2756class CollateProperty(Property):
2757    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2760class CopyGrantsProperty(Property):
2761    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2764class DataBlocksizeProperty(Property):
2765    arg_types = {
2766        "size": False,
2767        "units": False,
2768        "minimum": False,
2769        "maximum": False,
2770        "default": False,
2771    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2774class DataDeletionProperty(Property):
2775    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):
2778class DefinerProperty(Property):
2779    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2782class DistKeyProperty(Property):
2783    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2788class DistributedByProperty(Property):
2789    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):
2792class DistStyleProperty(Property):
2793    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2796class DuplicateKeyProperty(Property):
2797    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2800class EngineProperty(Property):
2801    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2804class HeapProperty(Property):
2805    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2808class ToTableProperty(Property):
2809    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2812class ExecuteAsProperty(Property):
2813    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2816class ExternalProperty(Property):
2817    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2820class FallbackProperty(Property):
2821    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2824class FileFormatProperty(Property):
2825    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2828class CredentialsProperty(Property):
2829    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2832class FreespaceProperty(Property):
2833    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2836class GlobalProperty(Property):
2837    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2840class IcebergProperty(Property):
2841    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2844class InheritsProperty(Property):
2845    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2848class InputModelProperty(Property):
2849    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2852class OutputModelProperty(Property):
2853    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2856class IsolatedLoadingProperty(Property):
2857    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2860class JournalProperty(Property):
2861    arg_types = {
2862        "no": False,
2863        "dual": False,
2864        "before": False,
2865        "local": False,
2866        "after": False,
2867    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2870class LanguageProperty(Property):
2871    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2874class EnviromentProperty(Property):
2875    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2879class ClusteredByProperty(Property):
2880    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2883class DictProperty(Property):
2884    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2887class DictSubProperty(Property):
2888    pass
key = 'dictsubproperty'
class DictRange(Property):
2891class DictRange(Property):
2892    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2895class DynamicProperty(Property):
2896    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2901class OnCluster(Property):
2902    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2906class EmptyProperty(Property):
2907    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2910class LikeProperty(Property):
2911    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2914class LocationProperty(Property):
2915    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2918class LockProperty(Property):
2919    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2922class LockingProperty(Property):
2923    arg_types = {
2924        "this": False,
2925        "kind": True,
2926        "for_or_in": False,
2927        "lock_type": True,
2928        "override": False,
2929    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2932class LogProperty(Property):
2933    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2936class MaterializedProperty(Property):
2937    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2940class MergeBlockRatioProperty(Property):
2941    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):
2944class NoPrimaryIndexProperty(Property):
2945    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2948class OnProperty(Property):
2949    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2952class OnCommitProperty(Property):
2953    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2956class PartitionedByProperty(Property):
2957    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
2960class PartitionedByBucket(Property):
2961    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
2964class PartitionByTruncate(Property):
2965    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
2969class PartitionByRangeProperty(Property):
2970    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2974class PartitionByRangePropertyDynamic(Expression):
2975    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):
2979class UniqueKeyProperty(Property):
2980    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2984class PartitionBoundSpec(Expression):
2985    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2986    arg_types = {
2987        "this": False,
2988        "expression": False,
2989        "from_expressions": False,
2990        "to_expressions": False,
2991    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2994class PartitionedOfProperty(Property):
2995    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2996    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2999class StreamingTableProperty(Property):
3000    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3003class RemoteWithConnectionModelProperty(Property):
3004    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3007class ReturnsProperty(Property):
3008    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):
3011class StrictProperty(Property):
3012    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3015class RowFormatProperty(Property):
3016    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3019class RowFormatDelimitedProperty(Property):
3020    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3021    arg_types = {
3022        "fields": False,
3023        "escaped": False,
3024        "collection_items": False,
3025        "map_keys": False,
3026        "lines": False,
3027        "null": False,
3028        "serde": False,
3029    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3032class RowFormatSerdeProperty(Property):
3033    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3037class QueryTransform(Expression):
3038    arg_types = {
3039        "expressions": True,
3040        "command_script": True,
3041        "schema": False,
3042        "row_format_before": False,
3043        "record_writer": False,
3044        "row_format_after": False,
3045        "record_reader": False,
3046    }
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):
3049class SampleProperty(Property):
3050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3054class SecurityProperty(Property):
3055    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3058class SchemaCommentProperty(Property):
3059    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
3062class SerdeProperties(Property):
3063    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3066class SetProperty(Property):
3067    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3070class SharingProperty(Property):
3071    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3074class SetConfigProperty(Property):
3075    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3078class SettingsProperty(Property):
3079    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3082class SortKeyProperty(Property):
3083    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3086class SqlReadWriteProperty(Property):
3087    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3090class SqlSecurityProperty(Property):
3091    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3094class StabilityProperty(Property):
3095    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3098class StorageHandlerProperty(Property):
3099    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3102class TemporaryProperty(Property):
3103    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3106class SecureProperty(Property):
3107    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3111class Tags(ColumnConstraintKind, Property):
3112    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3115class TransformModelProperty(Property):
3116    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3119class TransientProperty(Property):
3120    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3123class UnloggedProperty(Property):
3124    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3128class UsingTemplateProperty(Property):
3129    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3133class ViewAttributeProperty(Property):
3134    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3137class VolatileProperty(Property):
3138    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3141class WithDataProperty(Property):
3142    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3145class WithJournalTableProperty(Property):
3146    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3149class WithSchemaBindingProperty(Property):
3150    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3153class WithSystemVersioningProperty(Property):
3154    arg_types = {
3155        "on": False,
3156        "this": False,
3157        "data_consistency": False,
3158        "retention_period": False,
3159        "with": True,
3160    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3163class WithProcedureOptions(Property):
3164    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3167class EncodeProperty(Property):
3168    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3171class IncludeProperty(Property):
3172    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3175class ForceProperty(Property):
3176    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3179class Properties(Expression):
3180    arg_types = {"expressions": True}
3181
3182    NAME_TO_PROPERTY = {
3183        "ALGORITHM": AlgorithmProperty,
3184        "AUTO_INCREMENT": AutoIncrementProperty,
3185        "CHARACTER SET": CharacterSetProperty,
3186        "CLUSTERED_BY": ClusteredByProperty,
3187        "COLLATE": CollateProperty,
3188        "COMMENT": SchemaCommentProperty,
3189        "CREDENTIALS": CredentialsProperty,
3190        "DEFINER": DefinerProperty,
3191        "DISTKEY": DistKeyProperty,
3192        "DISTRIBUTED_BY": DistributedByProperty,
3193        "DISTSTYLE": DistStyleProperty,
3194        "ENGINE": EngineProperty,
3195        "EXECUTE AS": ExecuteAsProperty,
3196        "FORMAT": FileFormatProperty,
3197        "LANGUAGE": LanguageProperty,
3198        "LOCATION": LocationProperty,
3199        "LOCK": LockProperty,
3200        "PARTITIONED_BY": PartitionedByProperty,
3201        "RETURNS": ReturnsProperty,
3202        "ROW_FORMAT": RowFormatProperty,
3203        "SORTKEY": SortKeyProperty,
3204        "ENCODE": EncodeProperty,
3205        "INCLUDE": IncludeProperty,
3206    }
3207
3208    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3209
3210    # CREATE property locations
3211    # Form: schema specified
3212    #   create [POST_CREATE]
3213    #     table a [POST_NAME]
3214    #     (b int) [POST_SCHEMA]
3215    #     with ([POST_WITH])
3216    #     index (b) [POST_INDEX]
3217    #
3218    # Form: alias selection
3219    #   create [POST_CREATE]
3220    #     table a [POST_NAME]
3221    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3222    #     index (c) [POST_INDEX]
3223    class Location(AutoName):
3224        POST_CREATE = auto()
3225        POST_NAME = auto()
3226        POST_SCHEMA = auto()
3227        POST_WITH = auto()
3228        POST_ALIAS = auto()
3229        POST_EXPRESSION = auto()
3230        POST_INDEX = auto()
3231        UNSUPPORTED = auto()
3232
3233    @classmethod
3234    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3235        expressions = []
3236        for key, value in properties_dict.items():
3237            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3238            if property_cls:
3239                expressions.append(property_cls(this=convert(value)))
3240            else:
3241                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3242
3243        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:
3233    @classmethod
3234    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3235        expressions = []
3236        for key, value in properties_dict.items():
3237            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3238            if property_cls:
3239                expressions.append(property_cls(this=convert(value)))
3240            else:
3241                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3242
3243        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3223    class Location(AutoName):
3224        POST_CREATE = auto()
3225        POST_NAME = auto()
3226        POST_SCHEMA = auto()
3227        POST_WITH = auto()
3228        POST_ALIAS = auto()
3229        POST_EXPRESSION = auto()
3230        POST_INDEX = auto()
3231        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):
3246class Qualify(Expression):
3247    pass
key = 'qualify'
class InputOutputFormat(Expression):
3250class InputOutputFormat(Expression):
3251    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3255class Return(Expression):
3256    pass
key = 'return'
class Reference(Expression):
3259class Reference(Expression):
3260    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3263class Tuple(Expression):
3264    arg_types = {"expressions": False}
3265
3266    def isin(
3267        self,
3268        *expressions: t.Any,
3269        query: t.Optional[ExpOrStr] = None,
3270        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3271        copy: bool = True,
3272        **opts,
3273    ) -> In:
3274        return In(
3275            this=maybe_copy(self, copy),
3276            expressions=[convert(e, copy=copy) for e in expressions],
3277            query=maybe_parse(query, copy=copy, **opts) if query else None,
3278            unnest=(
3279                Unnest(
3280                    expressions=[
3281                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3282                        for e in ensure_list(unnest)
3283                    ]
3284                )
3285                if unnest
3286                else None
3287            ),
3288        )
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:
3266    def isin(
3267        self,
3268        *expressions: t.Any,
3269        query: t.Optional[ExpOrStr] = None,
3270        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3271        copy: bool = True,
3272        **opts,
3273    ) -> In:
3274        return In(
3275            this=maybe_copy(self, copy),
3276            expressions=[convert(e, copy=copy) for e in expressions],
3277            query=maybe_parse(query, copy=copy, **opts) if query else None,
3278            unnest=(
3279                Unnest(
3280                    expressions=[
3281                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3282                        for e in ensure_list(unnest)
3283                    ]
3284                )
3285                if unnest
3286                else None
3287            ),
3288        )
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):
3319class QueryOption(Expression):
3320    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3324class WithTableHint(Expression):
3325    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3329class IndexTableHint(Expression):
3330    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3334class HistoricalData(Expression):
3335    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3339class Put(Expression):
3340    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3344class Get(Expression):
3345    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3348class Table(Expression):
3349    arg_types = {
3350        "this": False,
3351        "alias": False,
3352        "db": False,
3353        "catalog": False,
3354        "laterals": False,
3355        "joins": False,
3356        "pivots": False,
3357        "hints": False,
3358        "system_time": False,
3359        "version": False,
3360        "format": False,
3361        "pattern": False,
3362        "ordinality": False,
3363        "when": False,
3364        "only": False,
3365        "partition": False,
3366        "changes": False,
3367        "rows_from": False,
3368        "sample": False,
3369    }
3370
3371    @property
3372    def name(self) -> str:
3373        if not self.this or isinstance(self.this, Func):
3374            return ""
3375        return self.this.name
3376
3377    @property
3378    def db(self) -> str:
3379        return self.text("db")
3380
3381    @property
3382    def catalog(self) -> str:
3383        return self.text("catalog")
3384
3385    @property
3386    def selects(self) -> t.List[Expression]:
3387        return []
3388
3389    @property
3390    def named_selects(self) -> t.List[str]:
3391        return []
3392
3393    @property
3394    def parts(self) -> t.List[Expression]:
3395        """Return the parts of a table in order catalog, db, table."""
3396        parts: t.List[Expression] = []
3397
3398        for arg in ("catalog", "db", "this"):
3399            part = self.args.get(arg)
3400
3401            if isinstance(part, Dot):
3402                parts.extend(part.flatten())
3403            elif isinstance(part, Expression):
3404                parts.append(part)
3405
3406        return parts
3407
3408    def to_column(self, copy: bool = True) -> Expression:
3409        parts = self.parts
3410        last_part = parts[-1]
3411
3412        if isinstance(last_part, Identifier):
3413            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3414        else:
3415            # This branch will be reached if a function or array is wrapped in a `Table`
3416            col = last_part
3417
3418        alias = self.args.get("alias")
3419        if alias:
3420            col = alias_(col, alias.this, copy=copy)
3421
3422        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
3371    @property
3372    def name(self) -> str:
3373        if not self.this or isinstance(self.this, Func):
3374            return ""
3375        return self.this.name
db: str
3377    @property
3378    def db(self) -> str:
3379        return self.text("db")
catalog: str
3381    @property
3382    def catalog(self) -> str:
3383        return self.text("catalog")
selects: List[Expression]
3385    @property
3386    def selects(self) -> t.List[Expression]:
3387        return []
named_selects: List[str]
3389    @property
3390    def named_selects(self) -> t.List[str]:
3391        return []
parts: List[Expression]
3393    @property
3394    def parts(self) -> t.List[Expression]:
3395        """Return the parts of a table in order catalog, db, table."""
3396        parts: t.List[Expression] = []
3397
3398        for arg in ("catalog", "db", "this"):
3399            part = self.args.get(arg)
3400
3401            if isinstance(part, Dot):
3402                parts.extend(part.flatten())
3403            elif isinstance(part, Expression):
3404                parts.append(part)
3405
3406        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3408    def to_column(self, copy: bool = True) -> Expression:
3409        parts = self.parts
3410        last_part = parts[-1]
3411
3412        if isinstance(last_part, Identifier):
3413            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3414        else:
3415            # This branch will be reached if a function or array is wrapped in a `Table`
3416            col = last_part
3417
3418        alias = self.args.get("alias")
3419        if alias:
3420            col = alias_(col, alias.this, copy=copy)
3421
3422        return col
key = 'table'
class SetOperation(Query):
3425class SetOperation(Query):
3426    arg_types = {
3427        "with": False,
3428        "this": True,
3429        "expression": True,
3430        "distinct": False,
3431        "by_name": False,
3432        "side": False,
3433        "kind": False,
3434        "on": False,
3435        **QUERY_MODIFIERS,
3436    }
3437
3438    def select(
3439        self: S,
3440        *expressions: t.Optional[ExpOrStr],
3441        append: bool = True,
3442        dialect: DialectType = None,
3443        copy: bool = True,
3444        **opts,
3445    ) -> S:
3446        this = maybe_copy(self, copy)
3447        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3448        this.expression.unnest().select(
3449            *expressions, append=append, dialect=dialect, copy=False, **opts
3450        )
3451        return this
3452
3453    @property
3454    def named_selects(self) -> t.List[str]:
3455        return self.this.unnest().named_selects
3456
3457    @property
3458    def is_star(self) -> bool:
3459        return self.this.is_star or self.expression.is_star
3460
3461    @property
3462    def selects(self) -> t.List[Expression]:
3463        return self.this.unnest().selects
3464
3465    @property
3466    def left(self) -> Query:
3467        return self.this
3468
3469    @property
3470    def right(self) -> Query:
3471        return self.expression
3472
3473    @property
3474    def kind(self) -> str:
3475        return self.text("kind").upper()
3476
3477    @property
3478    def side(self) -> str:
3479        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:
3438    def select(
3439        self: S,
3440        *expressions: t.Optional[ExpOrStr],
3441        append: bool = True,
3442        dialect: DialectType = None,
3443        copy: bool = True,
3444        **opts,
3445    ) -> S:
3446        this = maybe_copy(self, copy)
3447        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3448        this.expression.unnest().select(
3449            *expressions, append=append, dialect=dialect, copy=False, **opts
3450        )
3451        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]
3453    @property
3454    def named_selects(self) -> t.List[str]:
3455        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3457    @property
3458    def is_star(self) -> bool:
3459        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3461    @property
3462    def selects(self) -> t.List[Expression]:
3463        return self.this.unnest().selects

Returns the query's projections.

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

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:
3538    def set_(
3539        self,
3540        *expressions: ExpOrStr,
3541        append: bool = True,
3542        dialect: DialectType = None,
3543        copy: bool = True,
3544        **opts,
3545    ) -> Update:
3546        """
3547        Append to or set the SET expressions.
3548
3549        Example:
3550            >>> Update().table("my_table").set_("x = 1").sql()
3551            'UPDATE my_table SET x = 1'
3552
3553        Args:
3554            *expressions: the SQL code strings to parse.
3555                If `Expression` instance(s) are passed, they will be used as-is.
3556                Multiple expressions are combined with a comma.
3557            append: if `True`, add the new expressions to any existing SET expressions.
3558                Otherwise, this resets the expressions.
3559            dialect: the dialect used to parse the input expressions.
3560            copy: if `False`, modify this expression instance in-place.
3561            opts: other options to use to parse the input expressions.
3562        """
3563        return _apply_list_builder(
3564            *expressions,
3565            instance=self,
3566            arg="expressions",
3567            append=append,
3568            into=Expression,
3569            prefix=None,
3570            dialect=dialect,
3571            copy=copy,
3572            **opts,
3573        )

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

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:
3614    def from_(
3615        self,
3616        expression: t.Optional[ExpOrStr] = None,
3617        dialect: DialectType = None,
3618        copy: bool = True,
3619        **opts,
3620    ) -> Update:
3621        """
3622        Set the FROM expression.
3623
3624        Example:
3625            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3626            'UPDATE my_table SET x = 1 FROM baz'
3627
3628        Args:
3629            expression : the SQL code strings to parse.
3630                If a `From` instance is passed, this is used as-is.
3631                If another `Expression` instance is passed, it will be wrapped in a `From`.
3632                If nothing is passed in then a from is not applied to the expression
3633            dialect: the dialect used to parse the input expression.
3634            copy: if `False`, modify this expression instance in-place.
3635            opts: other options to use to parse the input expressions.
3636
3637        Returns:
3638            The modified Update expression.
3639        """
3640        if not expression:
3641            return maybe_copy(self, copy)
3642
3643        return _apply_builder(
3644            expression=expression,
3645            instance=self,
3646            arg="from",
3647            into=From,
3648            prefix="FROM",
3649            dialect=dialect,
3650            copy=copy,
3651            **opts,
3652        )

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:
3654    def with_(
3655        self,
3656        alias: ExpOrStr,
3657        as_: ExpOrStr,
3658        recursive: t.Optional[bool] = None,
3659        materialized: t.Optional[bool] = None,
3660        append: bool = True,
3661        dialect: DialectType = None,
3662        copy: bool = True,
3663        **opts,
3664    ) -> Update:
3665        """
3666        Append to or set the common table expressions.
3667
3668        Example:
3669            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3670            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3671
3672        Args:
3673            alias: the SQL code string to parse as the table name.
3674                If an `Expression` instance is passed, this is used as-is.
3675            as_: the SQL code string to parse as the table expression.
3676                If an `Expression` instance is passed, it will be used as-is.
3677            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3678            materialized: set the MATERIALIZED part of the expression.
3679            append: if `True`, add to any existing expressions.
3680                Otherwise, this resets the expressions.
3681            dialect: the dialect used to parse the input expression.
3682            copy: if `False`, modify this expression instance in-place.
3683            opts: other options to use to parse the input expressions.
3684
3685        Returns:
3686            The modified expression.
3687        """
3688        return _apply_cte_builder(
3689            self,
3690            alias,
3691            as_,
3692            recursive=recursive,
3693            materialized=materialized,
3694            append=append,
3695            dialect=dialect,
3696            copy=copy,
3697            **opts,
3698        )

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

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:
3778    def group_by(
3779        self,
3780        *expressions: t.Optional[ExpOrStr],
3781        append: bool = True,
3782        dialect: DialectType = None,
3783        copy: bool = True,
3784        **opts,
3785    ) -> Select:
3786        """
3787        Set the GROUP BY expression.
3788
3789        Example:
3790            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3791            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3792
3793        Args:
3794            *expressions: the SQL code strings to parse.
3795                If a `Group` instance is passed, this is used as-is.
3796                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3797                If nothing is passed in then a group by is not applied to the expression
3798            append: if `True`, add to any existing expressions.
3799                Otherwise, this flattens all the `Group` expression into a single expression.
3800            dialect: the dialect used to parse the input expression.
3801            copy: if `False`, modify this expression instance in-place.
3802            opts: other options to use to parse the input expressions.
3803
3804        Returns:
3805            The modified Select expression.
3806        """
3807        if not expressions:
3808            return self if not copy else self.copy()
3809
3810        return _apply_child_list_builder(
3811            *expressions,
3812            instance=self,
3813            arg="group",
3814            append=append,
3815            copy=copy,
3816            prefix="GROUP BY",
3817            into=Group,
3818            dialect=dialect,
3819            **opts,
3820        )

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

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

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:
3902    def select(
3903        self,
3904        *expressions: t.Optional[ExpOrStr],
3905        append: bool = True,
3906        dialect: DialectType = None,
3907        copy: bool = True,
3908        **opts,
3909    ) -> Select:
3910        return _apply_list_builder(
3911            *expressions,
3912            instance=self,
3913            arg="expressions",
3914            append=append,
3915            dialect=dialect,
3916            into=Expression,
3917            copy=copy,
3918            **opts,
3919        )

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:
3921    def lateral(
3922        self,
3923        *expressions: t.Optional[ExpOrStr],
3924        append: bool = True,
3925        dialect: DialectType = None,
3926        copy: bool = True,
3927        **opts,
3928    ) -> Select:
3929        """
3930        Append to or set the LATERAL expressions.
3931
3932        Example:
3933            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3934            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3935
3936        Args:
3937            *expressions: the SQL code strings to parse.
3938                If an `Expression` instance is passed, it will be used as-is.
3939            append: if `True`, add to any existing expressions.
3940                Otherwise, this resets the expressions.
3941            dialect: the dialect used to parse the input expressions.
3942            copy: if `False`, modify this expression instance in-place.
3943            opts: other options to use to parse the input expressions.
3944
3945        Returns:
3946            The modified Select expression.
3947        """
3948        return _apply_list_builder(
3949            *expressions,
3950            instance=self,
3951            arg="laterals",
3952            append=append,
3953            into=Lateral,
3954            prefix="LATERAL VIEW",
3955            dialect=dialect,
3956            copy=copy,
3957            **opts,
3958        )

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:
3960    def join(
3961        self,
3962        expression: ExpOrStr,
3963        on: t.Optional[ExpOrStr] = None,
3964        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3965        append: bool = True,
3966        join_type: t.Optional[str] = None,
3967        join_alias: t.Optional[Identifier | str] = None,
3968        dialect: DialectType = None,
3969        copy: bool = True,
3970        **opts,
3971    ) -> Select:
3972        """
3973        Append to or set the JOIN expressions.
3974
3975        Example:
3976            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3977            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3978
3979            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3980            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3981
3982            Use `join_type` to change the type of join:
3983
3984            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3985            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3986
3987        Args:
3988            expression: the SQL code string to parse.
3989                If an `Expression` instance is passed, it will be used as-is.
3990            on: optionally specify the join "on" criteria as a SQL string.
3991                If an `Expression` instance is passed, it will be used as-is.
3992            using: optionally specify the join "using" criteria as a SQL string.
3993                If an `Expression` instance is passed, it will be used as-is.
3994            append: if `True`, add to any existing expressions.
3995                Otherwise, this resets the expressions.
3996            join_type: if set, alter the parsed join type.
3997            join_alias: an optional alias for the joined source.
3998            dialect: the dialect used to parse the input expressions.
3999            copy: if `False`, modify this expression instance in-place.
4000            opts: other options to use to parse the input expressions.
4001
4002        Returns:
4003            Select: the modified expression.
4004        """
4005        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4006
4007        try:
4008            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4009        except ParseError:
4010            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4011
4012        join = expression if isinstance(expression, Join) else Join(this=expression)
4013
4014        if isinstance(join.this, Select):
4015            join.this.replace(join.this.subquery())
4016
4017        if join_type:
4018            method: t.Optional[Token]
4019            side: t.Optional[Token]
4020            kind: t.Optional[Token]
4021
4022            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4023
4024            if method:
4025                join.set("method", method.text)
4026            if side:
4027                join.set("side", side.text)
4028            if kind:
4029                join.set("kind", kind.text)
4030
4031        if on:
4032            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4033            join.set("on", on)
4034
4035        if using:
4036            join = _apply_list_builder(
4037                *ensure_list(using),
4038                instance=join,
4039                arg="using",
4040                append=append,
4041                copy=copy,
4042                into=Identifier,
4043                **opts,
4044            )
4045
4046        if join_alias:
4047            join.set("this", alias_(join.this, join_alias, table=True))
4048
4049        return _apply_list_builder(
4050            join,
4051            instance=self,
4052            arg="joins",
4053            append=append,
4054            copy=copy,
4055            **opts,
4056        )

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 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:
4058    def where(
4059        self,
4060        *expressions: t.Optional[ExpOrStr],
4061        append: bool = True,
4062        dialect: DialectType = None,
4063        copy: bool = True,
4064        **opts,
4065    ) -> Select:
4066        """
4067        Append to or set the WHERE expressions.
4068
4069        Example:
4070            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
4071            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
4072
4073        Args:
4074            *expressions: the SQL code strings to parse.
4075                If an `Expression` instance is passed, it will be used as-is.
4076                Multiple expressions are combined with an AND operator.
4077            append: if `True`, AND the new expressions to any existing expression.
4078                Otherwise, this resets the expression.
4079            dialect: the dialect used to parse the input expressions.
4080            copy: if `False`, modify this expression instance in-place.
4081            opts: other options to use to parse the input expressions.
4082
4083        Returns:
4084            Select: the modified expression.
4085        """
4086        return _apply_conjunction_builder(
4087            *expressions,
4088            instance=self,
4089            arg="where",
4090            append=append,
4091            into=Where,
4092            dialect=dialect,
4093            copy=copy,
4094            **opts,
4095        )

Append to or set the WHERE expressions.

Example:
>>> 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:

Select: the modified expression.

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

Append to or set the HAVING expressions.

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

The modified Select expression.

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

Set the OFFSET expression.

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

Select: the modified expression.

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

Convert this expression to a CREATE TABLE AS statement.

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

The new Create expression.

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

Set the locking read mode for this expression.

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

The modified expression.

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

Set hints for this expression.

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

The modified expression.

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

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

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

Returns the first non subquery.

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

Append to or set the SELECT expressions.

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

The modified Query expression.

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

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

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

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

Checks whether an expression is a star.

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

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

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

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

Tags are used for generating arbitrary sql like SELECT x.

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

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

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

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

Returns a Python object equivalent of the SQL node.

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

Returns a Python object equivalent of the SQL node.

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

Constructs a DataType object.

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

The constructed DataType object.

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

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

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

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

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

An enumeration.

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

Checks whether an expression is a star.

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

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

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

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

Build a Dot object with a sequence of expressions.

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

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

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

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

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

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

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

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

Returns a Python object equivalent of the SQL node.

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

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

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

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

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

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

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

Automatically converts unit arg into a var.

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

The base class for all function expressions.

Attributes:
  • is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
  • _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
is_var_len_args = False
@classmethod
def from_arg_list(cls, args):
5336    @classmethod
5337    def from_arg_list(cls, args):
5338        if cls.is_var_len_args:
5339            all_arg_keys = list(cls.arg_types)
5340            # If this function supports variable length argument treat the last argument as such.
5341            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5342            num_non_var = len(non_var_len_arg_keys)
5343
5344            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5345            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5346        else:
5347            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5348
5349        return cls(**args_dict)
@classmethod
def sql_names(cls):
5351    @classmethod
5352    def sql_names(cls):
5353        if cls is Func:
5354            raise NotImplementedError(
5355                "SQL name is only supported by concrete function implementations"
5356            )
5357        if "_sql_names" not in cls.__dict__:
5358            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5359        return cls._sql_names
@classmethod
def sql_name(cls):
5361    @classmethod
5362    def sql_name(cls):
5363        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5365    @classmethod
5366    def default_parser_mappings(cls):
5367        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5370class AggFunc(Func):
5371    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5374class ParameterizedAgg(AggFunc):
5375    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5378class Abs(Func):
5379    pass
key = 'abs'
class ArgMax(AggFunc):
5382class ArgMax(AggFunc):
5383    arg_types = {"this": True, "expression": True, "count": False}
5384    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5387class ArgMin(AggFunc):
5388    arg_types = {"this": True, "expression": True, "count": False}
5389    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5392class ApproxTopK(AggFunc):
5393    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5396class Flatten(Func):
5397    pass
key = 'flatten'
class Transform(Func):
5401class Transform(Func):
5402    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5405class Anonymous(Func):
5406    arg_types = {"this": True, "expressions": False}
5407    is_var_len_args = True
5408
5409    @property
5410    def name(self) -> str:
5411        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
5409    @property
5410    def name(self) -> str:
5411        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5414class AnonymousAggFunc(AggFunc):
5415    arg_types = {"this": True, "expressions": False}
5416    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5420class CombinedAggFunc(AnonymousAggFunc):
5421    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5424class CombinedParameterizedAgg(ParameterizedAgg):
5425    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5430class Hll(AggFunc):
5431    arg_types = {"this": True, "expressions": False}
5432    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5435class ApproxDistinct(AggFunc):
5436    arg_types = {"this": True, "accuracy": False}
5437    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5440class Apply(Func):
5441    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5444class Array(Func):
5445    arg_types = {"expressions": False, "bracket_notation": False}
5446    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5450class ToArray(Func):
5451    pass
key = 'toarray'
class List(Func):
5455class List(Func):
5456    arg_types = {"expressions": False}
5457    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5461class Pad(Func):
5462    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):
5467class ToChar(Func):
5468    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5473class ToNumber(Func):
5474    arg_types = {
5475        "this": True,
5476        "format": False,
5477        "nlsparam": False,
5478        "precision": False,
5479        "scale": False,
5480    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5484class ToDouble(Func):
5485    arg_types = {
5486        "this": True,
5487        "format": False,
5488    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5491class Columns(Func):
5492    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5496class Convert(Func):
5497    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5501class ConvertToCharset(Func):
5502    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5505class ConvertTimezone(Func):
5506    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):
5509class GenerateSeries(Func):
5510    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):
5516class ExplodingGenerateSeries(GenerateSeries):
5517    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5520class ArrayAgg(AggFunc):
5521    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5524class ArrayUniqueAgg(AggFunc):
5525    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5528class ArrayAll(Func):
5529    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5533class ArrayAny(Func):
5534    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5537class ArrayConcat(Func):
5538    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5539    arg_types = {"this": True, "expressions": False}
5540    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5543class ArrayConstructCompact(Func):
5544    arg_types = {"expressions": True}
5545    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5548class ArrayContains(Binary, Func):
5549    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5552class ArrayContainsAll(Binary, Func):
5553    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5556class ArrayFilter(Func):
5557    arg_types = {"this": True, "expression": True}
5558    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5561class ArrayToString(Func):
5562    arg_types = {"this": True, "expression": True, "null": False}
5563    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5567class String(Func):
5568    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5571class StringToArray(Func):
5572    arg_types = {"this": True, "expression": True, "null": False}
5573    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5576class ArrayOverlaps(Binary, Func):
5577    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5580class ArraySize(Func):
5581    arg_types = {"this": True, "expression": False}
5582    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5585class ArraySort(Func):
5586    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5589class ArraySum(Func):
5590    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5593class ArrayUnionAgg(AggFunc):
5594    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5597class Avg(AggFunc):
5598    pass
key = 'avg'
class AnyValue(AggFunc):
5601class AnyValue(AggFunc):
5602    pass
key = 'anyvalue'
class Lag(AggFunc):
5605class Lag(AggFunc):
5606    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5609class Lead(AggFunc):
5610    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5615class First(AggFunc):
5616    pass
key = 'first'
class Last(AggFunc):
5619class Last(AggFunc):
5620    pass
key = 'last'
class FirstValue(AggFunc):
5623class FirstValue(AggFunc):
5624    pass
key = 'firstvalue'
class LastValue(AggFunc):
5627class LastValue(AggFunc):
5628    pass
key = 'lastvalue'
class NthValue(AggFunc):
5631class NthValue(AggFunc):
5632    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5635class Case(Func):
5636    arg_types = {"this": False, "ifs": True, "default": False}
5637
5638    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5639        instance = maybe_copy(self, copy)
5640        instance.append(
5641            "ifs",
5642            If(
5643                this=maybe_parse(condition, copy=copy, **opts),
5644                true=maybe_parse(then, copy=copy, **opts),
5645            ),
5646        )
5647        return instance
5648
5649    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5650        instance = maybe_copy(self, copy)
5651        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5652        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:
5638    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5639        instance = maybe_copy(self, copy)
5640        instance.append(
5641            "ifs",
5642            If(
5643                this=maybe_parse(condition, copy=copy, **opts),
5644                true=maybe_parse(then, copy=copy, **opts),
5645            ),
5646        )
5647        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5649    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5650        instance = maybe_copy(self, copy)
5651        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5652        return instance
key = 'case'
class Cast(Func):
5655class Cast(Func):
5656    arg_types = {
5657        "this": True,
5658        "to": True,
5659        "format": False,
5660        "safe": False,
5661        "action": False,
5662        "default": False,
5663    }
5664
5665    @property
5666    def name(self) -> str:
5667        return self.this.name
5668
5669    @property
5670    def to(self) -> DataType:
5671        return self.args["to"]
5672
5673    @property
5674    def output_name(self) -> str:
5675        return self.name
5676
5677    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5678        """
5679        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5680        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5681        array<int> != array<float>.
5682
5683        Args:
5684            dtypes: the data types to compare this Cast's DataType to.
5685
5686        Returns:
5687            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5688        """
5689        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5665    @property
5666    def name(self) -> str:
5667        return self.this.name
to: DataType
5669    @property
5670    def to(self) -> DataType:
5671        return self.args["to"]
output_name: str
5673    @property
5674    def output_name(self) -> str:
5675        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
5677    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5678        """
5679        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5680        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5681        array<int> != array<float>.
5682
5683        Args:
5684            dtypes: the data types to compare this Cast's DataType to.
5685
5686        Returns:
5687            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5688        """
5689        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):
5692class TryCast(Cast):
5693    pass
key = 'trycast'
class JSONCast(Cast):
5697class JSONCast(Cast):
5698    pass
key = 'jsoncast'
class Try(Func):
5701class Try(Func):
5702    pass
key = 'try'
class CastToStrType(Func):
5705class CastToStrType(Func):
5706    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5710class TranslateCharacters(Expression):
5711    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5714class Collate(Binary, Func):
5715    pass
key = 'collate'
class Ceil(Func):
5718class Ceil(Func):
5719    arg_types = {"this": True, "decimals": False, "to": False}
5720    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5723class Coalesce(Func):
5724    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5725    is_var_len_args = True
5726    _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):
5729class Chr(Func):
5730    arg_types = {"expressions": True, "charset": False}
5731    is_var_len_args = True
5732    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5735class Concat(Func):
5736    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5737    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5740class ConcatWs(Concat):
5741    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5744class Contains(Func):
5745    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5749class ConnectByRoot(Func):
5750    pass
key = 'connectbyroot'
class Count(AggFunc):
5753class Count(AggFunc):
5754    arg_types = {"this": False, "expressions": False, "big_int": False}
5755    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5758class CountIf(AggFunc):
5759    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5763class Cbrt(Func):
5764    pass
key = 'cbrt'
class CurrentDate(Func):
5767class CurrentDate(Func):
5768    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5771class CurrentDatetime(Func):
5772    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5775class CurrentTime(Func):
5776    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5779class CurrentTimestamp(Func):
5780    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5783class CurrentSchema(Func):
5784    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5787class CurrentUser(Func):
5788    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5791class DateAdd(Func, IntervalOp):
5792    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5795class DateBin(Func, IntervalOp):
5796    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):
5799class DateSub(Func, IntervalOp):
5800    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5803class DateDiff(Func, TimeUnit):
5804    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5805    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):
5808class DateTrunc(Func):
5809    arg_types = {"unit": True, "this": True, "zone": False}
5810
5811    def __init__(self, **args):
5812        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5813        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5814        unabbreviate = args.pop("unabbreviate", True)
5815
5816        unit = args.get("unit")
5817        if isinstance(unit, TimeUnit.VAR_LIKE):
5818            unit_name = unit.name.upper()
5819            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5820                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5821
5822            args["unit"] = Literal.string(unit_name)
5823        elif isinstance(unit, Week):
5824            unit.set("this", Literal.string(unit.this.name.upper()))
5825
5826        super().__init__(**args)
5827
5828    @property
5829    def unit(self) -> Expression:
5830        return self.args["unit"]
DateTrunc(**args)
5811    def __init__(self, **args):
5812        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5813        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5814        unabbreviate = args.pop("unabbreviate", True)
5815
5816        unit = args.get("unit")
5817        if isinstance(unit, TimeUnit.VAR_LIKE):
5818            unit_name = unit.name.upper()
5819            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5820                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5821
5822            args["unit"] = Literal.string(unit_name)
5823        elif isinstance(unit, Week):
5824            unit.set("this", Literal.string(unit.this.name.upper()))
5825
5826        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5828    @property
5829    def unit(self) -> Expression:
5830        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5835class Datetime(Func):
5836    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5839class DatetimeAdd(Func, IntervalOp):
5840    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5843class DatetimeSub(Func, IntervalOp):
5844    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5847class DatetimeDiff(Func, TimeUnit):
5848    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5851class DatetimeTrunc(Func, TimeUnit):
5852    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5855class DayOfWeek(Func):
5856    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5861class DayOfWeekIso(Func):
5862    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5865class DayOfMonth(Func):
5866    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5869class DayOfYear(Func):
5870    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5873class ToDays(Func):
5874    pass
key = 'todays'
class WeekOfYear(Func):
5877class WeekOfYear(Func):
5878    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5881class MonthsBetween(Func):
5882    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5885class MakeInterval(Func):
5886    arg_types = {
5887        "year": False,
5888        "month": False,
5889        "day": False,
5890        "hour": False,
5891        "minute": False,
5892        "second": False,
5893    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5896class LastDay(Func, TimeUnit):
5897    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5898    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5901class Extract(Func):
5902    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5905class Exists(Func, SubqueryPredicate):
5906    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5909class Timestamp(Func):
5910    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5913class TimestampAdd(Func, TimeUnit):
5914    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5917class TimestampSub(Func, TimeUnit):
5918    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5921class TimestampDiff(Func, TimeUnit):
5922    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5923    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5926class TimestampTrunc(Func, TimeUnit):
5927    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5930class TimeAdd(Func, TimeUnit):
5931    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5934class TimeSub(Func, TimeUnit):
5935    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5938class TimeDiff(Func, TimeUnit):
5939    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5942class TimeTrunc(Func, TimeUnit):
5943    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5946class DateFromParts(Func):
5947    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5948    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5951class TimeFromParts(Func):
5952    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5953    arg_types = {
5954        "hour": True,
5955        "min": True,
5956        "sec": True,
5957        "nano": False,
5958        "fractions": False,
5959        "precision": False,
5960    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5963class DateStrToDate(Func):
5964    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5967class DateToDateStr(Func):
5968    pass
key = 'datetodatestr'
class DateToDi(Func):
5971class DateToDi(Func):
5972    pass
key = 'datetodi'
class Date(Func):
5976class Date(Func):
5977    arg_types = {"this": False, "zone": False, "expressions": False}
5978    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5981class Day(Func):
5982    pass
key = 'day'
class Decode(Func):
5985class Decode(Func):
5986    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5989class DiToDate(Func):
5990    pass
key = 'ditodate'
class Encode(Func):
5993class Encode(Func):
5994    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5997class Exp(Func):
5998    pass
key = 'exp'
class Explode(Func, UDTF):
6002class Explode(Func, UDTF):
6003    arg_types = {"this": True, "expressions": False}
6004    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6008class Inline(Func):
6009    pass
key = 'inline'
class ExplodeOuter(Explode):
6012class ExplodeOuter(Explode):
6013    pass
key = 'explodeouter'
class Posexplode(Explode):
6016class Posexplode(Explode):
6017    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6020class PosexplodeOuter(Posexplode, ExplodeOuter):
6021    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
6024class Unnest(Func, UDTF):
6025    arg_types = {
6026        "expressions": True,
6027        "alias": False,
6028        "offset": False,
6029        "explode_array": False,
6030    }
6031
6032    @property
6033    def selects(self) -> t.List[Expression]:
6034        columns = super().selects
6035        offset = self.args.get("offset")
6036        if offset:
6037            columns = columns + [to_identifier("offset") if offset is True else offset]
6038        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6032    @property
6033    def selects(self) -> t.List[Expression]:
6034        columns = super().selects
6035        offset = self.args.get("offset")
6036        if offset:
6037            columns = columns + [to_identifier("offset") if offset is True else offset]
6038        return columns
key = 'unnest'
class Floor(Func):
6041class Floor(Func):
6042    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6045class FromBase64(Func):
6046    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6049class FeaturesAtTime(Func):
6050    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):
6053class ToBase64(Func):
6054    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6058class FromISO8601Timestamp(Func):
6059    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6062class GapFill(Func):
6063    arg_types = {
6064        "this": True,
6065        "ts_column": True,
6066        "bucket_width": True,
6067        "partitioning_columns": False,
6068        "value_columns": False,
6069        "origin": False,
6070        "ignore_nulls": False,
6071    }
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):
6075class GenerateDateArray(Func):
6076    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6080class GenerateTimestampArray(Func):
6081    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6084class Greatest(Func):
6085    arg_types = {"this": True, "expressions": False}
6086    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6091class OverflowTruncateBehavior(Expression):
6092    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6095class GroupConcat(AggFunc):
6096    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6099class Hex(Func):
6100    pass
key = 'hex'
class LowerHex(Hex):
6103class LowerHex(Hex):
6104    pass
key = 'lowerhex'
class And(Connector, Func):
6107class And(Connector, Func):
6108    pass
key = 'and'
class Or(Connector, Func):
6111class Or(Connector, Func):
6112    pass
key = 'or'
class Xor(Connector, Func):
6115class Xor(Connector, Func):
6116    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6119class If(Func):
6120    arg_types = {"this": True, "true": True, "false": False}
6121    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6124class Nullif(Func):
6125    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6128class Initcap(Func):
6129    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6132class IsAscii(Func):
6133    pass
key = 'isascii'
class IsNan(Func):
6136class IsNan(Func):
6137    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6141class Int64(Func):
6142    pass
key = 'int64'
class IsInf(Func):
6145class IsInf(Func):
6146    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6150class JSON(Expression):
6151    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6154class JSONPath(Expression):
6155    arg_types = {"expressions": True, "escape": False}
6156
6157    @property
6158    def output_name(self) -> str:
6159        last_segment = self.expressions[-1].this
6160        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6157    @property
6158    def output_name(self) -> str:
6159        last_segment = self.expressions[-1].this
6160        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):
6163class JSONPathPart(Expression):
6164    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6167class JSONPathFilter(JSONPathPart):
6168    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6171class JSONPathKey(JSONPathPart):
6172    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6175class JSONPathRecursive(JSONPathPart):
6176    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6179class JSONPathRoot(JSONPathPart):
6180    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6183class JSONPathScript(JSONPathPart):
6184    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6187class JSONPathSlice(JSONPathPart):
6188    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6191class JSONPathSelector(JSONPathPart):
6192    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6195class JSONPathSubscript(JSONPathPart):
6196    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6199class JSONPathUnion(JSONPathPart):
6200    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6203class JSONPathWildcard(JSONPathPart):
6204    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6207class FormatJson(Expression):
6208    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6211class JSONKeyValue(Expression):
6212    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6215class JSONObject(Func):
6216    arg_types = {
6217        "expressions": False,
6218        "null_handling": False,
6219        "unique_keys": False,
6220        "return_type": False,
6221        "encoding": False,
6222    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6225class JSONObjectAgg(AggFunc):
6226    arg_types = {
6227        "expressions": False,
6228        "null_handling": False,
6229        "unique_keys": False,
6230        "return_type": False,
6231        "encoding": False,
6232    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6236class JSONBObjectAgg(AggFunc):
6237    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6241class JSONArray(Func):
6242    arg_types = {
6243        "expressions": True,
6244        "null_handling": False,
6245        "return_type": False,
6246        "strict": False,
6247    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6251class JSONArrayAgg(Func):
6252    arg_types = {
6253        "this": True,
6254        "order": False,
6255        "null_handling": False,
6256        "return_type": False,
6257        "strict": False,
6258    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6261class JSONExists(Func):
6262    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):
6267class JSONColumnDef(Expression):
6268    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):
6271class JSONSchema(Expression):
6272    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6276class JSONValue(Expression):
6277    arg_types = {
6278        "this": True,
6279        "path": True,
6280        "returning": False,
6281        "on_condition": False,
6282    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6285class JSONValueArray(Func):
6286    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6290class JSONTable(Func):
6291    arg_types = {
6292        "this": True,
6293        "schema": True,
6294        "path": False,
6295        "error_handling": False,
6296        "empty_handling": False,
6297    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6301class ObjectInsert(Func):
6302    arg_types = {
6303        "this": True,
6304        "key": True,
6305        "value": True,
6306        "update_flag": False,
6307    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6310class OpenJSONColumnDef(Expression):
6311    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):
6314class OpenJSON(Func):
6315    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6318class JSONBContains(Binary, Func):
6319    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6322class JSONBExists(Func):
6323    arg_types = {"this": True, "path": True}
6324    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6327class JSONExtract(Binary, Func):
6328    arg_types = {
6329        "this": True,
6330        "expression": True,
6331        "only_json_types": False,
6332        "expressions": False,
6333        "variant_extract": False,
6334        "json_query": False,
6335        "option": False,
6336        "quote": False,
6337        "on_condition": False,
6338    }
6339    _sql_names = ["JSON_EXTRACT"]
6340    is_var_len_args = True
6341
6342    @property
6343    def output_name(self) -> str:
6344        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
6342    @property
6343    def output_name(self) -> str:
6344        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):
6348class JSONExtractQuote(Expression):
6349    arg_types = {
6350        "option": True,
6351        "scalar": False,
6352    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6355class JSONExtractArray(Func):
6356    arg_types = {"this": True, "expression": False}
6357    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6360class JSONExtractScalar(Binary, Func):
6361    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6362    _sql_names = ["JSON_EXTRACT_SCALAR"]
6363    is_var_len_args = True
6364
6365    @property
6366    def output_name(self) -> str:
6367        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
6365    @property
6366    def output_name(self) -> str:
6367        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):
6370class JSONBExtract(Binary, Func):
6371    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6374class JSONBExtractScalar(Binary, Func):
6375    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6378class JSONFormat(Func):
6379    arg_types = {"this": False, "options": False, "is_json": False}
6380    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6384class JSONArrayContains(Binary, Predicate, Func):
6385    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6388class ParseJSON(Func):
6389    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6390    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6391    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6392    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6395class Least(Func):
6396    arg_types = {"this": True, "expressions": False}
6397    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6400class Left(Func):
6401    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6408class Length(Func):
6409    arg_types = {"this": True, "binary": False, "encoding": False}
6410    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6413class Levenshtein(Func):
6414    arg_types = {
6415        "this": True,
6416        "expression": False,
6417        "ins_cost": False,
6418        "del_cost": False,
6419        "sub_cost": False,
6420        "max_dist": False,
6421    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6424class Ln(Func):
6425    pass
key = 'ln'
class Log(Func):
6428class Log(Func):
6429    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6432class LogicalOr(AggFunc):
6433    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6436class LogicalAnd(AggFunc):
6437    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6440class Lower(Func):
6441    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6444class Map(Func):
6445    arg_types = {"keys": False, "values": False}
6446
6447    @property
6448    def keys(self) -> t.List[Expression]:
6449        keys = self.args.get("keys")
6450        return keys.expressions if keys else []
6451
6452    @property
6453    def values(self) -> t.List[Expression]:
6454        values = self.args.get("values")
6455        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6447    @property
6448    def keys(self) -> t.List[Expression]:
6449        keys = self.args.get("keys")
6450        return keys.expressions if keys else []
values: List[Expression]
6452    @property
6453    def values(self) -> t.List[Expression]:
6454        values = self.args.get("values")
6455        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6459class ToMap(Func):
6460    pass
key = 'tomap'
class MapFromEntries(Func):
6463class MapFromEntries(Func):
6464    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6468class ScopeResolution(Expression):
6469    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6472class Stream(Expression):
6473    pass
key = 'stream'
class StarMap(Func):
6476class StarMap(Func):
6477    pass
key = 'starmap'
class VarMap(Func):
6480class VarMap(Func):
6481    arg_types = {"keys": True, "values": True}
6482    is_var_len_args = True
6483
6484    @property
6485    def keys(self) -> t.List[Expression]:
6486        return self.args["keys"].expressions
6487
6488    @property
6489    def values(self) -> t.List[Expression]:
6490        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6484    @property
6485    def keys(self) -> t.List[Expression]:
6486        return self.args["keys"].expressions
values: List[Expression]
6488    @property
6489    def values(self) -> t.List[Expression]:
6490        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6494class MatchAgainst(Func):
6495    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6498class Max(AggFunc):
6499    arg_types = {"this": True, "expressions": False}
6500    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6503class MD5(Func):
6504    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6508class MD5Digest(Func):
6509    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6512class Median(AggFunc):
6513    pass
key = 'median'
class Min(AggFunc):
6516class Min(AggFunc):
6517    arg_types = {"this": True, "expressions": False}
6518    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6521class Month(Func):
6522    pass
key = 'month'
class AddMonths(Func):
6525class AddMonths(Func):
6526    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6529class Nvl2(Func):
6530    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6533class Normalize(Func):
6534    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6537class Overlay(Func):
6538    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):
6542class Predict(Func):
6543    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6546class Pow(Binary, Func):
6547    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6550class PercentileCont(AggFunc):
6551    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6554class PercentileDisc(AggFunc):
6555    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6558class Quantile(AggFunc):
6559    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6562class ApproxQuantile(Quantile):
6563    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):
6566class Quarter(Func):
6567    pass
key = 'quarter'
class Rand(Func):
6572class Rand(Func):
6573    _sql_names = ["RAND", "RANDOM"]
6574    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6577class Randn(Func):
6578    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6581class RangeN(Func):
6582    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6585class ReadCSV(Func):
6586    _sql_names = ["READ_CSV"]
6587    is_var_len_args = True
6588    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6591class Reduce(Func):
6592    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):
6595class RegexpExtract(Func):
6596    arg_types = {
6597        "this": True,
6598        "expression": True,
6599        "position": False,
6600        "occurrence": False,
6601        "parameters": False,
6602        "group": False,
6603    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6606class RegexpExtractAll(Func):
6607    arg_types = {
6608        "this": True,
6609        "expression": True,
6610        "position": False,
6611        "occurrence": False,
6612        "parameters": False,
6613        "group": False,
6614    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6617class RegexpReplace(Func):
6618    arg_types = {
6619        "this": True,
6620        "expression": True,
6621        "replacement": False,
6622        "position": False,
6623        "occurrence": False,
6624        "modifiers": False,
6625    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6628class RegexpLike(Binary, Func):
6629    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6632class RegexpILike(Binary, Func):
6633    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6638class RegexpSplit(Func):
6639    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6642class Repeat(Func):
6643    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6648class Round(Func):
6649    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6652class RowNumber(Func):
6653    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6656class SafeDivide(Func):
6657    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6660class SHA(Func):
6661    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6664class SHA2(Func):
6665    _sql_names = ["SHA2"]
6666    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6669class Sign(Func):
6670    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6673class SortArray(Func):
6674    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6677class Split(Func):
6678    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6682class SplitPart(Func):
6683    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6688class Substring(Func):
6689    _sql_names = ["SUBSTRING", "SUBSTR"]
6690    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6693class StandardHash(Func):
6694    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6697class StartsWith(Func):
6698    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6699    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6702class StrPosition(Func):
6703    arg_types = {
6704        "this": True,
6705        "substr": True,
6706        "position": False,
6707        "occurrence": False,
6708    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6711class StrToDate(Func):
6712    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6715class StrToTime(Func):
6716    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):
6721class StrToUnix(Func):
6722    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6727class StrToMap(Func):
6728    arg_types = {
6729        "this": True,
6730        "pair_delim": False,
6731        "key_value_delim": False,
6732        "duplicate_resolution_callback": False,
6733    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6736class NumberToStr(Func):
6737    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6740class FromBase(Func):
6741    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6744class Struct(Func):
6745    arg_types = {"expressions": False}
6746    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6749class StructExtract(Func):
6750    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6755class Stuff(Func):
6756    _sql_names = ["STUFF", "INSERT"]
6757    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):
6760class Sum(AggFunc):
6761    pass
key = 'sum'
class Sqrt(Func):
6764class Sqrt(Func):
6765    pass
key = 'sqrt'
class Stddev(AggFunc):
6768class Stddev(AggFunc):
6769    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6772class StddevPop(AggFunc):
6773    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6776class StddevSamp(AggFunc):
6777    pass
key = 'stddevsamp'
class Time(Func):
6781class Time(Func):
6782    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6785class TimeToStr(Func):
6786    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):
6789class TimeToTimeStr(Func):
6790    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6793class TimeToUnix(Func):
6794    pass
key = 'timetounix'
class TimeStrToDate(Func):
6797class TimeStrToDate(Func):
6798    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6801class TimeStrToTime(Func):
6802    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6805class TimeStrToUnix(Func):
6806    pass
key = 'timestrtounix'
class Trim(Func):
6809class Trim(Func):
6810    arg_types = {
6811        "this": True,
6812        "expression": False,
6813        "position": False,
6814        "collation": False,
6815    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6818class TsOrDsAdd(Func, TimeUnit):
6819    # return_type is used to correctly cast the arguments of this expression when transpiling it
6820    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6821
6822    @property
6823    def return_type(self) -> DataType:
6824        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
6822    @property
6823    def return_type(self) -> DataType:
6824        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6827class TsOrDsDiff(Func, TimeUnit):
6828    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6831class TsOrDsToDateStr(Func):
6832    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6835class TsOrDsToDate(Func):
6836    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6839class TsOrDsToDatetime(Func):
6840    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6843class TsOrDsToTime(Func):
6844    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6847class TsOrDsToTimestamp(Func):
6848    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6851class TsOrDiToDi(Func):
6852    pass
key = 'tsorditodi'
class Unhex(Func):
6855class Unhex(Func):
6856    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6859class Unicode(Func):
6860    pass
key = 'unicode'
class UnixDate(Func):
6864class UnixDate(Func):
6865    pass
key = 'unixdate'
class UnixToStr(Func):
6868class UnixToStr(Func):
6869    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6874class UnixToTime(Func):
6875    arg_types = {
6876        "this": True,
6877        "scale": False,
6878        "zone": False,
6879        "hours": False,
6880        "minutes": False,
6881        "format": False,
6882    }
6883
6884    SECONDS = Literal.number(0)
6885    DECIS = Literal.number(1)
6886    CENTIS = Literal.number(2)
6887    MILLIS = Literal.number(3)
6888    DECIMILLIS = Literal.number(4)
6889    CENTIMILLIS = Literal.number(5)
6890    MICROS = Literal.number(6)
6891    DECIMICROS = Literal.number(7)
6892    CENTIMICROS = Literal.number(8)
6893    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):
6896class UnixToTimeStr(Func):
6897    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6900class UnixSeconds(Func):
6901    pass
key = 'unixseconds'
class Uuid(Func):
6904class Uuid(Func):
6905    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6906
6907    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6910class TimestampFromParts(Func):
6911    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6912    arg_types = {
6913        "year": True,
6914        "month": True,
6915        "day": True,
6916        "hour": True,
6917        "min": True,
6918        "sec": True,
6919        "nano": False,
6920        "zone": False,
6921        "milli": False,
6922    }
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):
6925class Upper(Func):
6926    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6929class Corr(Binary, AggFunc):
6930    pass
key = 'corr'
class Variance(AggFunc):
6933class Variance(AggFunc):
6934    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6937class VariancePop(AggFunc):
6938    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6941class CovarSamp(Binary, AggFunc):
6942    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6945class CovarPop(Binary, AggFunc):
6946    pass
key = 'covarpop'
class Week(Func):
6949class Week(Func):
6950    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6953class XMLElement(Func):
6954    _sql_names = ["XMLELEMENT"]
6955    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6958class XMLTable(Func):
6959    arg_types = {
6960        "this": True,
6961        "namespaces": False,
6962        "passing": False,
6963        "columns": False,
6964        "by_ref": False,
6965    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6968class XMLNamespace(Expression):
6969    pass
key = 'xmlnamespace'
class Year(Func):
6972class Year(Func):
6973    pass
key = 'year'
class Use(Expression):
6976class Use(Expression):
6977    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6980class Merge(DML):
6981    arg_types = {
6982        "this": True,
6983        "using": True,
6984        "on": True,
6985        "whens": True,
6986        "with": False,
6987        "returning": False,
6988    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6991class When(Expression):
6992    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):
6995class Whens(Expression):
6996    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6997
6998    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7003class NextValueFor(Func):
7004    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7009class Semicolon(Expression):
7010    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CONVERT_TO_CHARSET': <class 'ConvertToCharset'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_ASCII': <class 'IsAscii'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'CHAR_LENGTH': <class 'Length'>, 'CHARACTER_LENGTH': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OR': <class 'Or'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, '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:
7050def maybe_parse(
7051    sql_or_expression: ExpOrStr,
7052    *,
7053    into: t.Optional[IntoType] = None,
7054    dialect: DialectType = None,
7055    prefix: t.Optional[str] = None,
7056    copy: bool = False,
7057    **opts,
7058) -> Expression:
7059    """Gracefully handle a possible string or expression.
7060
7061    Example:
7062        >>> maybe_parse("1")
7063        Literal(this=1, is_string=False)
7064        >>> maybe_parse(to_identifier("x"))
7065        Identifier(this=x, quoted=False)
7066
7067    Args:
7068        sql_or_expression: the SQL code string or an expression
7069        into: the SQLGlot Expression to parse into
7070        dialect: the dialect used to parse the input expressions (in the case that an
7071            input expression is a SQL string).
7072        prefix: a string to prefix the sql with before it gets parsed
7073            (automatically includes a space)
7074        copy: whether to copy the expression.
7075        **opts: other options to use to parse the input expressions (again, in the case
7076            that an input expression is a SQL string).
7077
7078    Returns:
7079        Expression: the parsed or given expression.
7080    """
7081    if isinstance(sql_or_expression, Expression):
7082        if copy:
7083            return sql_or_expression.copy()
7084        return sql_or_expression
7085
7086    if sql_or_expression is None:
7087        raise ParseError("SQL cannot be None")
7088
7089    import sqlglot
7090
7091    sql = str(sql_or_expression)
7092    if prefix:
7093        sql = f"{prefix} {sql}"
7094
7095    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):
7106def maybe_copy(instance, copy=True):
7107    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:
7362def union(
7363    *expressions: ExpOrStr,
7364    distinct: bool = True,
7365    dialect: DialectType = None,
7366    copy: bool = True,
7367    **opts,
7368) -> Union:
7369    """
7370    Initializes a syntax tree for the `UNION` operation.
7371
7372    Example:
7373        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7374        'SELECT * FROM foo UNION SELECT * FROM bla'
7375
7376    Args:
7377        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7378            If `Expression` instances are passed, they will be used as-is.
7379        distinct: set the DISTINCT flag if and only if this is true.
7380        dialect: the dialect used to parse the input expression.
7381        copy: whether to copy the expression.
7382        opts: other options to use to parse the input expressions.
7383
7384    Returns:
7385        The new Union instance.
7386    """
7387    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7388    return _apply_set_operation(
7389        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7390    )

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:
7393def intersect(
7394    *expressions: ExpOrStr,
7395    distinct: bool = True,
7396    dialect: DialectType = None,
7397    copy: bool = True,
7398    **opts,
7399) -> Intersect:
7400    """
7401    Initializes a syntax tree for the `INTERSECT` operation.
7402
7403    Example:
7404        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7405        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7406
7407    Args:
7408        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7409            If `Expression` instances are passed, they will be used as-is.
7410        distinct: set the DISTINCT flag if and only if this is true.
7411        dialect: the dialect used to parse the input expression.
7412        copy: whether to copy the expression.
7413        opts: other options to use to parse the input expressions.
7414
7415    Returns:
7416        The new Intersect instance.
7417    """
7418    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7419    return _apply_set_operation(
7420        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7421    )

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:
7424def except_(
7425    *expressions: ExpOrStr,
7426    distinct: bool = True,
7427    dialect: DialectType = None,
7428    copy: bool = True,
7429    **opts,
7430) -> Except:
7431    """
7432    Initializes a syntax tree for the `EXCEPT` operation.
7433
7434    Example:
7435        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7436        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7437
7438    Args:
7439        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7440            If `Expression` instances are passed, they will be used as-is.
7441        distinct: set the DISTINCT flag if and only if this is true.
7442        dialect: the dialect used to parse the input expression.
7443        copy: whether to copy the expression.
7444        opts: other options to use to parse the input expressions.
7445
7446    Returns:
7447        The new Except instance.
7448    """
7449    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7450    return _apply_set_operation(
7451        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7452    )

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

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:
7723def and_(
7724    *expressions: t.Optional[ExpOrStr],
7725    dialect: DialectType = None,
7726    copy: bool = True,
7727    wrap: bool = True,
7728    **opts,
7729) -> Condition:
7730    """
7731    Combine multiple conditions with an AND logical operator.
7732
7733    Example:
7734        >>> and_("x=1", and_("y=1", "z=1")).sql()
7735        'x = 1 AND (y = 1 AND z = 1)'
7736
7737    Args:
7738        *expressions: the SQL code strings to parse.
7739            If an Expression instance is passed, this is used as-is.
7740        dialect: the dialect used to parse the input expression.
7741        copy: whether to copy `expressions` (only applies to Expressions).
7742        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7743            precedence issues, but can be turned off when the produced AST is too deep and
7744            causes recursion-related issues.
7745        **opts: other options to use to parse the input expressions.
7746
7747    Returns:
7748        The new condition
7749    """
7750    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:
7753def or_(
7754    *expressions: t.Optional[ExpOrStr],
7755    dialect: DialectType = None,
7756    copy: bool = True,
7757    wrap: bool = True,
7758    **opts,
7759) -> Condition:
7760    """
7761    Combine multiple conditions with an OR logical operator.
7762
7763    Example:
7764        >>> or_("x=1", or_("y=1", "z=1")).sql()
7765        'x = 1 OR (y = 1 OR z = 1)'
7766
7767    Args:
7768        *expressions: the SQL code strings to parse.
7769            If an Expression instance is passed, this is used as-is.
7770        dialect: the dialect used to parse the input expression.
7771        copy: whether to copy `expressions` (only applies to Expressions).
7772        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7773            precedence issues, but can be turned off when the produced AST is too deep and
7774            causes recursion-related issues.
7775        **opts: other options to use to parse the input expressions.
7776
7777    Returns:
7778        The new condition
7779    """
7780    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:
7783def xor(
7784    *expressions: t.Optional[ExpOrStr],
7785    dialect: DialectType = None,
7786    copy: bool = True,
7787    wrap: bool = True,
7788    **opts,
7789) -> Condition:
7790    """
7791    Combine multiple conditions with an XOR logical operator.
7792
7793    Example:
7794        >>> xor("x=1", xor("y=1", "z=1")).sql()
7795        'x = 1 XOR (y = 1 XOR z = 1)'
7796
7797    Args:
7798        *expressions: the SQL code strings to parse.
7799            If an Expression instance is passed, this is used as-is.
7800        dialect: the dialect used to parse the input expression.
7801        copy: whether to copy `expressions` (only applies to Expressions).
7802        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7803            precedence issues, but can be turned off when the produced AST is too deep and
7804            causes recursion-related issues.
7805        **opts: other options to use to parse the input expressions.
7806
7807    Returns:
7808        The new condition
7809    """
7810    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:
7813def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7814    """
7815    Wrap a condition with a NOT operator.
7816
7817    Example:
7818        >>> not_("this_suit='black'").sql()
7819        "NOT this_suit = 'black'"
7820
7821    Args:
7822        expression: the SQL code string to parse.
7823            If an Expression instance is passed, this is used as-is.
7824        dialect: the dialect used to parse the input expression.
7825        copy: whether to copy the expression or not.
7826        **opts: other options to use to parse the input expressions.
7827
7828    Returns:
7829        The new condition.
7830    """
7831    this = condition(
7832        expression,
7833        dialect=dialect,
7834        copy=copy,
7835        **opts,
7836    )
7837    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:
7840def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7841    """
7842    Wrap an expression in parentheses.
7843
7844    Example:
7845        >>> paren("5 + 3").sql()
7846        '(5 + 3)'
7847
7848    Args:
7849        expression: the SQL code string to parse.
7850            If an Expression instance is passed, this is used as-is.
7851        copy: whether to copy the expression or not.
7852
7853    Returns:
7854        The wrapped expression.
7855    """
7856    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):
7872def to_identifier(name, quoted=None, copy=True):
7873    """Builds an identifier.
7874
7875    Args:
7876        name: The name to turn into an identifier.
7877        quoted: Whether to force quote the identifier.
7878        copy: Whether to copy name if it's an Identifier.
7879
7880    Returns:
7881        The identifier ast node.
7882    """
7883
7884    if name is None:
7885        return None
7886
7887    if isinstance(name, Identifier):
7888        identifier = maybe_copy(name, copy)
7889    elif isinstance(name, str):
7890        identifier = Identifier(
7891            this=name,
7892            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7893        )
7894    else:
7895        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7896    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:
7899def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7900    """
7901    Parses a given string into an identifier.
7902
7903    Args:
7904        name: The name to parse into an identifier.
7905        dialect: The dialect to parse against.
7906
7907    Returns:
7908        The identifier ast node.
7909    """
7910    try:
7911        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7912    except (ParseError, TokenError):
7913        expression = to_identifier(name)
7914
7915    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]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
7921def to_interval(interval: str | Literal) -> Interval:
7922    """Builds an interval expression from a string like '1 day' or '5 months'."""
7923    if isinstance(interval, Literal):
7924        if not interval.is_string:
7925            raise ValueError("Invalid interval string.")
7926
7927        interval = interval.this
7928
7929    interval = maybe_parse(f"INTERVAL {interval}")
7930    assert isinstance(interval, Interval)
7931    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:
7934def to_table(
7935    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7936) -> Table:
7937    """
7938    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7939    If a table is passed in then that table is returned.
7940
7941    Args:
7942        sql_path: a `[catalog].[schema].[table]` string.
7943        dialect: the source dialect according to which the table name will be parsed.
7944        copy: Whether to copy a table if it is passed in.
7945        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7946
7947    Returns:
7948        A table expression.
7949    """
7950    if isinstance(sql_path, Table):
7951        return maybe_copy(sql_path, copy=copy)
7952
7953    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7954
7955    for k, v in kwargs.items():
7956        table.set(k, v)
7957
7958    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:
7961def to_column(
7962    sql_path: str | Column,
7963    quoted: t.Optional[bool] = None,
7964    dialect: DialectType = None,
7965    copy: bool = True,
7966    **kwargs,
7967) -> Column:
7968    """
7969    Create a column from a `[table].[column]` sql path. Table is optional.
7970    If a column is passed in then that column is returned.
7971
7972    Args:
7973        sql_path: a `[table].[column]` string.
7974        quoted: Whether or not to force quote identifiers.
7975        dialect: the source dialect according to which the column name will be parsed.
7976        copy: Whether to copy a column if it is passed in.
7977        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7978
7979    Returns:
7980        A column expression.
7981    """
7982    if isinstance(sql_path, Column):
7983        return maybe_copy(sql_path, copy=copy)
7984
7985    try:
7986        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7987    except ParseError:
7988        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7989
7990    for k, v in kwargs.items():
7991        col.set(k, v)
7992
7993    if quoted:
7994        for i in col.find_all(Identifier):
7995            i.set("quoted", True)
7996
7997    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):
8000def alias_(
8001    expression: ExpOrStr,
8002    alias: t.Optional[str | Identifier],
8003    table: bool | t.Sequence[str | Identifier] = False,
8004    quoted: t.Optional[bool] = None,
8005    dialect: DialectType = None,
8006    copy: bool = True,
8007    **opts,
8008):
8009    """Create an Alias expression.
8010
8011    Example:
8012        >>> alias_('foo', 'bar').sql()
8013        'foo AS bar'
8014
8015        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8016        '(SELECT 1, 2) AS bar(a, b)'
8017
8018    Args:
8019        expression: the SQL code strings to parse.
8020            If an Expression instance is passed, this is used as-is.
8021        alias: the alias name to use. If the name has
8022            special characters it is quoted.
8023        table: Whether to create a table alias, can also be a list of columns.
8024        quoted: whether to quote the alias
8025        dialect: the dialect used to parse the input expression.
8026        copy: Whether to copy the expression.
8027        **opts: other options to use to parse the input expressions.
8028
8029    Returns:
8030        Alias: the aliased expression
8031    """
8032    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8033    alias = to_identifier(alias, quoted=quoted)
8034
8035    if table:
8036        table_alias = TableAlias(this=alias)
8037        exp.set("alias", table_alias)
8038
8039        if not isinstance(table, bool):
8040            for column in table:
8041                table_alias.append("columns", to_identifier(column, quoted=quoted))
8042
8043        return exp
8044
8045    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8046    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8047    # for the complete Window expression.
8048    #
8049    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8050
8051    if "alias" in exp.arg_types and not isinstance(exp, Window):
8052        exp.set("alias", alias)
8053        return exp
8054    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:
8057def subquery(
8058    expression: ExpOrStr,
8059    alias: t.Optional[Identifier | str] = None,
8060    dialect: DialectType = None,
8061    **opts,
8062) -> Select:
8063    """
8064    Build a subquery expression that's selected from.
8065
8066    Example:
8067        >>> subquery('select x from tbl', 'bar').select('x').sql()
8068        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8069
8070    Args:
8071        expression: the SQL code strings to parse.
8072            If an Expression instance is passed, this is used as-is.
8073        alias: the alias name to use.
8074        dialect: the dialect used to parse the input expression.
8075        **opts: other options to use to parse the input expressions.
8076
8077    Returns:
8078        A new Select instance with the subquery expression included.
8079    """
8080
8081    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8082    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):
8113def column(
8114    col,
8115    table=None,
8116    db=None,
8117    catalog=None,
8118    *,
8119    fields=None,
8120    quoted=None,
8121    copy=True,
8122):
8123    """
8124    Build a Column.
8125
8126    Args:
8127        col: Column name.
8128        table: Table name.
8129        db: Database name.
8130        catalog: Catalog name.
8131        fields: Additional fields using dots.
8132        quoted: Whether to force quotes on the column's identifiers.
8133        copy: Whether to copy identifiers if passed in.
8134
8135    Returns:
8136        The new Column instance.
8137    """
8138    this = Column(
8139        this=to_identifier(col, quoted=quoted, copy=copy),
8140        table=to_identifier(table, quoted=quoted, copy=copy),
8141        db=to_identifier(db, quoted=quoted, copy=copy),
8142        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8143    )
8144
8145    if fields:
8146        this = Dot.build(
8147            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8148        )
8149    return this

Build a Column.

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

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8152def cast(
8153    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8154) -> Cast:
8155    """Cast an expression to a data type.
8156
8157    Example:
8158        >>> cast('x + 1', 'int').sql()
8159        'CAST(x + 1 AS INT)'
8160
8161    Args:
8162        expression: The expression to cast.
8163        to: The datatype to cast to.
8164        copy: Whether to copy the supplied expressions.
8165        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8166            - The expression to be cast is already a exp.Cast expression
8167            - The existing cast is to a type that is logically equivalent to new type
8168
8169            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8170            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8171            and instead just return the original expression `CAST(x as DATETIME)`.
8172
8173            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8174            mapping is applied in the target dialect generator.
8175
8176    Returns:
8177        The new Cast instance.
8178    """
8179    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8180    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8181
8182    # dont re-cast if the expression is already a cast to the correct type
8183    if isinstance(expr, Cast):
8184        from sqlglot.dialects.dialect import Dialect
8185
8186        target_dialect = Dialect.get_or_raise(dialect)
8187        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8188
8189        existing_cast_type: DataType.Type = expr.to.this
8190        new_cast_type: DataType.Type = data_type.this
8191        types_are_equivalent = type_mapping.get(
8192            existing_cast_type, existing_cast_type.value
8193        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8194
8195        if expr.is_type(data_type) or types_are_equivalent:
8196            return expr
8197
8198    expr = Cast(this=expr, to=data_type)
8199    expr.type = data_type
8200
8201    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:
8204def table_(
8205    table: Identifier | str,
8206    db: t.Optional[Identifier | str] = None,
8207    catalog: t.Optional[Identifier | str] = None,
8208    quoted: t.Optional[bool] = None,
8209    alias: t.Optional[Identifier | str] = None,
8210) -> Table:
8211    """Build a Table.
8212
8213    Args:
8214        table: Table name.
8215        db: Database name.
8216        catalog: Catalog name.
8217        quote: Whether to force quotes on the table's identifiers.
8218        alias: Table's alias.
8219
8220    Returns:
8221        The new Table instance.
8222    """
8223    return Table(
8224        this=to_identifier(table, quoted=quoted) if table else None,
8225        db=to_identifier(db, quoted=quoted) if db else None,
8226        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8227        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8228    )

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:
8231def values(
8232    values: t.Iterable[t.Tuple[t.Any, ...]],
8233    alias: t.Optional[str] = None,
8234    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8235) -> Values:
8236    """Build VALUES statement.
8237
8238    Example:
8239        >>> values([(1, '2')]).sql()
8240        "VALUES (1, '2')"
8241
8242    Args:
8243        values: values statements that will be converted to SQL
8244        alias: optional alias
8245        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8246         If either are provided then an alias is also required.
8247
8248    Returns:
8249        Values: the Values expression object
8250    """
8251    if columns and not alias:
8252        raise ValueError("Alias is required when providing columns")
8253
8254    return Values(
8255        expressions=[convert(tup) for tup in values],
8256        alias=(
8257            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8258            if columns
8259            else (TableAlias(this=to_identifier(alias)) if alias else None)
8260        ),
8261    )

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:
8264def var(name: t.Optional[ExpOrStr]) -> Var:
8265    """Build a SQL variable.
8266
8267    Example:
8268        >>> repr(var('x'))
8269        'Var(this=x)'
8270
8271        >>> repr(var(column('x', table='y')))
8272        'Var(this=x)'
8273
8274    Args:
8275        name: The name of the var or an expression who's name will become the var.
8276
8277    Returns:
8278        The new variable node.
8279    """
8280    if not name:
8281        raise ValueError("Cannot convert empty name into var.")
8282
8283    if isinstance(name, Expression):
8284        name = name.name
8285    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:
8288def rename_table(
8289    old_name: str | Table,
8290    new_name: str | Table,
8291    dialect: DialectType = None,
8292) -> Alter:
8293    """Build ALTER TABLE... RENAME... expression
8294
8295    Args:
8296        old_name: The old name of the table
8297        new_name: The new name of the table
8298        dialect: The dialect to parse the table.
8299
8300    Returns:
8301        Alter table expression
8302    """
8303    old_table = to_table(old_name, dialect=dialect)
8304    new_table = to_table(new_name, dialect=dialect)
8305    return Alter(
8306        this=old_table,
8307        kind="TABLE",
8308        actions=[
8309            AlterRename(this=new_table),
8310        ],
8311    )

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:
8314def rename_column(
8315    table_name: str | Table,
8316    old_column_name: str | Column,
8317    new_column_name: str | Column,
8318    exists: t.Optional[bool] = None,
8319    dialect: DialectType = None,
8320) -> Alter:
8321    """Build ALTER TABLE... RENAME COLUMN... expression
8322
8323    Args:
8324        table_name: Name of the table
8325        old_column: The old name of the column
8326        new_column: The new name of the column
8327        exists: Whether to add the `IF EXISTS` clause
8328        dialect: The dialect to parse the table/column.
8329
8330    Returns:
8331        Alter table expression
8332    """
8333    table = to_table(table_name, dialect=dialect)
8334    old_column = to_column(old_column_name, dialect=dialect)
8335    new_column = to_column(new_column_name, dialect=dialect)
8336    return Alter(
8337        this=table,
8338        kind="TABLE",
8339        actions=[
8340            RenameColumn(this=old_column, to=new_column, exists=exists),
8341        ],
8342    )

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:
8345def convert(value: t.Any, copy: bool = False) -> Expression:
8346    """Convert a python value into an expression object.
8347
8348    Raises an error if a conversion is not possible.
8349
8350    Args:
8351        value: A python object.
8352        copy: Whether to copy `value` (only applies to Expressions and collections).
8353
8354    Returns:
8355        The equivalent expression object.
8356    """
8357    if isinstance(value, Expression):
8358        return maybe_copy(value, copy)
8359    if isinstance(value, str):
8360        return Literal.string(value)
8361    if isinstance(value, bool):
8362        return Boolean(this=value)
8363    if value is None or (isinstance(value, float) and math.isnan(value)):
8364        return null()
8365    if isinstance(value, numbers.Number):
8366        return Literal.number(value)
8367    if isinstance(value, bytes):
8368        return HexString(this=value.hex())
8369    if isinstance(value, datetime.datetime):
8370        datetime_literal = Literal.string(value.isoformat(sep=" "))
8371
8372        tz = None
8373        if value.tzinfo:
8374            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8375            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8376            tz = Literal.string(str(value.tzinfo))
8377
8378        return TimeStrToTime(this=datetime_literal, zone=tz)
8379    if isinstance(value, datetime.date):
8380        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8381        return DateStrToDate(this=date_literal)
8382    if isinstance(value, tuple):
8383        if hasattr(value, "_fields"):
8384            return Struct(
8385                expressions=[
8386                    PropertyEQ(
8387                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8388                    )
8389                    for k in value._fields
8390                ]
8391            )
8392        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8393    if isinstance(value, list):
8394        return Array(expressions=[convert(v, copy=copy) for v in value])
8395    if isinstance(value, dict):
8396        return Map(
8397            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8398            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8399        )
8400    if hasattr(value, "__dict__"):
8401        return Struct(
8402            expressions=[
8403                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8404                for k, v in value.__dict__.items()
8405            ]
8406        )
8407    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:
8410def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8411    """
8412    Replace children of an expression with the result of a lambda fun(child) -> exp.
8413    """
8414    for k, v in tuple(expression.args.items()):
8415        is_list_arg = type(v) is list
8416
8417        child_nodes = v if is_list_arg else [v]
8418        new_child_nodes = []
8419
8420        for cn in child_nodes:
8421            if isinstance(cn, Expression):
8422                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8423                    new_child_nodes.append(child_node)
8424            else:
8425                new_child_nodes.append(cn)
8426
8427        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:
8430def replace_tree(
8431    expression: Expression,
8432    fun: t.Callable,
8433    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8434) -> Expression:
8435    """
8436    Replace an entire tree with the result of function calls on each node.
8437
8438    This will be traversed in reverse dfs, so leaves first.
8439    If new nodes are created as a result of function calls, they will also be traversed.
8440    """
8441    stack = list(expression.dfs(prune=prune))
8442
8443    while stack:
8444        node = stack.pop()
8445        new_node = fun(node)
8446
8447        if new_node is not node:
8448            node.replace(new_node)
8449
8450            if isinstance(new_node, Expression):
8451                stack.append(new_node)
8452
8453    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]:
8456def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8457    """
8458    Return all table names referenced through columns in an expression.
8459
8460    Example:
8461        >>> import sqlglot
8462        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8463        ['a', 'c']
8464
8465    Args:
8466        expression: expression to find table names.
8467        exclude: a table name to exclude
8468
8469    Returns:
8470        A list of unique names.
8471    """
8472    return {
8473        table
8474        for table in (column.table for column in expression.find_all(Column))
8475        if table and table != exclude
8476    }

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:
8479def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8480    """Get the full name of a table as a string.
8481
8482    Args:
8483        table: Table expression node or string.
8484        dialect: The dialect to generate the table name for.
8485        identify: Determines when an identifier should be quoted. Possible values are:
8486            False (default): Never quote, except in cases where it's mandatory by the dialect.
8487            True: Always quote.
8488
8489    Examples:
8490        >>> from sqlglot import exp, parse_one
8491        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8492        'a.b.c'
8493
8494    Returns:
8495        The table name.
8496    """
8497
8498    table = maybe_parse(table, into=Table, dialect=dialect)
8499
8500    if not table:
8501        raise ValueError(f"Cannot parse {table}")
8502
8503    return ".".join(
8504        (
8505            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8506            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8507            else part.name
8508        )
8509        for part in table.parts
8510    )

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:
8513def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8514    """Returns a case normalized table name without quotes.
8515
8516    Args:
8517        table: the table to normalize
8518        dialect: the dialect to use for normalization rules
8519        copy: whether to copy the expression.
8520
8521    Examples:
8522        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8523        'A-B.c'
8524    """
8525    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8526
8527    return ".".join(
8528        p.name
8529        for p in normalize_identifiers(
8530            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8531        ).parts
8532    )

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:
8535def replace_tables(
8536    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8537) -> E:
8538    """Replace all tables in expression according to the mapping.
8539
8540    Args:
8541        expression: expression node to be transformed and replaced.
8542        mapping: mapping of table names.
8543        dialect: the dialect of the mapping table
8544        copy: whether to copy the expression.
8545
8546    Examples:
8547        >>> from sqlglot import exp, parse_one
8548        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8549        'SELECT * FROM c /* a.b */'
8550
8551    Returns:
8552        The mapped expression.
8553    """
8554
8555    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8556
8557    def _replace_tables(node: Expression) -> Expression:
8558        if isinstance(node, Table) and node.meta.get("replace") is not False:
8559            original = normalize_table_name(node, dialect=dialect)
8560            new_name = mapping.get(original)
8561
8562            if new_name:
8563                table = to_table(
8564                    new_name,
8565                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8566                    dialect=dialect,
8567                )
8568                table.add_comments([original])
8569                return table
8570        return node
8571
8572    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:
8575def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8576    """Replace placeholders in an expression.
8577
8578    Args:
8579        expression: expression node to be transformed and replaced.
8580        args: positional names that will substitute unnamed placeholders in the given order.
8581        kwargs: keyword arguments that will substitute named placeholders.
8582
8583    Examples:
8584        >>> from sqlglot import exp, parse_one
8585        >>> replace_placeholders(
8586        ...     parse_one("select * from :tbl where ? = ?"),
8587        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8588        ... ).sql()
8589        "SELECT * FROM foo WHERE str_col = 'b'"
8590
8591    Returns:
8592        The mapped expression.
8593    """
8594
8595    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8596        if isinstance(node, Placeholder):
8597            if node.this:
8598                new_name = kwargs.get(node.this)
8599                if new_name is not None:
8600                    return convert(new_name)
8601            else:
8602                try:
8603                    return convert(next(args))
8604                except StopIteration:
8605                    pass
8606        return node
8607
8608    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:
8611def expand(
8612    expression: Expression,
8613    sources: t.Dict[str, Query | t.Callable[[], Query]],
8614    dialect: DialectType = None,
8615    copy: bool = True,
8616) -> Expression:
8617    """Transforms an expression by expanding all referenced sources into subqueries.
8618
8619    Examples:
8620        >>> from sqlglot import parse_one
8621        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8622        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8623
8624        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8625        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8626
8627    Args:
8628        expression: The expression to expand.
8629        sources: A dict of name to query or a callable that provides a query on demand.
8630        dialect: The dialect of the sources dict or the callable.
8631        copy: Whether to copy the expression during transformation. Defaults to True.
8632
8633    Returns:
8634        The transformed expression.
8635    """
8636    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8637
8638    def _expand(node: Expression):
8639        if isinstance(node, Table):
8640            name = normalize_table_name(node, dialect=dialect)
8641            source = normalized_sources.get(name)
8642
8643            if source:
8644                # Create a subquery with the same alias (or table name if no alias)
8645                parsed_source = source() if callable(source) else source
8646                subquery = parsed_source.subquery(node.alias or name)
8647                subquery.comments = [f"source: {name}"]
8648
8649                # Continue expanding within the subquery
8650                return subquery.transform(_expand, copy=False)
8651
8652        return node
8653
8654    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:
8657def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8658    """
8659    Returns a Func expression.
8660
8661    Examples:
8662        >>> func("abs", 5).sql()
8663        'ABS(5)'
8664
8665        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8666        'CAST(5 AS DOUBLE)'
8667
8668    Args:
8669        name: the name of the function to build.
8670        args: the args used to instantiate the function of interest.
8671        copy: whether to copy the argument expressions.
8672        dialect: the source dialect.
8673        kwargs: the kwargs used to instantiate the function of interest.
8674
8675    Note:
8676        The arguments `args` and `kwargs` are mutually exclusive.
8677
8678    Returns:
8679        An instance of the function of interest, or an anonymous function, if `name` doesn't
8680        correspond to an existing `sqlglot.expressions.Func` class.
8681    """
8682    if args and kwargs:
8683        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8684
8685    from sqlglot.dialects.dialect import Dialect
8686
8687    dialect = Dialect.get_or_raise(dialect)
8688
8689    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8690    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8691
8692    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8693    if constructor:
8694        if converted:
8695            if "dialect" in constructor.__code__.co_varnames:
8696                function = constructor(converted, dialect=dialect)
8697            else:
8698                function = constructor(converted)
8699        elif constructor.__name__ == "from_arg_list":
8700            function = constructor.__self__(**kwargs)  # type: ignore
8701        else:
8702            constructor = FUNCTION_BY_NAME.get(name.upper())
8703            if constructor:
8704                function = constructor(**kwargs)
8705            else:
8706                raise ValueError(
8707                    f"Unable to convert '{name}' into a Func. Either manually construct "
8708                    "the Func expression of interest or parse the function call."
8709                )
8710    else:
8711        kwargs = kwargs or {"expressions": converted}
8712        function = Anonymous(this=name, **kwargs)
8713
8714    for error_message in function.error_messages(converted):
8715        raise ValueError(error_message)
8716
8717    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:
8720def case(
8721    expression: t.Optional[ExpOrStr] = None,
8722    **opts,
8723) -> Case:
8724    """
8725    Initialize a CASE statement.
8726
8727    Example:
8728        case().when("a = 1", "foo").else_("bar")
8729
8730    Args:
8731        expression: Optionally, the input expression (not all dialects support this)
8732        **opts: Extra keyword arguments for parsing `expression`
8733    """
8734    if expression is not None:
8735        this = maybe_parse(expression, **opts)
8736    else:
8737        this = None
8738    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:
8741def array(
8742    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8743) -> Array:
8744    """
8745    Returns an array.
8746
8747    Examples:
8748        >>> array(1, 'x').sql()
8749        'ARRAY(1, x)'
8750
8751    Args:
8752        expressions: the expressions to add to the array.
8753        copy: whether to copy the argument expressions.
8754        dialect: the source dialect.
8755        kwargs: the kwargs used to instantiate the function of interest.
8756
8757    Returns:
8758        An array expression.
8759    """
8760    return Array(
8761        expressions=[
8762            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8763            for expression in expressions
8764        ]
8765    )

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:
8768def tuple_(
8769    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8770) -> Tuple:
8771    """
8772    Returns an tuple.
8773
8774    Examples:
8775        >>> tuple_(1, 'x').sql()
8776        '(1, x)'
8777
8778    Args:
8779        expressions: the expressions to add to the tuple.
8780        copy: whether to copy the argument expressions.
8781        dialect: the source dialect.
8782        kwargs: the kwargs used to instantiate the function of interest.
8783
8784    Returns:
8785        A tuple expression.
8786    """
8787    return Tuple(
8788        expressions=[
8789            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8790            for expression in expressions
8791        ]
8792    )

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:
8795def true() -> Boolean:
8796    """
8797    Returns a true Boolean expression.
8798    """
8799    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8802def false() -> Boolean:
8803    """
8804    Returns a false Boolean expression.
8805    """
8806    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8809def null() -> Null:
8810    """
8811    Returns a Null expression.
8812    """
8813    return Null()

Returns a Null expression.

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