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 ArrayConcatAgg(AggFunc):
5543    pass
5544
5545
5546class ArrayConstructCompact(Func):
5547    arg_types = {"expressions": True}
5548    is_var_len_args = True
5549
5550
5551class ArrayContains(Binary, Func):
5552    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5553
5554
5555class ArrayContainsAll(Binary, Func):
5556    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5557
5558
5559class ArrayFilter(Func):
5560    arg_types = {"this": True, "expression": True}
5561    _sql_names = ["FILTER", "ARRAY_FILTER"]
5562
5563
5564class ArrayToString(Func):
5565    arg_types = {"this": True, "expression": True, "null": False}
5566    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5567
5568
5569# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5570class String(Func):
5571    arg_types = {"this": True, "zone": False}
5572
5573
5574class StringToArray(Func):
5575    arg_types = {"this": True, "expression": True, "null": False}
5576    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
5577
5578
5579class ArrayOverlaps(Binary, Func):
5580    pass
5581
5582
5583class ArraySize(Func):
5584    arg_types = {"this": True, "expression": False}
5585    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5586
5587
5588class ArraySort(Func):
5589    arg_types = {"this": True, "expression": False}
5590
5591
5592class ArraySum(Func):
5593    arg_types = {"this": True, "expression": False}
5594
5595
5596class ArrayUnionAgg(AggFunc):
5597    pass
5598
5599
5600class Avg(AggFunc):
5601    pass
5602
5603
5604class AnyValue(AggFunc):
5605    pass
5606
5607
5608class Lag(AggFunc):
5609    arg_types = {"this": True, "offset": False, "default": False}
5610
5611
5612class Lead(AggFunc):
5613    arg_types = {"this": True, "offset": False, "default": False}
5614
5615
5616# some dialects have a distinction between first and first_value, usually first is an aggregate func
5617# and first_value is a window func
5618class First(AggFunc):
5619    pass
5620
5621
5622class Last(AggFunc):
5623    pass
5624
5625
5626class FirstValue(AggFunc):
5627    pass
5628
5629
5630class LastValue(AggFunc):
5631    pass
5632
5633
5634class NthValue(AggFunc):
5635    arg_types = {"this": True, "offset": True}
5636
5637
5638class Case(Func):
5639    arg_types = {"this": False, "ifs": True, "default": False}
5640
5641    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5642        instance = maybe_copy(self, copy)
5643        instance.append(
5644            "ifs",
5645            If(
5646                this=maybe_parse(condition, copy=copy, **opts),
5647                true=maybe_parse(then, copy=copy, **opts),
5648            ),
5649        )
5650        return instance
5651
5652    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5653        instance = maybe_copy(self, copy)
5654        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5655        return instance
5656
5657
5658class Cast(Func):
5659    arg_types = {
5660        "this": True,
5661        "to": True,
5662        "format": False,
5663        "safe": False,
5664        "action": False,
5665        "default": False,
5666    }
5667
5668    @property
5669    def name(self) -> str:
5670        return self.this.name
5671
5672    @property
5673    def to(self) -> DataType:
5674        return self.args["to"]
5675
5676    @property
5677    def output_name(self) -> str:
5678        return self.name
5679
5680    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5681        """
5682        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5683        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5684        array<int> != array<float>.
5685
5686        Args:
5687            dtypes: the data types to compare this Cast's DataType to.
5688
5689        Returns:
5690            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5691        """
5692        return self.to.is_type(*dtypes)
5693
5694
5695class TryCast(Cast):
5696    pass
5697
5698
5699# https://clickhouse.com/docs/sql-reference/data-types/newjson#reading-json-paths-as-sub-columns
5700class JSONCast(Cast):
5701    pass
5702
5703
5704class Try(Func):
5705    pass
5706
5707
5708class CastToStrType(Func):
5709    arg_types = {"this": True, "to": True}
5710
5711
5712# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/String-Operators-and-Functions/TRANSLATE/TRANSLATE-Function-Syntax
5713class TranslateCharacters(Expression):
5714    arg_types = {"this": True, "expression": True, "with_error": False}
5715
5716
5717class Collate(Binary, Func):
5718    pass
5719
5720
5721class Ceil(Func):
5722    arg_types = {"this": True, "decimals": False, "to": False}
5723    _sql_names = ["CEIL", "CEILING"]
5724
5725
5726class Coalesce(Func):
5727    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5728    is_var_len_args = True
5729    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5730
5731
5732class Chr(Func):
5733    arg_types = {"expressions": True, "charset": False}
5734    is_var_len_args = True
5735    _sql_names = ["CHR", "CHAR"]
5736
5737
5738class Concat(Func):
5739    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5740    is_var_len_args = True
5741
5742
5743class ConcatWs(Concat):
5744    _sql_names = ["CONCAT_WS"]
5745
5746
5747class Contains(Func):
5748    arg_types = {"this": True, "expression": True}
5749
5750
5751# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5752class ConnectByRoot(Func):
5753    pass
5754
5755
5756class Count(AggFunc):
5757    arg_types = {"this": False, "expressions": False, "big_int": False}
5758    is_var_len_args = True
5759
5760
5761class CountIf(AggFunc):
5762    _sql_names = ["COUNT_IF", "COUNTIF"]
5763
5764
5765# cube root
5766class Cbrt(Func):
5767    pass
5768
5769
5770class CurrentDate(Func):
5771    arg_types = {"this": False}
5772
5773
5774class CurrentDatetime(Func):
5775    arg_types = {"this": False}
5776
5777
5778class CurrentTime(Func):
5779    arg_types = {"this": False}
5780
5781
5782class CurrentTimestamp(Func):
5783    arg_types = {"this": False, "sysdate": False}
5784
5785
5786class CurrentSchema(Func):
5787    arg_types = {"this": False}
5788
5789
5790class CurrentUser(Func):
5791    arg_types = {"this": False}
5792
5793
5794class DateAdd(Func, IntervalOp):
5795    arg_types = {"this": True, "expression": True, "unit": False}
5796
5797
5798class DateBin(Func, IntervalOp):
5799    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5800
5801
5802class DateSub(Func, IntervalOp):
5803    arg_types = {"this": True, "expression": True, "unit": False}
5804
5805
5806class DateDiff(Func, TimeUnit):
5807    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5808    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5809
5810
5811class DateTrunc(Func):
5812    arg_types = {"unit": True, "this": True, "zone": False}
5813
5814    def __init__(self, **args):
5815        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5816        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5817        unabbreviate = args.pop("unabbreviate", True)
5818
5819        unit = args.get("unit")
5820        if isinstance(unit, TimeUnit.VAR_LIKE):
5821            unit_name = unit.name.upper()
5822            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5823                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5824
5825            args["unit"] = Literal.string(unit_name)
5826        elif isinstance(unit, Week):
5827            unit.set("this", Literal.string(unit.this.name.upper()))
5828
5829        super().__init__(**args)
5830
5831    @property
5832    def unit(self) -> Expression:
5833        return self.args["unit"]
5834
5835
5836# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5837# expression can either be time_expr or time_zone
5838class Datetime(Func):
5839    arg_types = {"this": True, "expression": False}
5840
5841
5842class DatetimeAdd(Func, IntervalOp):
5843    arg_types = {"this": True, "expression": True, "unit": False}
5844
5845
5846class DatetimeSub(Func, IntervalOp):
5847    arg_types = {"this": True, "expression": True, "unit": False}
5848
5849
5850class DatetimeDiff(Func, TimeUnit):
5851    arg_types = {"this": True, "expression": True, "unit": False}
5852
5853
5854class DatetimeTrunc(Func, TimeUnit):
5855    arg_types = {"this": True, "unit": True, "zone": False}
5856
5857
5858class DayOfWeek(Func):
5859    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5860
5861
5862# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5863# ISO day of week function in duckdb is ISODOW
5864class DayOfWeekIso(Func):
5865    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5866
5867
5868class DayOfMonth(Func):
5869    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5870
5871
5872class DayOfYear(Func):
5873    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5874
5875
5876class ToDays(Func):
5877    pass
5878
5879
5880class WeekOfYear(Func):
5881    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5882
5883
5884class MonthsBetween(Func):
5885    arg_types = {"this": True, "expression": True, "roundoff": False}
5886
5887
5888class MakeInterval(Func):
5889    arg_types = {
5890        "year": False,
5891        "month": False,
5892        "day": False,
5893        "hour": False,
5894        "minute": False,
5895        "second": False,
5896    }
5897
5898
5899class LastDay(Func, TimeUnit):
5900    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5901    arg_types = {"this": True, "unit": False}
5902
5903
5904class Extract(Func):
5905    arg_types = {"this": True, "expression": True}
5906
5907
5908class Exists(Func, SubqueryPredicate):
5909    arg_types = {"this": True, "expression": False}
5910
5911
5912class Timestamp(Func):
5913    arg_types = {"this": False, "zone": False, "with_tz": False}
5914
5915
5916class TimestampAdd(Func, TimeUnit):
5917    arg_types = {"this": True, "expression": True, "unit": False}
5918
5919
5920class TimestampSub(Func, TimeUnit):
5921    arg_types = {"this": True, "expression": True, "unit": False}
5922
5923
5924class TimestampDiff(Func, TimeUnit):
5925    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5926    arg_types = {"this": True, "expression": True, "unit": False}
5927
5928
5929class TimestampTrunc(Func, TimeUnit):
5930    arg_types = {"this": True, "unit": True, "zone": False}
5931
5932
5933class TimeAdd(Func, TimeUnit):
5934    arg_types = {"this": True, "expression": True, "unit": False}
5935
5936
5937class TimeSub(Func, TimeUnit):
5938    arg_types = {"this": True, "expression": True, "unit": False}
5939
5940
5941class TimeDiff(Func, TimeUnit):
5942    arg_types = {"this": True, "expression": True, "unit": False}
5943
5944
5945class TimeTrunc(Func, TimeUnit):
5946    arg_types = {"this": True, "unit": True, "zone": False}
5947
5948
5949class DateFromParts(Func):
5950    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5951    arg_types = {"year": True, "month": True, "day": True}
5952
5953
5954class TimeFromParts(Func):
5955    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5956    arg_types = {
5957        "hour": True,
5958        "min": True,
5959        "sec": True,
5960        "nano": False,
5961        "fractions": False,
5962        "precision": False,
5963    }
5964
5965
5966class DateStrToDate(Func):
5967    pass
5968
5969
5970class DateToDateStr(Func):
5971    pass
5972
5973
5974class DateToDi(Func):
5975    pass
5976
5977
5978# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5979class Date(Func):
5980    arg_types = {"this": False, "zone": False, "expressions": False}
5981    is_var_len_args = True
5982
5983
5984class Day(Func):
5985    pass
5986
5987
5988class Decode(Func):
5989    arg_types = {"this": True, "charset": True, "replace": False}
5990
5991
5992class DiToDate(Func):
5993    pass
5994
5995
5996class Encode(Func):
5997    arg_types = {"this": True, "charset": True}
5998
5999
6000class Exp(Func):
6001    pass
6002
6003
6004# https://docs.snowflake.com/en/sql-reference/functions/flatten
6005class Explode(Func, UDTF):
6006    arg_types = {"this": True, "expressions": False}
6007    is_var_len_args = True
6008
6009
6010# https://spark.apache.org/docs/latest/api/sql/#inline
6011class Inline(Func):
6012    pass
6013
6014
6015class ExplodeOuter(Explode):
6016    pass
6017
6018
6019class Posexplode(Explode):
6020    pass
6021
6022
6023class PosexplodeOuter(Posexplode, ExplodeOuter):
6024    pass
6025
6026
6027class Unnest(Func, UDTF):
6028    arg_types = {
6029        "expressions": True,
6030        "alias": False,
6031        "offset": False,
6032        "explode_array": False,
6033    }
6034
6035    @property
6036    def selects(self) -> t.List[Expression]:
6037        columns = super().selects
6038        offset = self.args.get("offset")
6039        if offset:
6040            columns = columns + [to_identifier("offset") if offset is True else offset]
6041        return columns
6042
6043
6044class Floor(Func):
6045    arg_types = {"this": True, "decimals": False, "to": False}
6046
6047
6048class FromBase64(Func):
6049    pass
6050
6051
6052class FeaturesAtTime(Func):
6053    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
6054
6055
6056class ToBase64(Func):
6057    pass
6058
6059
6060# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
6061class FromISO8601Timestamp(Func):
6062    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
6063
6064
6065class GapFill(Func):
6066    arg_types = {
6067        "this": True,
6068        "ts_column": True,
6069        "bucket_width": True,
6070        "partitioning_columns": False,
6071        "value_columns": False,
6072        "origin": False,
6073        "ignore_nulls": False,
6074    }
6075
6076
6077# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
6078class GenerateDateArray(Func):
6079    arg_types = {"start": True, "end": True, "step": False}
6080
6081
6082# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
6083class GenerateTimestampArray(Func):
6084    arg_types = {"start": True, "end": True, "step": True}
6085
6086
6087class Greatest(Func):
6088    arg_types = {"this": True, "expressions": False}
6089    is_var_len_args = True
6090
6091
6092# Trino's `ON OVERFLOW TRUNCATE [filler_string] {WITH | WITHOUT} COUNT`
6093# https://trino.io/docs/current/functions/aggregate.html#listagg
6094class OverflowTruncateBehavior(Expression):
6095    arg_types = {"this": False, "with_count": True}
6096
6097
6098class GroupConcat(AggFunc):
6099    arg_types = {"this": True, "separator": False, "on_overflow": False}
6100
6101
6102class Hex(Func):
6103    pass
6104
6105
6106class LowerHex(Hex):
6107    pass
6108
6109
6110class And(Connector, Func):
6111    pass
6112
6113
6114class Or(Connector, Func):
6115    pass
6116
6117
6118class Xor(Connector, Func):
6119    arg_types = {"this": False, "expression": False, "expressions": False}
6120
6121
6122class If(Func):
6123    arg_types = {"this": True, "true": True, "false": False}
6124    _sql_names = ["IF", "IIF"]
6125
6126
6127class Nullif(Func):
6128    arg_types = {"this": True, "expression": True}
6129
6130
6131class Initcap(Func):
6132    arg_types = {"this": True, "expression": False}
6133
6134
6135class IsAscii(Func):
6136    pass
6137
6138
6139class IsNan(Func):
6140    _sql_names = ["IS_NAN", "ISNAN"]
6141
6142
6143# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#int64_for_json
6144class Int64(Func):
6145    pass
6146
6147
6148class IsInf(Func):
6149    _sql_names = ["IS_INF", "ISINF"]
6150
6151
6152# https://www.postgresql.org/docs/current/functions-json.html
6153class JSON(Expression):
6154    arg_types = {"this": False, "with": False, "unique": False}
6155
6156
6157class JSONPath(Expression):
6158    arg_types = {"expressions": True, "escape": False}
6159
6160    @property
6161    def output_name(self) -> str:
6162        last_segment = self.expressions[-1].this
6163        return last_segment if isinstance(last_segment, str) else ""
6164
6165
6166class JSONPathPart(Expression):
6167    arg_types = {}
6168
6169
6170class JSONPathFilter(JSONPathPart):
6171    arg_types = {"this": True}
6172
6173
6174class JSONPathKey(JSONPathPart):
6175    arg_types = {"this": True}
6176
6177
6178class JSONPathRecursive(JSONPathPart):
6179    arg_types = {"this": False}
6180
6181
6182class JSONPathRoot(JSONPathPart):
6183    pass
6184
6185
6186class JSONPathScript(JSONPathPart):
6187    arg_types = {"this": True}
6188
6189
6190class JSONPathSlice(JSONPathPart):
6191    arg_types = {"start": False, "end": False, "step": False}
6192
6193
6194class JSONPathSelector(JSONPathPart):
6195    arg_types = {"this": True}
6196
6197
6198class JSONPathSubscript(JSONPathPart):
6199    arg_types = {"this": True}
6200
6201
6202class JSONPathUnion(JSONPathPart):
6203    arg_types = {"expressions": True}
6204
6205
6206class JSONPathWildcard(JSONPathPart):
6207    pass
6208
6209
6210class FormatJson(Expression):
6211    pass
6212
6213
6214class JSONKeyValue(Expression):
6215    arg_types = {"this": True, "expression": True}
6216
6217
6218class JSONObject(Func):
6219    arg_types = {
6220        "expressions": False,
6221        "null_handling": False,
6222        "unique_keys": False,
6223        "return_type": False,
6224        "encoding": False,
6225    }
6226
6227
6228class JSONObjectAgg(AggFunc):
6229    arg_types = {
6230        "expressions": False,
6231        "null_handling": False,
6232        "unique_keys": False,
6233        "return_type": False,
6234        "encoding": False,
6235    }
6236
6237
6238# https://www.postgresql.org/docs/9.5/functions-aggregate.html
6239class JSONBObjectAgg(AggFunc):
6240    arg_types = {"this": True, "expression": True}
6241
6242
6243# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
6244class JSONArray(Func):
6245    arg_types = {
6246        "expressions": True,
6247        "null_handling": False,
6248        "return_type": False,
6249        "strict": False,
6250    }
6251
6252
6253# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
6254class JSONArrayAgg(Func):
6255    arg_types = {
6256        "this": True,
6257        "order": False,
6258        "null_handling": False,
6259        "return_type": False,
6260        "strict": False,
6261    }
6262
6263
6264class JSONExists(Func):
6265    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
6266
6267
6268# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6269# Note: parsing of JSON column definitions is currently incomplete.
6270class JSONColumnDef(Expression):
6271    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
6272
6273
6274class JSONSchema(Expression):
6275    arg_types = {"expressions": True}
6276
6277
6278# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
6279class JSONValue(Expression):
6280    arg_types = {
6281        "this": True,
6282        "path": True,
6283        "returning": False,
6284        "on_condition": False,
6285    }
6286
6287
6288class JSONValueArray(Func):
6289    arg_types = {"this": True, "expression": False}
6290
6291
6292# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6293class JSONTable(Func):
6294    arg_types = {
6295        "this": True,
6296        "schema": True,
6297        "path": False,
6298        "error_handling": False,
6299        "empty_handling": False,
6300    }
6301
6302
6303# https://docs.snowflake.com/en/sql-reference/functions/object_insert
6304class ObjectInsert(Func):
6305    arg_types = {
6306        "this": True,
6307        "key": True,
6308        "value": True,
6309        "update_flag": False,
6310    }
6311
6312
6313class OpenJSONColumnDef(Expression):
6314    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
6315
6316
6317class OpenJSON(Func):
6318    arg_types = {"this": True, "path": False, "expressions": False}
6319
6320
6321class JSONBContains(Binary, Func):
6322    _sql_names = ["JSONB_CONTAINS"]
6323
6324
6325class JSONBExists(Func):
6326    arg_types = {"this": True, "path": True}
6327    _sql_names = ["JSONB_EXISTS"]
6328
6329
6330class JSONExtract(Binary, Func):
6331    arg_types = {
6332        "this": True,
6333        "expression": True,
6334        "only_json_types": False,
6335        "expressions": False,
6336        "variant_extract": False,
6337        "json_query": False,
6338        "option": False,
6339        "quote": False,
6340        "on_condition": False,
6341    }
6342    _sql_names = ["JSON_EXTRACT"]
6343    is_var_len_args = True
6344
6345    @property
6346    def output_name(self) -> str:
6347        return self.expression.output_name if not self.expressions else ""
6348
6349
6350# https://trino.io/docs/current/functions/json.html#json-query
6351class JSONExtractQuote(Expression):
6352    arg_types = {
6353        "option": True,
6354        "scalar": False,
6355    }
6356
6357
6358class JSONExtractArray(Func):
6359    arg_types = {"this": True, "expression": False}
6360    _sql_names = ["JSON_EXTRACT_ARRAY"]
6361
6362
6363class JSONExtractScalar(Binary, Func):
6364    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6365    _sql_names = ["JSON_EXTRACT_SCALAR"]
6366    is_var_len_args = True
6367
6368    @property
6369    def output_name(self) -> str:
6370        return self.expression.output_name
6371
6372
6373class JSONBExtract(Binary, Func):
6374    _sql_names = ["JSONB_EXTRACT"]
6375
6376
6377class JSONBExtractScalar(Binary, Func):
6378    _sql_names = ["JSONB_EXTRACT_SCALAR"]
6379
6380
6381class JSONFormat(Func):
6382    arg_types = {"this": False, "options": False, "is_json": False}
6383    _sql_names = ["JSON_FORMAT"]
6384
6385
6386# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
6387class JSONArrayContains(Binary, Predicate, Func):
6388    _sql_names = ["JSON_ARRAY_CONTAINS"]
6389
6390
6391class ParseJSON(Func):
6392    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6393    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6394    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6395    arg_types = {"this": True, "expression": False, "safe": False}
6396
6397
6398class Least(Func):
6399    arg_types = {"this": True, "expressions": False}
6400    is_var_len_args = True
6401
6402
6403class Left(Func):
6404    arg_types = {"this": True, "expression": True}
6405
6406
6407class Right(Func):
6408    arg_types = {"this": True, "expression": True}
6409
6410
6411class Length(Func):
6412    arg_types = {"this": True, "binary": False, "encoding": False}
6413    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
6414
6415
6416class Levenshtein(Func):
6417    arg_types = {
6418        "this": True,
6419        "expression": False,
6420        "ins_cost": False,
6421        "del_cost": False,
6422        "sub_cost": False,
6423        "max_dist": False,
6424    }
6425
6426
6427class Ln(Func):
6428    pass
6429
6430
6431class Log(Func):
6432    arg_types = {"this": True, "expression": False}
6433
6434
6435class LogicalOr(AggFunc):
6436    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
6437
6438
6439class LogicalAnd(AggFunc):
6440    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
6441
6442
6443class Lower(Func):
6444    _sql_names = ["LOWER", "LCASE"]
6445
6446
6447class Map(Func):
6448    arg_types = {"keys": False, "values": False}
6449
6450    @property
6451    def keys(self) -> t.List[Expression]:
6452        keys = self.args.get("keys")
6453        return keys.expressions if keys else []
6454
6455    @property
6456    def values(self) -> t.List[Expression]:
6457        values = self.args.get("values")
6458        return values.expressions if values else []
6459
6460
6461# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
6462class ToMap(Func):
6463    pass
6464
6465
6466class MapFromEntries(Func):
6467    pass
6468
6469
6470# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
6471class ScopeResolution(Expression):
6472    arg_types = {"this": False, "expression": True}
6473
6474
6475class Stream(Expression):
6476    pass
6477
6478
6479class StarMap(Func):
6480    pass
6481
6482
6483class VarMap(Func):
6484    arg_types = {"keys": True, "values": True}
6485    is_var_len_args = True
6486
6487    @property
6488    def keys(self) -> t.List[Expression]:
6489        return self.args["keys"].expressions
6490
6491    @property
6492    def values(self) -> t.List[Expression]:
6493        return self.args["values"].expressions
6494
6495
6496# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
6497class MatchAgainst(Func):
6498    arg_types = {"this": True, "expressions": True, "modifier": False}
6499
6500
6501class Max(AggFunc):
6502    arg_types = {"this": True, "expressions": False}
6503    is_var_len_args = True
6504
6505
6506class MD5(Func):
6507    _sql_names = ["MD5"]
6508
6509
6510# Represents the variant of the MD5 function that returns a binary value
6511class MD5Digest(Func):
6512    _sql_names = ["MD5_DIGEST"]
6513
6514
6515class Median(AggFunc):
6516    pass
6517
6518
6519class Min(AggFunc):
6520    arg_types = {"this": True, "expressions": False}
6521    is_var_len_args = True
6522
6523
6524class Month(Func):
6525    pass
6526
6527
6528class AddMonths(Func):
6529    arg_types = {"this": True, "expression": True}
6530
6531
6532class Nvl2(Func):
6533    arg_types = {"this": True, "true": True, "false": False}
6534
6535
6536class Normalize(Func):
6537    arg_types = {"this": True, "form": False}
6538
6539
6540class Overlay(Func):
6541    arg_types = {"this": True, "expression": True, "from": True, "for": False}
6542
6543
6544# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
6545class Predict(Func):
6546    arg_types = {"this": True, "expression": True, "params_struct": False}
6547
6548
6549class Pow(Binary, Func):
6550    _sql_names = ["POWER", "POW"]
6551
6552
6553class PercentileCont(AggFunc):
6554    arg_types = {"this": True, "expression": False}
6555
6556
6557class PercentileDisc(AggFunc):
6558    arg_types = {"this": True, "expression": False}
6559
6560
6561class Quantile(AggFunc):
6562    arg_types = {"this": True, "quantile": True}
6563
6564
6565class ApproxQuantile(Quantile):
6566    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
6567
6568
6569class Quarter(Func):
6570    pass
6571
6572
6573# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
6574# teradata lower and upper bounds
6575class Rand(Func):
6576    _sql_names = ["RAND", "RANDOM"]
6577    arg_types = {"this": False, "lower": False, "upper": False}
6578
6579
6580class Randn(Func):
6581    arg_types = {"this": False}
6582
6583
6584class RangeN(Func):
6585    arg_types = {"this": True, "expressions": True, "each": False}
6586
6587
6588class ReadCSV(Func):
6589    _sql_names = ["READ_CSV"]
6590    is_var_len_args = True
6591    arg_types = {"this": True, "expressions": False}
6592
6593
6594class Reduce(Func):
6595    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
6596
6597
6598class RegexpExtract(Func):
6599    arg_types = {
6600        "this": True,
6601        "expression": True,
6602        "position": False,
6603        "occurrence": False,
6604        "parameters": False,
6605        "group": False,
6606    }
6607
6608
6609class RegexpExtractAll(Func):
6610    arg_types = {
6611        "this": True,
6612        "expression": True,
6613        "position": False,
6614        "occurrence": False,
6615        "parameters": False,
6616        "group": False,
6617    }
6618
6619
6620class RegexpReplace(Func):
6621    arg_types = {
6622        "this": True,
6623        "expression": True,
6624        "replacement": False,
6625        "position": False,
6626        "occurrence": False,
6627        "modifiers": False,
6628    }
6629
6630
6631class RegexpLike(Binary, Func):
6632    arg_types = {"this": True, "expression": True, "flag": False}
6633
6634
6635class RegexpILike(Binary, Func):
6636    arg_types = {"this": True, "expression": True, "flag": False}
6637
6638
6639# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6640# limit is the number of times a pattern is applied
6641class RegexpSplit(Func):
6642    arg_types = {"this": True, "expression": True, "limit": False}
6643
6644
6645class Repeat(Func):
6646    arg_types = {"this": True, "times": True}
6647
6648
6649# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6650# tsql third argument function == trunctaion if not 0
6651class Round(Func):
6652    arg_types = {"this": True, "decimals": False, "truncate": False}
6653
6654
6655class RowNumber(Func):
6656    arg_types = {"this": False}
6657
6658
6659class SafeDivide(Func):
6660    arg_types = {"this": True, "expression": True}
6661
6662
6663class SHA(Func):
6664    _sql_names = ["SHA", "SHA1"]
6665
6666
6667class SHA2(Func):
6668    _sql_names = ["SHA2"]
6669    arg_types = {"this": True, "length": False}
6670
6671
6672class Sign(Func):
6673    _sql_names = ["SIGN", "SIGNUM"]
6674
6675
6676class SortArray(Func):
6677    arg_types = {"this": True, "asc": False}
6678
6679
6680class Split(Func):
6681    arg_types = {"this": True, "expression": True, "limit": False}
6682
6683
6684# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split_part.html
6685class SplitPart(Func):
6686    arg_types = {"this": True, "delimiter": True, "part_index": True}
6687
6688
6689# Start may be omitted in the case of postgres
6690# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6691class Substring(Func):
6692    _sql_names = ["SUBSTRING", "SUBSTR"]
6693    arg_types = {"this": True, "start": False, "length": False}
6694
6695
6696class StandardHash(Func):
6697    arg_types = {"this": True, "expression": False}
6698
6699
6700class StartsWith(Func):
6701    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6702    arg_types = {"this": True, "expression": True}
6703
6704
6705class StrPosition(Func):
6706    arg_types = {
6707        "this": True,
6708        "substr": True,
6709        "position": False,
6710        "occurrence": False,
6711    }
6712
6713
6714class StrToDate(Func):
6715    arg_types = {"this": True, "format": False, "safe": False}
6716
6717
6718class StrToTime(Func):
6719    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6720
6721
6722# Spark allows unix_timestamp()
6723# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6724class StrToUnix(Func):
6725    arg_types = {"this": False, "format": False}
6726
6727
6728# https://prestodb.io/docs/current/functions/string.html
6729# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6730class StrToMap(Func):
6731    arg_types = {
6732        "this": True,
6733        "pair_delim": False,
6734        "key_value_delim": False,
6735        "duplicate_resolution_callback": False,
6736    }
6737
6738
6739class NumberToStr(Func):
6740    arg_types = {"this": True, "format": True, "culture": False}
6741
6742
6743class FromBase(Func):
6744    arg_types = {"this": True, "expression": True}
6745
6746
6747class Struct(Func):
6748    arg_types = {"expressions": False}
6749    is_var_len_args = True
6750
6751
6752class StructExtract(Func):
6753    arg_types = {"this": True, "expression": True}
6754
6755
6756# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6757# https://docs.snowflake.com/en/sql-reference/functions/insert
6758class Stuff(Func):
6759    _sql_names = ["STUFF", "INSERT"]
6760    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6761
6762
6763class Sum(AggFunc):
6764    pass
6765
6766
6767class Sqrt(Func):
6768    pass
6769
6770
6771class Stddev(AggFunc):
6772    _sql_names = ["STDDEV", "STDEV"]
6773
6774
6775class StddevPop(AggFunc):
6776    pass
6777
6778
6779class StddevSamp(AggFunc):
6780    pass
6781
6782
6783# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6784class Time(Func):
6785    arg_types = {"this": False, "zone": False}
6786
6787
6788class TimeToStr(Func):
6789    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6790
6791
6792class TimeToTimeStr(Func):
6793    pass
6794
6795
6796class TimeToUnix(Func):
6797    pass
6798
6799
6800class TimeStrToDate(Func):
6801    pass
6802
6803
6804class TimeStrToTime(Func):
6805    arg_types = {"this": True, "zone": False}
6806
6807
6808class TimeStrToUnix(Func):
6809    pass
6810
6811
6812class Trim(Func):
6813    arg_types = {
6814        "this": True,
6815        "expression": False,
6816        "position": False,
6817        "collation": False,
6818    }
6819
6820
6821class TsOrDsAdd(Func, TimeUnit):
6822    # return_type is used to correctly cast the arguments of this expression when transpiling it
6823    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6824
6825    @property
6826    def return_type(self) -> DataType:
6827        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
6828
6829
6830class TsOrDsDiff(Func, TimeUnit):
6831    arg_types = {"this": True, "expression": True, "unit": False}
6832
6833
6834class TsOrDsToDateStr(Func):
6835    pass
6836
6837
6838class TsOrDsToDate(Func):
6839    arg_types = {"this": True, "format": False, "safe": False}
6840
6841
6842class TsOrDsToDatetime(Func):
6843    pass
6844
6845
6846class TsOrDsToTime(Func):
6847    arg_types = {"this": True, "format": False, "safe": False}
6848
6849
6850class TsOrDsToTimestamp(Func):
6851    pass
6852
6853
6854class TsOrDiToDi(Func):
6855    pass
6856
6857
6858class Unhex(Func):
6859    arg_types = {"this": True, "expression": False}
6860
6861
6862class Unicode(Func):
6863    pass
6864
6865
6866# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
6867class UnixDate(Func):
6868    pass
6869
6870
6871class UnixToStr(Func):
6872    arg_types = {"this": True, "format": False}
6873
6874
6875# https://prestodb.io/docs/current/functions/datetime.html
6876# presto has weird zone/hours/minutes
6877class UnixToTime(Func):
6878    arg_types = {
6879        "this": True,
6880        "scale": False,
6881        "zone": False,
6882        "hours": False,
6883        "minutes": False,
6884        "format": False,
6885    }
6886
6887    SECONDS = Literal.number(0)
6888    DECIS = Literal.number(1)
6889    CENTIS = Literal.number(2)
6890    MILLIS = Literal.number(3)
6891    DECIMILLIS = Literal.number(4)
6892    CENTIMILLIS = Literal.number(5)
6893    MICROS = Literal.number(6)
6894    DECIMICROS = Literal.number(7)
6895    CENTIMICROS = Literal.number(8)
6896    NANOS = Literal.number(9)
6897
6898
6899class UnixToTimeStr(Func):
6900    pass
6901
6902
6903class UnixSeconds(Func):
6904    pass
6905
6906
6907class Uuid(Func):
6908    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6909
6910    arg_types = {"this": False, "name": False}
6911
6912
6913class TimestampFromParts(Func):
6914    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6915    arg_types = {
6916        "year": True,
6917        "month": True,
6918        "day": True,
6919        "hour": True,
6920        "min": True,
6921        "sec": True,
6922        "nano": False,
6923        "zone": False,
6924        "milli": False,
6925    }
6926
6927
6928class Upper(Func):
6929    _sql_names = ["UPPER", "UCASE"]
6930
6931
6932class Corr(Binary, AggFunc):
6933    pass
6934
6935
6936class Variance(AggFunc):
6937    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6938
6939
6940class VariancePop(AggFunc):
6941    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6942
6943
6944class CovarSamp(Binary, AggFunc):
6945    pass
6946
6947
6948class CovarPop(Binary, AggFunc):
6949    pass
6950
6951
6952class Week(Func):
6953    arg_types = {"this": True, "mode": False}
6954
6955
6956class XMLElement(Func):
6957    _sql_names = ["XMLELEMENT"]
6958    arg_types = {"this": True, "expressions": False}
6959
6960
6961class XMLTable(Func):
6962    arg_types = {
6963        "this": True,
6964        "namespaces": False,
6965        "passing": False,
6966        "columns": False,
6967        "by_ref": False,
6968    }
6969
6970
6971class XMLNamespace(Expression):
6972    pass
6973
6974
6975class Year(Func):
6976    pass
6977
6978
6979class Use(Expression):
6980    arg_types = {"this": False, "expressions": False, "kind": False}
6981
6982
6983class Merge(DML):
6984    arg_types = {
6985        "this": True,
6986        "using": True,
6987        "on": True,
6988        "whens": True,
6989        "with": False,
6990        "returning": False,
6991    }
6992
6993
6994class When(Expression):
6995    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6996
6997
6998class Whens(Expression):
6999    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7000
7001    arg_types = {"expressions": True}
7002
7003
7004# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
7005# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
7006class NextValueFor(Func):
7007    arg_types = {"this": True, "order": False}
7008
7009
7010# Refers to a trailing semi-colon. This is only used to preserve trailing comments
7011# select 1; -- my comment
7012class Semicolon(Expression):
7013    arg_types = {}
7014
7015
7016def _norm_arg(arg):
7017    return arg.lower() if type(arg) is str else arg
7018
7019
7020ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
7021FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
7022
7023JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
7024
7025PERCENTILES = (PercentileCont, PercentileDisc)
7026
7027
7028# Helpers
7029@t.overload
7030def maybe_parse(
7031    sql_or_expression: ExpOrStr,
7032    *,
7033    into: t.Type[E],
7034    dialect: DialectType = None,
7035    prefix: t.Optional[str] = None,
7036    copy: bool = False,
7037    **opts,
7038) -> E: ...
7039
7040
7041@t.overload
7042def maybe_parse(
7043    sql_or_expression: str | E,
7044    *,
7045    into: t.Optional[IntoType] = None,
7046    dialect: DialectType = None,
7047    prefix: t.Optional[str] = None,
7048    copy: bool = False,
7049    **opts,
7050) -> E: ...
7051
7052
7053def maybe_parse(
7054    sql_or_expression: ExpOrStr,
7055    *,
7056    into: t.Optional[IntoType] = None,
7057    dialect: DialectType = None,
7058    prefix: t.Optional[str] = None,
7059    copy: bool = False,
7060    **opts,
7061) -> Expression:
7062    """Gracefully handle a possible string or expression.
7063
7064    Example:
7065        >>> maybe_parse("1")
7066        Literal(this=1, is_string=False)
7067        >>> maybe_parse(to_identifier("x"))
7068        Identifier(this=x, quoted=False)
7069
7070    Args:
7071        sql_or_expression: the SQL code string or an expression
7072        into: the SQLGlot Expression to parse into
7073        dialect: the dialect used to parse the input expressions (in the case that an
7074            input expression is a SQL string).
7075        prefix: a string to prefix the sql with before it gets parsed
7076            (automatically includes a space)
7077        copy: whether to copy the expression.
7078        **opts: other options to use to parse the input expressions (again, in the case
7079            that an input expression is a SQL string).
7080
7081    Returns:
7082        Expression: the parsed or given expression.
7083    """
7084    if isinstance(sql_or_expression, Expression):
7085        if copy:
7086            return sql_or_expression.copy()
7087        return sql_or_expression
7088
7089    if sql_or_expression is None:
7090        raise ParseError("SQL cannot be None")
7091
7092    import sqlglot
7093
7094    sql = str(sql_or_expression)
7095    if prefix:
7096        sql = f"{prefix} {sql}"
7097
7098    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
7099
7100
7101@t.overload
7102def maybe_copy(instance: None, copy: bool = True) -> None: ...
7103
7104
7105@t.overload
7106def maybe_copy(instance: E, copy: bool = True) -> E: ...
7107
7108
7109def maybe_copy(instance, copy=True):
7110    return instance.copy() if copy and instance else instance
7111
7112
7113def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str:
7114    """Generate a textual representation of an Expression tree"""
7115    indent = "\n" + ("  " * (level + 1))
7116    delim = f",{indent}"
7117
7118    if isinstance(node, Expression):
7119        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
7120
7121        if (node.type or verbose) and not isinstance(node, DataType):
7122            args["_type"] = node.type
7123        if node.comments or verbose:
7124            args["_comments"] = node.comments
7125
7126        if verbose:
7127            args["_id"] = id(node)
7128
7129        # Inline leaves for a more compact representation
7130        if node.is_leaf():
7131            indent = ""
7132            delim = ", "
7133
7134        repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted)
7135        items = delim.join(
7136            [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()]
7137        )
7138        return f"{node.__class__.__name__}({indent}{items})"
7139
7140    if isinstance(node, list):
7141        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
7142        items = f"{indent}{items}" if items else ""
7143        return f"[{items}]"
7144
7145    # We use the representation of the string to avoid stripping out important whitespace
7146    if repr_str and isinstance(node, str):
7147        node = repr(node)
7148
7149    # Indent multiline strings to match the current level
7150    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
7151
7152
7153def _is_wrong_expression(expression, into):
7154    return isinstance(expression, Expression) and not isinstance(expression, into)
7155
7156
7157def _apply_builder(
7158    expression,
7159    instance,
7160    arg,
7161    copy=True,
7162    prefix=None,
7163    into=None,
7164    dialect=None,
7165    into_arg="this",
7166    **opts,
7167):
7168    if _is_wrong_expression(expression, into):
7169        expression = into(**{into_arg: expression})
7170    instance = maybe_copy(instance, copy)
7171    expression = maybe_parse(
7172        sql_or_expression=expression,
7173        prefix=prefix,
7174        into=into,
7175        dialect=dialect,
7176        **opts,
7177    )
7178    instance.set(arg, expression)
7179    return instance
7180
7181
7182def _apply_child_list_builder(
7183    *expressions,
7184    instance,
7185    arg,
7186    append=True,
7187    copy=True,
7188    prefix=None,
7189    into=None,
7190    dialect=None,
7191    properties=None,
7192    **opts,
7193):
7194    instance = maybe_copy(instance, copy)
7195    parsed = []
7196    properties = {} if properties is None else properties
7197
7198    for expression in expressions:
7199        if expression is not None:
7200            if _is_wrong_expression(expression, into):
7201                expression = into(expressions=[expression])
7202
7203            expression = maybe_parse(
7204                expression,
7205                into=into,
7206                dialect=dialect,
7207                prefix=prefix,
7208                **opts,
7209            )
7210            for k, v in expression.args.items():
7211                if k == "expressions":
7212                    parsed.extend(v)
7213                else:
7214                    properties[k] = v
7215
7216    existing = instance.args.get(arg)
7217    if append and existing:
7218        parsed = existing.expressions + parsed
7219
7220    child = into(expressions=parsed)
7221    for k, v in properties.items():
7222        child.set(k, v)
7223    instance.set(arg, child)
7224
7225    return instance
7226
7227
7228def _apply_list_builder(
7229    *expressions,
7230    instance,
7231    arg,
7232    append=True,
7233    copy=True,
7234    prefix=None,
7235    into=None,
7236    dialect=None,
7237    **opts,
7238):
7239    inst = maybe_copy(instance, copy)
7240
7241    expressions = [
7242        maybe_parse(
7243            sql_or_expression=expression,
7244            into=into,
7245            prefix=prefix,
7246            dialect=dialect,
7247            **opts,
7248        )
7249        for expression in expressions
7250        if expression is not None
7251    ]
7252
7253    existing_expressions = inst.args.get(arg)
7254    if append and existing_expressions:
7255        expressions = existing_expressions + expressions
7256
7257    inst.set(arg, expressions)
7258    return inst
7259
7260
7261def _apply_conjunction_builder(
7262    *expressions,
7263    instance,
7264    arg,
7265    into=None,
7266    append=True,
7267    copy=True,
7268    dialect=None,
7269    **opts,
7270):
7271    expressions = [exp for exp in expressions if exp is not None and exp != ""]
7272    if not expressions:
7273        return instance
7274
7275    inst = maybe_copy(instance, copy)
7276
7277    existing = inst.args.get(arg)
7278    if append and existing is not None:
7279        expressions = [existing.this if into else existing] + list(expressions)
7280
7281    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
7282
7283    inst.set(arg, into(this=node) if into else node)
7284    return inst
7285
7286
7287def _apply_cte_builder(
7288    instance: E,
7289    alias: ExpOrStr,
7290    as_: ExpOrStr,
7291    recursive: t.Optional[bool] = None,
7292    materialized: t.Optional[bool] = None,
7293    append: bool = True,
7294    dialect: DialectType = None,
7295    copy: bool = True,
7296    scalar: bool = False,
7297    **opts,
7298) -> E:
7299    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
7300    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
7301    if scalar and not isinstance(as_expression, Subquery):
7302        # scalar CTE must be wrapped in a subquery
7303        as_expression = Subquery(this=as_expression)
7304    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
7305    return _apply_child_list_builder(
7306        cte,
7307        instance=instance,
7308        arg="with",
7309        append=append,
7310        copy=copy,
7311        into=With,
7312        properties={"recursive": recursive or False},
7313    )
7314
7315
7316def _combine(
7317    expressions: t.Sequence[t.Optional[ExpOrStr]],
7318    operator: t.Type[Connector],
7319    dialect: DialectType = None,
7320    copy: bool = True,
7321    wrap: bool = True,
7322    **opts,
7323) -> Expression:
7324    conditions = [
7325        condition(expression, dialect=dialect, copy=copy, **opts)
7326        for expression in expressions
7327        if expression is not None
7328    ]
7329
7330    this, *rest = conditions
7331    if rest and wrap:
7332        this = _wrap(this, Connector)
7333    for expression in rest:
7334        this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression)
7335
7336    return this
7337
7338
7339@t.overload
7340def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
7341
7342
7343@t.overload
7344def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
7345
7346
7347def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
7348    return Paren(this=expression) if isinstance(expression, kind) else expression
7349
7350
7351def _apply_set_operation(
7352    *expressions: ExpOrStr,
7353    set_operation: t.Type[S],
7354    distinct: bool = True,
7355    dialect: DialectType = None,
7356    copy: bool = True,
7357    **opts,
7358) -> S:
7359    return reduce(
7360        lambda x, y: set_operation(this=x, expression=y, distinct=distinct),
7361        (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7362    )
7363
7364
7365def union(
7366    *expressions: ExpOrStr,
7367    distinct: bool = True,
7368    dialect: DialectType = None,
7369    copy: bool = True,
7370    **opts,
7371) -> Union:
7372    """
7373    Initializes a syntax tree for the `UNION` operation.
7374
7375    Example:
7376        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7377        'SELECT * FROM foo UNION SELECT * FROM bla'
7378
7379    Args:
7380        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7381            If `Expression` instances are passed, they will be used as-is.
7382        distinct: set the DISTINCT flag if and only if this is true.
7383        dialect: the dialect used to parse the input expression.
7384        copy: whether to copy the expression.
7385        opts: other options to use to parse the input expressions.
7386
7387    Returns:
7388        The new Union instance.
7389    """
7390    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7391    return _apply_set_operation(
7392        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7393    )
7394
7395
7396def intersect(
7397    *expressions: ExpOrStr,
7398    distinct: bool = True,
7399    dialect: DialectType = None,
7400    copy: bool = True,
7401    **opts,
7402) -> Intersect:
7403    """
7404    Initializes a syntax tree for the `INTERSECT` operation.
7405
7406    Example:
7407        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7408        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7409
7410    Args:
7411        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7412            If `Expression` instances are passed, they will be used as-is.
7413        distinct: set the DISTINCT flag if and only if this is true.
7414        dialect: the dialect used to parse the input expression.
7415        copy: whether to copy the expression.
7416        opts: other options to use to parse the input expressions.
7417
7418    Returns:
7419        The new Intersect instance.
7420    """
7421    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7422    return _apply_set_operation(
7423        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7424    )
7425
7426
7427def except_(
7428    *expressions: ExpOrStr,
7429    distinct: bool = True,
7430    dialect: DialectType = None,
7431    copy: bool = True,
7432    **opts,
7433) -> Except:
7434    """
7435    Initializes a syntax tree for the `EXCEPT` operation.
7436
7437    Example:
7438        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7439        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7440
7441    Args:
7442        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7443            If `Expression` instances are passed, they will be used as-is.
7444        distinct: set the DISTINCT flag if and only if this is true.
7445        dialect: the dialect used to parse the input expression.
7446        copy: whether to copy the expression.
7447        opts: other options to use to parse the input expressions.
7448
7449    Returns:
7450        The new Except instance.
7451    """
7452    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7453    return _apply_set_operation(
7454        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7455    )
7456
7457
7458def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7459    """
7460    Initializes a syntax tree from one or multiple SELECT expressions.
7461
7462    Example:
7463        >>> select("col1", "col2").from_("tbl").sql()
7464        'SELECT col1, col2 FROM tbl'
7465
7466    Args:
7467        *expressions: the SQL code string to parse as the expressions of a
7468            SELECT statement. If an Expression instance is passed, this is used as-is.
7469        dialect: the dialect used to parse the input expressions (in the case that an
7470            input expression is a SQL string).
7471        **opts: other options to use to parse the input expressions (again, in the case
7472            that an input expression is a SQL string).
7473
7474    Returns:
7475        Select: the syntax tree for the SELECT statement.
7476    """
7477    return Select().select(*expressions, dialect=dialect, **opts)
7478
7479
7480def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7481    """
7482    Initializes a syntax tree from a FROM expression.
7483
7484    Example:
7485        >>> from_("tbl").select("col1", "col2").sql()
7486        'SELECT col1, col2 FROM tbl'
7487
7488    Args:
7489        *expression: the SQL code string to parse as the FROM expressions of a
7490            SELECT statement. If an Expression instance is passed, this is used as-is.
7491        dialect: the dialect used to parse the input expression (in the case that the
7492            input expression is a SQL string).
7493        **opts: other options to use to parse the input expressions (again, in the case
7494            that the input expression is a SQL string).
7495
7496    Returns:
7497        Select: the syntax tree for the SELECT statement.
7498    """
7499    return Select().from_(expression, dialect=dialect, **opts)
7500
7501
7502def update(
7503    table: str | Table,
7504    properties: t.Optional[dict] = None,
7505    where: t.Optional[ExpOrStr] = None,
7506    from_: t.Optional[ExpOrStr] = None,
7507    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7508    dialect: DialectType = None,
7509    **opts,
7510) -> Update:
7511    """
7512    Creates an update statement.
7513
7514    Example:
7515        >>> 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()
7516        "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"
7517
7518    Args:
7519        properties: dictionary of properties to SET which are
7520            auto converted to sql objects eg None -> NULL
7521        where: sql conditional parsed into a WHERE statement
7522        from_: sql statement parsed into a FROM statement
7523        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7524        dialect: the dialect used to parse the input expressions.
7525        **opts: other options to use to parse the input expressions.
7526
7527    Returns:
7528        Update: the syntax tree for the UPDATE statement.
7529    """
7530    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7531    if properties:
7532        update_expr.set(
7533            "expressions",
7534            [
7535                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7536                for k, v in properties.items()
7537            ],
7538        )
7539    if from_:
7540        update_expr.set(
7541            "from",
7542            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7543        )
7544    if isinstance(where, Condition):
7545        where = Where(this=where)
7546    if where:
7547        update_expr.set(
7548            "where",
7549            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7550        )
7551    if with_:
7552        cte_list = [
7553            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7554            for alias, qry in with_.items()
7555        ]
7556        update_expr.set(
7557            "with",
7558            With(expressions=cte_list),
7559        )
7560    return update_expr
7561
7562
7563def delete(
7564    table: ExpOrStr,
7565    where: t.Optional[ExpOrStr] = None,
7566    returning: t.Optional[ExpOrStr] = None,
7567    dialect: DialectType = None,
7568    **opts,
7569) -> Delete:
7570    """
7571    Builds a delete statement.
7572
7573    Example:
7574        >>> delete("my_table", where="id > 1").sql()
7575        'DELETE FROM my_table WHERE id > 1'
7576
7577    Args:
7578        where: sql conditional parsed into a WHERE statement
7579        returning: sql conditional parsed into a RETURNING statement
7580        dialect: the dialect used to parse the input expressions.
7581        **opts: other options to use to parse the input expressions.
7582
7583    Returns:
7584        Delete: the syntax tree for the DELETE statement.
7585    """
7586    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7587    if where:
7588        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7589    if returning:
7590        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7591    return delete_expr
7592
7593
7594def insert(
7595    expression: ExpOrStr,
7596    into: ExpOrStr,
7597    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7598    overwrite: t.Optional[bool] = None,
7599    returning: t.Optional[ExpOrStr] = None,
7600    dialect: DialectType = None,
7601    copy: bool = True,
7602    **opts,
7603) -> Insert:
7604    """
7605    Builds an INSERT statement.
7606
7607    Example:
7608        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7609        'INSERT INTO tbl VALUES (1, 2, 3)'
7610
7611    Args:
7612        expression: the sql string or expression of the INSERT statement
7613        into: the tbl to insert data to.
7614        columns: optionally the table's column names.
7615        overwrite: whether to INSERT OVERWRITE or not.
7616        returning: sql conditional parsed into a RETURNING statement
7617        dialect: the dialect used to parse the input expressions.
7618        copy: whether to copy the expression.
7619        **opts: other options to use to parse the input expressions.
7620
7621    Returns:
7622        Insert: the syntax tree for the INSERT statement.
7623    """
7624    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7625    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7626
7627    if columns:
7628        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7629
7630    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7631
7632    if returning:
7633        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7634
7635    return insert
7636
7637
7638def merge(
7639    *when_exprs: ExpOrStr,
7640    into: ExpOrStr,
7641    using: ExpOrStr,
7642    on: ExpOrStr,
7643    returning: t.Optional[ExpOrStr] = None,
7644    dialect: DialectType = None,
7645    copy: bool = True,
7646    **opts,
7647) -> Merge:
7648    """
7649    Builds a MERGE statement.
7650
7651    Example:
7652        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7653        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7654        ...       into="my_table",
7655        ...       using="source_table",
7656        ...       on="my_table.id = source_table.id").sql()
7657        '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)'
7658
7659    Args:
7660        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7661        into: The target table to merge data into.
7662        using: The source table to merge data from.
7663        on: The join condition for the merge.
7664        returning: The columns to return from the merge.
7665        dialect: The dialect used to parse the input expressions.
7666        copy: Whether to copy the expression.
7667        **opts: Other options to use to parse the input expressions.
7668
7669    Returns:
7670        Merge: The syntax tree for the MERGE statement.
7671    """
7672    expressions: t.List[Expression] = []
7673    for when_expr in when_exprs:
7674        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7675        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7676
7677    merge = Merge(
7678        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7679        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7680        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7681        whens=Whens(expressions=expressions),
7682    )
7683    if returning:
7684        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7685
7686    return merge
7687
7688
7689def condition(
7690    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7691) -> Condition:
7692    """
7693    Initialize a logical condition expression.
7694
7695    Example:
7696        >>> condition("x=1").sql()
7697        'x = 1'
7698
7699        This is helpful for composing larger logical syntax trees:
7700        >>> where = condition("x=1")
7701        >>> where = where.and_("y=1")
7702        >>> Select().from_("tbl").select("*").where(where).sql()
7703        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7704
7705    Args:
7706        *expression: the SQL code string to parse.
7707            If an Expression instance is passed, this is used as-is.
7708        dialect: the dialect used to parse the input expression (in the case that the
7709            input expression is a SQL string).
7710        copy: Whether to copy `expression` (only applies to expressions).
7711        **opts: other options to use to parse the input expressions (again, in the case
7712            that the input expression is a SQL string).
7713
7714    Returns:
7715        The new Condition instance
7716    """
7717    return maybe_parse(
7718        expression,
7719        into=Condition,
7720        dialect=dialect,
7721        copy=copy,
7722        **opts,
7723    )
7724
7725
7726def and_(
7727    *expressions: t.Optional[ExpOrStr],
7728    dialect: DialectType = None,
7729    copy: bool = True,
7730    wrap: bool = True,
7731    **opts,
7732) -> Condition:
7733    """
7734    Combine multiple conditions with an AND logical operator.
7735
7736    Example:
7737        >>> and_("x=1", and_("y=1", "z=1")).sql()
7738        'x = 1 AND (y = 1 AND z = 1)'
7739
7740    Args:
7741        *expressions: the SQL code strings to parse.
7742            If an Expression instance is passed, this is used as-is.
7743        dialect: the dialect used to parse the input expression.
7744        copy: whether to copy `expressions` (only applies to Expressions).
7745        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7746            precedence issues, but can be turned off when the produced AST is too deep and
7747            causes recursion-related issues.
7748        **opts: other options to use to parse the input expressions.
7749
7750    Returns:
7751        The new condition
7752    """
7753    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
7754
7755
7756def or_(
7757    *expressions: t.Optional[ExpOrStr],
7758    dialect: DialectType = None,
7759    copy: bool = True,
7760    wrap: bool = True,
7761    **opts,
7762) -> Condition:
7763    """
7764    Combine multiple conditions with an OR logical operator.
7765
7766    Example:
7767        >>> or_("x=1", or_("y=1", "z=1")).sql()
7768        'x = 1 OR (y = 1 OR z = 1)'
7769
7770    Args:
7771        *expressions: the SQL code strings to parse.
7772            If an Expression instance is passed, this is used as-is.
7773        dialect: the dialect used to parse the input expression.
7774        copy: whether to copy `expressions` (only applies to Expressions).
7775        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7776            precedence issues, but can be turned off when the produced AST is too deep and
7777            causes recursion-related issues.
7778        **opts: other options to use to parse the input expressions.
7779
7780    Returns:
7781        The new condition
7782    """
7783    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
7784
7785
7786def xor(
7787    *expressions: t.Optional[ExpOrStr],
7788    dialect: DialectType = None,
7789    copy: bool = True,
7790    wrap: bool = True,
7791    **opts,
7792) -> Condition:
7793    """
7794    Combine multiple conditions with an XOR logical operator.
7795
7796    Example:
7797        >>> xor("x=1", xor("y=1", "z=1")).sql()
7798        'x = 1 XOR (y = 1 XOR z = 1)'
7799
7800    Args:
7801        *expressions: the SQL code strings to parse.
7802            If an Expression instance is passed, this is used as-is.
7803        dialect: the dialect used to parse the input expression.
7804        copy: whether to copy `expressions` (only applies to Expressions).
7805        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7806            precedence issues, but can be turned off when the produced AST is too deep and
7807            causes recursion-related issues.
7808        **opts: other options to use to parse the input expressions.
7809
7810    Returns:
7811        The new condition
7812    """
7813    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
7814
7815
7816def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7817    """
7818    Wrap a condition with a NOT operator.
7819
7820    Example:
7821        >>> not_("this_suit='black'").sql()
7822        "NOT this_suit = 'black'"
7823
7824    Args:
7825        expression: the SQL code string to parse.
7826            If an Expression instance is passed, this is used as-is.
7827        dialect: the dialect used to parse the input expression.
7828        copy: whether to copy the expression or not.
7829        **opts: other options to use to parse the input expressions.
7830
7831    Returns:
7832        The new condition.
7833    """
7834    this = condition(
7835        expression,
7836        dialect=dialect,
7837        copy=copy,
7838        **opts,
7839    )
7840    return Not(this=_wrap(this, Connector))
7841
7842
7843def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7844    """
7845    Wrap an expression in parentheses.
7846
7847    Example:
7848        >>> paren("5 + 3").sql()
7849        '(5 + 3)'
7850
7851    Args:
7852        expression: the SQL code string to parse.
7853            If an Expression instance is passed, this is used as-is.
7854        copy: whether to copy the expression or not.
7855
7856    Returns:
7857        The wrapped expression.
7858    """
7859    return Paren(this=maybe_parse(expression, copy=copy))
7860
7861
7862SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
7863
7864
7865@t.overload
7866def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
7867
7868
7869@t.overload
7870def to_identifier(
7871    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
7872) -> Identifier: ...
7873
7874
7875def to_identifier(name, quoted=None, copy=True):
7876    """Builds an identifier.
7877
7878    Args:
7879        name: The name to turn into an identifier.
7880        quoted: Whether to force quote the identifier.
7881        copy: Whether to copy name if it's an Identifier.
7882
7883    Returns:
7884        The identifier ast node.
7885    """
7886
7887    if name is None:
7888        return None
7889
7890    if isinstance(name, Identifier):
7891        identifier = maybe_copy(name, copy)
7892    elif isinstance(name, str):
7893        identifier = Identifier(
7894            this=name,
7895            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7896        )
7897    else:
7898        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7899    return identifier
7900
7901
7902def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7903    """
7904    Parses a given string into an identifier.
7905
7906    Args:
7907        name: The name to parse into an identifier.
7908        dialect: The dialect to parse against.
7909
7910    Returns:
7911        The identifier ast node.
7912    """
7913    try:
7914        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7915    except (ParseError, TokenError):
7916        expression = to_identifier(name)
7917
7918    return expression
7919
7920
7921INTERVAL_STRING_RE = re.compile(r"\s*(-?[0-9]+)\s*([a-zA-Z]+)\s*")
7922
7923
7924def to_interval(interval: str | Literal) -> Interval:
7925    """Builds an interval expression from a string like '1 day' or '5 months'."""
7926    if isinstance(interval, Literal):
7927        if not interval.is_string:
7928            raise ValueError("Invalid interval string.")
7929
7930        interval = interval.this
7931
7932    interval = maybe_parse(f"INTERVAL {interval}")
7933    assert isinstance(interval, Interval)
7934    return interval
7935
7936
7937def to_table(
7938    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7939) -> Table:
7940    """
7941    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7942    If a table is passed in then that table is returned.
7943
7944    Args:
7945        sql_path: a `[catalog].[schema].[table]` string.
7946        dialect: the source dialect according to which the table name will be parsed.
7947        copy: Whether to copy a table if it is passed in.
7948        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7949
7950    Returns:
7951        A table expression.
7952    """
7953    if isinstance(sql_path, Table):
7954        return maybe_copy(sql_path, copy=copy)
7955
7956    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7957
7958    for k, v in kwargs.items():
7959        table.set(k, v)
7960
7961    return table
7962
7963
7964def to_column(
7965    sql_path: str | Column,
7966    quoted: t.Optional[bool] = None,
7967    dialect: DialectType = None,
7968    copy: bool = True,
7969    **kwargs,
7970) -> Column:
7971    """
7972    Create a column from a `[table].[column]` sql path. Table is optional.
7973    If a column is passed in then that column is returned.
7974
7975    Args:
7976        sql_path: a `[table].[column]` string.
7977        quoted: Whether or not to force quote identifiers.
7978        dialect: the source dialect according to which the column name will be parsed.
7979        copy: Whether to copy a column if it is passed in.
7980        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7981
7982    Returns:
7983        A column expression.
7984    """
7985    if isinstance(sql_path, Column):
7986        return maybe_copy(sql_path, copy=copy)
7987
7988    try:
7989        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7990    except ParseError:
7991        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7992
7993    for k, v in kwargs.items():
7994        col.set(k, v)
7995
7996    if quoted:
7997        for i in col.find_all(Identifier):
7998            i.set("quoted", True)
7999
8000    return col
8001
8002
8003def alias_(
8004    expression: ExpOrStr,
8005    alias: t.Optional[str | Identifier],
8006    table: bool | t.Sequence[str | Identifier] = False,
8007    quoted: t.Optional[bool] = None,
8008    dialect: DialectType = None,
8009    copy: bool = True,
8010    **opts,
8011):
8012    """Create an Alias expression.
8013
8014    Example:
8015        >>> alias_('foo', 'bar').sql()
8016        'foo AS bar'
8017
8018        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8019        '(SELECT 1, 2) AS bar(a, b)'
8020
8021    Args:
8022        expression: the SQL code strings to parse.
8023            If an Expression instance is passed, this is used as-is.
8024        alias: the alias name to use. If the name has
8025            special characters it is quoted.
8026        table: Whether to create a table alias, can also be a list of columns.
8027        quoted: whether to quote the alias
8028        dialect: the dialect used to parse the input expression.
8029        copy: Whether to copy the expression.
8030        **opts: other options to use to parse the input expressions.
8031
8032    Returns:
8033        Alias: the aliased expression
8034    """
8035    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8036    alias = to_identifier(alias, quoted=quoted)
8037
8038    if table:
8039        table_alias = TableAlias(this=alias)
8040        exp.set("alias", table_alias)
8041
8042        if not isinstance(table, bool):
8043            for column in table:
8044                table_alias.append("columns", to_identifier(column, quoted=quoted))
8045
8046        return exp
8047
8048    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8049    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8050    # for the complete Window expression.
8051    #
8052    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8053
8054    if "alias" in exp.arg_types and not isinstance(exp, Window):
8055        exp.set("alias", alias)
8056        return exp
8057    return Alias(this=exp, alias=alias)
8058
8059
8060def subquery(
8061    expression: ExpOrStr,
8062    alias: t.Optional[Identifier | str] = None,
8063    dialect: DialectType = None,
8064    **opts,
8065) -> Select:
8066    """
8067    Build a subquery expression that's selected from.
8068
8069    Example:
8070        >>> subquery('select x from tbl', 'bar').select('x').sql()
8071        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8072
8073    Args:
8074        expression: the SQL code strings to parse.
8075            If an Expression instance is passed, this is used as-is.
8076        alias: the alias name to use.
8077        dialect: the dialect used to parse the input expression.
8078        **opts: other options to use to parse the input expressions.
8079
8080    Returns:
8081        A new Select instance with the subquery expression included.
8082    """
8083
8084    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8085    return Select().from_(expression, dialect=dialect, **opts)
8086
8087
8088@t.overload
8089def column(
8090    col: str | Identifier,
8091    table: t.Optional[str | Identifier] = None,
8092    db: t.Optional[str | Identifier] = None,
8093    catalog: t.Optional[str | Identifier] = None,
8094    *,
8095    fields: t.Collection[t.Union[str, Identifier]],
8096    quoted: t.Optional[bool] = None,
8097    copy: bool = True,
8098) -> Dot:
8099    pass
8100
8101
8102@t.overload
8103def column(
8104    col: str | Identifier,
8105    table: t.Optional[str | Identifier] = None,
8106    db: t.Optional[str | Identifier] = None,
8107    catalog: t.Optional[str | Identifier] = None,
8108    *,
8109    fields: Lit[None] = None,
8110    quoted: t.Optional[bool] = None,
8111    copy: bool = True,
8112) -> Column:
8113    pass
8114
8115
8116def column(
8117    col,
8118    table=None,
8119    db=None,
8120    catalog=None,
8121    *,
8122    fields=None,
8123    quoted=None,
8124    copy=True,
8125):
8126    """
8127    Build a Column.
8128
8129    Args:
8130        col: Column name.
8131        table: Table name.
8132        db: Database name.
8133        catalog: Catalog name.
8134        fields: Additional fields using dots.
8135        quoted: Whether to force quotes on the column's identifiers.
8136        copy: Whether to copy identifiers if passed in.
8137
8138    Returns:
8139        The new Column instance.
8140    """
8141    this = Column(
8142        this=to_identifier(col, quoted=quoted, copy=copy),
8143        table=to_identifier(table, quoted=quoted, copy=copy),
8144        db=to_identifier(db, quoted=quoted, copy=copy),
8145        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8146    )
8147
8148    if fields:
8149        this = Dot.build(
8150            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8151        )
8152    return this
8153
8154
8155def cast(
8156    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8157) -> Cast:
8158    """Cast an expression to a data type.
8159
8160    Example:
8161        >>> cast('x + 1', 'int').sql()
8162        'CAST(x + 1 AS INT)'
8163
8164    Args:
8165        expression: The expression to cast.
8166        to: The datatype to cast to.
8167        copy: Whether to copy the supplied expressions.
8168        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8169            - The expression to be cast is already a exp.Cast expression
8170            - The existing cast is to a type that is logically equivalent to new type
8171
8172            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8173            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8174            and instead just return the original expression `CAST(x as DATETIME)`.
8175
8176            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8177            mapping is applied in the target dialect generator.
8178
8179    Returns:
8180        The new Cast instance.
8181    """
8182    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8183    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8184
8185    # dont re-cast if the expression is already a cast to the correct type
8186    if isinstance(expr, Cast):
8187        from sqlglot.dialects.dialect import Dialect
8188
8189        target_dialect = Dialect.get_or_raise(dialect)
8190        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8191
8192        existing_cast_type: DataType.Type = expr.to.this
8193        new_cast_type: DataType.Type = data_type.this
8194        types_are_equivalent = type_mapping.get(
8195            existing_cast_type, existing_cast_type.value
8196        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8197
8198        if expr.is_type(data_type) or types_are_equivalent:
8199            return expr
8200
8201    expr = Cast(this=expr, to=data_type)
8202    expr.type = data_type
8203
8204    return expr
8205
8206
8207def table_(
8208    table: Identifier | str,
8209    db: t.Optional[Identifier | str] = None,
8210    catalog: t.Optional[Identifier | str] = None,
8211    quoted: t.Optional[bool] = None,
8212    alias: t.Optional[Identifier | str] = None,
8213) -> Table:
8214    """Build a Table.
8215
8216    Args:
8217        table: Table name.
8218        db: Database name.
8219        catalog: Catalog name.
8220        quote: Whether to force quotes on the table's identifiers.
8221        alias: Table's alias.
8222
8223    Returns:
8224        The new Table instance.
8225    """
8226    return Table(
8227        this=to_identifier(table, quoted=quoted) if table else None,
8228        db=to_identifier(db, quoted=quoted) if db else None,
8229        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8230        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8231    )
8232
8233
8234def values(
8235    values: t.Iterable[t.Tuple[t.Any, ...]],
8236    alias: t.Optional[str] = None,
8237    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8238) -> Values:
8239    """Build VALUES statement.
8240
8241    Example:
8242        >>> values([(1, '2')]).sql()
8243        "VALUES (1, '2')"
8244
8245    Args:
8246        values: values statements that will be converted to SQL
8247        alias: optional alias
8248        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8249         If either are provided then an alias is also required.
8250
8251    Returns:
8252        Values: the Values expression object
8253    """
8254    if columns and not alias:
8255        raise ValueError("Alias is required when providing columns")
8256
8257    return Values(
8258        expressions=[convert(tup) for tup in values],
8259        alias=(
8260            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8261            if columns
8262            else (TableAlias(this=to_identifier(alias)) if alias else None)
8263        ),
8264    )
8265
8266
8267def var(name: t.Optional[ExpOrStr]) -> Var:
8268    """Build a SQL variable.
8269
8270    Example:
8271        >>> repr(var('x'))
8272        'Var(this=x)'
8273
8274        >>> repr(var(column('x', table='y')))
8275        'Var(this=x)'
8276
8277    Args:
8278        name: The name of the var or an expression who's name will become the var.
8279
8280    Returns:
8281        The new variable node.
8282    """
8283    if not name:
8284        raise ValueError("Cannot convert empty name into var.")
8285
8286    if isinstance(name, Expression):
8287        name = name.name
8288    return Var(this=name)
8289
8290
8291def rename_table(
8292    old_name: str | Table,
8293    new_name: str | Table,
8294    dialect: DialectType = None,
8295) -> Alter:
8296    """Build ALTER TABLE... RENAME... expression
8297
8298    Args:
8299        old_name: The old name of the table
8300        new_name: The new name of the table
8301        dialect: The dialect to parse the table.
8302
8303    Returns:
8304        Alter table expression
8305    """
8306    old_table = to_table(old_name, dialect=dialect)
8307    new_table = to_table(new_name, dialect=dialect)
8308    return Alter(
8309        this=old_table,
8310        kind="TABLE",
8311        actions=[
8312            AlterRename(this=new_table),
8313        ],
8314    )
8315
8316
8317def rename_column(
8318    table_name: str | Table,
8319    old_column_name: str | Column,
8320    new_column_name: str | Column,
8321    exists: t.Optional[bool] = None,
8322    dialect: DialectType = None,
8323) -> Alter:
8324    """Build ALTER TABLE... RENAME COLUMN... expression
8325
8326    Args:
8327        table_name: Name of the table
8328        old_column: The old name of the column
8329        new_column: The new name of the column
8330        exists: Whether to add the `IF EXISTS` clause
8331        dialect: The dialect to parse the table/column.
8332
8333    Returns:
8334        Alter table expression
8335    """
8336    table = to_table(table_name, dialect=dialect)
8337    old_column = to_column(old_column_name, dialect=dialect)
8338    new_column = to_column(new_column_name, dialect=dialect)
8339    return Alter(
8340        this=table,
8341        kind="TABLE",
8342        actions=[
8343            RenameColumn(this=old_column, to=new_column, exists=exists),
8344        ],
8345    )
8346
8347
8348def convert(value: t.Any, copy: bool = False) -> Expression:
8349    """Convert a python value into an expression object.
8350
8351    Raises an error if a conversion is not possible.
8352
8353    Args:
8354        value: A python object.
8355        copy: Whether to copy `value` (only applies to Expressions and collections).
8356
8357    Returns:
8358        The equivalent expression object.
8359    """
8360    if isinstance(value, Expression):
8361        return maybe_copy(value, copy)
8362    if isinstance(value, str):
8363        return Literal.string(value)
8364    if isinstance(value, bool):
8365        return Boolean(this=value)
8366    if value is None or (isinstance(value, float) and math.isnan(value)):
8367        return null()
8368    if isinstance(value, numbers.Number):
8369        return Literal.number(value)
8370    if isinstance(value, bytes):
8371        return HexString(this=value.hex())
8372    if isinstance(value, datetime.datetime):
8373        datetime_literal = Literal.string(value.isoformat(sep=" "))
8374
8375        tz = None
8376        if value.tzinfo:
8377            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8378            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8379            tz = Literal.string(str(value.tzinfo))
8380
8381        return TimeStrToTime(this=datetime_literal, zone=tz)
8382    if isinstance(value, datetime.date):
8383        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8384        return DateStrToDate(this=date_literal)
8385    if isinstance(value, tuple):
8386        if hasattr(value, "_fields"):
8387            return Struct(
8388                expressions=[
8389                    PropertyEQ(
8390                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8391                    )
8392                    for k in value._fields
8393                ]
8394            )
8395        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8396    if isinstance(value, list):
8397        return Array(expressions=[convert(v, copy=copy) for v in value])
8398    if isinstance(value, dict):
8399        return Map(
8400            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8401            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8402        )
8403    if hasattr(value, "__dict__"):
8404        return Struct(
8405            expressions=[
8406                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8407                for k, v in value.__dict__.items()
8408            ]
8409        )
8410    raise ValueError(f"Cannot convert {value}")
8411
8412
8413def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8414    """
8415    Replace children of an expression with the result of a lambda fun(child) -> exp.
8416    """
8417    for k, v in tuple(expression.args.items()):
8418        is_list_arg = type(v) is list
8419
8420        child_nodes = v if is_list_arg else [v]
8421        new_child_nodes = []
8422
8423        for cn in child_nodes:
8424            if isinstance(cn, Expression):
8425                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8426                    new_child_nodes.append(child_node)
8427            else:
8428                new_child_nodes.append(cn)
8429
8430        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
8431
8432
8433def replace_tree(
8434    expression: Expression,
8435    fun: t.Callable,
8436    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8437) -> Expression:
8438    """
8439    Replace an entire tree with the result of function calls on each node.
8440
8441    This will be traversed in reverse dfs, so leaves first.
8442    If new nodes are created as a result of function calls, they will also be traversed.
8443    """
8444    stack = list(expression.dfs(prune=prune))
8445
8446    while stack:
8447        node = stack.pop()
8448        new_node = fun(node)
8449
8450        if new_node is not node:
8451            node.replace(new_node)
8452
8453            if isinstance(new_node, Expression):
8454                stack.append(new_node)
8455
8456    return new_node
8457
8458
8459def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8460    """
8461    Return all table names referenced through columns in an expression.
8462
8463    Example:
8464        >>> import sqlglot
8465        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8466        ['a', 'c']
8467
8468    Args:
8469        expression: expression to find table names.
8470        exclude: a table name to exclude
8471
8472    Returns:
8473        A list of unique names.
8474    """
8475    return {
8476        table
8477        for table in (column.table for column in expression.find_all(Column))
8478        if table and table != exclude
8479    }
8480
8481
8482def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8483    """Get the full name of a table as a string.
8484
8485    Args:
8486        table: Table expression node or string.
8487        dialect: The dialect to generate the table name for.
8488        identify: Determines when an identifier should be quoted. Possible values are:
8489            False (default): Never quote, except in cases where it's mandatory by the dialect.
8490            True: Always quote.
8491
8492    Examples:
8493        >>> from sqlglot import exp, parse_one
8494        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8495        'a.b.c'
8496
8497    Returns:
8498        The table name.
8499    """
8500
8501    table = maybe_parse(table, into=Table, dialect=dialect)
8502
8503    if not table:
8504        raise ValueError(f"Cannot parse {table}")
8505
8506    return ".".join(
8507        (
8508            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8509            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8510            else part.name
8511        )
8512        for part in table.parts
8513    )
8514
8515
8516def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8517    """Returns a case normalized table name without quotes.
8518
8519    Args:
8520        table: the table to normalize
8521        dialect: the dialect to use for normalization rules
8522        copy: whether to copy the expression.
8523
8524    Examples:
8525        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8526        'A-B.c'
8527    """
8528    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8529
8530    return ".".join(
8531        p.name
8532        for p in normalize_identifiers(
8533            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8534        ).parts
8535    )
8536
8537
8538def replace_tables(
8539    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8540) -> E:
8541    """Replace all tables in expression according to the mapping.
8542
8543    Args:
8544        expression: expression node to be transformed and replaced.
8545        mapping: mapping of table names.
8546        dialect: the dialect of the mapping table
8547        copy: whether to copy the expression.
8548
8549    Examples:
8550        >>> from sqlglot import exp, parse_one
8551        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8552        'SELECT * FROM c /* a.b */'
8553
8554    Returns:
8555        The mapped expression.
8556    """
8557
8558    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8559
8560    def _replace_tables(node: Expression) -> Expression:
8561        if isinstance(node, Table) and node.meta.get("replace") is not False:
8562            original = normalize_table_name(node, dialect=dialect)
8563            new_name = mapping.get(original)
8564
8565            if new_name:
8566                table = to_table(
8567                    new_name,
8568                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8569                    dialect=dialect,
8570                )
8571                table.add_comments([original])
8572                return table
8573        return node
8574
8575    return expression.transform(_replace_tables, copy=copy)  # type: ignore
8576
8577
8578def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8579    """Replace placeholders in an expression.
8580
8581    Args:
8582        expression: expression node to be transformed and replaced.
8583        args: positional names that will substitute unnamed placeholders in the given order.
8584        kwargs: keyword arguments that will substitute named placeholders.
8585
8586    Examples:
8587        >>> from sqlglot import exp, parse_one
8588        >>> replace_placeholders(
8589        ...     parse_one("select * from :tbl where ? = ?"),
8590        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8591        ... ).sql()
8592        "SELECT * FROM foo WHERE str_col = 'b'"
8593
8594    Returns:
8595        The mapped expression.
8596    """
8597
8598    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8599        if isinstance(node, Placeholder):
8600            if node.this:
8601                new_name = kwargs.get(node.this)
8602                if new_name is not None:
8603                    return convert(new_name)
8604            else:
8605                try:
8606                    return convert(next(args))
8607                except StopIteration:
8608                    pass
8609        return node
8610
8611    return expression.transform(_replace_placeholders, iter(args), **kwargs)
8612
8613
8614def expand(
8615    expression: Expression,
8616    sources: t.Dict[str, Query | t.Callable[[], Query]],
8617    dialect: DialectType = None,
8618    copy: bool = True,
8619) -> Expression:
8620    """Transforms an expression by expanding all referenced sources into subqueries.
8621
8622    Examples:
8623        >>> from sqlglot import parse_one
8624        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8625        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8626
8627        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8628        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8629
8630    Args:
8631        expression: The expression to expand.
8632        sources: A dict of name to query or a callable that provides a query on demand.
8633        dialect: The dialect of the sources dict or the callable.
8634        copy: Whether to copy the expression during transformation. Defaults to True.
8635
8636    Returns:
8637        The transformed expression.
8638    """
8639    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8640
8641    def _expand(node: Expression):
8642        if isinstance(node, Table):
8643            name = normalize_table_name(node, dialect=dialect)
8644            source = normalized_sources.get(name)
8645
8646            if source:
8647                # Create a subquery with the same alias (or table name if no alias)
8648                parsed_source = source() if callable(source) else source
8649                subquery = parsed_source.subquery(node.alias or name)
8650                subquery.comments = [f"source: {name}"]
8651
8652                # Continue expanding within the subquery
8653                return subquery.transform(_expand, copy=False)
8654
8655        return node
8656
8657    return expression.transform(_expand, copy=copy)
8658
8659
8660def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8661    """
8662    Returns a Func expression.
8663
8664    Examples:
8665        >>> func("abs", 5).sql()
8666        'ABS(5)'
8667
8668        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8669        'CAST(5 AS DOUBLE)'
8670
8671    Args:
8672        name: the name of the function to build.
8673        args: the args used to instantiate the function of interest.
8674        copy: whether to copy the argument expressions.
8675        dialect: the source dialect.
8676        kwargs: the kwargs used to instantiate the function of interest.
8677
8678    Note:
8679        The arguments `args` and `kwargs` are mutually exclusive.
8680
8681    Returns:
8682        An instance of the function of interest, or an anonymous function, if `name` doesn't
8683        correspond to an existing `sqlglot.expressions.Func` class.
8684    """
8685    if args and kwargs:
8686        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8687
8688    from sqlglot.dialects.dialect import Dialect
8689
8690    dialect = Dialect.get_or_raise(dialect)
8691
8692    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8693    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8694
8695    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8696    if constructor:
8697        if converted:
8698            if "dialect" in constructor.__code__.co_varnames:
8699                function = constructor(converted, dialect=dialect)
8700            else:
8701                function = constructor(converted)
8702        elif constructor.__name__ == "from_arg_list":
8703            function = constructor.__self__(**kwargs)  # type: ignore
8704        else:
8705            constructor = FUNCTION_BY_NAME.get(name.upper())
8706            if constructor:
8707                function = constructor(**kwargs)
8708            else:
8709                raise ValueError(
8710                    f"Unable to convert '{name}' into a Func. Either manually construct "
8711                    "the Func expression of interest or parse the function call."
8712                )
8713    else:
8714        kwargs = kwargs or {"expressions": converted}
8715        function = Anonymous(this=name, **kwargs)
8716
8717    for error_message in function.error_messages(converted):
8718        raise ValueError(error_message)
8719
8720    return function
8721
8722
8723def case(
8724    expression: t.Optional[ExpOrStr] = None,
8725    **opts,
8726) -> Case:
8727    """
8728    Initialize a CASE statement.
8729
8730    Example:
8731        case().when("a = 1", "foo").else_("bar")
8732
8733    Args:
8734        expression: Optionally, the input expression (not all dialects support this)
8735        **opts: Extra keyword arguments for parsing `expression`
8736    """
8737    if expression is not None:
8738        this = maybe_parse(expression, **opts)
8739    else:
8740        this = None
8741    return Case(this=this, ifs=[])
8742
8743
8744def array(
8745    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8746) -> Array:
8747    """
8748    Returns an array.
8749
8750    Examples:
8751        >>> array(1, 'x').sql()
8752        'ARRAY(1, x)'
8753
8754    Args:
8755        expressions: the expressions to add to the array.
8756        copy: whether to copy the argument expressions.
8757        dialect: the source dialect.
8758        kwargs: the kwargs used to instantiate the function of interest.
8759
8760    Returns:
8761        An array expression.
8762    """
8763    return Array(
8764        expressions=[
8765            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8766            for expression in expressions
8767        ]
8768    )
8769
8770
8771def tuple_(
8772    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8773) -> Tuple:
8774    """
8775    Returns an tuple.
8776
8777    Examples:
8778        >>> tuple_(1, 'x').sql()
8779        '(1, x)'
8780
8781    Args:
8782        expressions: the expressions to add to the tuple.
8783        copy: whether to copy the argument expressions.
8784        dialect: the source dialect.
8785        kwargs: the kwargs used to instantiate the function of interest.
8786
8787    Returns:
8788        A tuple expression.
8789    """
8790    return Tuple(
8791        expressions=[
8792            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8793            for expression in expressions
8794        ]
8795    )
8796
8797
8798def true() -> Boolean:
8799    """
8800    Returns a true Boolean expression.
8801    """
8802    return Boolean(this=True)
8803
8804
8805def false() -> Boolean:
8806    """
8807    Returns a false Boolean expression.
8808    """
8809    return Boolean(this=False)
8810
8811
8812def null() -> Null:
8813    """
8814    Returns a Null expression.
8815    """
8816    return Null()
8817
8818
8819NONNULL_CONSTANTS = (
8820    Literal,
8821    Boolean,
8822)
8823
8824CONSTANTS = (
8825    Literal,
8826    Boolean,
8827    Null,
8828)
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.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.NESTED: 'NESTED'>, <Type.UNION: 'UNION'>, <Type.ARRAY: 'ARRAY'>, <Type.STRUCT: 'STRUCT'>, <Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.LIST: 'LIST'>}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>}
INTEGER_TYPES = {<Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT256: 'INT256'>, <Type.UINT256: 'UINT256'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.BIT: 'BIT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.FLOAT: 'FLOAT'>, <Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.UDECIMAL: 'UDECIMAL'>}
NUMERIC_TYPES = {<Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.INT256: 'INT256'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UBIGINT: 'UBIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.MONEY: 'MONEY'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL32: 'DECIMAL32'>}
TEMPORAL_TYPES = {<Type.DATETIME2: 'DATETIME2'>, <Type.DATE32: 'DATE32'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIME: 'TIME'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>}
@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 ArrayConcatAgg(AggFunc):
5543class ArrayConcatAgg(AggFunc):
5544    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5547class ArrayConstructCompact(Func):
5548    arg_types = {"expressions": True}
5549    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5552class ArrayContains(Binary, Func):
5553    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5556class ArrayContainsAll(Binary, Func):
5557    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5560class ArrayFilter(Func):
5561    arg_types = {"this": True, "expression": True}
5562    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5565class ArrayToString(Func):
5566    arg_types = {"this": True, "expression": True, "null": False}
5567    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5571class String(Func):
5572    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5575class StringToArray(Func):
5576    arg_types = {"this": True, "expression": True, "null": False}
5577    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5580class ArrayOverlaps(Binary, Func):
5581    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5584class ArraySize(Func):
5585    arg_types = {"this": True, "expression": False}
5586    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5589class ArraySort(Func):
5590    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5593class ArraySum(Func):
5594    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5597class ArrayUnionAgg(AggFunc):
5598    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5601class Avg(AggFunc):
5602    pass
key = 'avg'
class AnyValue(AggFunc):
5605class AnyValue(AggFunc):
5606    pass
key = 'anyvalue'
class Lag(AggFunc):
5609class Lag(AggFunc):
5610    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5613class Lead(AggFunc):
5614    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5619class First(AggFunc):
5620    pass
key = 'first'
class Last(AggFunc):
5623class Last(AggFunc):
5624    pass
key = 'last'
class FirstValue(AggFunc):
5627class FirstValue(AggFunc):
5628    pass
key = 'firstvalue'
class LastValue(AggFunc):
5631class LastValue(AggFunc):
5632    pass
key = 'lastvalue'
class NthValue(AggFunc):
5635class NthValue(AggFunc):
5636    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5639class Case(Func):
5640    arg_types = {"this": False, "ifs": True, "default": False}
5641
5642    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5643        instance = maybe_copy(self, copy)
5644        instance.append(
5645            "ifs",
5646            If(
5647                this=maybe_parse(condition, copy=copy, **opts),
5648                true=maybe_parse(then, copy=copy, **opts),
5649            ),
5650        )
5651        return instance
5652
5653    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5654        instance = maybe_copy(self, copy)
5655        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5656        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:
5642    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5643        instance = maybe_copy(self, copy)
5644        instance.append(
5645            "ifs",
5646            If(
5647                this=maybe_parse(condition, copy=copy, **opts),
5648                true=maybe_parse(then, copy=copy, **opts),
5649            ),
5650        )
5651        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5653    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5654        instance = maybe_copy(self, copy)
5655        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5656        return instance
key = 'case'
class Cast(Func):
5659class Cast(Func):
5660    arg_types = {
5661        "this": True,
5662        "to": True,
5663        "format": False,
5664        "safe": False,
5665        "action": False,
5666        "default": False,
5667    }
5668
5669    @property
5670    def name(self) -> str:
5671        return self.this.name
5672
5673    @property
5674    def to(self) -> DataType:
5675        return self.args["to"]
5676
5677    @property
5678    def output_name(self) -> str:
5679        return self.name
5680
5681    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5682        """
5683        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5684        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5685        array<int> != array<float>.
5686
5687        Args:
5688            dtypes: the data types to compare this Cast's DataType to.
5689
5690        Returns:
5691            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5692        """
5693        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5669    @property
5670    def name(self) -> str:
5671        return self.this.name
to: DataType
5673    @property
5674    def to(self) -> DataType:
5675        return self.args["to"]
output_name: str
5677    @property
5678    def output_name(self) -> str:
5679        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:
5681    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5682        """
5683        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5684        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5685        array<int> != array<float>.
5686
5687        Args:
5688            dtypes: the data types to compare this Cast's DataType to.
5689
5690        Returns:
5691            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5692        """
5693        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):
5696class TryCast(Cast):
5697    pass
key = 'trycast'
class JSONCast(Cast):
5701class JSONCast(Cast):
5702    pass
key = 'jsoncast'
class Try(Func):
5705class Try(Func):
5706    pass
key = 'try'
class CastToStrType(Func):
5709class CastToStrType(Func):
5710    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5714class TranslateCharacters(Expression):
5715    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5718class Collate(Binary, Func):
5719    pass
key = 'collate'
class Ceil(Func):
5722class Ceil(Func):
5723    arg_types = {"this": True, "decimals": False, "to": False}
5724    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5727class Coalesce(Func):
5728    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5729    is_var_len_args = True
5730    _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):
5733class Chr(Func):
5734    arg_types = {"expressions": True, "charset": False}
5735    is_var_len_args = True
5736    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5739class Concat(Func):
5740    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5741    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5744class ConcatWs(Concat):
5745    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5748class Contains(Func):
5749    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5753class ConnectByRoot(Func):
5754    pass
key = 'connectbyroot'
class Count(AggFunc):
5757class Count(AggFunc):
5758    arg_types = {"this": False, "expressions": False, "big_int": False}
5759    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5762class CountIf(AggFunc):
5763    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5767class Cbrt(Func):
5768    pass
key = 'cbrt'
class CurrentDate(Func):
5771class CurrentDate(Func):
5772    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5775class CurrentDatetime(Func):
5776    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5779class CurrentTime(Func):
5780    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5783class CurrentTimestamp(Func):
5784    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5787class CurrentSchema(Func):
5788    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5791class CurrentUser(Func):
5792    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5795class DateAdd(Func, IntervalOp):
5796    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5799class DateBin(Func, IntervalOp):
5800    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):
5803class DateSub(Func, IntervalOp):
5804    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5807class DateDiff(Func, TimeUnit):
5808    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5809    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):
5812class DateTrunc(Func):
5813    arg_types = {"unit": True, "this": True, "zone": False}
5814
5815    def __init__(self, **args):
5816        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5817        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5818        unabbreviate = args.pop("unabbreviate", True)
5819
5820        unit = args.get("unit")
5821        if isinstance(unit, TimeUnit.VAR_LIKE):
5822            unit_name = unit.name.upper()
5823            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5824                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5825
5826            args["unit"] = Literal.string(unit_name)
5827        elif isinstance(unit, Week):
5828            unit.set("this", Literal.string(unit.this.name.upper()))
5829
5830        super().__init__(**args)
5831
5832    @property
5833    def unit(self) -> Expression:
5834        return self.args["unit"]
DateTrunc(**args)
5815    def __init__(self, **args):
5816        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5817        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5818        unabbreviate = args.pop("unabbreviate", True)
5819
5820        unit = args.get("unit")
5821        if isinstance(unit, TimeUnit.VAR_LIKE):
5822            unit_name = unit.name.upper()
5823            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5824                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5825
5826            args["unit"] = Literal.string(unit_name)
5827        elif isinstance(unit, Week):
5828            unit.set("this", Literal.string(unit.this.name.upper()))
5829
5830        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5832    @property
5833    def unit(self) -> Expression:
5834        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5839class Datetime(Func):
5840    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5843class DatetimeAdd(Func, IntervalOp):
5844    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5847class DatetimeSub(Func, IntervalOp):
5848    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5851class DatetimeDiff(Func, TimeUnit):
5852    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5855class DatetimeTrunc(Func, TimeUnit):
5856    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5859class DayOfWeek(Func):
5860    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5865class DayOfWeekIso(Func):
5866    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5869class DayOfMonth(Func):
5870    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5873class DayOfYear(Func):
5874    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5877class ToDays(Func):
5878    pass
key = 'todays'
class WeekOfYear(Func):
5881class WeekOfYear(Func):
5882    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5885class MonthsBetween(Func):
5886    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5889class MakeInterval(Func):
5890    arg_types = {
5891        "year": False,
5892        "month": False,
5893        "day": False,
5894        "hour": False,
5895        "minute": False,
5896        "second": False,
5897    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5900class LastDay(Func, TimeUnit):
5901    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5902    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5905class Extract(Func):
5906    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5909class Exists(Func, SubqueryPredicate):
5910    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5913class Timestamp(Func):
5914    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5917class TimestampAdd(Func, TimeUnit):
5918    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5921class TimestampSub(Func, TimeUnit):
5922    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5925class TimestampDiff(Func, TimeUnit):
5926    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5927    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5930class TimestampTrunc(Func, TimeUnit):
5931    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5934class TimeAdd(Func, TimeUnit):
5935    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5938class TimeSub(Func, TimeUnit):
5939    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5942class TimeDiff(Func, TimeUnit):
5943    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5946class TimeTrunc(Func, TimeUnit):
5947    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5950class DateFromParts(Func):
5951    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5952    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5955class TimeFromParts(Func):
5956    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5957    arg_types = {
5958        "hour": True,
5959        "min": True,
5960        "sec": True,
5961        "nano": False,
5962        "fractions": False,
5963        "precision": False,
5964    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5967class DateStrToDate(Func):
5968    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5971class DateToDateStr(Func):
5972    pass
key = 'datetodatestr'
class DateToDi(Func):
5975class DateToDi(Func):
5976    pass
key = 'datetodi'
class Date(Func):
5980class Date(Func):
5981    arg_types = {"this": False, "zone": False, "expressions": False}
5982    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5985class Day(Func):
5986    pass
key = 'day'
class Decode(Func):
5989class Decode(Func):
5990    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5993class DiToDate(Func):
5994    pass
key = 'ditodate'
class Encode(Func):
5997class Encode(Func):
5998    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6001class Exp(Func):
6002    pass
key = 'exp'
class Explode(Func, UDTF):
6006class Explode(Func, UDTF):
6007    arg_types = {"this": True, "expressions": False}
6008    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6012class Inline(Func):
6013    pass
key = 'inline'
class ExplodeOuter(Explode):
6016class ExplodeOuter(Explode):
6017    pass
key = 'explodeouter'
class Posexplode(Explode):
6020class Posexplode(Explode):
6021    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6024class PosexplodeOuter(Posexplode, ExplodeOuter):
6025    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
6028class Unnest(Func, UDTF):
6029    arg_types = {
6030        "expressions": True,
6031        "alias": False,
6032        "offset": False,
6033        "explode_array": False,
6034    }
6035
6036    @property
6037    def selects(self) -> t.List[Expression]:
6038        columns = super().selects
6039        offset = self.args.get("offset")
6040        if offset:
6041            columns = columns + [to_identifier("offset") if offset is True else offset]
6042        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6036    @property
6037    def selects(self) -> t.List[Expression]:
6038        columns = super().selects
6039        offset = self.args.get("offset")
6040        if offset:
6041            columns = columns + [to_identifier("offset") if offset is True else offset]
6042        return columns
key = 'unnest'
class Floor(Func):
6045class Floor(Func):
6046    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6049class FromBase64(Func):
6050    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6053class FeaturesAtTime(Func):
6054    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):
6057class ToBase64(Func):
6058    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6062class FromISO8601Timestamp(Func):
6063    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6066class GapFill(Func):
6067    arg_types = {
6068        "this": True,
6069        "ts_column": True,
6070        "bucket_width": True,
6071        "partitioning_columns": False,
6072        "value_columns": False,
6073        "origin": False,
6074        "ignore_nulls": False,
6075    }
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):
6079class GenerateDateArray(Func):
6080    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6084class GenerateTimestampArray(Func):
6085    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6088class Greatest(Func):
6089    arg_types = {"this": True, "expressions": False}
6090    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6095class OverflowTruncateBehavior(Expression):
6096    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6099class GroupConcat(AggFunc):
6100    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6103class Hex(Func):
6104    pass
key = 'hex'
class LowerHex(Hex):
6107class LowerHex(Hex):
6108    pass
key = 'lowerhex'
class And(Connector, Func):
6111class And(Connector, Func):
6112    pass
key = 'and'
class Or(Connector, Func):
6115class Or(Connector, Func):
6116    pass
key = 'or'
class Xor(Connector, Func):
6119class Xor(Connector, Func):
6120    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6123class If(Func):
6124    arg_types = {"this": True, "true": True, "false": False}
6125    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6128class Nullif(Func):
6129    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6132class Initcap(Func):
6133    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6136class IsAscii(Func):
6137    pass
key = 'isascii'
class IsNan(Func):
6140class IsNan(Func):
6141    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6145class Int64(Func):
6146    pass
key = 'int64'
class IsInf(Func):
6149class IsInf(Func):
6150    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6154class JSON(Expression):
6155    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6158class JSONPath(Expression):
6159    arg_types = {"expressions": True, "escape": False}
6160
6161    @property
6162    def output_name(self) -> str:
6163        last_segment = self.expressions[-1].this
6164        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6161    @property
6162    def output_name(self) -> str:
6163        last_segment = self.expressions[-1].this
6164        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):
6167class JSONPathPart(Expression):
6168    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6171class JSONPathFilter(JSONPathPart):
6172    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6175class JSONPathKey(JSONPathPart):
6176    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6179class JSONPathRecursive(JSONPathPart):
6180    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6183class JSONPathRoot(JSONPathPart):
6184    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6187class JSONPathScript(JSONPathPart):
6188    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6191class JSONPathSlice(JSONPathPart):
6192    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6195class JSONPathSelector(JSONPathPart):
6196    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6199class JSONPathSubscript(JSONPathPart):
6200    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6203class JSONPathUnion(JSONPathPart):
6204    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6207class JSONPathWildcard(JSONPathPart):
6208    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6211class FormatJson(Expression):
6212    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6215class JSONKeyValue(Expression):
6216    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6219class JSONObject(Func):
6220    arg_types = {
6221        "expressions": False,
6222        "null_handling": False,
6223        "unique_keys": False,
6224        "return_type": False,
6225        "encoding": False,
6226    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6229class JSONObjectAgg(AggFunc):
6230    arg_types = {
6231        "expressions": False,
6232        "null_handling": False,
6233        "unique_keys": False,
6234        "return_type": False,
6235        "encoding": False,
6236    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6240class JSONBObjectAgg(AggFunc):
6241    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6245class JSONArray(Func):
6246    arg_types = {
6247        "expressions": True,
6248        "null_handling": False,
6249        "return_type": False,
6250        "strict": False,
6251    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6255class JSONArrayAgg(Func):
6256    arg_types = {
6257        "this": True,
6258        "order": False,
6259        "null_handling": False,
6260        "return_type": False,
6261        "strict": False,
6262    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6265class JSONExists(Func):
6266    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):
6271class JSONColumnDef(Expression):
6272    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):
6275class JSONSchema(Expression):
6276    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6280class JSONValue(Expression):
6281    arg_types = {
6282        "this": True,
6283        "path": True,
6284        "returning": False,
6285        "on_condition": False,
6286    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6289class JSONValueArray(Func):
6290    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6294class JSONTable(Func):
6295    arg_types = {
6296        "this": True,
6297        "schema": True,
6298        "path": False,
6299        "error_handling": False,
6300        "empty_handling": False,
6301    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6305class ObjectInsert(Func):
6306    arg_types = {
6307        "this": True,
6308        "key": True,
6309        "value": True,
6310        "update_flag": False,
6311    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6314class OpenJSONColumnDef(Expression):
6315    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):
6318class OpenJSON(Func):
6319    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6322class JSONBContains(Binary, Func):
6323    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6326class JSONBExists(Func):
6327    arg_types = {"this": True, "path": True}
6328    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6331class JSONExtract(Binary, Func):
6332    arg_types = {
6333        "this": True,
6334        "expression": True,
6335        "only_json_types": False,
6336        "expressions": False,
6337        "variant_extract": False,
6338        "json_query": False,
6339        "option": False,
6340        "quote": False,
6341        "on_condition": False,
6342    }
6343    _sql_names = ["JSON_EXTRACT"]
6344    is_var_len_args = True
6345
6346    @property
6347    def output_name(self) -> str:
6348        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
6346    @property
6347    def output_name(self) -> str:
6348        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):
6352class JSONExtractQuote(Expression):
6353    arg_types = {
6354        "option": True,
6355        "scalar": False,
6356    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6359class JSONExtractArray(Func):
6360    arg_types = {"this": True, "expression": False}
6361    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6364class JSONExtractScalar(Binary, Func):
6365    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6366    _sql_names = ["JSON_EXTRACT_SCALAR"]
6367    is_var_len_args = True
6368
6369    @property
6370    def output_name(self) -> str:
6371        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
6369    @property
6370    def output_name(self) -> str:
6371        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):
6374class JSONBExtract(Binary, Func):
6375    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6378class JSONBExtractScalar(Binary, Func):
6379    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6382class JSONFormat(Func):
6383    arg_types = {"this": False, "options": False, "is_json": False}
6384    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6388class JSONArrayContains(Binary, Predicate, Func):
6389    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6392class ParseJSON(Func):
6393    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6394    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6395    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6396    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6399class Least(Func):
6400    arg_types = {"this": True, "expressions": False}
6401    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6404class Left(Func):
6405    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6412class Length(Func):
6413    arg_types = {"this": True, "binary": False, "encoding": False}
6414    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6417class Levenshtein(Func):
6418    arg_types = {
6419        "this": True,
6420        "expression": False,
6421        "ins_cost": False,
6422        "del_cost": False,
6423        "sub_cost": False,
6424        "max_dist": False,
6425    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6428class Ln(Func):
6429    pass
key = 'ln'
class Log(Func):
6432class Log(Func):
6433    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6436class LogicalOr(AggFunc):
6437    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6440class LogicalAnd(AggFunc):
6441    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6444class Lower(Func):
6445    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6448class Map(Func):
6449    arg_types = {"keys": False, "values": False}
6450
6451    @property
6452    def keys(self) -> t.List[Expression]:
6453        keys = self.args.get("keys")
6454        return keys.expressions if keys else []
6455
6456    @property
6457    def values(self) -> t.List[Expression]:
6458        values = self.args.get("values")
6459        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6451    @property
6452    def keys(self) -> t.List[Expression]:
6453        keys = self.args.get("keys")
6454        return keys.expressions if keys else []
values: List[Expression]
6456    @property
6457    def values(self) -> t.List[Expression]:
6458        values = self.args.get("values")
6459        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6463class ToMap(Func):
6464    pass
key = 'tomap'
class MapFromEntries(Func):
6467class MapFromEntries(Func):
6468    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6472class ScopeResolution(Expression):
6473    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6476class Stream(Expression):
6477    pass
key = 'stream'
class StarMap(Func):
6480class StarMap(Func):
6481    pass
key = 'starmap'
class VarMap(Func):
6484class VarMap(Func):
6485    arg_types = {"keys": True, "values": True}
6486    is_var_len_args = True
6487
6488    @property
6489    def keys(self) -> t.List[Expression]:
6490        return self.args["keys"].expressions
6491
6492    @property
6493    def values(self) -> t.List[Expression]:
6494        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6488    @property
6489    def keys(self) -> t.List[Expression]:
6490        return self.args["keys"].expressions
values: List[Expression]
6492    @property
6493    def values(self) -> t.List[Expression]:
6494        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6498class MatchAgainst(Func):
6499    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6502class Max(AggFunc):
6503    arg_types = {"this": True, "expressions": False}
6504    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6507class MD5(Func):
6508    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6512class MD5Digest(Func):
6513    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6516class Median(AggFunc):
6517    pass
key = 'median'
class Min(AggFunc):
6520class Min(AggFunc):
6521    arg_types = {"this": True, "expressions": False}
6522    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6525class Month(Func):
6526    pass
key = 'month'
class AddMonths(Func):
6529class AddMonths(Func):
6530    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6533class Nvl2(Func):
6534    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6537class Normalize(Func):
6538    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6541class Overlay(Func):
6542    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):
6546class Predict(Func):
6547    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6550class Pow(Binary, Func):
6551    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6554class PercentileCont(AggFunc):
6555    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6558class PercentileDisc(AggFunc):
6559    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6562class Quantile(AggFunc):
6563    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6566class ApproxQuantile(Quantile):
6567    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):
6570class Quarter(Func):
6571    pass
key = 'quarter'
class Rand(Func):
6576class Rand(Func):
6577    _sql_names = ["RAND", "RANDOM"]
6578    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6581class Randn(Func):
6582    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6585class RangeN(Func):
6586    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6589class ReadCSV(Func):
6590    _sql_names = ["READ_CSV"]
6591    is_var_len_args = True
6592    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6595class Reduce(Func):
6596    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):
6599class RegexpExtract(Func):
6600    arg_types = {
6601        "this": True,
6602        "expression": True,
6603        "position": False,
6604        "occurrence": False,
6605        "parameters": False,
6606        "group": False,
6607    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6610class RegexpExtractAll(Func):
6611    arg_types = {
6612        "this": True,
6613        "expression": True,
6614        "position": False,
6615        "occurrence": False,
6616        "parameters": False,
6617        "group": False,
6618    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6621class RegexpReplace(Func):
6622    arg_types = {
6623        "this": True,
6624        "expression": True,
6625        "replacement": False,
6626        "position": False,
6627        "occurrence": False,
6628        "modifiers": False,
6629    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6632class RegexpLike(Binary, Func):
6633    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6636class RegexpILike(Binary, Func):
6637    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6642class RegexpSplit(Func):
6643    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6646class Repeat(Func):
6647    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6652class Round(Func):
6653    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6656class RowNumber(Func):
6657    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6660class SafeDivide(Func):
6661    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6664class SHA(Func):
6665    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6668class SHA2(Func):
6669    _sql_names = ["SHA2"]
6670    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6673class Sign(Func):
6674    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6677class SortArray(Func):
6678    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6681class Split(Func):
6682    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6686class SplitPart(Func):
6687    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6692class Substring(Func):
6693    _sql_names = ["SUBSTRING", "SUBSTR"]
6694    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6697class StandardHash(Func):
6698    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6701class StartsWith(Func):
6702    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6703    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6706class StrPosition(Func):
6707    arg_types = {
6708        "this": True,
6709        "substr": True,
6710        "position": False,
6711        "occurrence": False,
6712    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6715class StrToDate(Func):
6716    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6719class StrToTime(Func):
6720    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):
6725class StrToUnix(Func):
6726    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6731class StrToMap(Func):
6732    arg_types = {
6733        "this": True,
6734        "pair_delim": False,
6735        "key_value_delim": False,
6736        "duplicate_resolution_callback": False,
6737    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6740class NumberToStr(Func):
6741    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6744class FromBase(Func):
6745    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6748class Struct(Func):
6749    arg_types = {"expressions": False}
6750    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6753class StructExtract(Func):
6754    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6759class Stuff(Func):
6760    _sql_names = ["STUFF", "INSERT"]
6761    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):
6764class Sum(AggFunc):
6765    pass
key = 'sum'
class Sqrt(Func):
6768class Sqrt(Func):
6769    pass
key = 'sqrt'
class Stddev(AggFunc):
6772class Stddev(AggFunc):
6773    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6776class StddevPop(AggFunc):
6777    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6780class StddevSamp(AggFunc):
6781    pass
key = 'stddevsamp'
class Time(Func):
6785class Time(Func):
6786    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6789class TimeToStr(Func):
6790    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):
6793class TimeToTimeStr(Func):
6794    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6797class TimeToUnix(Func):
6798    pass
key = 'timetounix'
class TimeStrToDate(Func):
6801class TimeStrToDate(Func):
6802    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6805class TimeStrToTime(Func):
6806    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6809class TimeStrToUnix(Func):
6810    pass
key = 'timestrtounix'
class Trim(Func):
6813class Trim(Func):
6814    arg_types = {
6815        "this": True,
6816        "expression": False,
6817        "position": False,
6818        "collation": False,
6819    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6822class TsOrDsAdd(Func, TimeUnit):
6823    # return_type is used to correctly cast the arguments of this expression when transpiling it
6824    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6825
6826    @property
6827    def return_type(self) -> DataType:
6828        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
6826    @property
6827    def return_type(self) -> DataType:
6828        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6831class TsOrDsDiff(Func, TimeUnit):
6832    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6835class TsOrDsToDateStr(Func):
6836    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6839class TsOrDsToDate(Func):
6840    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6843class TsOrDsToDatetime(Func):
6844    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6847class TsOrDsToTime(Func):
6848    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6851class TsOrDsToTimestamp(Func):
6852    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6855class TsOrDiToDi(Func):
6856    pass
key = 'tsorditodi'
class Unhex(Func):
6859class Unhex(Func):
6860    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6863class Unicode(Func):
6864    pass
key = 'unicode'
class UnixDate(Func):
6868class UnixDate(Func):
6869    pass
key = 'unixdate'
class UnixToStr(Func):
6872class UnixToStr(Func):
6873    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6878class UnixToTime(Func):
6879    arg_types = {
6880        "this": True,
6881        "scale": False,
6882        "zone": False,
6883        "hours": False,
6884        "minutes": False,
6885        "format": False,
6886    }
6887
6888    SECONDS = Literal.number(0)
6889    DECIS = Literal.number(1)
6890    CENTIS = Literal.number(2)
6891    MILLIS = Literal.number(3)
6892    DECIMILLIS = Literal.number(4)
6893    CENTIMILLIS = Literal.number(5)
6894    MICROS = Literal.number(6)
6895    DECIMICROS = Literal.number(7)
6896    CENTIMICROS = Literal.number(8)
6897    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):
6900class UnixToTimeStr(Func):
6901    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6904class UnixSeconds(Func):
6905    pass
key = 'unixseconds'
class Uuid(Func):
6908class Uuid(Func):
6909    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6910
6911    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6914class TimestampFromParts(Func):
6915    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6916    arg_types = {
6917        "year": True,
6918        "month": True,
6919        "day": True,
6920        "hour": True,
6921        "min": True,
6922        "sec": True,
6923        "nano": False,
6924        "zone": False,
6925        "milli": False,
6926    }
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):
6929class Upper(Func):
6930    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6933class Corr(Binary, AggFunc):
6934    pass
key = 'corr'
class Variance(AggFunc):
6937class Variance(AggFunc):
6938    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6941class VariancePop(AggFunc):
6942    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6945class CovarSamp(Binary, AggFunc):
6946    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6949class CovarPop(Binary, AggFunc):
6950    pass
key = 'covarpop'
class Week(Func):
6953class Week(Func):
6954    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6957class XMLElement(Func):
6958    _sql_names = ["XMLELEMENT"]
6959    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6962class XMLTable(Func):
6963    arg_types = {
6964        "this": True,
6965        "namespaces": False,
6966        "passing": False,
6967        "columns": False,
6968        "by_ref": False,
6969    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6972class XMLNamespace(Expression):
6973    pass
key = 'xmlnamespace'
class Year(Func):
6976class Year(Func):
6977    pass
key = 'year'
class Use(Expression):
6980class Use(Expression):
6981    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6984class Merge(DML):
6985    arg_types = {
6986        "this": True,
6987        "using": True,
6988        "on": True,
6989        "whens": True,
6990        "with": False,
6991        "returning": False,
6992    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6995class When(Expression):
6996    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):
6999class Whens(Expression):
7000    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7001
7002    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7007class NextValueFor(Func):
7008    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7013class Semicolon(Expression):
7014    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConcatAgg'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONCAT_AGG': <class 'ArrayConcatAgg'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_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:
7054def maybe_parse(
7055    sql_or_expression: ExpOrStr,
7056    *,
7057    into: t.Optional[IntoType] = None,
7058    dialect: DialectType = None,
7059    prefix: t.Optional[str] = None,
7060    copy: bool = False,
7061    **opts,
7062) -> Expression:
7063    """Gracefully handle a possible string or expression.
7064
7065    Example:
7066        >>> maybe_parse("1")
7067        Literal(this=1, is_string=False)
7068        >>> maybe_parse(to_identifier("x"))
7069        Identifier(this=x, quoted=False)
7070
7071    Args:
7072        sql_or_expression: the SQL code string or an expression
7073        into: the SQLGlot Expression to parse into
7074        dialect: the dialect used to parse the input expressions (in the case that an
7075            input expression is a SQL string).
7076        prefix: a string to prefix the sql with before it gets parsed
7077            (automatically includes a space)
7078        copy: whether to copy the expression.
7079        **opts: other options to use to parse the input expressions (again, in the case
7080            that an input expression is a SQL string).
7081
7082    Returns:
7083        Expression: the parsed or given expression.
7084    """
7085    if isinstance(sql_or_expression, Expression):
7086        if copy:
7087            return sql_or_expression.copy()
7088        return sql_or_expression
7089
7090    if sql_or_expression is None:
7091        raise ParseError("SQL cannot be None")
7092
7093    import sqlglot
7094
7095    sql = str(sql_or_expression)
7096    if prefix:
7097        sql = f"{prefix} {sql}"
7098
7099    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):
7110def maybe_copy(instance, copy=True):
7111    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:
7366def union(
7367    *expressions: ExpOrStr,
7368    distinct: bool = True,
7369    dialect: DialectType = None,
7370    copy: bool = True,
7371    **opts,
7372) -> Union:
7373    """
7374    Initializes a syntax tree for the `UNION` operation.
7375
7376    Example:
7377        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7378        'SELECT * FROM foo UNION SELECT * FROM bla'
7379
7380    Args:
7381        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7382            If `Expression` instances are passed, they will be used as-is.
7383        distinct: set the DISTINCT flag if and only if this is true.
7384        dialect: the dialect used to parse the input expression.
7385        copy: whether to copy the expression.
7386        opts: other options to use to parse the input expressions.
7387
7388    Returns:
7389        The new Union instance.
7390    """
7391    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7392    return _apply_set_operation(
7393        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7394    )

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

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

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

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:
7727def and_(
7728    *expressions: t.Optional[ExpOrStr],
7729    dialect: DialectType = None,
7730    copy: bool = True,
7731    wrap: bool = True,
7732    **opts,
7733) -> Condition:
7734    """
7735    Combine multiple conditions with an AND logical operator.
7736
7737    Example:
7738        >>> and_("x=1", and_("y=1", "z=1")).sql()
7739        'x = 1 AND (y = 1 AND z = 1)'
7740
7741    Args:
7742        *expressions: the SQL code strings to parse.
7743            If an Expression instance is passed, this is used as-is.
7744        dialect: the dialect used to parse the input expression.
7745        copy: whether to copy `expressions` (only applies to Expressions).
7746        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7747            precedence issues, but can be turned off when the produced AST is too deep and
7748            causes recursion-related issues.
7749        **opts: other options to use to parse the input expressions.
7750
7751    Returns:
7752        The new condition
7753    """
7754    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:
7757def or_(
7758    *expressions: t.Optional[ExpOrStr],
7759    dialect: DialectType = None,
7760    copy: bool = True,
7761    wrap: bool = True,
7762    **opts,
7763) -> Condition:
7764    """
7765    Combine multiple conditions with an OR logical operator.
7766
7767    Example:
7768        >>> or_("x=1", or_("y=1", "z=1")).sql()
7769        'x = 1 OR (y = 1 OR z = 1)'
7770
7771    Args:
7772        *expressions: the SQL code strings to parse.
7773            If an Expression instance is passed, this is used as-is.
7774        dialect: the dialect used to parse the input expression.
7775        copy: whether to copy `expressions` (only applies to Expressions).
7776        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7777            precedence issues, but can be turned off when the produced AST is too deep and
7778            causes recursion-related issues.
7779        **opts: other options to use to parse the input expressions.
7780
7781    Returns:
7782        The new condition
7783    """
7784    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:
7787def xor(
7788    *expressions: t.Optional[ExpOrStr],
7789    dialect: DialectType = None,
7790    copy: bool = True,
7791    wrap: bool = True,
7792    **opts,
7793) -> Condition:
7794    """
7795    Combine multiple conditions with an XOR logical operator.
7796
7797    Example:
7798        >>> xor("x=1", xor("y=1", "z=1")).sql()
7799        'x = 1 XOR (y = 1 XOR z = 1)'
7800
7801    Args:
7802        *expressions: the SQL code strings to parse.
7803            If an Expression instance is passed, this is used as-is.
7804        dialect: the dialect used to parse the input expression.
7805        copy: whether to copy `expressions` (only applies to Expressions).
7806        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7807            precedence issues, but can be turned off when the produced AST is too deep and
7808            causes recursion-related issues.
7809        **opts: other options to use to parse the input expressions.
7810
7811    Returns:
7812        The new condition
7813    """
7814    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:
7817def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7818    """
7819    Wrap a condition with a NOT operator.
7820
7821    Example:
7822        >>> not_("this_suit='black'").sql()
7823        "NOT this_suit = 'black'"
7824
7825    Args:
7826        expression: the SQL code string to parse.
7827            If an Expression instance is passed, this is used as-is.
7828        dialect: the dialect used to parse the input expression.
7829        copy: whether to copy the expression or not.
7830        **opts: other options to use to parse the input expressions.
7831
7832    Returns:
7833        The new condition.
7834    """
7835    this = condition(
7836        expression,
7837        dialect=dialect,
7838        copy=copy,
7839        **opts,
7840    )
7841    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:
7844def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7845    """
7846    Wrap an expression in parentheses.
7847
7848    Example:
7849        >>> paren("5 + 3").sql()
7850        '(5 + 3)'
7851
7852    Args:
7853        expression: the SQL code string to parse.
7854            If an Expression instance is passed, this is used as-is.
7855        copy: whether to copy the expression or not.
7856
7857    Returns:
7858        The wrapped expression.
7859    """
7860    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):
7876def to_identifier(name, quoted=None, copy=True):
7877    """Builds an identifier.
7878
7879    Args:
7880        name: The name to turn into an identifier.
7881        quoted: Whether to force quote the identifier.
7882        copy: Whether to copy name if it's an Identifier.
7883
7884    Returns:
7885        The identifier ast node.
7886    """
7887
7888    if name is None:
7889        return None
7890
7891    if isinstance(name, Identifier):
7892        identifier = maybe_copy(name, copy)
7893    elif isinstance(name, str):
7894        identifier = Identifier(
7895            this=name,
7896            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7897        )
7898    else:
7899        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7900    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:
7903def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7904    """
7905    Parses a given string into an identifier.
7906
7907    Args:
7908        name: The name to parse into an identifier.
7909        dialect: The dialect to parse against.
7910
7911    Returns:
7912        The identifier ast node.
7913    """
7914    try:
7915        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7916    except (ParseError, TokenError):
7917        expression = to_identifier(name)
7918
7919    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:
7925def to_interval(interval: str | Literal) -> Interval:
7926    """Builds an interval expression from a string like '1 day' or '5 months'."""
7927    if isinstance(interval, Literal):
7928        if not interval.is_string:
7929            raise ValueError("Invalid interval string.")
7930
7931        interval = interval.this
7932
7933    interval = maybe_parse(f"INTERVAL {interval}")
7934    assert isinstance(interval, Interval)
7935    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:
7938def to_table(
7939    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7940) -> Table:
7941    """
7942    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7943    If a table is passed in then that table is returned.
7944
7945    Args:
7946        sql_path: a `[catalog].[schema].[table]` string.
7947        dialect: the source dialect according to which the table name will be parsed.
7948        copy: Whether to copy a table if it is passed in.
7949        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7950
7951    Returns:
7952        A table expression.
7953    """
7954    if isinstance(sql_path, Table):
7955        return maybe_copy(sql_path, copy=copy)
7956
7957    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7958
7959    for k, v in kwargs.items():
7960        table.set(k, v)
7961
7962    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:
7965def to_column(
7966    sql_path: str | Column,
7967    quoted: t.Optional[bool] = None,
7968    dialect: DialectType = None,
7969    copy: bool = True,
7970    **kwargs,
7971) -> Column:
7972    """
7973    Create a column from a `[table].[column]` sql path. Table is optional.
7974    If a column is passed in then that column is returned.
7975
7976    Args:
7977        sql_path: a `[table].[column]` string.
7978        quoted: Whether or not to force quote identifiers.
7979        dialect: the source dialect according to which the column name will be parsed.
7980        copy: Whether to copy a column if it is passed in.
7981        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7982
7983    Returns:
7984        A column expression.
7985    """
7986    if isinstance(sql_path, Column):
7987        return maybe_copy(sql_path, copy=copy)
7988
7989    try:
7990        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7991    except ParseError:
7992        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7993
7994    for k, v in kwargs.items():
7995        col.set(k, v)
7996
7997    if quoted:
7998        for i in col.find_all(Identifier):
7999            i.set("quoted", True)
8000
8001    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):
8004def alias_(
8005    expression: ExpOrStr,
8006    alias: t.Optional[str | Identifier],
8007    table: bool | t.Sequence[str | Identifier] = False,
8008    quoted: t.Optional[bool] = None,
8009    dialect: DialectType = None,
8010    copy: bool = True,
8011    **opts,
8012):
8013    """Create an Alias expression.
8014
8015    Example:
8016        >>> alias_('foo', 'bar').sql()
8017        'foo AS bar'
8018
8019        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8020        '(SELECT 1, 2) AS bar(a, b)'
8021
8022    Args:
8023        expression: the SQL code strings to parse.
8024            If an Expression instance is passed, this is used as-is.
8025        alias: the alias name to use. If the name has
8026            special characters it is quoted.
8027        table: Whether to create a table alias, can also be a list of columns.
8028        quoted: whether to quote the alias
8029        dialect: the dialect used to parse the input expression.
8030        copy: Whether to copy the expression.
8031        **opts: other options to use to parse the input expressions.
8032
8033    Returns:
8034        Alias: the aliased expression
8035    """
8036    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8037    alias = to_identifier(alias, quoted=quoted)
8038
8039    if table:
8040        table_alias = TableAlias(this=alias)
8041        exp.set("alias", table_alias)
8042
8043        if not isinstance(table, bool):
8044            for column in table:
8045                table_alias.append("columns", to_identifier(column, quoted=quoted))
8046
8047        return exp
8048
8049    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8050    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8051    # for the complete Window expression.
8052    #
8053    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8054
8055    if "alias" in exp.arg_types and not isinstance(exp, Window):
8056        exp.set("alias", alias)
8057        return exp
8058    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:
8061def subquery(
8062    expression: ExpOrStr,
8063    alias: t.Optional[Identifier | str] = None,
8064    dialect: DialectType = None,
8065    **opts,
8066) -> Select:
8067    """
8068    Build a subquery expression that's selected from.
8069
8070    Example:
8071        >>> subquery('select x from tbl', 'bar').select('x').sql()
8072        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8073
8074    Args:
8075        expression: the SQL code strings to parse.
8076            If an Expression instance is passed, this is used as-is.
8077        alias: the alias name to use.
8078        dialect: the dialect used to parse the input expression.
8079        **opts: other options to use to parse the input expressions.
8080
8081    Returns:
8082        A new Select instance with the subquery expression included.
8083    """
8084
8085    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8086    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):
8117def column(
8118    col,
8119    table=None,
8120    db=None,
8121    catalog=None,
8122    *,
8123    fields=None,
8124    quoted=None,
8125    copy=True,
8126):
8127    """
8128    Build a Column.
8129
8130    Args:
8131        col: Column name.
8132        table: Table name.
8133        db: Database name.
8134        catalog: Catalog name.
8135        fields: Additional fields using dots.
8136        quoted: Whether to force quotes on the column's identifiers.
8137        copy: Whether to copy identifiers if passed in.
8138
8139    Returns:
8140        The new Column instance.
8141    """
8142    this = Column(
8143        this=to_identifier(col, quoted=quoted, copy=copy),
8144        table=to_identifier(table, quoted=quoted, copy=copy),
8145        db=to_identifier(db, quoted=quoted, copy=copy),
8146        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8147    )
8148
8149    if fields:
8150        this = Dot.build(
8151            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8152        )
8153    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:
8156def cast(
8157    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8158) -> Cast:
8159    """Cast an expression to a data type.
8160
8161    Example:
8162        >>> cast('x + 1', 'int').sql()
8163        'CAST(x + 1 AS INT)'
8164
8165    Args:
8166        expression: The expression to cast.
8167        to: The datatype to cast to.
8168        copy: Whether to copy the supplied expressions.
8169        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8170            - The expression to be cast is already a exp.Cast expression
8171            - The existing cast is to a type that is logically equivalent to new type
8172
8173            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8174            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8175            and instead just return the original expression `CAST(x as DATETIME)`.
8176
8177            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8178            mapping is applied in the target dialect generator.
8179
8180    Returns:
8181        The new Cast instance.
8182    """
8183    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8184    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8185
8186    # dont re-cast if the expression is already a cast to the correct type
8187    if isinstance(expr, Cast):
8188        from sqlglot.dialects.dialect import Dialect
8189
8190        target_dialect = Dialect.get_or_raise(dialect)
8191        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8192
8193        existing_cast_type: DataType.Type = expr.to.this
8194        new_cast_type: DataType.Type = data_type.this
8195        types_are_equivalent = type_mapping.get(
8196            existing_cast_type, existing_cast_type.value
8197        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8198
8199        if expr.is_type(data_type) or types_are_equivalent:
8200            return expr
8201
8202    expr = Cast(this=expr, to=data_type)
8203    expr.type = data_type
8204
8205    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:
8208def table_(
8209    table: Identifier | str,
8210    db: t.Optional[Identifier | str] = None,
8211    catalog: t.Optional[Identifier | str] = None,
8212    quoted: t.Optional[bool] = None,
8213    alias: t.Optional[Identifier | str] = None,
8214) -> Table:
8215    """Build a Table.
8216
8217    Args:
8218        table: Table name.
8219        db: Database name.
8220        catalog: Catalog name.
8221        quote: Whether to force quotes on the table's identifiers.
8222        alias: Table's alias.
8223
8224    Returns:
8225        The new Table instance.
8226    """
8227    return Table(
8228        this=to_identifier(table, quoted=quoted) if table else None,
8229        db=to_identifier(db, quoted=quoted) if db else None,
8230        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8231        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8232    )

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

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

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

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

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

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

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

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

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:
8799def true() -> Boolean:
8800    """
8801    Returns a true Boolean expression.
8802    """
8803    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8806def false() -> Boolean:
8807    """
8808    Returns a false Boolean expression.
8809    """
8810    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8813def null() -> Null:
8814    """
8815    Returns a Null expression.
8816    """
8817    return Null()

Returns a Null expression.

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