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    }
2501
2502    @property
2503    def method(self) -> str:
2504        return self.text("method").upper()
2505
2506    @property
2507    def kind(self) -> str:
2508        return self.text("kind").upper()
2509
2510    @property
2511    def side(self) -> str:
2512        return self.text("side").upper()
2513
2514    @property
2515    def hint(self) -> str:
2516        return self.text("hint").upper()
2517
2518    @property
2519    def alias_or_name(self) -> str:
2520        return self.this.alias_or_name
2521
2522    @property
2523    def is_semi_or_anti_join(self) -> bool:
2524        return self.kind in ("SEMI", "ANTI")
2525
2526    def on(
2527        self,
2528        *expressions: t.Optional[ExpOrStr],
2529        append: bool = True,
2530        dialect: DialectType = None,
2531        copy: bool = True,
2532        **opts,
2533    ) -> Join:
2534        """
2535        Append to or set the ON expressions.
2536
2537        Example:
2538            >>> import sqlglot
2539            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2540            'JOIN x ON y = 1'
2541
2542        Args:
2543            *expressions: the SQL code strings to parse.
2544                If an `Expression` instance is passed, it will be used as-is.
2545                Multiple expressions are combined with an AND operator.
2546            append: if `True`, AND the new expressions to any existing expression.
2547                Otherwise, this resets the expression.
2548            dialect: the dialect used to parse the input expressions.
2549            copy: if `False`, modify this expression instance in-place.
2550            opts: other options to use to parse the input expressions.
2551
2552        Returns:
2553            The modified Join expression.
2554        """
2555        join = _apply_conjunction_builder(
2556            *expressions,
2557            instance=self,
2558            arg="on",
2559            append=append,
2560            dialect=dialect,
2561            copy=copy,
2562            **opts,
2563        )
2564
2565        if join.kind == "CROSS":
2566            join.set("kind", None)
2567
2568        return join
2569
2570    def using(
2571        self,
2572        *expressions: t.Optional[ExpOrStr],
2573        append: bool = True,
2574        dialect: DialectType = None,
2575        copy: bool = True,
2576        **opts,
2577    ) -> Join:
2578        """
2579        Append to or set the USING expressions.
2580
2581        Example:
2582            >>> import sqlglot
2583            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2584            'JOIN x USING (foo, bla)'
2585
2586        Args:
2587            *expressions: the SQL code strings to parse.
2588                If an `Expression` instance is passed, it will be used as-is.
2589            append: if `True`, concatenate the new expressions to the existing "using" list.
2590                Otherwise, this resets the expression.
2591            dialect: the dialect used to parse the input expressions.
2592            copy: if `False`, modify this expression instance in-place.
2593            opts: other options to use to parse the input expressions.
2594
2595        Returns:
2596            The modified Join expression.
2597        """
2598        join = _apply_list_builder(
2599            *expressions,
2600            instance=self,
2601            arg="using",
2602            append=append,
2603            dialect=dialect,
2604            copy=copy,
2605            **opts,
2606        )
2607
2608        if join.kind == "CROSS":
2609            join.set("kind", None)
2610
2611        return join
2612
2613
2614class Lateral(UDTF):
2615    arg_types = {
2616        "this": True,
2617        "view": False,
2618        "outer": False,
2619        "alias": False,
2620        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2621        "ordinality": False,
2622    }
2623
2624
2625# https://docs.snowflake.com/sql-reference/literals-table
2626# https://docs.snowflake.com/en/sql-reference/functions-table#using-a-table-function
2627class TableFromRows(UDTF):
2628    arg_types = {
2629        "this": True,
2630        "alias": False,
2631        "joins": False,
2632        "pivots": False,
2633        "sample": False,
2634    }
2635
2636
2637class MatchRecognizeMeasure(Expression):
2638    arg_types = {
2639        "this": True,
2640        "window_frame": False,
2641    }
2642
2643
2644class MatchRecognize(Expression):
2645    arg_types = {
2646        "partition_by": False,
2647        "order": False,
2648        "measures": False,
2649        "rows": False,
2650        "after": False,
2651        "pattern": False,
2652        "define": False,
2653        "alias": False,
2654    }
2655
2656
2657# Clickhouse FROM FINAL modifier
2658# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
2659class Final(Expression):
2660    pass
2661
2662
2663class Offset(Expression):
2664    arg_types = {"this": False, "expression": True, "expressions": False}
2665
2666
2667class Order(Expression):
2668    arg_types = {"this": False, "expressions": True, "siblings": False}
2669
2670
2671# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
2672class WithFill(Expression):
2673    arg_types = {
2674        "from": False,
2675        "to": False,
2676        "step": False,
2677        "interpolate": False,
2678    }
2679
2680
2681# hive specific sorts
2682# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
2683class Cluster(Order):
2684    pass
2685
2686
2687class Distribute(Order):
2688    pass
2689
2690
2691class Sort(Order):
2692    pass
2693
2694
2695class Ordered(Expression):
2696    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2697
2698    @property
2699    def name(self) -> str:
2700        return self.this.name
2701
2702
2703class Property(Expression):
2704    arg_types = {"this": True, "value": True}
2705
2706
2707class GrantPrivilege(Expression):
2708    arg_types = {"this": True, "expressions": False}
2709
2710
2711class GrantPrincipal(Expression):
2712    arg_types = {"this": True, "kind": False}
2713
2714
2715class AllowedValuesProperty(Expression):
2716    arg_types = {"expressions": True}
2717
2718
2719class AlgorithmProperty(Property):
2720    arg_types = {"this": True}
2721
2722
2723class AutoIncrementProperty(Property):
2724    arg_types = {"this": True}
2725
2726
2727# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2728class AutoRefreshProperty(Property):
2729    arg_types = {"this": True}
2730
2731
2732class BackupProperty(Property):
2733    arg_types = {"this": True}
2734
2735
2736class BlockCompressionProperty(Property):
2737    arg_types = {
2738        "autotemp": False,
2739        "always": False,
2740        "default": False,
2741        "manual": False,
2742        "never": False,
2743    }
2744
2745
2746class CharacterSetProperty(Property):
2747    arg_types = {"this": True, "default": True}
2748
2749
2750class ChecksumProperty(Property):
2751    arg_types = {"on": False, "default": False}
2752
2753
2754class CollateProperty(Property):
2755    arg_types = {"this": True, "default": False}
2756
2757
2758class CopyGrantsProperty(Property):
2759    arg_types = {}
2760
2761
2762class DataBlocksizeProperty(Property):
2763    arg_types = {
2764        "size": False,
2765        "units": False,
2766        "minimum": False,
2767        "maximum": False,
2768        "default": False,
2769    }
2770
2771
2772class DataDeletionProperty(Property):
2773    arg_types = {"on": True, "filter_col": False, "retention_period": False}
2774
2775
2776class DefinerProperty(Property):
2777    arg_types = {"this": True}
2778
2779
2780class DistKeyProperty(Property):
2781    arg_types = {"this": True}
2782
2783
2784# https://docs.starrocks.io/docs/sql-reference/sql-statements/data-definition/CREATE_TABLE/#distribution_desc
2785# https://doris.apache.org/docs/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE?_highlight=create&_highlight=table#distribution_desc
2786class DistributedByProperty(Property):
2787    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
2788
2789
2790class DistStyleProperty(Property):
2791    arg_types = {"this": True}
2792
2793
2794class DuplicateKeyProperty(Property):
2795    arg_types = {"expressions": True}
2796
2797
2798class EngineProperty(Property):
2799    arg_types = {"this": True}
2800
2801
2802class HeapProperty(Property):
2803    arg_types = {}
2804
2805
2806class ToTableProperty(Property):
2807    arg_types = {"this": True}
2808
2809
2810class ExecuteAsProperty(Property):
2811    arg_types = {"this": True}
2812
2813
2814class ExternalProperty(Property):
2815    arg_types = {"this": False}
2816
2817
2818class FallbackProperty(Property):
2819    arg_types = {"no": True, "protection": False}
2820
2821
2822class FileFormatProperty(Property):
2823    arg_types = {"this": False, "expressions": False}
2824
2825
2826class CredentialsProperty(Property):
2827    arg_types = {"expressions": True}
2828
2829
2830class FreespaceProperty(Property):
2831    arg_types = {"this": True, "percent": False}
2832
2833
2834class GlobalProperty(Property):
2835    arg_types = {}
2836
2837
2838class IcebergProperty(Property):
2839    arg_types = {}
2840
2841
2842class InheritsProperty(Property):
2843    arg_types = {"expressions": True}
2844
2845
2846class InputModelProperty(Property):
2847    arg_types = {"this": True}
2848
2849
2850class OutputModelProperty(Property):
2851    arg_types = {"this": True}
2852
2853
2854class IsolatedLoadingProperty(Property):
2855    arg_types = {"no": False, "concurrent": False, "target": False}
2856
2857
2858class JournalProperty(Property):
2859    arg_types = {
2860        "no": False,
2861        "dual": False,
2862        "before": False,
2863        "local": False,
2864        "after": False,
2865    }
2866
2867
2868class LanguageProperty(Property):
2869    arg_types = {"this": True}
2870
2871
2872# spark ddl
2873class ClusteredByProperty(Property):
2874    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2875
2876
2877class DictProperty(Property):
2878    arg_types = {"this": True, "kind": True, "settings": False}
2879
2880
2881class DictSubProperty(Property):
2882    pass
2883
2884
2885class DictRange(Property):
2886    arg_types = {"this": True, "min": True, "max": True}
2887
2888
2889class DynamicProperty(Property):
2890    arg_types = {}
2891
2892
2893# Clickhouse CREATE ... ON CLUSTER modifier
2894# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2895class OnCluster(Property):
2896    arg_types = {"this": True}
2897
2898
2899# Clickhouse EMPTY table "property"
2900class EmptyProperty(Property):
2901    arg_types = {}
2902
2903
2904class LikeProperty(Property):
2905    arg_types = {"this": True, "expressions": False}
2906
2907
2908class LocationProperty(Property):
2909    arg_types = {"this": True}
2910
2911
2912class LockProperty(Property):
2913    arg_types = {"this": True}
2914
2915
2916class LockingProperty(Property):
2917    arg_types = {
2918        "this": False,
2919        "kind": True,
2920        "for_or_in": False,
2921        "lock_type": True,
2922        "override": False,
2923    }
2924
2925
2926class LogProperty(Property):
2927    arg_types = {"no": True}
2928
2929
2930class MaterializedProperty(Property):
2931    arg_types = {"this": False}
2932
2933
2934class MergeBlockRatioProperty(Property):
2935    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2936
2937
2938class NoPrimaryIndexProperty(Property):
2939    arg_types = {}
2940
2941
2942class OnProperty(Property):
2943    arg_types = {"this": True}
2944
2945
2946class OnCommitProperty(Property):
2947    arg_types = {"delete": False}
2948
2949
2950class PartitionedByProperty(Property):
2951    arg_types = {"this": True}
2952
2953
2954class PartitionedByBucket(Property):
2955    arg_types = {"this": True, "expression": True}
2956
2957
2958class PartitionByTruncate(Property):
2959    arg_types = {"this": True, "expression": True}
2960
2961
2962# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2963class PartitionByRangeProperty(Property):
2964    arg_types = {"partition_expressions": True, "create_expressions": True}
2965
2966
2967# https://docs.starrocks.io/docs/table_design/data_distribution/#range-partitioning
2968class PartitionByRangePropertyDynamic(Expression):
2969    arg_types = {"this": False, "start": True, "end": True, "every": True}
2970
2971
2972# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2973class UniqueKeyProperty(Property):
2974    arg_types = {"expressions": True}
2975
2976
2977# https://www.postgresql.org/docs/current/sql-createtable.html
2978class PartitionBoundSpec(Expression):
2979    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2980    arg_types = {
2981        "this": False,
2982        "expression": False,
2983        "from_expressions": False,
2984        "to_expressions": False,
2985    }
2986
2987
2988class PartitionedOfProperty(Property):
2989    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2990    arg_types = {"this": True, "expression": True}
2991
2992
2993class StreamingTableProperty(Property):
2994    arg_types = {}
2995
2996
2997class RemoteWithConnectionModelProperty(Property):
2998    arg_types = {"this": True}
2999
3000
3001class ReturnsProperty(Property):
3002    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
3003
3004
3005class StrictProperty(Property):
3006    arg_types = {}
3007
3008
3009class RowFormatProperty(Property):
3010    arg_types = {"this": True}
3011
3012
3013class RowFormatDelimitedProperty(Property):
3014    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3015    arg_types = {
3016        "fields": False,
3017        "escaped": False,
3018        "collection_items": False,
3019        "map_keys": False,
3020        "lines": False,
3021        "null": False,
3022        "serde": False,
3023    }
3024
3025
3026class RowFormatSerdeProperty(Property):
3027    arg_types = {"this": True, "serde_properties": False}
3028
3029
3030# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
3031class QueryTransform(Expression):
3032    arg_types = {
3033        "expressions": True,
3034        "command_script": True,
3035        "schema": False,
3036        "row_format_before": False,
3037        "record_writer": False,
3038        "row_format_after": False,
3039        "record_reader": False,
3040    }
3041
3042
3043class SampleProperty(Property):
3044    arg_types = {"this": True}
3045
3046
3047# https://prestodb.io/docs/current/sql/create-view.html#synopsis
3048class SecurityProperty(Property):
3049    arg_types = {"this": True}
3050
3051
3052class SchemaCommentProperty(Property):
3053    arg_types = {"this": True}
3054
3055
3056class SerdeProperties(Property):
3057    arg_types = {"expressions": True, "with": False}
3058
3059
3060class SetProperty(Property):
3061    arg_types = {"multi": True}
3062
3063
3064class SharingProperty(Property):
3065    arg_types = {"this": False}
3066
3067
3068class SetConfigProperty(Property):
3069    arg_types = {"this": True}
3070
3071
3072class SettingsProperty(Property):
3073    arg_types = {"expressions": True}
3074
3075
3076class SortKeyProperty(Property):
3077    arg_types = {"this": True, "compound": False}
3078
3079
3080class SqlReadWriteProperty(Property):
3081    arg_types = {"this": True}
3082
3083
3084class SqlSecurityProperty(Property):
3085    arg_types = {"definer": True}
3086
3087
3088class StabilityProperty(Property):
3089    arg_types = {"this": True}
3090
3091
3092class StorageHandlerProperty(Property):
3093    arg_types = {"this": True}
3094
3095
3096class TemporaryProperty(Property):
3097    arg_types = {"this": False}
3098
3099
3100class SecureProperty(Property):
3101    arg_types = {}
3102
3103
3104# https://docs.snowflake.com/en/sql-reference/sql/create-table
3105class Tags(ColumnConstraintKind, Property):
3106    arg_types = {"expressions": True}
3107
3108
3109class TransformModelProperty(Property):
3110    arg_types = {"expressions": True}
3111
3112
3113class TransientProperty(Property):
3114    arg_types = {"this": False}
3115
3116
3117class UnloggedProperty(Property):
3118    arg_types = {}
3119
3120
3121# https://docs.snowflake.com/en/sql-reference/sql/create-table#create-table-using-template
3122class UsingTemplateProperty(Property):
3123    arg_types = {"this": True}
3124
3125
3126# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
3127class ViewAttributeProperty(Property):
3128    arg_types = {"this": True}
3129
3130
3131class VolatileProperty(Property):
3132    arg_types = {"this": False}
3133
3134
3135class WithDataProperty(Property):
3136    arg_types = {"no": True, "statistics": False}
3137
3138
3139class WithJournalTableProperty(Property):
3140    arg_types = {"this": True}
3141
3142
3143class WithSchemaBindingProperty(Property):
3144    arg_types = {"this": True}
3145
3146
3147class WithSystemVersioningProperty(Property):
3148    arg_types = {
3149        "on": False,
3150        "this": False,
3151        "data_consistency": False,
3152        "retention_period": False,
3153        "with": True,
3154    }
3155
3156
3157class WithProcedureOptions(Property):
3158    arg_types = {"expressions": True}
3159
3160
3161class EncodeProperty(Property):
3162    arg_types = {"this": True, "properties": False, "key": False}
3163
3164
3165class IncludeProperty(Property):
3166    arg_types = {"this": True, "alias": False, "column_def": False}
3167
3168
3169class ForceProperty(Property):
3170    arg_types = {}
3171
3172
3173class Properties(Expression):
3174    arg_types = {"expressions": True}
3175
3176    NAME_TO_PROPERTY = {
3177        "ALGORITHM": AlgorithmProperty,
3178        "AUTO_INCREMENT": AutoIncrementProperty,
3179        "CHARACTER SET": CharacterSetProperty,
3180        "CLUSTERED_BY": ClusteredByProperty,
3181        "COLLATE": CollateProperty,
3182        "COMMENT": SchemaCommentProperty,
3183        "CREDENTIALS": CredentialsProperty,
3184        "DEFINER": DefinerProperty,
3185        "DISTKEY": DistKeyProperty,
3186        "DISTRIBUTED_BY": DistributedByProperty,
3187        "DISTSTYLE": DistStyleProperty,
3188        "ENGINE": EngineProperty,
3189        "EXECUTE AS": ExecuteAsProperty,
3190        "FORMAT": FileFormatProperty,
3191        "LANGUAGE": LanguageProperty,
3192        "LOCATION": LocationProperty,
3193        "LOCK": LockProperty,
3194        "PARTITIONED_BY": PartitionedByProperty,
3195        "RETURNS": ReturnsProperty,
3196        "ROW_FORMAT": RowFormatProperty,
3197        "SORTKEY": SortKeyProperty,
3198        "ENCODE": EncodeProperty,
3199        "INCLUDE": IncludeProperty,
3200    }
3201
3202    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3203
3204    # CREATE property locations
3205    # Form: schema specified
3206    #   create [POST_CREATE]
3207    #     table a [POST_NAME]
3208    #     (b int) [POST_SCHEMA]
3209    #     with ([POST_WITH])
3210    #     index (b) [POST_INDEX]
3211    #
3212    # Form: alias selection
3213    #   create [POST_CREATE]
3214    #     table a [POST_NAME]
3215    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3216    #     index (c) [POST_INDEX]
3217    class Location(AutoName):
3218        POST_CREATE = auto()
3219        POST_NAME = auto()
3220        POST_SCHEMA = auto()
3221        POST_WITH = auto()
3222        POST_ALIAS = auto()
3223        POST_EXPRESSION = auto()
3224        POST_INDEX = auto()
3225        UNSUPPORTED = auto()
3226
3227    @classmethod
3228    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3229        expressions = []
3230        for key, value in properties_dict.items():
3231            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3232            if property_cls:
3233                expressions.append(property_cls(this=convert(value)))
3234            else:
3235                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3236
3237        return cls(expressions=expressions)
3238
3239
3240class Qualify(Expression):
3241    pass
3242
3243
3244class InputOutputFormat(Expression):
3245    arg_types = {"input_format": False, "output_format": False}
3246
3247
3248# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
3249class Return(Expression):
3250    pass
3251
3252
3253class Reference(Expression):
3254    arg_types = {"this": True, "expressions": False, "options": False}
3255
3256
3257class Tuple(Expression):
3258    arg_types = {"expressions": False}
3259
3260    def isin(
3261        self,
3262        *expressions: t.Any,
3263        query: t.Optional[ExpOrStr] = None,
3264        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3265        copy: bool = True,
3266        **opts,
3267    ) -> In:
3268        return In(
3269            this=maybe_copy(self, copy),
3270            expressions=[convert(e, copy=copy) for e in expressions],
3271            query=maybe_parse(query, copy=copy, **opts) if query else None,
3272            unnest=(
3273                Unnest(
3274                    expressions=[
3275                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3276                        for e in ensure_list(unnest)
3277                    ]
3278                )
3279                if unnest
3280                else None
3281            ),
3282        )
3283
3284
3285QUERY_MODIFIERS = {
3286    "match": False,
3287    "laterals": False,
3288    "joins": False,
3289    "connect": False,
3290    "pivots": False,
3291    "prewhere": False,
3292    "where": False,
3293    "group": False,
3294    "having": False,
3295    "qualify": False,
3296    "windows": False,
3297    "distribute": False,
3298    "sort": False,
3299    "cluster": False,
3300    "order": False,
3301    "limit": False,
3302    "offset": False,
3303    "locks": False,
3304    "sample": False,
3305    "settings": False,
3306    "format": False,
3307    "options": False,
3308}
3309
3310
3311# https://learn.microsoft.com/en-us/sql/t-sql/queries/option-clause-transact-sql?view=sql-server-ver16
3312# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-ver16
3313class QueryOption(Expression):
3314    arg_types = {"this": True, "expression": False}
3315
3316
3317# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
3318class WithTableHint(Expression):
3319    arg_types = {"expressions": True}
3320
3321
3322# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
3323class IndexTableHint(Expression):
3324    arg_types = {"this": True, "expressions": False, "target": False}
3325
3326
3327# https://docs.snowflake.com/en/sql-reference/constructs/at-before
3328class HistoricalData(Expression):
3329    arg_types = {"this": True, "kind": True, "expression": True}
3330
3331
3332# https://docs.snowflake.com/en/sql-reference/sql/put
3333class Put(Expression):
3334    arg_types = {"this": True, "target": True, "properties": False}
3335
3336
3337# https://docs.snowflake.com/en/sql-reference/sql/get
3338class Get(Expression):
3339    arg_types = {"this": True, "target": True, "properties": False}
3340
3341
3342class Table(Expression):
3343    arg_types = {
3344        "this": False,
3345        "alias": False,
3346        "db": False,
3347        "catalog": False,
3348        "laterals": False,
3349        "joins": False,
3350        "pivots": False,
3351        "hints": False,
3352        "system_time": False,
3353        "version": False,
3354        "format": False,
3355        "pattern": False,
3356        "ordinality": False,
3357        "when": False,
3358        "only": False,
3359        "partition": False,
3360        "changes": False,
3361        "rows_from": False,
3362        "sample": False,
3363    }
3364
3365    @property
3366    def name(self) -> str:
3367        if not self.this or isinstance(self.this, Func):
3368            return ""
3369        return self.this.name
3370
3371    @property
3372    def db(self) -> str:
3373        return self.text("db")
3374
3375    @property
3376    def catalog(self) -> str:
3377        return self.text("catalog")
3378
3379    @property
3380    def selects(self) -> t.List[Expression]:
3381        return []
3382
3383    @property
3384    def named_selects(self) -> t.List[str]:
3385        return []
3386
3387    @property
3388    def parts(self) -> t.List[Expression]:
3389        """Return the parts of a table in order catalog, db, table."""
3390        parts: t.List[Expression] = []
3391
3392        for arg in ("catalog", "db", "this"):
3393            part = self.args.get(arg)
3394
3395            if isinstance(part, Dot):
3396                parts.extend(part.flatten())
3397            elif isinstance(part, Expression):
3398                parts.append(part)
3399
3400        return parts
3401
3402    def to_column(self, copy: bool = True) -> Expression:
3403        parts = self.parts
3404        last_part = parts[-1]
3405
3406        if isinstance(last_part, Identifier):
3407            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3408        else:
3409            # This branch will be reached if a function or array is wrapped in a `Table`
3410            col = last_part
3411
3412        alias = self.args.get("alias")
3413        if alias:
3414            col = alias_(col, alias.this, copy=copy)
3415
3416        return col
3417
3418
3419class SetOperation(Query):
3420    arg_types = {
3421        "with": False,
3422        "this": True,
3423        "expression": True,
3424        "distinct": False,
3425        "by_name": False,
3426        "side": False,
3427        "kind": False,
3428        "on": False,
3429        **QUERY_MODIFIERS,
3430    }
3431
3432    def select(
3433        self: S,
3434        *expressions: t.Optional[ExpOrStr],
3435        append: bool = True,
3436        dialect: DialectType = None,
3437        copy: bool = True,
3438        **opts,
3439    ) -> S:
3440        this = maybe_copy(self, copy)
3441        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3442        this.expression.unnest().select(
3443            *expressions, append=append, dialect=dialect, copy=False, **opts
3444        )
3445        return this
3446
3447    @property
3448    def named_selects(self) -> t.List[str]:
3449        return self.this.unnest().named_selects
3450
3451    @property
3452    def is_star(self) -> bool:
3453        return self.this.is_star or self.expression.is_star
3454
3455    @property
3456    def selects(self) -> t.List[Expression]:
3457        return self.this.unnest().selects
3458
3459    @property
3460    def left(self) -> Query:
3461        return self.this
3462
3463    @property
3464    def right(self) -> Query:
3465        return self.expression
3466
3467    @property
3468    def kind(self) -> str:
3469        return self.text("kind").upper()
3470
3471    @property
3472    def side(self) -> str:
3473        return self.text("side").upper()
3474
3475
3476class Union(SetOperation):
3477    pass
3478
3479
3480class Except(SetOperation):
3481    pass
3482
3483
3484class Intersect(SetOperation):
3485    pass
3486
3487
3488class Update(DML):
3489    arg_types = {
3490        "with": False,
3491        "this": False,
3492        "expressions": True,
3493        "from": False,
3494        "where": False,
3495        "returning": False,
3496        "order": False,
3497        "limit": False,
3498    }
3499
3500    def table(
3501        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3502    ) -> Update:
3503        """
3504        Set the table to update.
3505
3506        Example:
3507            >>> Update().table("my_table").set_("x = 1").sql()
3508            'UPDATE my_table SET x = 1'
3509
3510        Args:
3511            expression : the SQL code strings to parse.
3512                If a `Table` instance is passed, this is used as-is.
3513                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3514            dialect: the dialect used to parse the input expression.
3515            copy: if `False`, modify this expression instance in-place.
3516            opts: other options to use to parse the input expressions.
3517
3518        Returns:
3519            The modified Update expression.
3520        """
3521        return _apply_builder(
3522            expression=expression,
3523            instance=self,
3524            arg="this",
3525            into=Table,
3526            prefix=None,
3527            dialect=dialect,
3528            copy=copy,
3529            **opts,
3530        )
3531
3532    def set_(
3533        self,
3534        *expressions: ExpOrStr,
3535        append: bool = True,
3536        dialect: DialectType = None,
3537        copy: bool = True,
3538        **opts,
3539    ) -> Update:
3540        """
3541        Append to or set the SET expressions.
3542
3543        Example:
3544            >>> Update().table("my_table").set_("x = 1").sql()
3545            'UPDATE my_table SET x = 1'
3546
3547        Args:
3548            *expressions: the SQL code strings to parse.
3549                If `Expression` instance(s) are passed, they will be used as-is.
3550                Multiple expressions are combined with a comma.
3551            append: if `True`, add the new expressions to any existing SET expressions.
3552                Otherwise, this resets the expressions.
3553            dialect: the dialect used to parse the input expressions.
3554            copy: if `False`, modify this expression instance in-place.
3555            opts: other options to use to parse the input expressions.
3556        """
3557        return _apply_list_builder(
3558            *expressions,
3559            instance=self,
3560            arg="expressions",
3561            append=append,
3562            into=Expression,
3563            prefix=None,
3564            dialect=dialect,
3565            copy=copy,
3566            **opts,
3567        )
3568
3569    def where(
3570        self,
3571        *expressions: t.Optional[ExpOrStr],
3572        append: bool = True,
3573        dialect: DialectType = None,
3574        copy: bool = True,
3575        **opts,
3576    ) -> Select:
3577        """
3578        Append to or set the WHERE expressions.
3579
3580        Example:
3581            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3582            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3583
3584        Args:
3585            *expressions: the SQL code strings to parse.
3586                If an `Expression` instance is passed, it will be used as-is.
3587                Multiple expressions are combined with an AND operator.
3588            append: if `True`, AND the new expressions to any existing expression.
3589                Otherwise, this resets the expression.
3590            dialect: the dialect used to parse the input expressions.
3591            copy: if `False`, modify this expression instance in-place.
3592            opts: other options to use to parse the input expressions.
3593
3594        Returns:
3595            Select: the modified expression.
3596        """
3597        return _apply_conjunction_builder(
3598            *expressions,
3599            instance=self,
3600            arg="where",
3601            append=append,
3602            into=Where,
3603            dialect=dialect,
3604            copy=copy,
3605            **opts,
3606        )
3607
3608    def from_(
3609        self,
3610        expression: t.Optional[ExpOrStr] = None,
3611        dialect: DialectType = None,
3612        copy: bool = True,
3613        **opts,
3614    ) -> Update:
3615        """
3616        Set the FROM expression.
3617
3618        Example:
3619            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3620            'UPDATE my_table SET x = 1 FROM baz'
3621
3622        Args:
3623            expression : the SQL code strings to parse.
3624                If a `From` instance is passed, this is used as-is.
3625                If another `Expression` instance is passed, it will be wrapped in a `From`.
3626                If nothing is passed in then a from is not applied to the expression
3627            dialect: the dialect used to parse the input expression.
3628            copy: if `False`, modify this expression instance in-place.
3629            opts: other options to use to parse the input expressions.
3630
3631        Returns:
3632            The modified Update expression.
3633        """
3634        if not expression:
3635            return maybe_copy(self, copy)
3636
3637        return _apply_builder(
3638            expression=expression,
3639            instance=self,
3640            arg="from",
3641            into=From,
3642            prefix="FROM",
3643            dialect=dialect,
3644            copy=copy,
3645            **opts,
3646        )
3647
3648    def with_(
3649        self,
3650        alias: ExpOrStr,
3651        as_: ExpOrStr,
3652        recursive: t.Optional[bool] = None,
3653        materialized: t.Optional[bool] = None,
3654        append: bool = True,
3655        dialect: DialectType = None,
3656        copy: bool = True,
3657        **opts,
3658    ) -> Update:
3659        """
3660        Append to or set the common table expressions.
3661
3662        Example:
3663            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3664            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3665
3666        Args:
3667            alias: the SQL code string to parse as the table name.
3668                If an `Expression` instance is passed, this is used as-is.
3669            as_: the SQL code string to parse as the table expression.
3670                If an `Expression` instance is passed, it will be used as-is.
3671            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3672            materialized: set the MATERIALIZED part of the expression.
3673            append: if `True`, add to any existing expressions.
3674                Otherwise, this resets the expressions.
3675            dialect: the dialect used to parse the input expression.
3676            copy: if `False`, modify this expression instance in-place.
3677            opts: other options to use to parse the input expressions.
3678
3679        Returns:
3680            The modified expression.
3681        """
3682        return _apply_cte_builder(
3683            self,
3684            alias,
3685            as_,
3686            recursive=recursive,
3687            materialized=materialized,
3688            append=append,
3689            dialect=dialect,
3690            copy=copy,
3691            **opts,
3692        )
3693
3694
3695class Values(UDTF):
3696    arg_types = {"expressions": True, "alias": False}
3697
3698
3699class Var(Expression):
3700    pass
3701
3702
3703class Version(Expression):
3704    """
3705    Time travel, iceberg, bigquery etc
3706    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3707    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3708    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3709    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3710    this is either TIMESTAMP or VERSION
3711    kind is ("AS OF", "BETWEEN")
3712    """
3713
3714    arg_types = {"this": True, "kind": True, "expression": False}
3715
3716
3717class Schema(Expression):
3718    arg_types = {"this": False, "expressions": False}
3719
3720
3721# https://dev.mysql.com/doc/refman/8.0/en/select.html
3722# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
3723class Lock(Expression):
3724    arg_types = {"update": True, "expressions": False, "wait": False}
3725
3726
3727class Select(Query):
3728    arg_types = {
3729        "with": False,
3730        "kind": False,
3731        "expressions": False,
3732        "hint": False,
3733        "distinct": False,
3734        "into": False,
3735        "from": False,
3736        "operation_modifiers": False,
3737        **QUERY_MODIFIERS,
3738    }
3739
3740    def from_(
3741        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3742    ) -> Select:
3743        """
3744        Set the FROM expression.
3745
3746        Example:
3747            >>> Select().from_("tbl").select("x").sql()
3748            'SELECT x FROM tbl'
3749
3750        Args:
3751            expression : the SQL code strings to parse.
3752                If a `From` instance is passed, this is used as-is.
3753                If another `Expression` instance is passed, it will be wrapped in a `From`.
3754            dialect: the dialect used to parse the input expression.
3755            copy: if `False`, modify this expression instance in-place.
3756            opts: other options to use to parse the input expressions.
3757
3758        Returns:
3759            The modified Select expression.
3760        """
3761        return _apply_builder(
3762            expression=expression,
3763            instance=self,
3764            arg="from",
3765            into=From,
3766            prefix="FROM",
3767            dialect=dialect,
3768            copy=copy,
3769            **opts,
3770        )
3771
3772    def group_by(
3773        self,
3774        *expressions: t.Optional[ExpOrStr],
3775        append: bool = True,
3776        dialect: DialectType = None,
3777        copy: bool = True,
3778        **opts,
3779    ) -> Select:
3780        """
3781        Set the GROUP BY expression.
3782
3783        Example:
3784            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3785            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3786
3787        Args:
3788            *expressions: the SQL code strings to parse.
3789                If a `Group` instance is passed, this is used as-is.
3790                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3791                If nothing is passed in then a group by is not applied to the expression
3792            append: if `True`, add to any existing expressions.
3793                Otherwise, this flattens all the `Group` expression into a single expression.
3794            dialect: the dialect used to parse the input expression.
3795            copy: if `False`, modify this expression instance in-place.
3796            opts: other options to use to parse the input expressions.
3797
3798        Returns:
3799            The modified Select expression.
3800        """
3801        if not expressions:
3802            return self if not copy else self.copy()
3803
3804        return _apply_child_list_builder(
3805            *expressions,
3806            instance=self,
3807            arg="group",
3808            append=append,
3809            copy=copy,
3810            prefix="GROUP BY",
3811            into=Group,
3812            dialect=dialect,
3813            **opts,
3814        )
3815
3816    def sort_by(
3817        self,
3818        *expressions: t.Optional[ExpOrStr],
3819        append: bool = True,
3820        dialect: DialectType = None,
3821        copy: bool = True,
3822        **opts,
3823    ) -> Select:
3824        """
3825        Set the SORT BY expression.
3826
3827        Example:
3828            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3829            'SELECT x FROM tbl SORT BY x DESC'
3830
3831        Args:
3832            *expressions: the SQL code strings to parse.
3833                If a `Group` instance is passed, this is used as-is.
3834                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3835            append: if `True`, add to any existing expressions.
3836                Otherwise, this flattens all the `Order` expression into a single expression.
3837            dialect: the dialect used to parse the input expression.
3838            copy: if `False`, modify this expression instance in-place.
3839            opts: other options to use to parse the input expressions.
3840
3841        Returns:
3842            The modified Select expression.
3843        """
3844        return _apply_child_list_builder(
3845            *expressions,
3846            instance=self,
3847            arg="sort",
3848            append=append,
3849            copy=copy,
3850            prefix="SORT BY",
3851            into=Sort,
3852            dialect=dialect,
3853            **opts,
3854        )
3855
3856    def cluster_by(
3857        self,
3858        *expressions: t.Optional[ExpOrStr],
3859        append: bool = True,
3860        dialect: DialectType = None,
3861        copy: bool = True,
3862        **opts,
3863    ) -> Select:
3864        """
3865        Set the CLUSTER BY expression.
3866
3867        Example:
3868            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3869            'SELECT x FROM tbl CLUSTER BY x DESC'
3870
3871        Args:
3872            *expressions: the SQL code strings to parse.
3873                If a `Group` instance is passed, this is used as-is.
3874                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3875            append: if `True`, add to any existing expressions.
3876                Otherwise, this flattens all the `Order` expression into a single expression.
3877            dialect: the dialect used to parse the input expression.
3878            copy: if `False`, modify this expression instance in-place.
3879            opts: other options to use to parse the input expressions.
3880
3881        Returns:
3882            The modified Select expression.
3883        """
3884        return _apply_child_list_builder(
3885            *expressions,
3886            instance=self,
3887            arg="cluster",
3888            append=append,
3889            copy=copy,
3890            prefix="CLUSTER BY",
3891            into=Cluster,
3892            dialect=dialect,
3893            **opts,
3894        )
3895
3896    def select(
3897        self,
3898        *expressions: t.Optional[ExpOrStr],
3899        append: bool = True,
3900        dialect: DialectType = None,
3901        copy: bool = True,
3902        **opts,
3903    ) -> Select:
3904        return _apply_list_builder(
3905            *expressions,
3906            instance=self,
3907            arg="expressions",
3908            append=append,
3909            dialect=dialect,
3910            into=Expression,
3911            copy=copy,
3912            **opts,
3913        )
3914
3915    def lateral(
3916        self,
3917        *expressions: t.Optional[ExpOrStr],
3918        append: bool = True,
3919        dialect: DialectType = None,
3920        copy: bool = True,
3921        **opts,
3922    ) -> Select:
3923        """
3924        Append to or set the LATERAL expressions.
3925
3926        Example:
3927            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3928            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3929
3930        Args:
3931            *expressions: the SQL code strings to parse.
3932                If an `Expression` instance is passed, it will be used as-is.
3933            append: if `True`, add to any existing expressions.
3934                Otherwise, this resets the expressions.
3935            dialect: the dialect used to parse the input expressions.
3936            copy: if `False`, modify this expression instance in-place.
3937            opts: other options to use to parse the input expressions.
3938
3939        Returns:
3940            The modified Select expression.
3941        """
3942        return _apply_list_builder(
3943            *expressions,
3944            instance=self,
3945            arg="laterals",
3946            append=append,
3947            into=Lateral,
3948            prefix="LATERAL VIEW",
3949            dialect=dialect,
3950            copy=copy,
3951            **opts,
3952        )
3953
3954    def join(
3955        self,
3956        expression: ExpOrStr,
3957        on: t.Optional[ExpOrStr] = None,
3958        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3959        append: bool = True,
3960        join_type: t.Optional[str] = None,
3961        join_alias: t.Optional[Identifier | str] = None,
3962        dialect: DialectType = None,
3963        copy: bool = True,
3964        **opts,
3965    ) -> Select:
3966        """
3967        Append to or set the JOIN expressions.
3968
3969        Example:
3970            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3971            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3972
3973            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3974            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3975
3976            Use `join_type` to change the type of join:
3977
3978            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3979            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3980
3981        Args:
3982            expression: the SQL code string to parse.
3983                If an `Expression` instance is passed, it will be used as-is.
3984            on: optionally specify the join "on" criteria as a SQL string.
3985                If an `Expression` instance is passed, it will be used as-is.
3986            using: optionally specify the join "using" criteria as a SQL string.
3987                If an `Expression` instance is passed, it will be used as-is.
3988            append: if `True`, add to any existing expressions.
3989                Otherwise, this resets the expressions.
3990            join_type: if set, alter the parsed join type.
3991            join_alias: an optional alias for the joined source.
3992            dialect: the dialect used to parse the input expressions.
3993            copy: if `False`, modify this expression instance in-place.
3994            opts: other options to use to parse the input expressions.
3995
3996        Returns:
3997            Select: the modified expression.
3998        """
3999        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4000
4001        try:
4002            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4003        except ParseError:
4004            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4005
4006        join = expression if isinstance(expression, Join) else Join(this=expression)
4007
4008        if isinstance(join.this, Select):
4009            join.this.replace(join.this.subquery())
4010
4011        if join_type:
4012            method: t.Optional[Token]
4013            side: t.Optional[Token]
4014            kind: t.Optional[Token]
4015
4016            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4017
4018            if method:
4019                join.set("method", method.text)
4020            if side:
4021                join.set("side", side.text)
4022            if kind:
4023                join.set("kind", kind.text)
4024
4025        if on:
4026            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4027            join.set("on", on)
4028
4029        if using:
4030            join = _apply_list_builder(
4031                *ensure_list(using),
4032                instance=join,
4033                arg="using",
4034                append=append,
4035                copy=copy,
4036                into=Identifier,
4037                **opts,
4038            )
4039
4040        if join_alias:
4041            join.set("this", alias_(join.this, join_alias, table=True))
4042
4043        return _apply_list_builder(
4044            join,
4045            instance=self,
4046            arg="joins",
4047            append=append,
4048            copy=copy,
4049            **opts,
4050        )
4051
4052    def where(
4053        self,
4054        *expressions: t.Optional[ExpOrStr],
4055        append: bool = True,
4056        dialect: DialectType = None,
4057        copy: bool = True,
4058        **opts,
4059    ) -> Select:
4060        """
4061        Append to or set the WHERE expressions.
4062
4063        Example:
4064            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
4065            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
4066
4067        Args:
4068            *expressions: the SQL code strings to parse.
4069                If an `Expression` instance is passed, it will be used as-is.
4070                Multiple expressions are combined with an AND operator.
4071            append: if `True`, AND the new expressions to any existing expression.
4072                Otherwise, this resets the expression.
4073            dialect: the dialect used to parse the input expressions.
4074            copy: if `False`, modify this expression instance in-place.
4075            opts: other options to use to parse the input expressions.
4076
4077        Returns:
4078            Select: the modified expression.
4079        """
4080        return _apply_conjunction_builder(
4081            *expressions,
4082            instance=self,
4083            arg="where",
4084            append=append,
4085            into=Where,
4086            dialect=dialect,
4087            copy=copy,
4088            **opts,
4089        )
4090
4091    def having(
4092        self,
4093        *expressions: t.Optional[ExpOrStr],
4094        append: bool = True,
4095        dialect: DialectType = None,
4096        copy: bool = True,
4097        **opts,
4098    ) -> Select:
4099        """
4100        Append to or set the HAVING expressions.
4101
4102        Example:
4103            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4104            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4105
4106        Args:
4107            *expressions: the SQL code strings to parse.
4108                If an `Expression` instance is passed, it will be used as-is.
4109                Multiple expressions are combined with an AND operator.
4110            append: if `True`, AND the new expressions to any existing expression.
4111                Otherwise, this resets the expression.
4112            dialect: the dialect used to parse the input expressions.
4113            copy: if `False`, modify this expression instance in-place.
4114            opts: other options to use to parse the input expressions.
4115
4116        Returns:
4117            The modified Select expression.
4118        """
4119        return _apply_conjunction_builder(
4120            *expressions,
4121            instance=self,
4122            arg="having",
4123            append=append,
4124            into=Having,
4125            dialect=dialect,
4126            copy=copy,
4127            **opts,
4128        )
4129
4130    def window(
4131        self,
4132        *expressions: t.Optional[ExpOrStr],
4133        append: bool = True,
4134        dialect: DialectType = None,
4135        copy: bool = True,
4136        **opts,
4137    ) -> Select:
4138        return _apply_list_builder(
4139            *expressions,
4140            instance=self,
4141            arg="windows",
4142            append=append,
4143            into=Window,
4144            dialect=dialect,
4145            copy=copy,
4146            **opts,
4147        )
4148
4149    def qualify(
4150        self,
4151        *expressions: t.Optional[ExpOrStr],
4152        append: bool = True,
4153        dialect: DialectType = None,
4154        copy: bool = True,
4155        **opts,
4156    ) -> Select:
4157        return _apply_conjunction_builder(
4158            *expressions,
4159            instance=self,
4160            arg="qualify",
4161            append=append,
4162            into=Qualify,
4163            dialect=dialect,
4164            copy=copy,
4165            **opts,
4166        )
4167
4168    def distinct(
4169        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4170    ) -> Select:
4171        """
4172        Set the OFFSET expression.
4173
4174        Example:
4175            >>> Select().from_("tbl").select("x").distinct().sql()
4176            'SELECT DISTINCT x FROM tbl'
4177
4178        Args:
4179            ons: the expressions to distinct on
4180            distinct: whether the Select should be distinct
4181            copy: if `False`, modify this expression instance in-place.
4182
4183        Returns:
4184            Select: the modified expression.
4185        """
4186        instance = maybe_copy(self, copy)
4187        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4188        instance.set("distinct", Distinct(on=on) if distinct else None)
4189        return instance
4190
4191    def ctas(
4192        self,
4193        table: ExpOrStr,
4194        properties: t.Optional[t.Dict] = None,
4195        dialect: DialectType = None,
4196        copy: bool = True,
4197        **opts,
4198    ) -> Create:
4199        """
4200        Convert this expression to a CREATE TABLE AS statement.
4201
4202        Example:
4203            >>> Select().select("*").from_("tbl").ctas("x").sql()
4204            'CREATE TABLE x AS SELECT * FROM tbl'
4205
4206        Args:
4207            table: the SQL code string to parse as the table name.
4208                If another `Expression` instance is passed, it will be used as-is.
4209            properties: an optional mapping of table properties
4210            dialect: the dialect used to parse the input table.
4211            copy: if `False`, modify this expression instance in-place.
4212            opts: other options to use to parse the input table.
4213
4214        Returns:
4215            The new Create expression.
4216        """
4217        instance = maybe_copy(self, copy)
4218        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4219
4220        properties_expression = None
4221        if properties:
4222            properties_expression = Properties.from_dict(properties)
4223
4224        return Create(
4225            this=table_expression,
4226            kind="TABLE",
4227            expression=instance,
4228            properties=properties_expression,
4229        )
4230
4231    def lock(self, update: bool = True, copy: bool = True) -> Select:
4232        """
4233        Set the locking read mode for this expression.
4234
4235        Examples:
4236            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4237            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4238
4239            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4240            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4241
4242        Args:
4243            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4244            copy: if `False`, modify this expression instance in-place.
4245
4246        Returns:
4247            The modified expression.
4248        """
4249        inst = maybe_copy(self, copy)
4250        inst.set("locks", [Lock(update=update)])
4251
4252        return inst
4253
4254    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4255        """
4256        Set hints for this expression.
4257
4258        Examples:
4259            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4260            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4261
4262        Args:
4263            hints: The SQL code strings to parse as the hints.
4264                If an `Expression` instance is passed, it will be used as-is.
4265            dialect: The dialect used to parse the hints.
4266            copy: If `False`, modify this expression instance in-place.
4267
4268        Returns:
4269            The modified expression.
4270        """
4271        inst = maybe_copy(self, copy)
4272        inst.set(
4273            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4274        )
4275
4276        return inst
4277
4278    @property
4279    def named_selects(self) -> t.List[str]:
4280        return [e.output_name for e in self.expressions if e.alias_or_name]
4281
4282    @property
4283    def is_star(self) -> bool:
4284        return any(expression.is_star for expression in self.expressions)
4285
4286    @property
4287    def selects(self) -> t.List[Expression]:
4288        return self.expressions
4289
4290
4291UNWRAPPED_QUERIES = (Select, SetOperation)
4292
4293
4294class Subquery(DerivedTable, Query):
4295    arg_types = {
4296        "this": True,
4297        "alias": False,
4298        "with": False,
4299        **QUERY_MODIFIERS,
4300    }
4301
4302    def unnest(self):
4303        """Returns the first non subquery."""
4304        expression = self
4305        while isinstance(expression, Subquery):
4306            expression = expression.this
4307        return expression
4308
4309    def unwrap(self) -> Subquery:
4310        expression = self
4311        while expression.same_parent and expression.is_wrapper:
4312            expression = t.cast(Subquery, expression.parent)
4313        return expression
4314
4315    def select(
4316        self,
4317        *expressions: t.Optional[ExpOrStr],
4318        append: bool = True,
4319        dialect: DialectType = None,
4320        copy: bool = True,
4321        **opts,
4322    ) -> Subquery:
4323        this = maybe_copy(self, copy)
4324        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4325        return this
4326
4327    @property
4328    def is_wrapper(self) -> bool:
4329        """
4330        Whether this Subquery acts as a simple wrapper around another expression.
4331
4332        SELECT * FROM (((SELECT * FROM t)))
4333                      ^
4334                      This corresponds to a "wrapper" Subquery node
4335        """
4336        return all(v is None for k, v in self.args.items() if k != "this")
4337
4338    @property
4339    def is_star(self) -> bool:
4340        return self.this.is_star
4341
4342    @property
4343    def output_name(self) -> str:
4344        return self.alias
4345
4346
4347class TableSample(Expression):
4348    arg_types = {
4349        "expressions": False,
4350        "method": False,
4351        "bucket_numerator": False,
4352        "bucket_denominator": False,
4353        "bucket_field": False,
4354        "percent": False,
4355        "rows": False,
4356        "size": False,
4357        "seed": False,
4358    }
4359
4360
4361class Tag(Expression):
4362    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4363
4364    arg_types = {
4365        "this": False,
4366        "prefix": False,
4367        "postfix": False,
4368    }
4369
4370
4371# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
4372# https://duckdb.org/docs/sql/statements/pivot
4373class Pivot(Expression):
4374    arg_types = {
4375        "this": False,
4376        "alias": False,
4377        "expressions": False,
4378        "fields": False,
4379        "unpivot": False,
4380        "using": False,
4381        "group": False,
4382        "columns": False,
4383        "include_nulls": False,
4384        "default_on_null": False,
4385        "into": False,
4386    }
4387
4388    @property
4389    def unpivot(self) -> bool:
4390        return bool(self.args.get("unpivot"))
4391
4392    @property
4393    def fields(self) -> t.List[Expression]:
4394        return self.args.get("fields", [])
4395
4396
4397# https://duckdb.org/docs/sql/statements/unpivot#simplified-unpivot-syntax
4398# UNPIVOT ... INTO [NAME <col_name> VALUE <col_value>][...,]
4399class UnpivotColumns(Expression):
4400    arg_types = {"this": True, "expressions": True}
4401
4402
4403class Window(Condition):
4404    arg_types = {
4405        "this": True,
4406        "partition_by": False,
4407        "order": False,
4408        "spec": False,
4409        "alias": False,
4410        "over": False,
4411        "first": False,
4412    }
4413
4414
4415class WindowSpec(Expression):
4416    arg_types = {
4417        "kind": False,
4418        "start": False,
4419        "start_side": False,
4420        "end": False,
4421        "end_side": False,
4422    }
4423
4424
4425class PreWhere(Expression):
4426    pass
4427
4428
4429class Where(Expression):
4430    pass
4431
4432
4433class Star(Expression):
4434    arg_types = {"except": False, "replace": False, "rename": False}
4435
4436    @property
4437    def name(self) -> str:
4438        return "*"
4439
4440    @property
4441    def output_name(self) -> str:
4442        return self.name
4443
4444
4445class Parameter(Condition):
4446    arg_types = {"this": True, "expression": False}
4447
4448
4449class SessionParameter(Condition):
4450    arg_types = {"this": True, "kind": False}
4451
4452
4453class Placeholder(Condition):
4454    arg_types = {"this": False, "kind": False}
4455
4456    @property
4457    def name(self) -> str:
4458        return self.this or "?"
4459
4460
4461class Null(Condition):
4462    arg_types: t.Dict[str, t.Any] = {}
4463
4464    @property
4465    def name(self) -> str:
4466        return "NULL"
4467
4468    def to_py(self) -> Lit[None]:
4469        return None
4470
4471
4472class Boolean(Condition):
4473    def to_py(self) -> bool:
4474        return self.this
4475
4476
4477class DataTypeParam(Expression):
4478    arg_types = {"this": True, "expression": False}
4479
4480    @property
4481    def name(self) -> str:
4482        return self.this.name
4483
4484
4485# The `nullable` arg is helpful when transpiling types from other dialects to ClickHouse, which
4486# assumes non-nullable types by default. Values `None` and `True` mean the type is nullable.
4487class DataType(Expression):
4488    arg_types = {
4489        "this": True,
4490        "expressions": False,
4491        "nested": False,
4492        "values": False,
4493        "prefix": False,
4494        "kind": False,
4495        "nullable": False,
4496    }
4497
4498    class Type(AutoName):
4499        ARRAY = auto()
4500        AGGREGATEFUNCTION = auto()
4501        SIMPLEAGGREGATEFUNCTION = auto()
4502        BIGDECIMAL = auto()
4503        BIGINT = auto()
4504        BIGSERIAL = auto()
4505        BINARY = auto()
4506        BIT = auto()
4507        BLOB = auto()
4508        BOOLEAN = auto()
4509        BPCHAR = auto()
4510        CHAR = auto()
4511        DATE = auto()
4512        DATE32 = auto()
4513        DATEMULTIRANGE = auto()
4514        DATERANGE = auto()
4515        DATETIME = auto()
4516        DATETIME2 = auto()
4517        DATETIME64 = auto()
4518        DECIMAL = auto()
4519        DECIMAL32 = auto()
4520        DECIMAL64 = auto()
4521        DECIMAL128 = auto()
4522        DECIMAL256 = auto()
4523        DOUBLE = auto()
4524        DYNAMIC = auto()
4525        ENUM = auto()
4526        ENUM8 = auto()
4527        ENUM16 = auto()
4528        FIXEDSTRING = auto()
4529        FLOAT = auto()
4530        GEOGRAPHY = auto()
4531        GEOMETRY = auto()
4532        POINT = auto()
4533        RING = auto()
4534        LINESTRING = auto()
4535        MULTILINESTRING = auto()
4536        POLYGON = auto()
4537        MULTIPOLYGON = auto()
4538        HLLSKETCH = auto()
4539        HSTORE = auto()
4540        IMAGE = auto()
4541        INET = auto()
4542        INT = auto()
4543        INT128 = auto()
4544        INT256 = auto()
4545        INT4MULTIRANGE = auto()
4546        INT4RANGE = auto()
4547        INT8MULTIRANGE = auto()
4548        INT8RANGE = auto()
4549        INTERVAL = auto()
4550        IPADDRESS = auto()
4551        IPPREFIX = auto()
4552        IPV4 = auto()
4553        IPV6 = auto()
4554        JSON = auto()
4555        JSONB = auto()
4556        LIST = auto()
4557        LONGBLOB = auto()
4558        LONGTEXT = auto()
4559        LOWCARDINALITY = auto()
4560        MAP = auto()
4561        MEDIUMBLOB = auto()
4562        MEDIUMINT = auto()
4563        MEDIUMTEXT = auto()
4564        MONEY = auto()
4565        NAME = auto()
4566        NCHAR = auto()
4567        NESTED = auto()
4568        NOTHING = auto()
4569        NULL = auto()
4570        NUMMULTIRANGE = auto()
4571        NUMRANGE = auto()
4572        NVARCHAR = auto()
4573        OBJECT = auto()
4574        RANGE = auto()
4575        ROWVERSION = auto()
4576        SERIAL = auto()
4577        SET = auto()
4578        SMALLDATETIME = auto()
4579        SMALLINT = auto()
4580        SMALLMONEY = auto()
4581        SMALLSERIAL = auto()
4582        STRUCT = auto()
4583        SUPER = auto()
4584        TEXT = auto()
4585        TINYBLOB = auto()
4586        TINYTEXT = auto()
4587        TIME = auto()
4588        TIMETZ = auto()
4589        TIMESTAMP = auto()
4590        TIMESTAMPNTZ = auto()
4591        TIMESTAMPLTZ = auto()
4592        TIMESTAMPTZ = auto()
4593        TIMESTAMP_S = auto()
4594        TIMESTAMP_MS = auto()
4595        TIMESTAMP_NS = auto()
4596        TINYINT = auto()
4597        TSMULTIRANGE = auto()
4598        TSRANGE = auto()
4599        TSTZMULTIRANGE = auto()
4600        TSTZRANGE = auto()
4601        UBIGINT = auto()
4602        UINT = auto()
4603        UINT128 = auto()
4604        UINT256 = auto()
4605        UMEDIUMINT = auto()
4606        UDECIMAL = auto()
4607        UDOUBLE = auto()
4608        UNION = auto()
4609        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4610        USERDEFINED = "USER-DEFINED"
4611        USMALLINT = auto()
4612        UTINYINT = auto()
4613        UUID = auto()
4614        VARBINARY = auto()
4615        VARCHAR = auto()
4616        VARIANT = auto()
4617        VECTOR = auto()
4618        XML = auto()
4619        YEAR = auto()
4620        TDIGEST = auto()
4621
4622    STRUCT_TYPES = {
4623        Type.NESTED,
4624        Type.OBJECT,
4625        Type.STRUCT,
4626        Type.UNION,
4627    }
4628
4629    ARRAY_TYPES = {
4630        Type.ARRAY,
4631        Type.LIST,
4632    }
4633
4634    NESTED_TYPES = {
4635        *STRUCT_TYPES,
4636        *ARRAY_TYPES,
4637        Type.MAP,
4638    }
4639
4640    TEXT_TYPES = {
4641        Type.CHAR,
4642        Type.NCHAR,
4643        Type.NVARCHAR,
4644        Type.TEXT,
4645        Type.VARCHAR,
4646        Type.NAME,
4647    }
4648
4649    SIGNED_INTEGER_TYPES = {
4650        Type.BIGINT,
4651        Type.INT,
4652        Type.INT128,
4653        Type.INT256,
4654        Type.MEDIUMINT,
4655        Type.SMALLINT,
4656        Type.TINYINT,
4657    }
4658
4659    UNSIGNED_INTEGER_TYPES = {
4660        Type.UBIGINT,
4661        Type.UINT,
4662        Type.UINT128,
4663        Type.UINT256,
4664        Type.UMEDIUMINT,
4665        Type.USMALLINT,
4666        Type.UTINYINT,
4667    }
4668
4669    INTEGER_TYPES = {
4670        *SIGNED_INTEGER_TYPES,
4671        *UNSIGNED_INTEGER_TYPES,
4672        Type.BIT,
4673    }
4674
4675    FLOAT_TYPES = {
4676        Type.DOUBLE,
4677        Type.FLOAT,
4678    }
4679
4680    REAL_TYPES = {
4681        *FLOAT_TYPES,
4682        Type.BIGDECIMAL,
4683        Type.DECIMAL,
4684        Type.DECIMAL32,
4685        Type.DECIMAL64,
4686        Type.DECIMAL128,
4687        Type.DECIMAL256,
4688        Type.MONEY,
4689        Type.SMALLMONEY,
4690        Type.UDECIMAL,
4691        Type.UDOUBLE,
4692    }
4693
4694    NUMERIC_TYPES = {
4695        *INTEGER_TYPES,
4696        *REAL_TYPES,
4697    }
4698
4699    TEMPORAL_TYPES = {
4700        Type.DATE,
4701        Type.DATE32,
4702        Type.DATETIME,
4703        Type.DATETIME2,
4704        Type.DATETIME64,
4705        Type.SMALLDATETIME,
4706        Type.TIME,
4707        Type.TIMESTAMP,
4708        Type.TIMESTAMPNTZ,
4709        Type.TIMESTAMPLTZ,
4710        Type.TIMESTAMPTZ,
4711        Type.TIMESTAMP_MS,
4712        Type.TIMESTAMP_NS,
4713        Type.TIMESTAMP_S,
4714        Type.TIMETZ,
4715    }
4716
4717    @classmethod
4718    def build(
4719        cls,
4720        dtype: DATA_TYPE,
4721        dialect: DialectType = None,
4722        udt: bool = False,
4723        copy: bool = True,
4724        **kwargs,
4725    ) -> DataType:
4726        """
4727        Constructs a DataType object.
4728
4729        Args:
4730            dtype: the data type of interest.
4731            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4732            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4733                DataType, thus creating a user-defined type.
4734            copy: whether to copy the data type.
4735            kwargs: additional arguments to pass in the constructor of DataType.
4736
4737        Returns:
4738            The constructed DataType object.
4739        """
4740        from sqlglot import parse_one
4741
4742        if isinstance(dtype, str):
4743            if dtype.upper() == "UNKNOWN":
4744                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4745
4746            try:
4747                data_type_exp = parse_one(
4748                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4749                )
4750            except ParseError:
4751                if udt:
4752                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4753                raise
4754        elif isinstance(dtype, DataType.Type):
4755            data_type_exp = DataType(this=dtype)
4756        elif isinstance(dtype, DataType):
4757            return maybe_copy(dtype, copy)
4758        else:
4759            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4760
4761        return DataType(**{**data_type_exp.args, **kwargs})
4762
4763    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4764        """
4765        Checks whether this DataType matches one of the provided data types. Nested types or precision
4766        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4767
4768        Args:
4769            dtypes: the data types to compare this DataType to.
4770            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4771                If false, it means that NULLABLE<INT> is equivalent to INT.
4772
4773        Returns:
4774            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4775        """
4776        self_is_nullable = self.args.get("nullable")
4777        for dtype in dtypes:
4778            other_type = DataType.build(dtype, copy=False, udt=True)
4779            other_is_nullable = other_type.args.get("nullable")
4780            if (
4781                other_type.expressions
4782                or (check_nullable and (self_is_nullable or other_is_nullable))
4783                or self.this == DataType.Type.USERDEFINED
4784                or other_type.this == DataType.Type.USERDEFINED
4785            ):
4786                matches = self == other_type
4787            else:
4788                matches = self.this == other_type.this
4789
4790            if matches:
4791                return True
4792        return False
4793
4794
4795DATA_TYPE = t.Union[str, DataType, DataType.Type]
4796
4797
4798# https://www.postgresql.org/docs/15/datatype-pseudo.html
4799class PseudoType(DataType):
4800    arg_types = {"this": True}
4801
4802
4803# https://www.postgresql.org/docs/15/datatype-oid.html
4804class ObjectIdentifier(DataType):
4805    arg_types = {"this": True}
4806
4807
4808# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4809class SubqueryPredicate(Predicate):
4810    pass
4811
4812
4813class All(SubqueryPredicate):
4814    pass
4815
4816
4817class Any(SubqueryPredicate):
4818    pass
4819
4820
4821# Commands to interact with the databases or engines. For most of the command
4822# expressions we parse whatever comes after the command's name as a string.
4823class Command(Expression):
4824    arg_types = {"this": True, "expression": False}
4825
4826
4827class Transaction(Expression):
4828    arg_types = {"this": False, "modes": False, "mark": False}
4829
4830
4831class Commit(Expression):
4832    arg_types = {"chain": False, "this": False, "durability": False}
4833
4834
4835class Rollback(Expression):
4836    arg_types = {"savepoint": False, "this": False}
4837
4838
4839class Alter(Expression):
4840    arg_types = {
4841        "this": True,
4842        "kind": True,
4843        "actions": True,
4844        "exists": False,
4845        "only": False,
4846        "options": False,
4847        "cluster": False,
4848        "not_valid": False,
4849    }
4850
4851    @property
4852    def kind(self) -> t.Optional[str]:
4853        kind = self.args.get("kind")
4854        return kind and kind.upper()
4855
4856    @property
4857    def actions(self) -> t.List[Expression]:
4858        return self.args.get("actions") or []
4859
4860
4861class Analyze(Expression):
4862    arg_types = {
4863        "kind": False,
4864        "this": False,
4865        "options": False,
4866        "mode": False,
4867        "partition": False,
4868        "expression": False,
4869        "properties": False,
4870    }
4871
4872
4873class AnalyzeStatistics(Expression):
4874    arg_types = {
4875        "kind": True,
4876        "option": False,
4877        "this": False,
4878        "expressions": False,
4879    }
4880
4881
4882class AnalyzeHistogram(Expression):
4883    arg_types = {
4884        "this": True,
4885        "expressions": True,
4886        "expression": False,
4887        "update_options": False,
4888    }
4889
4890
4891class AnalyzeSample(Expression):
4892    arg_types = {"kind": True, "sample": True}
4893
4894
4895class AnalyzeListChainedRows(Expression):
4896    arg_types = {"expression": False}
4897
4898
4899class AnalyzeDelete(Expression):
4900    arg_types = {"kind": False}
4901
4902
4903class AnalyzeWith(Expression):
4904    arg_types = {"expressions": True}
4905
4906
4907class AnalyzeValidate(Expression):
4908    arg_types = {
4909        "kind": True,
4910        "this": False,
4911        "expression": False,
4912    }
4913
4914
4915class AnalyzeColumns(Expression):
4916    pass
4917
4918
4919class UsingData(Expression):
4920    pass
4921
4922
4923class AddConstraint(Expression):
4924    arg_types = {"expressions": True}
4925
4926
4927class AttachOption(Expression):
4928    arg_types = {"this": True, "expression": False}
4929
4930
4931class DropPartition(Expression):
4932    arg_types = {"expressions": True, "exists": False}
4933
4934
4935# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#replace-partition
4936class ReplacePartition(Expression):
4937    arg_types = {"expression": True, "source": True}
4938
4939
4940# Binary expressions like (ADD a b)
4941class Binary(Condition):
4942    arg_types = {"this": True, "expression": True}
4943
4944    @property
4945    def left(self) -> Expression:
4946        return self.this
4947
4948    @property
4949    def right(self) -> Expression:
4950        return self.expression
4951
4952
4953class Add(Binary):
4954    pass
4955
4956
4957class Connector(Binary):
4958    pass
4959
4960
4961class BitwiseAnd(Binary):
4962    pass
4963
4964
4965class BitwiseLeftShift(Binary):
4966    pass
4967
4968
4969class BitwiseOr(Binary):
4970    pass
4971
4972
4973class BitwiseRightShift(Binary):
4974    pass
4975
4976
4977class BitwiseXor(Binary):
4978    pass
4979
4980
4981class Div(Binary):
4982    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4983
4984
4985class Overlaps(Binary):
4986    pass
4987
4988
4989class Dot(Binary):
4990    @property
4991    def is_star(self) -> bool:
4992        return self.expression.is_star
4993
4994    @property
4995    def name(self) -> str:
4996        return self.expression.name
4997
4998    @property
4999    def output_name(self) -> str:
5000        return self.name
5001
5002    @classmethod
5003    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5004        """Build a Dot object with a sequence of expressions."""
5005        if len(expressions) < 2:
5006            raise ValueError("Dot requires >= 2 expressions.")
5007
5008        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5009
5010    @property
5011    def parts(self) -> t.List[Expression]:
5012        """Return the parts of a table / column in order catalog, db, table."""
5013        this, *parts = self.flatten()
5014
5015        parts.reverse()
5016
5017        for arg in COLUMN_PARTS:
5018            part = this.args.get(arg)
5019
5020            if isinstance(part, Expression):
5021                parts.append(part)
5022
5023        parts.reverse()
5024        return parts
5025
5026
5027class DPipe(Binary):
5028    arg_types = {"this": True, "expression": True, "safe": False}
5029
5030
5031class EQ(Binary, Predicate):
5032    pass
5033
5034
5035class NullSafeEQ(Binary, Predicate):
5036    pass
5037
5038
5039class NullSafeNEQ(Binary, Predicate):
5040    pass
5041
5042
5043# Represents e.g. := in DuckDB which is mostly used for setting parameters
5044class PropertyEQ(Binary):
5045    pass
5046
5047
5048class Distance(Binary):
5049    pass
5050
5051
5052class Escape(Binary):
5053    pass
5054
5055
5056class Glob(Binary, Predicate):
5057    pass
5058
5059
5060class GT(Binary, Predicate):
5061    pass
5062
5063
5064class GTE(Binary, Predicate):
5065    pass
5066
5067
5068class ILike(Binary, Predicate):
5069    pass
5070
5071
5072class ILikeAny(Binary, Predicate):
5073    pass
5074
5075
5076class IntDiv(Binary):
5077    pass
5078
5079
5080class Is(Binary, Predicate):
5081    pass
5082
5083
5084class Kwarg(Binary):
5085    """Kwarg in special functions like func(kwarg => y)."""
5086
5087
5088class Like(Binary, Predicate):
5089    pass
5090
5091
5092class LikeAny(Binary, Predicate):
5093    pass
5094
5095
5096class LT(Binary, Predicate):
5097    pass
5098
5099
5100class LTE(Binary, Predicate):
5101    pass
5102
5103
5104class Mod(Binary):
5105    pass
5106
5107
5108class Mul(Binary):
5109    pass
5110
5111
5112class NEQ(Binary, Predicate):
5113    pass
5114
5115
5116# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
5117class Operator(Binary):
5118    arg_types = {"this": True, "operator": True, "expression": True}
5119
5120
5121class SimilarTo(Binary, Predicate):
5122    pass
5123
5124
5125class Slice(Binary):
5126    arg_types = {"this": False, "expression": False}
5127
5128
5129class Sub(Binary):
5130    pass
5131
5132
5133# Unary Expressions
5134# (NOT a)
5135class Unary(Condition):
5136    pass
5137
5138
5139class BitwiseNot(Unary):
5140    pass
5141
5142
5143class Not(Unary):
5144    pass
5145
5146
5147class Paren(Unary):
5148    @property
5149    def output_name(self) -> str:
5150        return self.this.name
5151
5152
5153class Neg(Unary):
5154    def to_py(self) -> int | Decimal:
5155        if self.is_number:
5156            return self.this.to_py() * -1
5157        return super().to_py()
5158
5159
5160class Alias(Expression):
5161    arg_types = {"this": True, "alias": False}
5162
5163    @property
5164    def output_name(self) -> str:
5165        return self.alias
5166
5167
5168# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
5169# other dialects require identifiers. This enables us to transpile between them easily.
5170class PivotAlias(Alias):
5171    pass
5172
5173
5174# Represents Snowflake's ANY [ ORDER BY ... ] syntax
5175# https://docs.snowflake.com/en/sql-reference/constructs/pivot
5176class PivotAny(Expression):
5177    arg_types = {"this": False}
5178
5179
5180class Aliases(Expression):
5181    arg_types = {"this": True, "expressions": True}
5182
5183    @property
5184    def aliases(self):
5185        return self.expressions
5186
5187
5188# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
5189class AtIndex(Expression):
5190    arg_types = {"this": True, "expression": True}
5191
5192
5193class AtTimeZone(Expression):
5194    arg_types = {"this": True, "zone": True}
5195
5196
5197class FromTimeZone(Expression):
5198    arg_types = {"this": True, "zone": True}
5199
5200
5201class Between(Predicate):
5202    arg_types = {"this": True, "low": True, "high": True}
5203
5204
5205class Bracket(Condition):
5206    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5207    arg_types = {
5208        "this": True,
5209        "expressions": True,
5210        "offset": False,
5211        "safe": False,
5212        "returns_list_for_maps": False,
5213    }
5214
5215    @property
5216    def output_name(self) -> str:
5217        if len(self.expressions) == 1:
5218            return self.expressions[0].output_name
5219
5220        return super().output_name
5221
5222
5223class Distinct(Expression):
5224    arg_types = {"expressions": False, "on": False}
5225
5226
5227class In(Predicate):
5228    arg_types = {
5229        "this": True,
5230        "expressions": False,
5231        "query": False,
5232        "unnest": False,
5233        "field": False,
5234        "is_global": False,
5235    }
5236
5237
5238# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
5239class ForIn(Expression):
5240    arg_types = {"this": True, "expression": True}
5241
5242
5243class TimeUnit(Expression):
5244    """Automatically converts unit arg into a var."""
5245
5246    arg_types = {"unit": False}
5247
5248    UNABBREVIATED_UNIT_NAME = {
5249        "D": "DAY",
5250        "H": "HOUR",
5251        "M": "MINUTE",
5252        "MS": "MILLISECOND",
5253        "NS": "NANOSECOND",
5254        "Q": "QUARTER",
5255        "S": "SECOND",
5256        "US": "MICROSECOND",
5257        "W": "WEEK",
5258        "Y": "YEAR",
5259    }
5260
5261    VAR_LIKE = (Column, Literal, Var)
5262
5263    def __init__(self, **args):
5264        unit = args.get("unit")
5265        if isinstance(unit, self.VAR_LIKE):
5266            args["unit"] = Var(
5267                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5268            )
5269        elif isinstance(unit, Week):
5270            unit.set("this", Var(this=unit.this.name.upper()))
5271
5272        super().__init__(**args)
5273
5274    @property
5275    def unit(self) -> t.Optional[Var | IntervalSpan]:
5276        return self.args.get("unit")
5277
5278
5279class IntervalOp(TimeUnit):
5280    arg_types = {"unit": False, "expression": True}
5281
5282    def interval(self):
5283        return Interval(
5284            this=self.expression.copy(),
5285            unit=self.unit.copy() if self.unit else None,
5286        )
5287
5288
5289# https://www.oracletutorial.com/oracle-basics/oracle-interval/
5290# https://trino.io/docs/current/language/types.html#interval-day-to-second
5291# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
5292class IntervalSpan(DataType):
5293    arg_types = {"this": True, "expression": True}
5294
5295
5296class Interval(TimeUnit):
5297    arg_types = {"this": False, "unit": False}
5298
5299
5300class IgnoreNulls(Expression):
5301    pass
5302
5303
5304class RespectNulls(Expression):
5305    pass
5306
5307
5308# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
5309class HavingMax(Expression):
5310    arg_types = {"this": True, "expression": True, "max": True}
5311
5312
5313# Functions
5314class Func(Condition):
5315    """
5316    The base class for all function expressions.
5317
5318    Attributes:
5319        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5320            treated as a variable length argument and the argument's value will be stored as a list.
5321        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5322            function expression. These values are used to map this node to a name during parsing as
5323            well as to provide the function's name during SQL string generation. By default the SQL
5324            name is set to the expression's class name transformed to snake case.
5325    """
5326
5327    is_var_len_args = False
5328
5329    @classmethod
5330    def from_arg_list(cls, args):
5331        if cls.is_var_len_args:
5332            all_arg_keys = list(cls.arg_types)
5333            # If this function supports variable length argument treat the last argument as such.
5334            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5335            num_non_var = len(non_var_len_arg_keys)
5336
5337            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5338            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5339        else:
5340            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5341
5342        return cls(**args_dict)
5343
5344    @classmethod
5345    def sql_names(cls):
5346        if cls is Func:
5347            raise NotImplementedError(
5348                "SQL name is only supported by concrete function implementations"
5349            )
5350        if "_sql_names" not in cls.__dict__:
5351            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5352        return cls._sql_names
5353
5354    @classmethod
5355    def sql_name(cls):
5356        return cls.sql_names()[0]
5357
5358    @classmethod
5359    def default_parser_mappings(cls):
5360        return {name: cls.from_arg_list for name in cls.sql_names()}
5361
5362
5363class AggFunc(Func):
5364    pass
5365
5366
5367class ParameterizedAgg(AggFunc):
5368    arg_types = {"this": True, "expressions": True, "params": True}
5369
5370
5371class Abs(Func):
5372    pass
5373
5374
5375class ArgMax(AggFunc):
5376    arg_types = {"this": True, "expression": True, "count": False}
5377    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
5378
5379
5380class ArgMin(AggFunc):
5381    arg_types = {"this": True, "expression": True, "count": False}
5382    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
5383
5384
5385class ApproxTopK(AggFunc):
5386    arg_types = {"this": True, "expression": False, "counters": False}
5387
5388
5389class Flatten(Func):
5390    pass
5391
5392
5393# https://spark.apache.org/docs/latest/api/sql/index.html#transform
5394class Transform(Func):
5395    arg_types = {"this": True, "expression": True}
5396
5397
5398class Anonymous(Func):
5399    arg_types = {"this": True, "expressions": False}
5400    is_var_len_args = True
5401
5402    @property
5403    def name(self) -> str:
5404        return self.this if isinstance(self.this, str) else self.this.name
5405
5406
5407class AnonymousAggFunc(AggFunc):
5408    arg_types = {"this": True, "expressions": False}
5409    is_var_len_args = True
5410
5411
5412# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
5413class CombinedAggFunc(AnonymousAggFunc):
5414    arg_types = {"this": True, "expressions": False}
5415
5416
5417class CombinedParameterizedAgg(ParameterizedAgg):
5418    arg_types = {"this": True, "expressions": True, "params": True}
5419
5420
5421# https://docs.snowflake.com/en/sql-reference/functions/hll
5422# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
5423class Hll(AggFunc):
5424    arg_types = {"this": True, "expressions": False}
5425    is_var_len_args = True
5426
5427
5428class ApproxDistinct(AggFunc):
5429    arg_types = {"this": True, "accuracy": False}
5430    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
5431
5432
5433class Apply(Func):
5434    arg_types = {"this": True, "expression": True}
5435
5436
5437class Array(Func):
5438    arg_types = {"expressions": False, "bracket_notation": False}
5439    is_var_len_args = True
5440
5441
5442# https://docs.snowflake.com/en/sql-reference/functions/to_array
5443class ToArray(Func):
5444    pass
5445
5446
5447# https://materialize.com/docs/sql/types/list/
5448class List(Func):
5449    arg_types = {"expressions": False}
5450    is_var_len_args = True
5451
5452
5453# String pad, kind True -> LPAD, False -> RPAD
5454class Pad(Func):
5455    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
5456
5457
5458# https://docs.snowflake.com/en/sql-reference/functions/to_char
5459# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
5460class ToChar(Func):
5461    arg_types = {"this": True, "format": False, "nlsparam": False}
5462
5463
5464# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
5465# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
5466class ToNumber(Func):
5467    arg_types = {
5468        "this": True,
5469        "format": False,
5470        "nlsparam": False,
5471        "precision": False,
5472        "scale": False,
5473    }
5474
5475
5476# https://docs.snowflake.com/en/sql-reference/functions/to_double
5477class ToDouble(Func):
5478    arg_types = {
5479        "this": True,
5480        "format": False,
5481    }
5482
5483
5484class Columns(Func):
5485    arg_types = {"this": True, "unpack": False}
5486
5487
5488# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
5489class Convert(Func):
5490    arg_types = {"this": True, "expression": True, "style": False}
5491
5492
5493class ConvertTimezone(Func):
5494    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
5495
5496
5497class GenerateSeries(Func):
5498    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
5499
5500
5501# Postgres' GENERATE_SERIES function returns a row set, i.e. it implicitly explodes when it's
5502# used in a projection, so this expression is a helper that facilitates transpilation to other
5503# dialects. For example, we'd generate UNNEST(GENERATE_SERIES(...)) in DuckDB
5504class ExplodingGenerateSeries(GenerateSeries):
5505    pass
5506
5507
5508class ArrayAgg(AggFunc):
5509    arg_types = {"this": True, "nulls_excluded": False}
5510
5511
5512class ArrayUniqueAgg(AggFunc):
5513    pass
5514
5515
5516class ArrayAll(Func):
5517    arg_types = {"this": True, "expression": True}
5518
5519
5520# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
5521class ArrayAny(Func):
5522    arg_types = {"this": True, "expression": True}
5523
5524
5525class ArrayConcat(Func):
5526    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5527    arg_types = {"this": True, "expressions": False}
5528    is_var_len_args = True
5529
5530
5531class ArrayConstructCompact(Func):
5532    arg_types = {"expressions": True}
5533    is_var_len_args = True
5534
5535
5536class ArrayContains(Binary, Func):
5537    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5538
5539
5540class ArrayContainsAll(Binary, Func):
5541    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5542
5543
5544class ArrayFilter(Func):
5545    arg_types = {"this": True, "expression": True}
5546    _sql_names = ["FILTER", "ARRAY_FILTER"]
5547
5548
5549class ArrayToString(Func):
5550    arg_types = {"this": True, "expression": True, "null": False}
5551    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5552
5553
5554# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5555class String(Func):
5556    arg_types = {"this": True, "zone": False}
5557
5558
5559class StringToArray(Func):
5560    arg_types = {"this": True, "expression": True, "null": False}
5561    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
5562
5563
5564class ArrayOverlaps(Binary, Func):
5565    pass
5566
5567
5568class ArraySize(Func):
5569    arg_types = {"this": True, "expression": False}
5570    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5571
5572
5573class ArraySort(Func):
5574    arg_types = {"this": True, "expression": False}
5575
5576
5577class ArraySum(Func):
5578    arg_types = {"this": True, "expression": False}
5579
5580
5581class ArrayUnionAgg(AggFunc):
5582    pass
5583
5584
5585class Avg(AggFunc):
5586    pass
5587
5588
5589class AnyValue(AggFunc):
5590    pass
5591
5592
5593class Lag(AggFunc):
5594    arg_types = {"this": True, "offset": False, "default": False}
5595
5596
5597class Lead(AggFunc):
5598    arg_types = {"this": True, "offset": False, "default": False}
5599
5600
5601# some dialects have a distinction between first and first_value, usually first is an aggregate func
5602# and first_value is a window func
5603class First(AggFunc):
5604    pass
5605
5606
5607class Last(AggFunc):
5608    pass
5609
5610
5611class FirstValue(AggFunc):
5612    pass
5613
5614
5615class LastValue(AggFunc):
5616    pass
5617
5618
5619class NthValue(AggFunc):
5620    arg_types = {"this": True, "offset": True}
5621
5622
5623class Case(Func):
5624    arg_types = {"this": False, "ifs": True, "default": False}
5625
5626    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5627        instance = maybe_copy(self, copy)
5628        instance.append(
5629            "ifs",
5630            If(
5631                this=maybe_parse(condition, copy=copy, **opts),
5632                true=maybe_parse(then, copy=copy, **opts),
5633            ),
5634        )
5635        return instance
5636
5637    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5638        instance = maybe_copy(self, copy)
5639        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5640        return instance
5641
5642
5643class Cast(Func):
5644    arg_types = {
5645        "this": True,
5646        "to": True,
5647        "format": False,
5648        "safe": False,
5649        "action": False,
5650        "default": False,
5651    }
5652
5653    @property
5654    def name(self) -> str:
5655        return self.this.name
5656
5657    @property
5658    def to(self) -> DataType:
5659        return self.args["to"]
5660
5661    @property
5662    def output_name(self) -> str:
5663        return self.name
5664
5665    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5666        """
5667        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5668        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5669        array<int> != array<float>.
5670
5671        Args:
5672            dtypes: the data types to compare this Cast's DataType to.
5673
5674        Returns:
5675            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5676        """
5677        return self.to.is_type(*dtypes)
5678
5679
5680class TryCast(Cast):
5681    pass
5682
5683
5684# https://clickhouse.com/docs/sql-reference/data-types/newjson#reading-json-paths-as-sub-columns
5685class JSONCast(Cast):
5686    pass
5687
5688
5689class Try(Func):
5690    pass
5691
5692
5693class CastToStrType(Func):
5694    arg_types = {"this": True, "to": True}
5695
5696
5697class Collate(Binary, Func):
5698    pass
5699
5700
5701class Ceil(Func):
5702    arg_types = {"this": True, "decimals": False, "to": False}
5703    _sql_names = ["CEIL", "CEILING"]
5704
5705
5706class Coalesce(Func):
5707    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5708    is_var_len_args = True
5709    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5710
5711
5712class Chr(Func):
5713    arg_types = {"expressions": True, "charset": False}
5714    is_var_len_args = True
5715    _sql_names = ["CHR", "CHAR"]
5716
5717
5718class Concat(Func):
5719    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5720    is_var_len_args = True
5721
5722
5723class ConcatWs(Concat):
5724    _sql_names = ["CONCAT_WS"]
5725
5726
5727class Contains(Func):
5728    arg_types = {"this": True, "expression": True}
5729
5730
5731# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5732class ConnectByRoot(Func):
5733    pass
5734
5735
5736class Count(AggFunc):
5737    arg_types = {"this": False, "expressions": False, "big_int": False}
5738    is_var_len_args = True
5739
5740
5741class CountIf(AggFunc):
5742    _sql_names = ["COUNT_IF", "COUNTIF"]
5743
5744
5745# cube root
5746class Cbrt(Func):
5747    pass
5748
5749
5750class CurrentDate(Func):
5751    arg_types = {"this": False}
5752
5753
5754class CurrentDatetime(Func):
5755    arg_types = {"this": False}
5756
5757
5758class CurrentTime(Func):
5759    arg_types = {"this": False}
5760
5761
5762class CurrentTimestamp(Func):
5763    arg_types = {"this": False, "sysdate": False}
5764
5765
5766class CurrentSchema(Func):
5767    arg_types = {"this": False}
5768
5769
5770class CurrentUser(Func):
5771    arg_types = {"this": False}
5772
5773
5774class DateAdd(Func, IntervalOp):
5775    arg_types = {"this": True, "expression": True, "unit": False}
5776
5777
5778class DateBin(Func, IntervalOp):
5779    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5780
5781
5782class DateSub(Func, IntervalOp):
5783    arg_types = {"this": True, "expression": True, "unit": False}
5784
5785
5786class DateDiff(Func, TimeUnit):
5787    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5788    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5789
5790
5791class DateTrunc(Func):
5792    arg_types = {"unit": True, "this": True, "zone": False}
5793
5794    def __init__(self, **args):
5795        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5796        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5797        unabbreviate = args.pop("unabbreviate", True)
5798
5799        unit = args.get("unit")
5800        if isinstance(unit, TimeUnit.VAR_LIKE):
5801            unit_name = unit.name.upper()
5802            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5803                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5804
5805            args["unit"] = Literal.string(unit_name)
5806        elif isinstance(unit, Week):
5807            unit.set("this", Literal.string(unit.this.name.upper()))
5808
5809        super().__init__(**args)
5810
5811    @property
5812    def unit(self) -> Expression:
5813        return self.args["unit"]
5814
5815
5816# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5817# expression can either be time_expr or time_zone
5818class Datetime(Func):
5819    arg_types = {"this": True, "expression": False}
5820
5821
5822class DatetimeAdd(Func, IntervalOp):
5823    arg_types = {"this": True, "expression": True, "unit": False}
5824
5825
5826class DatetimeSub(Func, IntervalOp):
5827    arg_types = {"this": True, "expression": True, "unit": False}
5828
5829
5830class DatetimeDiff(Func, TimeUnit):
5831    arg_types = {"this": True, "expression": True, "unit": False}
5832
5833
5834class DatetimeTrunc(Func, TimeUnit):
5835    arg_types = {"this": True, "unit": True, "zone": False}
5836
5837
5838class DayOfWeek(Func):
5839    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5840
5841
5842# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5843# ISO day of week function in duckdb is ISODOW
5844class DayOfWeekIso(Func):
5845    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5846
5847
5848class DayOfMonth(Func):
5849    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5850
5851
5852class DayOfYear(Func):
5853    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5854
5855
5856class ToDays(Func):
5857    pass
5858
5859
5860class WeekOfYear(Func):
5861    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5862
5863
5864class MonthsBetween(Func):
5865    arg_types = {"this": True, "expression": True, "roundoff": False}
5866
5867
5868class MakeInterval(Func):
5869    arg_types = {
5870        "year": False,
5871        "month": False,
5872        "day": False,
5873        "hour": False,
5874        "minute": False,
5875        "second": False,
5876    }
5877
5878
5879class LastDay(Func, TimeUnit):
5880    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5881    arg_types = {"this": True, "unit": False}
5882
5883
5884class Extract(Func):
5885    arg_types = {"this": True, "expression": True}
5886
5887
5888class Exists(Func, SubqueryPredicate):
5889    arg_types = {"this": True, "expression": False}
5890
5891
5892class Timestamp(Func):
5893    arg_types = {"this": False, "zone": False, "with_tz": False}
5894
5895
5896class TimestampAdd(Func, TimeUnit):
5897    arg_types = {"this": True, "expression": True, "unit": False}
5898
5899
5900class TimestampSub(Func, TimeUnit):
5901    arg_types = {"this": True, "expression": True, "unit": False}
5902
5903
5904class TimestampDiff(Func, TimeUnit):
5905    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5906    arg_types = {"this": True, "expression": True, "unit": False}
5907
5908
5909class TimestampTrunc(Func, TimeUnit):
5910    arg_types = {"this": True, "unit": True, "zone": False}
5911
5912
5913class TimeAdd(Func, TimeUnit):
5914    arg_types = {"this": True, "expression": True, "unit": False}
5915
5916
5917class TimeSub(Func, TimeUnit):
5918    arg_types = {"this": True, "expression": True, "unit": False}
5919
5920
5921class TimeDiff(Func, TimeUnit):
5922    arg_types = {"this": True, "expression": True, "unit": False}
5923
5924
5925class TimeTrunc(Func, TimeUnit):
5926    arg_types = {"this": True, "unit": True, "zone": False}
5927
5928
5929class DateFromParts(Func):
5930    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5931    arg_types = {"year": True, "month": True, "day": True}
5932
5933
5934class TimeFromParts(Func):
5935    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5936    arg_types = {
5937        "hour": True,
5938        "min": True,
5939        "sec": True,
5940        "nano": False,
5941        "fractions": False,
5942        "precision": False,
5943    }
5944
5945
5946class DateStrToDate(Func):
5947    pass
5948
5949
5950class DateToDateStr(Func):
5951    pass
5952
5953
5954class DateToDi(Func):
5955    pass
5956
5957
5958# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5959class Date(Func):
5960    arg_types = {"this": False, "zone": False, "expressions": False}
5961    is_var_len_args = True
5962
5963
5964class Day(Func):
5965    pass
5966
5967
5968class Decode(Func):
5969    arg_types = {"this": True, "charset": True, "replace": False}
5970
5971
5972class DiToDate(Func):
5973    pass
5974
5975
5976class Encode(Func):
5977    arg_types = {"this": True, "charset": True}
5978
5979
5980class Exp(Func):
5981    pass
5982
5983
5984# https://docs.snowflake.com/en/sql-reference/functions/flatten
5985class Explode(Func, UDTF):
5986    arg_types = {"this": True, "expressions": False}
5987    is_var_len_args = True
5988
5989
5990# https://spark.apache.org/docs/latest/api/sql/#inline
5991class Inline(Func):
5992    pass
5993
5994
5995class ExplodeOuter(Explode):
5996    pass
5997
5998
5999class Posexplode(Explode):
6000    pass
6001
6002
6003class PosexplodeOuter(Posexplode, ExplodeOuter):
6004    pass
6005
6006
6007class Unnest(Func, UDTF):
6008    arg_types = {
6009        "expressions": True,
6010        "alias": False,
6011        "offset": False,
6012        "explode_array": False,
6013    }
6014
6015    @property
6016    def selects(self) -> t.List[Expression]:
6017        columns = super().selects
6018        offset = self.args.get("offset")
6019        if offset:
6020            columns = columns + [to_identifier("offset") if offset is True else offset]
6021        return columns
6022
6023
6024class Floor(Func):
6025    arg_types = {"this": True, "decimals": False, "to": False}
6026
6027
6028class FromBase64(Func):
6029    pass
6030
6031
6032class FeaturesAtTime(Func):
6033    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
6034
6035
6036class ToBase64(Func):
6037    pass
6038
6039
6040# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
6041class FromISO8601Timestamp(Func):
6042    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
6043
6044
6045class GapFill(Func):
6046    arg_types = {
6047        "this": True,
6048        "ts_column": True,
6049        "bucket_width": True,
6050        "partitioning_columns": False,
6051        "value_columns": False,
6052        "origin": False,
6053        "ignore_nulls": False,
6054    }
6055
6056
6057# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
6058class GenerateDateArray(Func):
6059    arg_types = {"start": True, "end": True, "step": False}
6060
6061
6062# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
6063class GenerateTimestampArray(Func):
6064    arg_types = {"start": True, "end": True, "step": True}
6065
6066
6067class Greatest(Func):
6068    arg_types = {"this": True, "expressions": False}
6069    is_var_len_args = True
6070
6071
6072# Trino's `ON OVERFLOW TRUNCATE [filler_string] {WITH | WITHOUT} COUNT`
6073# https://trino.io/docs/current/functions/aggregate.html#listagg
6074class OverflowTruncateBehavior(Expression):
6075    arg_types = {"this": False, "with_count": True}
6076
6077
6078class GroupConcat(AggFunc):
6079    arg_types = {"this": True, "separator": False, "on_overflow": False}
6080
6081
6082class Hex(Func):
6083    pass
6084
6085
6086class LowerHex(Hex):
6087    pass
6088
6089
6090class And(Connector, Func):
6091    pass
6092
6093
6094class Or(Connector, Func):
6095    pass
6096
6097
6098class Xor(Connector, Func):
6099    arg_types = {"this": False, "expression": False, "expressions": False}
6100
6101
6102class If(Func):
6103    arg_types = {"this": True, "true": True, "false": False}
6104    _sql_names = ["IF", "IIF"]
6105
6106
6107class Nullif(Func):
6108    arg_types = {"this": True, "expression": True}
6109
6110
6111class Initcap(Func):
6112    arg_types = {"this": True, "expression": False}
6113
6114
6115class IsAscii(Func):
6116    pass
6117
6118
6119class IsNan(Func):
6120    _sql_names = ["IS_NAN", "ISNAN"]
6121
6122
6123# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#int64_for_json
6124class Int64(Func):
6125    pass
6126
6127
6128class IsInf(Func):
6129    _sql_names = ["IS_INF", "ISINF"]
6130
6131
6132# https://www.postgresql.org/docs/current/functions-json.html
6133class JSON(Expression):
6134    arg_types = {"this": False, "with": False, "unique": False}
6135
6136
6137class JSONPath(Expression):
6138    arg_types = {"expressions": True, "escape": False}
6139
6140    @property
6141    def output_name(self) -> str:
6142        last_segment = self.expressions[-1].this
6143        return last_segment if isinstance(last_segment, str) else ""
6144
6145
6146class JSONPathPart(Expression):
6147    arg_types = {}
6148
6149
6150class JSONPathFilter(JSONPathPart):
6151    arg_types = {"this": True}
6152
6153
6154class JSONPathKey(JSONPathPart):
6155    arg_types = {"this": True}
6156
6157
6158class JSONPathRecursive(JSONPathPart):
6159    arg_types = {"this": False}
6160
6161
6162class JSONPathRoot(JSONPathPart):
6163    pass
6164
6165
6166class JSONPathScript(JSONPathPart):
6167    arg_types = {"this": True}
6168
6169
6170class JSONPathSlice(JSONPathPart):
6171    arg_types = {"start": False, "end": False, "step": False}
6172
6173
6174class JSONPathSelector(JSONPathPart):
6175    arg_types = {"this": True}
6176
6177
6178class JSONPathSubscript(JSONPathPart):
6179    arg_types = {"this": True}
6180
6181
6182class JSONPathUnion(JSONPathPart):
6183    arg_types = {"expressions": True}
6184
6185
6186class JSONPathWildcard(JSONPathPart):
6187    pass
6188
6189
6190class FormatJson(Expression):
6191    pass
6192
6193
6194class JSONKeyValue(Expression):
6195    arg_types = {"this": True, "expression": True}
6196
6197
6198class JSONObject(Func):
6199    arg_types = {
6200        "expressions": False,
6201        "null_handling": False,
6202        "unique_keys": False,
6203        "return_type": False,
6204        "encoding": False,
6205    }
6206
6207
6208class JSONObjectAgg(AggFunc):
6209    arg_types = {
6210        "expressions": False,
6211        "null_handling": False,
6212        "unique_keys": False,
6213        "return_type": False,
6214        "encoding": False,
6215    }
6216
6217
6218# https://www.postgresql.org/docs/9.5/functions-aggregate.html
6219class JSONBObjectAgg(AggFunc):
6220    arg_types = {"this": True, "expression": True}
6221
6222
6223# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
6224class JSONArray(Func):
6225    arg_types = {
6226        "expressions": True,
6227        "null_handling": False,
6228        "return_type": False,
6229        "strict": False,
6230    }
6231
6232
6233# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
6234class JSONArrayAgg(Func):
6235    arg_types = {
6236        "this": True,
6237        "order": False,
6238        "null_handling": False,
6239        "return_type": False,
6240        "strict": False,
6241    }
6242
6243
6244class JSONExists(Func):
6245    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
6246
6247
6248# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6249# Note: parsing of JSON column definitions is currently incomplete.
6250class JSONColumnDef(Expression):
6251    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
6252
6253
6254class JSONSchema(Expression):
6255    arg_types = {"expressions": True}
6256
6257
6258# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
6259class JSONValue(Expression):
6260    arg_types = {
6261        "this": True,
6262        "path": True,
6263        "returning": False,
6264        "on_condition": False,
6265    }
6266
6267
6268class JSONValueArray(Func):
6269    arg_types = {"this": True, "expression": False}
6270
6271
6272# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6273class JSONTable(Func):
6274    arg_types = {
6275        "this": True,
6276        "schema": True,
6277        "path": False,
6278        "error_handling": False,
6279        "empty_handling": False,
6280    }
6281
6282
6283# https://docs.snowflake.com/en/sql-reference/functions/object_insert
6284class ObjectInsert(Func):
6285    arg_types = {
6286        "this": True,
6287        "key": True,
6288        "value": True,
6289        "update_flag": False,
6290    }
6291
6292
6293class OpenJSONColumnDef(Expression):
6294    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
6295
6296
6297class OpenJSON(Func):
6298    arg_types = {"this": True, "path": False, "expressions": False}
6299
6300
6301class JSONBContains(Binary, Func):
6302    _sql_names = ["JSONB_CONTAINS"]
6303
6304
6305class JSONBExists(Func):
6306    arg_types = {"this": True, "path": True}
6307    _sql_names = ["JSONB_EXISTS"]
6308
6309
6310class JSONExtract(Binary, Func):
6311    arg_types = {
6312        "this": True,
6313        "expression": True,
6314        "only_json_types": False,
6315        "expressions": False,
6316        "variant_extract": False,
6317        "json_query": False,
6318        "option": False,
6319        "quote": False,
6320        "on_condition": False,
6321    }
6322    _sql_names = ["JSON_EXTRACT"]
6323    is_var_len_args = True
6324
6325    @property
6326    def output_name(self) -> str:
6327        return self.expression.output_name if not self.expressions else ""
6328
6329
6330# https://trino.io/docs/current/functions/json.html#json-query
6331class JSONExtractQuote(Expression):
6332    arg_types = {
6333        "option": True,
6334        "scalar": False,
6335    }
6336
6337
6338class JSONExtractArray(Func):
6339    arg_types = {"this": True, "expression": False}
6340    _sql_names = ["JSON_EXTRACT_ARRAY"]
6341
6342
6343class JSONExtractScalar(Binary, Func):
6344    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6345    _sql_names = ["JSON_EXTRACT_SCALAR"]
6346    is_var_len_args = True
6347
6348    @property
6349    def output_name(self) -> str:
6350        return self.expression.output_name
6351
6352
6353class JSONBExtract(Binary, Func):
6354    _sql_names = ["JSONB_EXTRACT"]
6355
6356
6357class JSONBExtractScalar(Binary, Func):
6358    _sql_names = ["JSONB_EXTRACT_SCALAR"]
6359
6360
6361class JSONFormat(Func):
6362    arg_types = {"this": False, "options": False, "is_json": False}
6363    _sql_names = ["JSON_FORMAT"]
6364
6365
6366# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
6367class JSONArrayContains(Binary, Predicate, Func):
6368    _sql_names = ["JSON_ARRAY_CONTAINS"]
6369
6370
6371class ParseJSON(Func):
6372    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6373    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6374    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6375    arg_types = {"this": True, "expression": False, "safe": False}
6376
6377
6378class Least(Func):
6379    arg_types = {"this": True, "expressions": False}
6380    is_var_len_args = True
6381
6382
6383class Left(Func):
6384    arg_types = {"this": True, "expression": True}
6385
6386
6387class Right(Func):
6388    arg_types = {"this": True, "expression": True}
6389
6390
6391class Length(Func):
6392    arg_types = {"this": True, "binary": False, "encoding": False}
6393    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
6394
6395
6396class Levenshtein(Func):
6397    arg_types = {
6398        "this": True,
6399        "expression": False,
6400        "ins_cost": False,
6401        "del_cost": False,
6402        "sub_cost": False,
6403        "max_dist": False,
6404    }
6405
6406
6407class Ln(Func):
6408    pass
6409
6410
6411class Log(Func):
6412    arg_types = {"this": True, "expression": False}
6413
6414
6415class LogicalOr(AggFunc):
6416    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
6417
6418
6419class LogicalAnd(AggFunc):
6420    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
6421
6422
6423class Lower(Func):
6424    _sql_names = ["LOWER", "LCASE"]
6425
6426
6427class Map(Func):
6428    arg_types = {"keys": False, "values": False}
6429
6430    @property
6431    def keys(self) -> t.List[Expression]:
6432        keys = self.args.get("keys")
6433        return keys.expressions if keys else []
6434
6435    @property
6436    def values(self) -> t.List[Expression]:
6437        values = self.args.get("values")
6438        return values.expressions if values else []
6439
6440
6441# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
6442class ToMap(Func):
6443    pass
6444
6445
6446class MapFromEntries(Func):
6447    pass
6448
6449
6450# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
6451class ScopeResolution(Expression):
6452    arg_types = {"this": False, "expression": True}
6453
6454
6455class Stream(Expression):
6456    pass
6457
6458
6459class StarMap(Func):
6460    pass
6461
6462
6463class VarMap(Func):
6464    arg_types = {"keys": True, "values": True}
6465    is_var_len_args = True
6466
6467    @property
6468    def keys(self) -> t.List[Expression]:
6469        return self.args["keys"].expressions
6470
6471    @property
6472    def values(self) -> t.List[Expression]:
6473        return self.args["values"].expressions
6474
6475
6476# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
6477class MatchAgainst(Func):
6478    arg_types = {"this": True, "expressions": True, "modifier": False}
6479
6480
6481class Max(AggFunc):
6482    arg_types = {"this": True, "expressions": False}
6483    is_var_len_args = True
6484
6485
6486class MD5(Func):
6487    _sql_names = ["MD5"]
6488
6489
6490# Represents the variant of the MD5 function that returns a binary value
6491class MD5Digest(Func):
6492    _sql_names = ["MD5_DIGEST"]
6493
6494
6495class Median(AggFunc):
6496    pass
6497
6498
6499class Min(AggFunc):
6500    arg_types = {"this": True, "expressions": False}
6501    is_var_len_args = True
6502
6503
6504class Month(Func):
6505    pass
6506
6507
6508class AddMonths(Func):
6509    arg_types = {"this": True, "expression": True}
6510
6511
6512class Nvl2(Func):
6513    arg_types = {"this": True, "true": True, "false": False}
6514
6515
6516class Normalize(Func):
6517    arg_types = {"this": True, "form": False}
6518
6519
6520class Overlay(Func):
6521    arg_types = {"this": True, "expression": True, "from": True, "for": False}
6522
6523
6524# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
6525class Predict(Func):
6526    arg_types = {"this": True, "expression": True, "params_struct": False}
6527
6528
6529class Pow(Binary, Func):
6530    _sql_names = ["POWER", "POW"]
6531
6532
6533class PercentileCont(AggFunc):
6534    arg_types = {"this": True, "expression": False}
6535
6536
6537class PercentileDisc(AggFunc):
6538    arg_types = {"this": True, "expression": False}
6539
6540
6541class Quantile(AggFunc):
6542    arg_types = {"this": True, "quantile": True}
6543
6544
6545class ApproxQuantile(Quantile):
6546    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
6547
6548
6549class Quarter(Func):
6550    pass
6551
6552
6553# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
6554# teradata lower and upper bounds
6555class Rand(Func):
6556    _sql_names = ["RAND", "RANDOM"]
6557    arg_types = {"this": False, "lower": False, "upper": False}
6558
6559
6560class Randn(Func):
6561    arg_types = {"this": False}
6562
6563
6564class RangeN(Func):
6565    arg_types = {"this": True, "expressions": True, "each": False}
6566
6567
6568class ReadCSV(Func):
6569    _sql_names = ["READ_CSV"]
6570    is_var_len_args = True
6571    arg_types = {"this": True, "expressions": False}
6572
6573
6574class Reduce(Func):
6575    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
6576
6577
6578class RegexpExtract(Func):
6579    arg_types = {
6580        "this": True,
6581        "expression": True,
6582        "position": False,
6583        "occurrence": False,
6584        "parameters": False,
6585        "group": False,
6586    }
6587
6588
6589class RegexpExtractAll(Func):
6590    arg_types = {
6591        "this": True,
6592        "expression": True,
6593        "position": False,
6594        "occurrence": False,
6595        "parameters": False,
6596        "group": False,
6597    }
6598
6599
6600class RegexpReplace(Func):
6601    arg_types = {
6602        "this": True,
6603        "expression": True,
6604        "replacement": False,
6605        "position": False,
6606        "occurrence": False,
6607        "modifiers": False,
6608    }
6609
6610
6611class RegexpLike(Binary, Func):
6612    arg_types = {"this": True, "expression": True, "flag": False}
6613
6614
6615class RegexpILike(Binary, Func):
6616    arg_types = {"this": True, "expression": True, "flag": False}
6617
6618
6619# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6620# limit is the number of times a pattern is applied
6621class RegexpSplit(Func):
6622    arg_types = {"this": True, "expression": True, "limit": False}
6623
6624
6625class Repeat(Func):
6626    arg_types = {"this": True, "times": True}
6627
6628
6629# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6630# tsql third argument function == trunctaion if not 0
6631class Round(Func):
6632    arg_types = {"this": True, "decimals": False, "truncate": False}
6633
6634
6635class RowNumber(Func):
6636    arg_types = {"this": False}
6637
6638
6639class SafeDivide(Func):
6640    arg_types = {"this": True, "expression": True}
6641
6642
6643class SHA(Func):
6644    _sql_names = ["SHA", "SHA1"]
6645
6646
6647class SHA2(Func):
6648    _sql_names = ["SHA2"]
6649    arg_types = {"this": True, "length": False}
6650
6651
6652class Sign(Func):
6653    _sql_names = ["SIGN", "SIGNUM"]
6654
6655
6656class SortArray(Func):
6657    arg_types = {"this": True, "asc": False}
6658
6659
6660class Split(Func):
6661    arg_types = {"this": True, "expression": True, "limit": False}
6662
6663
6664# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split_part.html
6665class SplitPart(Func):
6666    arg_types = {"this": True, "delimiter": True, "part_index": True}
6667
6668
6669# Start may be omitted in the case of postgres
6670# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6671class Substring(Func):
6672    _sql_names = ["SUBSTRING", "SUBSTR"]
6673    arg_types = {"this": True, "start": False, "length": False}
6674
6675
6676class StandardHash(Func):
6677    arg_types = {"this": True, "expression": False}
6678
6679
6680class StartsWith(Func):
6681    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6682    arg_types = {"this": True, "expression": True}
6683
6684
6685class StrPosition(Func):
6686    arg_types = {
6687        "this": True,
6688        "substr": True,
6689        "position": False,
6690        "occurrence": False,
6691    }
6692
6693
6694class StrToDate(Func):
6695    arg_types = {"this": True, "format": False, "safe": False}
6696
6697
6698class StrToTime(Func):
6699    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6700
6701
6702# Spark allows unix_timestamp()
6703# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6704class StrToUnix(Func):
6705    arg_types = {"this": False, "format": False}
6706
6707
6708# https://prestodb.io/docs/current/functions/string.html
6709# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6710class StrToMap(Func):
6711    arg_types = {
6712        "this": True,
6713        "pair_delim": False,
6714        "key_value_delim": False,
6715        "duplicate_resolution_callback": False,
6716    }
6717
6718
6719class NumberToStr(Func):
6720    arg_types = {"this": True, "format": True, "culture": False}
6721
6722
6723class FromBase(Func):
6724    arg_types = {"this": True, "expression": True}
6725
6726
6727class Struct(Func):
6728    arg_types = {"expressions": False}
6729    is_var_len_args = True
6730
6731
6732class StructExtract(Func):
6733    arg_types = {"this": True, "expression": True}
6734
6735
6736# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6737# https://docs.snowflake.com/en/sql-reference/functions/insert
6738class Stuff(Func):
6739    _sql_names = ["STUFF", "INSERT"]
6740    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6741
6742
6743class Sum(AggFunc):
6744    pass
6745
6746
6747class Sqrt(Func):
6748    pass
6749
6750
6751class Stddev(AggFunc):
6752    _sql_names = ["STDDEV", "STDEV"]
6753
6754
6755class StddevPop(AggFunc):
6756    pass
6757
6758
6759class StddevSamp(AggFunc):
6760    pass
6761
6762
6763# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6764class Time(Func):
6765    arg_types = {"this": False, "zone": False}
6766
6767
6768class TimeToStr(Func):
6769    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6770
6771
6772class TimeToTimeStr(Func):
6773    pass
6774
6775
6776class TimeToUnix(Func):
6777    pass
6778
6779
6780class TimeStrToDate(Func):
6781    pass
6782
6783
6784class TimeStrToTime(Func):
6785    arg_types = {"this": True, "zone": False}
6786
6787
6788class TimeStrToUnix(Func):
6789    pass
6790
6791
6792class Trim(Func):
6793    arg_types = {
6794        "this": True,
6795        "expression": False,
6796        "position": False,
6797        "collation": False,
6798    }
6799
6800
6801class TsOrDsAdd(Func, TimeUnit):
6802    # return_type is used to correctly cast the arguments of this expression when transpiling it
6803    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6804
6805    @property
6806    def return_type(self) -> DataType:
6807        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
6808
6809
6810class TsOrDsDiff(Func, TimeUnit):
6811    arg_types = {"this": True, "expression": True, "unit": False}
6812
6813
6814class TsOrDsToDateStr(Func):
6815    pass
6816
6817
6818class TsOrDsToDate(Func):
6819    arg_types = {"this": True, "format": False, "safe": False}
6820
6821
6822class TsOrDsToDatetime(Func):
6823    pass
6824
6825
6826class TsOrDsToTime(Func):
6827    arg_types = {"this": True, "format": False, "safe": False}
6828
6829
6830class TsOrDsToTimestamp(Func):
6831    pass
6832
6833
6834class TsOrDiToDi(Func):
6835    pass
6836
6837
6838class Unhex(Func):
6839    arg_types = {"this": True, "expression": False}
6840
6841
6842class Unicode(Func):
6843    pass
6844
6845
6846# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
6847class UnixDate(Func):
6848    pass
6849
6850
6851class UnixToStr(Func):
6852    arg_types = {"this": True, "format": False}
6853
6854
6855# https://prestodb.io/docs/current/functions/datetime.html
6856# presto has weird zone/hours/minutes
6857class UnixToTime(Func):
6858    arg_types = {
6859        "this": True,
6860        "scale": False,
6861        "zone": False,
6862        "hours": False,
6863        "minutes": False,
6864        "format": False,
6865    }
6866
6867    SECONDS = Literal.number(0)
6868    DECIS = Literal.number(1)
6869    CENTIS = Literal.number(2)
6870    MILLIS = Literal.number(3)
6871    DECIMILLIS = Literal.number(4)
6872    CENTIMILLIS = Literal.number(5)
6873    MICROS = Literal.number(6)
6874    DECIMICROS = Literal.number(7)
6875    CENTIMICROS = Literal.number(8)
6876    NANOS = Literal.number(9)
6877
6878
6879class UnixToTimeStr(Func):
6880    pass
6881
6882
6883class UnixSeconds(Func):
6884    pass
6885
6886
6887class Uuid(Func):
6888    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6889
6890    arg_types = {"this": False, "name": False}
6891
6892
6893class TimestampFromParts(Func):
6894    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6895    arg_types = {
6896        "year": True,
6897        "month": True,
6898        "day": True,
6899        "hour": True,
6900        "min": True,
6901        "sec": True,
6902        "nano": False,
6903        "zone": False,
6904        "milli": False,
6905    }
6906
6907
6908class Upper(Func):
6909    _sql_names = ["UPPER", "UCASE"]
6910
6911
6912class Corr(Binary, AggFunc):
6913    pass
6914
6915
6916class Variance(AggFunc):
6917    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6918
6919
6920class VariancePop(AggFunc):
6921    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6922
6923
6924class CovarSamp(Binary, AggFunc):
6925    pass
6926
6927
6928class CovarPop(Binary, AggFunc):
6929    pass
6930
6931
6932class Week(Func):
6933    arg_types = {"this": True, "mode": False}
6934
6935
6936class XMLElement(Func):
6937    _sql_names = ["XMLELEMENT"]
6938    arg_types = {"this": True, "expressions": False}
6939
6940
6941class XMLTable(Func):
6942    arg_types = {
6943        "this": True,
6944        "namespaces": False,
6945        "passing": False,
6946        "columns": False,
6947        "by_ref": False,
6948    }
6949
6950
6951class XMLNamespace(Expression):
6952    pass
6953
6954
6955class Year(Func):
6956    pass
6957
6958
6959class Use(Expression):
6960    arg_types = {"this": False, "expressions": False, "kind": False}
6961
6962
6963class Merge(DML):
6964    arg_types = {
6965        "this": True,
6966        "using": True,
6967        "on": True,
6968        "whens": True,
6969        "with": False,
6970        "returning": False,
6971    }
6972
6973
6974class When(Expression):
6975    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6976
6977
6978class Whens(Expression):
6979    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6980
6981    arg_types = {"expressions": True}
6982
6983
6984# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
6985# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
6986class NextValueFor(Func):
6987    arg_types = {"this": True, "order": False}
6988
6989
6990# Refers to a trailing semi-colon. This is only used to preserve trailing comments
6991# select 1; -- my comment
6992class Semicolon(Expression):
6993    arg_types = {}
6994
6995
6996def _norm_arg(arg):
6997    return arg.lower() if type(arg) is str else arg
6998
6999
7000ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
7001FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
7002
7003JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
7004
7005PERCENTILES = (PercentileCont, PercentileDisc)
7006
7007
7008# Helpers
7009@t.overload
7010def maybe_parse(
7011    sql_or_expression: ExpOrStr,
7012    *,
7013    into: t.Type[E],
7014    dialect: DialectType = None,
7015    prefix: t.Optional[str] = None,
7016    copy: bool = False,
7017    **opts,
7018) -> E: ...
7019
7020
7021@t.overload
7022def maybe_parse(
7023    sql_or_expression: str | E,
7024    *,
7025    into: t.Optional[IntoType] = None,
7026    dialect: DialectType = None,
7027    prefix: t.Optional[str] = None,
7028    copy: bool = False,
7029    **opts,
7030) -> E: ...
7031
7032
7033def maybe_parse(
7034    sql_or_expression: ExpOrStr,
7035    *,
7036    into: t.Optional[IntoType] = None,
7037    dialect: DialectType = None,
7038    prefix: t.Optional[str] = None,
7039    copy: bool = False,
7040    **opts,
7041) -> Expression:
7042    """Gracefully handle a possible string or expression.
7043
7044    Example:
7045        >>> maybe_parse("1")
7046        Literal(this=1, is_string=False)
7047        >>> maybe_parse(to_identifier("x"))
7048        Identifier(this=x, quoted=False)
7049
7050    Args:
7051        sql_or_expression: the SQL code string or an expression
7052        into: the SQLGlot Expression to parse into
7053        dialect: the dialect used to parse the input expressions (in the case that an
7054            input expression is a SQL string).
7055        prefix: a string to prefix the sql with before it gets parsed
7056            (automatically includes a space)
7057        copy: whether to copy the expression.
7058        **opts: other options to use to parse the input expressions (again, in the case
7059            that an input expression is a SQL string).
7060
7061    Returns:
7062        Expression: the parsed or given expression.
7063    """
7064    if isinstance(sql_or_expression, Expression):
7065        if copy:
7066            return sql_or_expression.copy()
7067        return sql_or_expression
7068
7069    if sql_or_expression is None:
7070        raise ParseError("SQL cannot be None")
7071
7072    import sqlglot
7073
7074    sql = str(sql_or_expression)
7075    if prefix:
7076        sql = f"{prefix} {sql}"
7077
7078    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
7079
7080
7081@t.overload
7082def maybe_copy(instance: None, copy: bool = True) -> None: ...
7083
7084
7085@t.overload
7086def maybe_copy(instance: E, copy: bool = True) -> E: ...
7087
7088
7089def maybe_copy(instance, copy=True):
7090    return instance.copy() if copy and instance else instance
7091
7092
7093def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str:
7094    """Generate a textual representation of an Expression tree"""
7095    indent = "\n" + ("  " * (level + 1))
7096    delim = f",{indent}"
7097
7098    if isinstance(node, Expression):
7099        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
7100
7101        if (node.type or verbose) and not isinstance(node, DataType):
7102            args["_type"] = node.type
7103        if node.comments or verbose:
7104            args["_comments"] = node.comments
7105
7106        if verbose:
7107            args["_id"] = id(node)
7108
7109        # Inline leaves for a more compact representation
7110        if node.is_leaf():
7111            indent = ""
7112            delim = ", "
7113
7114        repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted)
7115        items = delim.join(
7116            [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()]
7117        )
7118        return f"{node.__class__.__name__}({indent}{items})"
7119
7120    if isinstance(node, list):
7121        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
7122        items = f"{indent}{items}" if items else ""
7123        return f"[{items}]"
7124
7125    # We use the representation of the string to avoid stripping out important whitespace
7126    if repr_str and isinstance(node, str):
7127        node = repr(node)
7128
7129    # Indent multiline strings to match the current level
7130    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
7131
7132
7133def _is_wrong_expression(expression, into):
7134    return isinstance(expression, Expression) and not isinstance(expression, into)
7135
7136
7137def _apply_builder(
7138    expression,
7139    instance,
7140    arg,
7141    copy=True,
7142    prefix=None,
7143    into=None,
7144    dialect=None,
7145    into_arg="this",
7146    **opts,
7147):
7148    if _is_wrong_expression(expression, into):
7149        expression = into(**{into_arg: expression})
7150    instance = maybe_copy(instance, copy)
7151    expression = maybe_parse(
7152        sql_or_expression=expression,
7153        prefix=prefix,
7154        into=into,
7155        dialect=dialect,
7156        **opts,
7157    )
7158    instance.set(arg, expression)
7159    return instance
7160
7161
7162def _apply_child_list_builder(
7163    *expressions,
7164    instance,
7165    arg,
7166    append=True,
7167    copy=True,
7168    prefix=None,
7169    into=None,
7170    dialect=None,
7171    properties=None,
7172    **opts,
7173):
7174    instance = maybe_copy(instance, copy)
7175    parsed = []
7176    properties = {} if properties is None else properties
7177
7178    for expression in expressions:
7179        if expression is not None:
7180            if _is_wrong_expression(expression, into):
7181                expression = into(expressions=[expression])
7182
7183            expression = maybe_parse(
7184                expression,
7185                into=into,
7186                dialect=dialect,
7187                prefix=prefix,
7188                **opts,
7189            )
7190            for k, v in expression.args.items():
7191                if k == "expressions":
7192                    parsed.extend(v)
7193                else:
7194                    properties[k] = v
7195
7196    existing = instance.args.get(arg)
7197    if append and existing:
7198        parsed = existing.expressions + parsed
7199
7200    child = into(expressions=parsed)
7201    for k, v in properties.items():
7202        child.set(k, v)
7203    instance.set(arg, child)
7204
7205    return instance
7206
7207
7208def _apply_list_builder(
7209    *expressions,
7210    instance,
7211    arg,
7212    append=True,
7213    copy=True,
7214    prefix=None,
7215    into=None,
7216    dialect=None,
7217    **opts,
7218):
7219    inst = maybe_copy(instance, copy)
7220
7221    expressions = [
7222        maybe_parse(
7223            sql_or_expression=expression,
7224            into=into,
7225            prefix=prefix,
7226            dialect=dialect,
7227            **opts,
7228        )
7229        for expression in expressions
7230        if expression is not None
7231    ]
7232
7233    existing_expressions = inst.args.get(arg)
7234    if append and existing_expressions:
7235        expressions = existing_expressions + expressions
7236
7237    inst.set(arg, expressions)
7238    return inst
7239
7240
7241def _apply_conjunction_builder(
7242    *expressions,
7243    instance,
7244    arg,
7245    into=None,
7246    append=True,
7247    copy=True,
7248    dialect=None,
7249    **opts,
7250):
7251    expressions = [exp for exp in expressions if exp is not None and exp != ""]
7252    if not expressions:
7253        return instance
7254
7255    inst = maybe_copy(instance, copy)
7256
7257    existing = inst.args.get(arg)
7258    if append and existing is not None:
7259        expressions = [existing.this if into else existing] + list(expressions)
7260
7261    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
7262
7263    inst.set(arg, into(this=node) if into else node)
7264    return inst
7265
7266
7267def _apply_cte_builder(
7268    instance: E,
7269    alias: ExpOrStr,
7270    as_: ExpOrStr,
7271    recursive: t.Optional[bool] = None,
7272    materialized: t.Optional[bool] = None,
7273    append: bool = True,
7274    dialect: DialectType = None,
7275    copy: bool = True,
7276    scalar: bool = False,
7277    **opts,
7278) -> E:
7279    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
7280    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
7281    if scalar and not isinstance(as_expression, Subquery):
7282        # scalar CTE must be wrapped in a subquery
7283        as_expression = Subquery(this=as_expression)
7284    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
7285    return _apply_child_list_builder(
7286        cte,
7287        instance=instance,
7288        arg="with",
7289        append=append,
7290        copy=copy,
7291        into=With,
7292        properties={"recursive": recursive or False},
7293    )
7294
7295
7296def _combine(
7297    expressions: t.Sequence[t.Optional[ExpOrStr]],
7298    operator: t.Type[Connector],
7299    dialect: DialectType = None,
7300    copy: bool = True,
7301    wrap: bool = True,
7302    **opts,
7303) -> Expression:
7304    conditions = [
7305        condition(expression, dialect=dialect, copy=copy, **opts)
7306        for expression in expressions
7307        if expression is not None
7308    ]
7309
7310    this, *rest = conditions
7311    if rest and wrap:
7312        this = _wrap(this, Connector)
7313    for expression in rest:
7314        this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression)
7315
7316    return this
7317
7318
7319@t.overload
7320def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
7321
7322
7323@t.overload
7324def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
7325
7326
7327def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
7328    return Paren(this=expression) if isinstance(expression, kind) else expression
7329
7330
7331def _apply_set_operation(
7332    *expressions: ExpOrStr,
7333    set_operation: t.Type[S],
7334    distinct: bool = True,
7335    dialect: DialectType = None,
7336    copy: bool = True,
7337    **opts,
7338) -> S:
7339    return reduce(
7340        lambda x, y: set_operation(this=x, expression=y, distinct=distinct),
7341        (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7342    )
7343
7344
7345def union(
7346    *expressions: ExpOrStr,
7347    distinct: bool = True,
7348    dialect: DialectType = None,
7349    copy: bool = True,
7350    **opts,
7351) -> Union:
7352    """
7353    Initializes a syntax tree for the `UNION` operation.
7354
7355    Example:
7356        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7357        'SELECT * FROM foo UNION SELECT * FROM bla'
7358
7359    Args:
7360        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7361            If `Expression` instances are passed, they will be used as-is.
7362        distinct: set the DISTINCT flag if and only if this is true.
7363        dialect: the dialect used to parse the input expression.
7364        copy: whether to copy the expression.
7365        opts: other options to use to parse the input expressions.
7366
7367    Returns:
7368        The new Union instance.
7369    """
7370    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7371    return _apply_set_operation(
7372        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7373    )
7374
7375
7376def intersect(
7377    *expressions: ExpOrStr,
7378    distinct: bool = True,
7379    dialect: DialectType = None,
7380    copy: bool = True,
7381    **opts,
7382) -> Intersect:
7383    """
7384    Initializes a syntax tree for the `INTERSECT` operation.
7385
7386    Example:
7387        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7388        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7389
7390    Args:
7391        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7392            If `Expression` instances are passed, they will be used as-is.
7393        distinct: set the DISTINCT flag if and only if this is true.
7394        dialect: the dialect used to parse the input expression.
7395        copy: whether to copy the expression.
7396        opts: other options to use to parse the input expressions.
7397
7398    Returns:
7399        The new Intersect instance.
7400    """
7401    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7402    return _apply_set_operation(
7403        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7404    )
7405
7406
7407def except_(
7408    *expressions: ExpOrStr,
7409    distinct: bool = True,
7410    dialect: DialectType = None,
7411    copy: bool = True,
7412    **opts,
7413) -> Except:
7414    """
7415    Initializes a syntax tree for the `EXCEPT` operation.
7416
7417    Example:
7418        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7419        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7420
7421    Args:
7422        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7423            If `Expression` instances are passed, they will be used as-is.
7424        distinct: set the DISTINCT flag if and only if this is true.
7425        dialect: the dialect used to parse the input expression.
7426        copy: whether to copy the expression.
7427        opts: other options to use to parse the input expressions.
7428
7429    Returns:
7430        The new Except instance.
7431    """
7432    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7433    return _apply_set_operation(
7434        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7435    )
7436
7437
7438def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7439    """
7440    Initializes a syntax tree from one or multiple SELECT expressions.
7441
7442    Example:
7443        >>> select("col1", "col2").from_("tbl").sql()
7444        'SELECT col1, col2 FROM tbl'
7445
7446    Args:
7447        *expressions: the SQL code string to parse as the expressions of a
7448            SELECT statement. If an Expression instance is passed, this is used as-is.
7449        dialect: the dialect used to parse the input expressions (in the case that an
7450            input expression is a SQL string).
7451        **opts: other options to use to parse the input expressions (again, in the case
7452            that an input expression is a SQL string).
7453
7454    Returns:
7455        Select: the syntax tree for the SELECT statement.
7456    """
7457    return Select().select(*expressions, dialect=dialect, **opts)
7458
7459
7460def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7461    """
7462    Initializes a syntax tree from a FROM expression.
7463
7464    Example:
7465        >>> from_("tbl").select("col1", "col2").sql()
7466        'SELECT col1, col2 FROM tbl'
7467
7468    Args:
7469        *expression: the SQL code string to parse as the FROM expressions of a
7470            SELECT statement. If an Expression instance is passed, this is used as-is.
7471        dialect: the dialect used to parse the input expression (in the case that the
7472            input expression is a SQL string).
7473        **opts: other options to use to parse the input expressions (again, in the case
7474            that the input expression is a SQL string).
7475
7476    Returns:
7477        Select: the syntax tree for the SELECT statement.
7478    """
7479    return Select().from_(expression, dialect=dialect, **opts)
7480
7481
7482def update(
7483    table: str | Table,
7484    properties: t.Optional[dict] = None,
7485    where: t.Optional[ExpOrStr] = None,
7486    from_: t.Optional[ExpOrStr] = None,
7487    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7488    dialect: DialectType = None,
7489    **opts,
7490) -> Update:
7491    """
7492    Creates an update statement.
7493
7494    Example:
7495        >>> 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()
7496        "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"
7497
7498    Args:
7499        properties: dictionary of properties to SET which are
7500            auto converted to sql objects eg None -> NULL
7501        where: sql conditional parsed into a WHERE statement
7502        from_: sql statement parsed into a FROM statement
7503        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7504        dialect: the dialect used to parse the input expressions.
7505        **opts: other options to use to parse the input expressions.
7506
7507    Returns:
7508        Update: the syntax tree for the UPDATE statement.
7509    """
7510    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7511    if properties:
7512        update_expr.set(
7513            "expressions",
7514            [
7515                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7516                for k, v in properties.items()
7517            ],
7518        )
7519    if from_:
7520        update_expr.set(
7521            "from",
7522            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7523        )
7524    if isinstance(where, Condition):
7525        where = Where(this=where)
7526    if where:
7527        update_expr.set(
7528            "where",
7529            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7530        )
7531    if with_:
7532        cte_list = [
7533            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7534            for alias, qry in with_.items()
7535        ]
7536        update_expr.set(
7537            "with",
7538            With(expressions=cte_list),
7539        )
7540    return update_expr
7541
7542
7543def delete(
7544    table: ExpOrStr,
7545    where: t.Optional[ExpOrStr] = None,
7546    returning: t.Optional[ExpOrStr] = None,
7547    dialect: DialectType = None,
7548    **opts,
7549) -> Delete:
7550    """
7551    Builds a delete statement.
7552
7553    Example:
7554        >>> delete("my_table", where="id > 1").sql()
7555        'DELETE FROM my_table WHERE id > 1'
7556
7557    Args:
7558        where: sql conditional parsed into a WHERE statement
7559        returning: sql conditional parsed into a RETURNING statement
7560        dialect: the dialect used to parse the input expressions.
7561        **opts: other options to use to parse the input expressions.
7562
7563    Returns:
7564        Delete: the syntax tree for the DELETE statement.
7565    """
7566    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7567    if where:
7568        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7569    if returning:
7570        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7571    return delete_expr
7572
7573
7574def insert(
7575    expression: ExpOrStr,
7576    into: ExpOrStr,
7577    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7578    overwrite: t.Optional[bool] = None,
7579    returning: t.Optional[ExpOrStr] = None,
7580    dialect: DialectType = None,
7581    copy: bool = True,
7582    **opts,
7583) -> Insert:
7584    """
7585    Builds an INSERT statement.
7586
7587    Example:
7588        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7589        'INSERT INTO tbl VALUES (1, 2, 3)'
7590
7591    Args:
7592        expression: the sql string or expression of the INSERT statement
7593        into: the tbl to insert data to.
7594        columns: optionally the table's column names.
7595        overwrite: whether to INSERT OVERWRITE or not.
7596        returning: sql conditional parsed into a RETURNING statement
7597        dialect: the dialect used to parse the input expressions.
7598        copy: whether to copy the expression.
7599        **opts: other options to use to parse the input expressions.
7600
7601    Returns:
7602        Insert: the syntax tree for the INSERT statement.
7603    """
7604    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7605    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7606
7607    if columns:
7608        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7609
7610    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7611
7612    if returning:
7613        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7614
7615    return insert
7616
7617
7618def merge(
7619    *when_exprs: ExpOrStr,
7620    into: ExpOrStr,
7621    using: ExpOrStr,
7622    on: ExpOrStr,
7623    returning: t.Optional[ExpOrStr] = None,
7624    dialect: DialectType = None,
7625    copy: bool = True,
7626    **opts,
7627) -> Merge:
7628    """
7629    Builds a MERGE statement.
7630
7631    Example:
7632        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7633        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7634        ...       into="my_table",
7635        ...       using="source_table",
7636        ...       on="my_table.id = source_table.id").sql()
7637        '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)'
7638
7639    Args:
7640        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7641        into: The target table to merge data into.
7642        using: The source table to merge data from.
7643        on: The join condition for the merge.
7644        returning: The columns to return from the merge.
7645        dialect: The dialect used to parse the input expressions.
7646        copy: Whether to copy the expression.
7647        **opts: Other options to use to parse the input expressions.
7648
7649    Returns:
7650        Merge: The syntax tree for the MERGE statement.
7651    """
7652    expressions: t.List[Expression] = []
7653    for when_expr in when_exprs:
7654        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7655        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7656
7657    merge = Merge(
7658        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7659        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7660        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7661        whens=Whens(expressions=expressions),
7662    )
7663    if returning:
7664        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7665
7666    return merge
7667
7668
7669def condition(
7670    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7671) -> Condition:
7672    """
7673    Initialize a logical condition expression.
7674
7675    Example:
7676        >>> condition("x=1").sql()
7677        'x = 1'
7678
7679        This is helpful for composing larger logical syntax trees:
7680        >>> where = condition("x=1")
7681        >>> where = where.and_("y=1")
7682        >>> Select().from_("tbl").select("*").where(where).sql()
7683        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7684
7685    Args:
7686        *expression: the SQL code string to parse.
7687            If an Expression instance is passed, this is used as-is.
7688        dialect: the dialect used to parse the input expression (in the case that the
7689            input expression is a SQL string).
7690        copy: Whether to copy `expression` (only applies to expressions).
7691        **opts: other options to use to parse the input expressions (again, in the case
7692            that the input expression is a SQL string).
7693
7694    Returns:
7695        The new Condition instance
7696    """
7697    return maybe_parse(
7698        expression,
7699        into=Condition,
7700        dialect=dialect,
7701        copy=copy,
7702        **opts,
7703    )
7704
7705
7706def and_(
7707    *expressions: t.Optional[ExpOrStr],
7708    dialect: DialectType = None,
7709    copy: bool = True,
7710    wrap: bool = True,
7711    **opts,
7712) -> Condition:
7713    """
7714    Combine multiple conditions with an AND logical operator.
7715
7716    Example:
7717        >>> and_("x=1", and_("y=1", "z=1")).sql()
7718        'x = 1 AND (y = 1 AND z = 1)'
7719
7720    Args:
7721        *expressions: the SQL code strings to parse.
7722            If an Expression instance is passed, this is used as-is.
7723        dialect: the dialect used to parse the input expression.
7724        copy: whether to copy `expressions` (only applies to Expressions).
7725        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7726            precedence issues, but can be turned off when the produced AST is too deep and
7727            causes recursion-related issues.
7728        **opts: other options to use to parse the input expressions.
7729
7730    Returns:
7731        The new condition
7732    """
7733    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
7734
7735
7736def or_(
7737    *expressions: t.Optional[ExpOrStr],
7738    dialect: DialectType = None,
7739    copy: bool = True,
7740    wrap: bool = True,
7741    **opts,
7742) -> Condition:
7743    """
7744    Combine multiple conditions with an OR logical operator.
7745
7746    Example:
7747        >>> or_("x=1", or_("y=1", "z=1")).sql()
7748        'x = 1 OR (y = 1 OR z = 1)'
7749
7750    Args:
7751        *expressions: the SQL code strings to parse.
7752            If an Expression instance is passed, this is used as-is.
7753        dialect: the dialect used to parse the input expression.
7754        copy: whether to copy `expressions` (only applies to Expressions).
7755        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7756            precedence issues, but can be turned off when the produced AST is too deep and
7757            causes recursion-related issues.
7758        **opts: other options to use to parse the input expressions.
7759
7760    Returns:
7761        The new condition
7762    """
7763    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
7764
7765
7766def xor(
7767    *expressions: t.Optional[ExpOrStr],
7768    dialect: DialectType = None,
7769    copy: bool = True,
7770    wrap: bool = True,
7771    **opts,
7772) -> Condition:
7773    """
7774    Combine multiple conditions with an XOR logical operator.
7775
7776    Example:
7777        >>> xor("x=1", xor("y=1", "z=1")).sql()
7778        'x = 1 XOR (y = 1 XOR z = 1)'
7779
7780    Args:
7781        *expressions: the SQL code strings to parse.
7782            If an Expression instance is passed, this is used as-is.
7783        dialect: the dialect used to parse the input expression.
7784        copy: whether to copy `expressions` (only applies to Expressions).
7785        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7786            precedence issues, but can be turned off when the produced AST is too deep and
7787            causes recursion-related issues.
7788        **opts: other options to use to parse the input expressions.
7789
7790    Returns:
7791        The new condition
7792    """
7793    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
7794
7795
7796def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7797    """
7798    Wrap a condition with a NOT operator.
7799
7800    Example:
7801        >>> not_("this_suit='black'").sql()
7802        "NOT this_suit = 'black'"
7803
7804    Args:
7805        expression: the SQL code string to parse.
7806            If an Expression instance is passed, this is used as-is.
7807        dialect: the dialect used to parse the input expression.
7808        copy: whether to copy the expression or not.
7809        **opts: other options to use to parse the input expressions.
7810
7811    Returns:
7812        The new condition.
7813    """
7814    this = condition(
7815        expression,
7816        dialect=dialect,
7817        copy=copy,
7818        **opts,
7819    )
7820    return Not(this=_wrap(this, Connector))
7821
7822
7823def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7824    """
7825    Wrap an expression in parentheses.
7826
7827    Example:
7828        >>> paren("5 + 3").sql()
7829        '(5 + 3)'
7830
7831    Args:
7832        expression: the SQL code string to parse.
7833            If an Expression instance is passed, this is used as-is.
7834        copy: whether to copy the expression or not.
7835
7836    Returns:
7837        The wrapped expression.
7838    """
7839    return Paren(this=maybe_parse(expression, copy=copy))
7840
7841
7842SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
7843
7844
7845@t.overload
7846def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
7847
7848
7849@t.overload
7850def to_identifier(
7851    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
7852) -> Identifier: ...
7853
7854
7855def to_identifier(name, quoted=None, copy=True):
7856    """Builds an identifier.
7857
7858    Args:
7859        name: The name to turn into an identifier.
7860        quoted: Whether to force quote the identifier.
7861        copy: Whether to copy name if it's an Identifier.
7862
7863    Returns:
7864        The identifier ast node.
7865    """
7866
7867    if name is None:
7868        return None
7869
7870    if isinstance(name, Identifier):
7871        identifier = maybe_copy(name, copy)
7872    elif isinstance(name, str):
7873        identifier = Identifier(
7874            this=name,
7875            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7876        )
7877    else:
7878        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7879    return identifier
7880
7881
7882def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7883    """
7884    Parses a given string into an identifier.
7885
7886    Args:
7887        name: The name to parse into an identifier.
7888        dialect: The dialect to parse against.
7889
7890    Returns:
7891        The identifier ast node.
7892    """
7893    try:
7894        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7895    except (ParseError, TokenError):
7896        expression = to_identifier(name)
7897
7898    return expression
7899
7900
7901INTERVAL_STRING_RE = re.compile(r"\s*(-?[0-9]+)\s*([a-zA-Z]+)\s*")
7902
7903
7904def to_interval(interval: str | Literal) -> Interval:
7905    """Builds an interval expression from a string like '1 day' or '5 months'."""
7906    if isinstance(interval, Literal):
7907        if not interval.is_string:
7908            raise ValueError("Invalid interval string.")
7909
7910        interval = interval.this
7911
7912    interval = maybe_parse(f"INTERVAL {interval}")
7913    assert isinstance(interval, Interval)
7914    return interval
7915
7916
7917def to_table(
7918    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7919) -> Table:
7920    """
7921    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7922    If a table is passed in then that table is returned.
7923
7924    Args:
7925        sql_path: a `[catalog].[schema].[table]` string.
7926        dialect: the source dialect according to which the table name will be parsed.
7927        copy: Whether to copy a table if it is passed in.
7928        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7929
7930    Returns:
7931        A table expression.
7932    """
7933    if isinstance(sql_path, Table):
7934        return maybe_copy(sql_path, copy=copy)
7935
7936    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7937
7938    for k, v in kwargs.items():
7939        table.set(k, v)
7940
7941    return table
7942
7943
7944def to_column(
7945    sql_path: str | Column,
7946    quoted: t.Optional[bool] = None,
7947    dialect: DialectType = None,
7948    copy: bool = True,
7949    **kwargs,
7950) -> Column:
7951    """
7952    Create a column from a `[table].[column]` sql path. Table is optional.
7953    If a column is passed in then that column is returned.
7954
7955    Args:
7956        sql_path: a `[table].[column]` string.
7957        quoted: Whether or not to force quote identifiers.
7958        dialect: the source dialect according to which the column name will be parsed.
7959        copy: Whether to copy a column if it is passed in.
7960        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7961
7962    Returns:
7963        A column expression.
7964    """
7965    if isinstance(sql_path, Column):
7966        return maybe_copy(sql_path, copy=copy)
7967
7968    try:
7969        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7970    except ParseError:
7971        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7972
7973    for k, v in kwargs.items():
7974        col.set(k, v)
7975
7976    if quoted:
7977        for i in col.find_all(Identifier):
7978            i.set("quoted", True)
7979
7980    return col
7981
7982
7983def alias_(
7984    expression: ExpOrStr,
7985    alias: t.Optional[str | Identifier],
7986    table: bool | t.Sequence[str | Identifier] = False,
7987    quoted: t.Optional[bool] = None,
7988    dialect: DialectType = None,
7989    copy: bool = True,
7990    **opts,
7991):
7992    """Create an Alias expression.
7993
7994    Example:
7995        >>> alias_('foo', 'bar').sql()
7996        'foo AS bar'
7997
7998        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7999        '(SELECT 1, 2) AS bar(a, b)'
8000
8001    Args:
8002        expression: the SQL code strings to parse.
8003            If an Expression instance is passed, this is used as-is.
8004        alias: the alias name to use. If the name has
8005            special characters it is quoted.
8006        table: Whether to create a table alias, can also be a list of columns.
8007        quoted: whether to quote the alias
8008        dialect: the dialect used to parse the input expression.
8009        copy: Whether to copy the expression.
8010        **opts: other options to use to parse the input expressions.
8011
8012    Returns:
8013        Alias: the aliased expression
8014    """
8015    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8016    alias = to_identifier(alias, quoted=quoted)
8017
8018    if table:
8019        table_alias = TableAlias(this=alias)
8020        exp.set("alias", table_alias)
8021
8022        if not isinstance(table, bool):
8023            for column in table:
8024                table_alias.append("columns", to_identifier(column, quoted=quoted))
8025
8026        return exp
8027
8028    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8029    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8030    # for the complete Window expression.
8031    #
8032    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8033
8034    if "alias" in exp.arg_types and not isinstance(exp, Window):
8035        exp.set("alias", alias)
8036        return exp
8037    return Alias(this=exp, alias=alias)
8038
8039
8040def subquery(
8041    expression: ExpOrStr,
8042    alias: t.Optional[Identifier | str] = None,
8043    dialect: DialectType = None,
8044    **opts,
8045) -> Select:
8046    """
8047    Build a subquery expression that's selected from.
8048
8049    Example:
8050        >>> subquery('select x from tbl', 'bar').select('x').sql()
8051        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8052
8053    Args:
8054        expression: the SQL code strings to parse.
8055            If an Expression instance is passed, this is used as-is.
8056        alias: the alias name to use.
8057        dialect: the dialect used to parse the input expression.
8058        **opts: other options to use to parse the input expressions.
8059
8060    Returns:
8061        A new Select instance with the subquery expression included.
8062    """
8063
8064    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8065    return Select().from_(expression, dialect=dialect, **opts)
8066
8067
8068@t.overload
8069def column(
8070    col: str | Identifier,
8071    table: t.Optional[str | Identifier] = None,
8072    db: t.Optional[str | Identifier] = None,
8073    catalog: t.Optional[str | Identifier] = None,
8074    *,
8075    fields: t.Collection[t.Union[str, Identifier]],
8076    quoted: t.Optional[bool] = None,
8077    copy: bool = True,
8078) -> Dot:
8079    pass
8080
8081
8082@t.overload
8083def column(
8084    col: str | Identifier,
8085    table: t.Optional[str | Identifier] = None,
8086    db: t.Optional[str | Identifier] = None,
8087    catalog: t.Optional[str | Identifier] = None,
8088    *,
8089    fields: Lit[None] = None,
8090    quoted: t.Optional[bool] = None,
8091    copy: bool = True,
8092) -> Column:
8093    pass
8094
8095
8096def column(
8097    col,
8098    table=None,
8099    db=None,
8100    catalog=None,
8101    *,
8102    fields=None,
8103    quoted=None,
8104    copy=True,
8105):
8106    """
8107    Build a Column.
8108
8109    Args:
8110        col: Column name.
8111        table: Table name.
8112        db: Database name.
8113        catalog: Catalog name.
8114        fields: Additional fields using dots.
8115        quoted: Whether to force quotes on the column's identifiers.
8116        copy: Whether to copy identifiers if passed in.
8117
8118    Returns:
8119        The new Column instance.
8120    """
8121    this = Column(
8122        this=to_identifier(col, quoted=quoted, copy=copy),
8123        table=to_identifier(table, quoted=quoted, copy=copy),
8124        db=to_identifier(db, quoted=quoted, copy=copy),
8125        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8126    )
8127
8128    if fields:
8129        this = Dot.build(
8130            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8131        )
8132    return this
8133
8134
8135def cast(
8136    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8137) -> Cast:
8138    """Cast an expression to a data type.
8139
8140    Example:
8141        >>> cast('x + 1', 'int').sql()
8142        'CAST(x + 1 AS INT)'
8143
8144    Args:
8145        expression: The expression to cast.
8146        to: The datatype to cast to.
8147        copy: Whether to copy the supplied expressions.
8148        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8149            - The expression to be cast is already a exp.Cast expression
8150            - The existing cast is to a type that is logically equivalent to new type
8151
8152            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8153            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8154            and instead just return the original expression `CAST(x as DATETIME)`.
8155
8156            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8157            mapping is applied in the target dialect generator.
8158
8159    Returns:
8160        The new Cast instance.
8161    """
8162    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8163    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8164
8165    # dont re-cast if the expression is already a cast to the correct type
8166    if isinstance(expr, Cast):
8167        from sqlglot.dialects.dialect import Dialect
8168
8169        target_dialect = Dialect.get_or_raise(dialect)
8170        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8171
8172        existing_cast_type: DataType.Type = expr.to.this
8173        new_cast_type: DataType.Type = data_type.this
8174        types_are_equivalent = type_mapping.get(
8175            existing_cast_type, existing_cast_type.value
8176        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8177
8178        if expr.is_type(data_type) or types_are_equivalent:
8179            return expr
8180
8181    expr = Cast(this=expr, to=data_type)
8182    expr.type = data_type
8183
8184    return expr
8185
8186
8187def table_(
8188    table: Identifier | str,
8189    db: t.Optional[Identifier | str] = None,
8190    catalog: t.Optional[Identifier | str] = None,
8191    quoted: t.Optional[bool] = None,
8192    alias: t.Optional[Identifier | str] = None,
8193) -> Table:
8194    """Build a Table.
8195
8196    Args:
8197        table: Table name.
8198        db: Database name.
8199        catalog: Catalog name.
8200        quote: Whether to force quotes on the table's identifiers.
8201        alias: Table's alias.
8202
8203    Returns:
8204        The new Table instance.
8205    """
8206    return Table(
8207        this=to_identifier(table, quoted=quoted) if table else None,
8208        db=to_identifier(db, quoted=quoted) if db else None,
8209        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8210        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8211    )
8212
8213
8214def values(
8215    values: t.Iterable[t.Tuple[t.Any, ...]],
8216    alias: t.Optional[str] = None,
8217    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8218) -> Values:
8219    """Build VALUES statement.
8220
8221    Example:
8222        >>> values([(1, '2')]).sql()
8223        "VALUES (1, '2')"
8224
8225    Args:
8226        values: values statements that will be converted to SQL
8227        alias: optional alias
8228        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8229         If either are provided then an alias is also required.
8230
8231    Returns:
8232        Values: the Values expression object
8233    """
8234    if columns and not alias:
8235        raise ValueError("Alias is required when providing columns")
8236
8237    return Values(
8238        expressions=[convert(tup) for tup in values],
8239        alias=(
8240            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8241            if columns
8242            else (TableAlias(this=to_identifier(alias)) if alias else None)
8243        ),
8244    )
8245
8246
8247def var(name: t.Optional[ExpOrStr]) -> Var:
8248    """Build a SQL variable.
8249
8250    Example:
8251        >>> repr(var('x'))
8252        'Var(this=x)'
8253
8254        >>> repr(var(column('x', table='y')))
8255        'Var(this=x)'
8256
8257    Args:
8258        name: The name of the var or an expression who's name will become the var.
8259
8260    Returns:
8261        The new variable node.
8262    """
8263    if not name:
8264        raise ValueError("Cannot convert empty name into var.")
8265
8266    if isinstance(name, Expression):
8267        name = name.name
8268    return Var(this=name)
8269
8270
8271def rename_table(
8272    old_name: str | Table,
8273    new_name: str | Table,
8274    dialect: DialectType = None,
8275) -> Alter:
8276    """Build ALTER TABLE... RENAME... expression
8277
8278    Args:
8279        old_name: The old name of the table
8280        new_name: The new name of the table
8281        dialect: The dialect to parse the table.
8282
8283    Returns:
8284        Alter table expression
8285    """
8286    old_table = to_table(old_name, dialect=dialect)
8287    new_table = to_table(new_name, dialect=dialect)
8288    return Alter(
8289        this=old_table,
8290        kind="TABLE",
8291        actions=[
8292            AlterRename(this=new_table),
8293        ],
8294    )
8295
8296
8297def rename_column(
8298    table_name: str | Table,
8299    old_column_name: str | Column,
8300    new_column_name: str | Column,
8301    exists: t.Optional[bool] = None,
8302    dialect: DialectType = None,
8303) -> Alter:
8304    """Build ALTER TABLE... RENAME COLUMN... expression
8305
8306    Args:
8307        table_name: Name of the table
8308        old_column: The old name of the column
8309        new_column: The new name of the column
8310        exists: Whether to add the `IF EXISTS` clause
8311        dialect: The dialect to parse the table/column.
8312
8313    Returns:
8314        Alter table expression
8315    """
8316    table = to_table(table_name, dialect=dialect)
8317    old_column = to_column(old_column_name, dialect=dialect)
8318    new_column = to_column(new_column_name, dialect=dialect)
8319    return Alter(
8320        this=table,
8321        kind="TABLE",
8322        actions=[
8323            RenameColumn(this=old_column, to=new_column, exists=exists),
8324        ],
8325    )
8326
8327
8328def convert(value: t.Any, copy: bool = False) -> Expression:
8329    """Convert a python value into an expression object.
8330
8331    Raises an error if a conversion is not possible.
8332
8333    Args:
8334        value: A python object.
8335        copy: Whether to copy `value` (only applies to Expressions and collections).
8336
8337    Returns:
8338        The equivalent expression object.
8339    """
8340    if isinstance(value, Expression):
8341        return maybe_copy(value, copy)
8342    if isinstance(value, str):
8343        return Literal.string(value)
8344    if isinstance(value, bool):
8345        return Boolean(this=value)
8346    if value is None or (isinstance(value, float) and math.isnan(value)):
8347        return null()
8348    if isinstance(value, numbers.Number):
8349        return Literal.number(value)
8350    if isinstance(value, bytes):
8351        return HexString(this=value.hex())
8352    if isinstance(value, datetime.datetime):
8353        datetime_literal = Literal.string(value.isoformat(sep=" "))
8354
8355        tz = None
8356        if value.tzinfo:
8357            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8358            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8359            tz = Literal.string(str(value.tzinfo))
8360
8361        return TimeStrToTime(this=datetime_literal, zone=tz)
8362    if isinstance(value, datetime.date):
8363        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8364        return DateStrToDate(this=date_literal)
8365    if isinstance(value, tuple):
8366        if hasattr(value, "_fields"):
8367            return Struct(
8368                expressions=[
8369                    PropertyEQ(
8370                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8371                    )
8372                    for k in value._fields
8373                ]
8374            )
8375        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8376    if isinstance(value, list):
8377        return Array(expressions=[convert(v, copy=copy) for v in value])
8378    if isinstance(value, dict):
8379        return Map(
8380            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8381            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8382        )
8383    if hasattr(value, "__dict__"):
8384        return Struct(
8385            expressions=[
8386                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8387                for k, v in value.__dict__.items()
8388            ]
8389        )
8390    raise ValueError(f"Cannot convert {value}")
8391
8392
8393def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8394    """
8395    Replace children of an expression with the result of a lambda fun(child) -> exp.
8396    """
8397    for k, v in tuple(expression.args.items()):
8398        is_list_arg = type(v) is list
8399
8400        child_nodes = v if is_list_arg else [v]
8401        new_child_nodes = []
8402
8403        for cn in child_nodes:
8404            if isinstance(cn, Expression):
8405                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8406                    new_child_nodes.append(child_node)
8407            else:
8408                new_child_nodes.append(cn)
8409
8410        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
8411
8412
8413def replace_tree(
8414    expression: Expression,
8415    fun: t.Callable,
8416    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8417) -> Expression:
8418    """
8419    Replace an entire tree with the result of function calls on each node.
8420
8421    This will be traversed in reverse dfs, so leaves first.
8422    If new nodes are created as a result of function calls, they will also be traversed.
8423    """
8424    stack = list(expression.dfs(prune=prune))
8425
8426    while stack:
8427        node = stack.pop()
8428        new_node = fun(node)
8429
8430        if new_node is not node:
8431            node.replace(new_node)
8432
8433            if isinstance(new_node, Expression):
8434                stack.append(new_node)
8435
8436    return new_node
8437
8438
8439def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8440    """
8441    Return all table names referenced through columns in an expression.
8442
8443    Example:
8444        >>> import sqlglot
8445        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8446        ['a', 'c']
8447
8448    Args:
8449        expression: expression to find table names.
8450        exclude: a table name to exclude
8451
8452    Returns:
8453        A list of unique names.
8454    """
8455    return {
8456        table
8457        for table in (column.table for column in expression.find_all(Column))
8458        if table and table != exclude
8459    }
8460
8461
8462def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8463    """Get the full name of a table as a string.
8464
8465    Args:
8466        table: Table expression node or string.
8467        dialect: The dialect to generate the table name for.
8468        identify: Determines when an identifier should be quoted. Possible values are:
8469            False (default): Never quote, except in cases where it's mandatory by the dialect.
8470            True: Always quote.
8471
8472    Examples:
8473        >>> from sqlglot import exp, parse_one
8474        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8475        'a.b.c'
8476
8477    Returns:
8478        The table name.
8479    """
8480
8481    table = maybe_parse(table, into=Table, dialect=dialect)
8482
8483    if not table:
8484        raise ValueError(f"Cannot parse {table}")
8485
8486    return ".".join(
8487        (
8488            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8489            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8490            else part.name
8491        )
8492        for part in table.parts
8493    )
8494
8495
8496def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8497    """Returns a case normalized table name without quotes.
8498
8499    Args:
8500        table: the table to normalize
8501        dialect: the dialect to use for normalization rules
8502        copy: whether to copy the expression.
8503
8504    Examples:
8505        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8506        'A-B.c'
8507    """
8508    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8509
8510    return ".".join(
8511        p.name
8512        for p in normalize_identifiers(
8513            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8514        ).parts
8515    )
8516
8517
8518def replace_tables(
8519    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8520) -> E:
8521    """Replace all tables in expression according to the mapping.
8522
8523    Args:
8524        expression: expression node to be transformed and replaced.
8525        mapping: mapping of table names.
8526        dialect: the dialect of the mapping table
8527        copy: whether to copy the expression.
8528
8529    Examples:
8530        >>> from sqlglot import exp, parse_one
8531        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8532        'SELECT * FROM c /* a.b */'
8533
8534    Returns:
8535        The mapped expression.
8536    """
8537
8538    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8539
8540    def _replace_tables(node: Expression) -> Expression:
8541        if isinstance(node, Table) and node.meta.get("replace") is not False:
8542            original = normalize_table_name(node, dialect=dialect)
8543            new_name = mapping.get(original)
8544
8545            if new_name:
8546                table = to_table(
8547                    new_name,
8548                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8549                    dialect=dialect,
8550                )
8551                table.add_comments([original])
8552                return table
8553        return node
8554
8555    return expression.transform(_replace_tables, copy=copy)  # type: ignore
8556
8557
8558def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8559    """Replace placeholders in an expression.
8560
8561    Args:
8562        expression: expression node to be transformed and replaced.
8563        args: positional names that will substitute unnamed placeholders in the given order.
8564        kwargs: keyword arguments that will substitute named placeholders.
8565
8566    Examples:
8567        >>> from sqlglot import exp, parse_one
8568        >>> replace_placeholders(
8569        ...     parse_one("select * from :tbl where ? = ?"),
8570        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8571        ... ).sql()
8572        "SELECT * FROM foo WHERE str_col = 'b'"
8573
8574    Returns:
8575        The mapped expression.
8576    """
8577
8578    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8579        if isinstance(node, Placeholder):
8580            if node.this:
8581                new_name = kwargs.get(node.this)
8582                if new_name is not None:
8583                    return convert(new_name)
8584            else:
8585                try:
8586                    return convert(next(args))
8587                except StopIteration:
8588                    pass
8589        return node
8590
8591    return expression.transform(_replace_placeholders, iter(args), **kwargs)
8592
8593
8594def expand(
8595    expression: Expression,
8596    sources: t.Dict[str, Query | t.Callable[[], Query]],
8597    dialect: DialectType = None,
8598    copy: bool = True,
8599) -> Expression:
8600    """Transforms an expression by expanding all referenced sources into subqueries.
8601
8602    Examples:
8603        >>> from sqlglot import parse_one
8604        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8605        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8606
8607        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8608        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8609
8610    Args:
8611        expression: The expression to expand.
8612        sources: A dict of name to query or a callable that provides a query on demand.
8613        dialect: The dialect of the sources dict or the callable.
8614        copy: Whether to copy the expression during transformation. Defaults to True.
8615
8616    Returns:
8617        The transformed expression.
8618    """
8619    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8620
8621    def _expand(node: Expression):
8622        if isinstance(node, Table):
8623            name = normalize_table_name(node, dialect=dialect)
8624            source = normalized_sources.get(name)
8625
8626            if source:
8627                # Create a subquery with the same alias (or table name if no alias)
8628                parsed_source = source() if callable(source) else source
8629                subquery = parsed_source.subquery(node.alias or name)
8630                subquery.comments = [f"source: {name}"]
8631
8632                # Continue expanding within the subquery
8633                return subquery.transform(_expand, copy=False)
8634
8635        return node
8636
8637    return expression.transform(_expand, copy=copy)
8638
8639
8640def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8641    """
8642    Returns a Func expression.
8643
8644    Examples:
8645        >>> func("abs", 5).sql()
8646        'ABS(5)'
8647
8648        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8649        'CAST(5 AS DOUBLE)'
8650
8651    Args:
8652        name: the name of the function to build.
8653        args: the args used to instantiate the function of interest.
8654        copy: whether to copy the argument expressions.
8655        dialect: the source dialect.
8656        kwargs: the kwargs used to instantiate the function of interest.
8657
8658    Note:
8659        The arguments `args` and `kwargs` are mutually exclusive.
8660
8661    Returns:
8662        An instance of the function of interest, or an anonymous function, if `name` doesn't
8663        correspond to an existing `sqlglot.expressions.Func` class.
8664    """
8665    if args and kwargs:
8666        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8667
8668    from sqlglot.dialects.dialect import Dialect
8669
8670    dialect = Dialect.get_or_raise(dialect)
8671
8672    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8673    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8674
8675    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8676    if constructor:
8677        if converted:
8678            if "dialect" in constructor.__code__.co_varnames:
8679                function = constructor(converted, dialect=dialect)
8680            else:
8681                function = constructor(converted)
8682        elif constructor.__name__ == "from_arg_list":
8683            function = constructor.__self__(**kwargs)  # type: ignore
8684        else:
8685            constructor = FUNCTION_BY_NAME.get(name.upper())
8686            if constructor:
8687                function = constructor(**kwargs)
8688            else:
8689                raise ValueError(
8690                    f"Unable to convert '{name}' into a Func. Either manually construct "
8691                    "the Func expression of interest or parse the function call."
8692                )
8693    else:
8694        kwargs = kwargs or {"expressions": converted}
8695        function = Anonymous(this=name, **kwargs)
8696
8697    for error_message in function.error_messages(converted):
8698        raise ValueError(error_message)
8699
8700    return function
8701
8702
8703def case(
8704    expression: t.Optional[ExpOrStr] = None,
8705    **opts,
8706) -> Case:
8707    """
8708    Initialize a CASE statement.
8709
8710    Example:
8711        case().when("a = 1", "foo").else_("bar")
8712
8713    Args:
8714        expression: Optionally, the input expression (not all dialects support this)
8715        **opts: Extra keyword arguments for parsing `expression`
8716    """
8717    if expression is not None:
8718        this = maybe_parse(expression, **opts)
8719    else:
8720        this = None
8721    return Case(this=this, ifs=[])
8722
8723
8724def array(
8725    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8726) -> Array:
8727    """
8728    Returns an array.
8729
8730    Examples:
8731        >>> array(1, 'x').sql()
8732        'ARRAY(1, x)'
8733
8734    Args:
8735        expressions: the expressions to add to the array.
8736        copy: whether to copy the argument expressions.
8737        dialect: the source dialect.
8738        kwargs: the kwargs used to instantiate the function of interest.
8739
8740    Returns:
8741        An array expression.
8742    """
8743    return Array(
8744        expressions=[
8745            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8746            for expression in expressions
8747        ]
8748    )
8749
8750
8751def tuple_(
8752    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8753) -> Tuple:
8754    """
8755    Returns an tuple.
8756
8757    Examples:
8758        >>> tuple_(1, 'x').sql()
8759        '(1, x)'
8760
8761    Args:
8762        expressions: the expressions to add to the tuple.
8763        copy: whether to copy the argument expressions.
8764        dialect: the source dialect.
8765        kwargs: the kwargs used to instantiate the function of interest.
8766
8767    Returns:
8768        A tuple expression.
8769    """
8770    return Tuple(
8771        expressions=[
8772            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8773            for expression in expressions
8774        ]
8775    )
8776
8777
8778def true() -> Boolean:
8779    """
8780    Returns a true Boolean expression.
8781    """
8782    return Boolean(this=True)
8783
8784
8785def false() -> Boolean:
8786    """
8787    Returns a false Boolean expression.
8788    """
8789    return Boolean(this=False)
8790
8791
8792def null() -> Null:
8793    """
8794    Returns a Null expression.
8795    """
8796    return Null()
8797
8798
8799NONNULL_CONSTANTS = (
8800    Literal,
8801    Boolean,
8802)
8803
8804CONSTANTS = (
8805    Literal,
8806    Boolean,
8807    Null,
8808)
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    }
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
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False}
method: str
2503    @property
2504    def method(self) -> str:
2505        return self.text("method").upper()
kind: str
2507    @property
2508    def kind(self) -> str:
2509        return self.text("kind").upper()
side: str
2511    @property
2512    def side(self) -> str:
2513        return self.text("side").upper()
hint: str
2515    @property
2516    def hint(self) -> str:
2517        return self.text("hint").upper()
alias_or_name: str
2519    @property
2520    def alias_or_name(self) -> str:
2521        return self.this.alias_or_name
is_semi_or_anti_join: bool
2523    @property
2524    def is_semi_or_anti_join(self) -> bool:
2525        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:
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

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

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):
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    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2628class TableFromRows(UDTF):
2629    arg_types = {
2630        "this": True,
2631        "alias": False,
2632        "joins": False,
2633        "pivots": False,
2634        "sample": False,
2635    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2638class MatchRecognizeMeasure(Expression):
2639    arg_types = {
2640        "this": True,
2641        "window_frame": False,
2642    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
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    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2660class Final(Expression):
2661    pass
key = 'final'
class Offset(Expression):
2664class Offset(Expression):
2665    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2668class Order(Expression):
2669    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2673class WithFill(Expression):
2674    arg_types = {
2675        "from": False,
2676        "to": False,
2677        "step": False,
2678        "interpolate": False,
2679    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2684class Cluster(Order):
2685    pass
key = 'cluster'
class Distribute(Order):
2688class Distribute(Order):
2689    pass
key = 'distribute'
class Sort(Order):
2692class Sort(Order):
2693    pass
key = 'sort'
class Ordered(Expression):
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
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2699    @property
2700    def name(self) -> str:
2701        return self.this.name
key = 'ordered'
class Property(Expression):
2704class Property(Expression):
2705    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2708class GrantPrivilege(Expression):
2709    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2712class GrantPrincipal(Expression):
2713    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2716class AllowedValuesProperty(Expression):
2717    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2720class AlgorithmProperty(Property):
2721    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2724class AutoIncrementProperty(Property):
2725    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2729class AutoRefreshProperty(Property):
2730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2733class BackupProperty(Property):
2734    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2737class BlockCompressionProperty(Property):
2738    arg_types = {
2739        "autotemp": False,
2740        "always": False,
2741        "default": False,
2742        "manual": False,
2743        "never": False,
2744    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2747class CharacterSetProperty(Property):
2748    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2751class ChecksumProperty(Property):
2752    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2755class CollateProperty(Property):
2756    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2759class CopyGrantsProperty(Property):
2760    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2763class DataBlocksizeProperty(Property):
2764    arg_types = {
2765        "size": False,
2766        "units": False,
2767        "minimum": False,
2768        "maximum": False,
2769        "default": False,
2770    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2773class DataDeletionProperty(Property):
2774    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):
2777class DefinerProperty(Property):
2778    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2781class DistKeyProperty(Property):
2782    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2787class DistributedByProperty(Property):
2788    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):
2791class DistStyleProperty(Property):
2792    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2795class DuplicateKeyProperty(Property):
2796    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2799class EngineProperty(Property):
2800    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2803class HeapProperty(Property):
2804    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2807class ToTableProperty(Property):
2808    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2811class ExecuteAsProperty(Property):
2812    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2815class ExternalProperty(Property):
2816    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2819class FallbackProperty(Property):
2820    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2823class FileFormatProperty(Property):
2824    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2827class CredentialsProperty(Property):
2828    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2831class FreespaceProperty(Property):
2832    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2835class GlobalProperty(Property):
2836    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2839class IcebergProperty(Property):
2840    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2843class InheritsProperty(Property):
2844    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2847class InputModelProperty(Property):
2848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2851class OutputModelProperty(Property):
2852    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2855class IsolatedLoadingProperty(Property):
2856    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2859class JournalProperty(Property):
2860    arg_types = {
2861        "no": False,
2862        "dual": False,
2863        "before": False,
2864        "local": False,
2865        "after": False,
2866    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2869class LanguageProperty(Property):
2870    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2874class ClusteredByProperty(Property):
2875    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2878class DictProperty(Property):
2879    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2882class DictSubProperty(Property):
2883    pass
key = 'dictsubproperty'
class DictRange(Property):
2886class DictRange(Property):
2887    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2890class DynamicProperty(Property):
2891    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2896class OnCluster(Property):
2897    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2901class EmptyProperty(Property):
2902    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2905class LikeProperty(Property):
2906    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2909class LocationProperty(Property):
2910    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2913class LockProperty(Property):
2914    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2917class LockingProperty(Property):
2918    arg_types = {
2919        "this": False,
2920        "kind": True,
2921        "for_or_in": False,
2922        "lock_type": True,
2923        "override": False,
2924    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2927class LogProperty(Property):
2928    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2931class MaterializedProperty(Property):
2932    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2935class MergeBlockRatioProperty(Property):
2936    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):
2939class NoPrimaryIndexProperty(Property):
2940    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2943class OnProperty(Property):
2944    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2947class OnCommitProperty(Property):
2948    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2951class PartitionedByProperty(Property):
2952    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
2955class PartitionedByBucket(Property):
2956    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
2959class PartitionByTruncate(Property):
2960    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
2964class PartitionByRangeProperty(Property):
2965    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2969class PartitionByRangePropertyDynamic(Expression):
2970    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):
2974class UniqueKeyProperty(Property):
2975    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2979class PartitionBoundSpec(Expression):
2980    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2981    arg_types = {
2982        "this": False,
2983        "expression": False,
2984        "from_expressions": False,
2985        "to_expressions": False,
2986    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2989class PartitionedOfProperty(Property):
2990    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2991    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2994class StreamingTableProperty(Property):
2995    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2998class RemoteWithConnectionModelProperty(Property):
2999    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3002class ReturnsProperty(Property):
3003    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):
3006class StrictProperty(Property):
3007    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3010class RowFormatProperty(Property):
3011    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3014class RowFormatDelimitedProperty(Property):
3015    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3016    arg_types = {
3017        "fields": False,
3018        "escaped": False,
3019        "collection_items": False,
3020        "map_keys": False,
3021        "lines": False,
3022        "null": False,
3023        "serde": False,
3024    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3027class RowFormatSerdeProperty(Property):
3028    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3032class QueryTransform(Expression):
3033    arg_types = {
3034        "expressions": True,
3035        "command_script": True,
3036        "schema": False,
3037        "row_format_before": False,
3038        "record_writer": False,
3039        "row_format_after": False,
3040        "record_reader": False,
3041    }
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):
3044class SampleProperty(Property):
3045    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3049class SecurityProperty(Property):
3050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3053class SchemaCommentProperty(Property):
3054    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
3057class SerdeProperties(Property):
3058    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3061class SetProperty(Property):
3062    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3065class SharingProperty(Property):
3066    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3069class SetConfigProperty(Property):
3070    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3073class SettingsProperty(Property):
3074    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3077class SortKeyProperty(Property):
3078    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3081class SqlReadWriteProperty(Property):
3082    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3085class SqlSecurityProperty(Property):
3086    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3089class StabilityProperty(Property):
3090    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3093class StorageHandlerProperty(Property):
3094    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3097class TemporaryProperty(Property):
3098    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3101class SecureProperty(Property):
3102    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3106class Tags(ColumnConstraintKind, Property):
3107    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3110class TransformModelProperty(Property):
3111    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3114class TransientProperty(Property):
3115    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3118class UnloggedProperty(Property):
3119    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3123class UsingTemplateProperty(Property):
3124    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3128class ViewAttributeProperty(Property):
3129    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3132class VolatileProperty(Property):
3133    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3136class WithDataProperty(Property):
3137    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3140class WithJournalTableProperty(Property):
3141    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3144class WithSchemaBindingProperty(Property):
3145    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3148class WithSystemVersioningProperty(Property):
3149    arg_types = {
3150        "on": False,
3151        "this": False,
3152        "data_consistency": False,
3153        "retention_period": False,
3154        "with": True,
3155    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3158class WithProcedureOptions(Property):
3159    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3162class EncodeProperty(Property):
3163    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3166class IncludeProperty(Property):
3167    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3170class ForceProperty(Property):
3171    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3174class Properties(Expression):
3175    arg_types = {"expressions": True}
3176
3177    NAME_TO_PROPERTY = {
3178        "ALGORITHM": AlgorithmProperty,
3179        "AUTO_INCREMENT": AutoIncrementProperty,
3180        "CHARACTER SET": CharacterSetProperty,
3181        "CLUSTERED_BY": ClusteredByProperty,
3182        "COLLATE": CollateProperty,
3183        "COMMENT": SchemaCommentProperty,
3184        "CREDENTIALS": CredentialsProperty,
3185        "DEFINER": DefinerProperty,
3186        "DISTKEY": DistKeyProperty,
3187        "DISTRIBUTED_BY": DistributedByProperty,
3188        "DISTSTYLE": DistStyleProperty,
3189        "ENGINE": EngineProperty,
3190        "EXECUTE AS": ExecuteAsProperty,
3191        "FORMAT": FileFormatProperty,
3192        "LANGUAGE": LanguageProperty,
3193        "LOCATION": LocationProperty,
3194        "LOCK": LockProperty,
3195        "PARTITIONED_BY": PartitionedByProperty,
3196        "RETURNS": ReturnsProperty,
3197        "ROW_FORMAT": RowFormatProperty,
3198        "SORTKEY": SortKeyProperty,
3199        "ENCODE": EncodeProperty,
3200        "INCLUDE": IncludeProperty,
3201    }
3202
3203    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3204
3205    # CREATE property locations
3206    # Form: schema specified
3207    #   create [POST_CREATE]
3208    #     table a [POST_NAME]
3209    #     (b int) [POST_SCHEMA]
3210    #     with ([POST_WITH])
3211    #     index (b) [POST_INDEX]
3212    #
3213    # Form: alias selection
3214    #   create [POST_CREATE]
3215    #     table a [POST_NAME]
3216    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3217    #     index (c) [POST_INDEX]
3218    class Location(AutoName):
3219        POST_CREATE = auto()
3220        POST_NAME = auto()
3221        POST_SCHEMA = auto()
3222        POST_WITH = auto()
3223        POST_ALIAS = auto()
3224        POST_EXPRESSION = auto()
3225        POST_INDEX = auto()
3226        UNSUPPORTED = auto()
3227
3228    @classmethod
3229    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3230        expressions = []
3231        for key, value in properties_dict.items():
3232            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3233            if property_cls:
3234                expressions.append(property_cls(this=convert(value)))
3235            else:
3236                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3237
3238        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:
3228    @classmethod
3229    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3230        expressions = []
3231        for key, value in properties_dict.items():
3232            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3233            if property_cls:
3234                expressions.append(property_cls(this=convert(value)))
3235            else:
3236                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3237
3238        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3218    class Location(AutoName):
3219        POST_CREATE = auto()
3220        POST_NAME = auto()
3221        POST_SCHEMA = auto()
3222        POST_WITH = auto()
3223        POST_ALIAS = auto()
3224        POST_EXPRESSION = auto()
3225        POST_INDEX = auto()
3226        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):
3241class Qualify(Expression):
3242    pass
key = 'qualify'
class InputOutputFormat(Expression):
3245class InputOutputFormat(Expression):
3246    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3250class Return(Expression):
3251    pass
key = 'return'
class Reference(Expression):
3254class Reference(Expression):
3255    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3258class Tuple(Expression):
3259    arg_types = {"expressions": False}
3260
3261    def isin(
3262        self,
3263        *expressions: t.Any,
3264        query: t.Optional[ExpOrStr] = None,
3265        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3266        copy: bool = True,
3267        **opts,
3268    ) -> In:
3269        return In(
3270            this=maybe_copy(self, copy),
3271            expressions=[convert(e, copy=copy) for e in expressions],
3272            query=maybe_parse(query, copy=copy, **opts) if query else None,
3273            unnest=(
3274                Unnest(
3275                    expressions=[
3276                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3277                        for e in ensure_list(unnest)
3278                    ]
3279                )
3280                if unnest
3281                else None
3282            ),
3283        )
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:
3261    def isin(
3262        self,
3263        *expressions: t.Any,
3264        query: t.Optional[ExpOrStr] = None,
3265        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3266        copy: bool = True,
3267        **opts,
3268    ) -> In:
3269        return In(
3270            this=maybe_copy(self, copy),
3271            expressions=[convert(e, copy=copy) for e in expressions],
3272            query=maybe_parse(query, copy=copy, **opts) if query else None,
3273            unnest=(
3274                Unnest(
3275                    expressions=[
3276                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3277                        for e in ensure_list(unnest)
3278                    ]
3279                )
3280                if unnest
3281                else None
3282            ),
3283        )
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):
3314class QueryOption(Expression):
3315    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3319class WithTableHint(Expression):
3320    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3324class IndexTableHint(Expression):
3325    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3329class HistoricalData(Expression):
3330    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3334class Put(Expression):
3335    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3339class Get(Expression):
3340    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3343class Table(Expression):
3344    arg_types = {
3345        "this": False,
3346        "alias": False,
3347        "db": False,
3348        "catalog": False,
3349        "laterals": False,
3350        "joins": False,
3351        "pivots": False,
3352        "hints": False,
3353        "system_time": False,
3354        "version": False,
3355        "format": False,
3356        "pattern": False,
3357        "ordinality": False,
3358        "when": False,
3359        "only": False,
3360        "partition": False,
3361        "changes": False,
3362        "rows_from": False,
3363        "sample": False,
3364    }
3365
3366    @property
3367    def name(self) -> str:
3368        if not self.this or isinstance(self.this, Func):
3369            return ""
3370        return self.this.name
3371
3372    @property
3373    def db(self) -> str:
3374        return self.text("db")
3375
3376    @property
3377    def catalog(self) -> str:
3378        return self.text("catalog")
3379
3380    @property
3381    def selects(self) -> t.List[Expression]:
3382        return []
3383
3384    @property
3385    def named_selects(self) -> t.List[str]:
3386        return []
3387
3388    @property
3389    def parts(self) -> t.List[Expression]:
3390        """Return the parts of a table in order catalog, db, table."""
3391        parts: t.List[Expression] = []
3392
3393        for arg in ("catalog", "db", "this"):
3394            part = self.args.get(arg)
3395
3396            if isinstance(part, Dot):
3397                parts.extend(part.flatten())
3398            elif isinstance(part, Expression):
3399                parts.append(part)
3400
3401        return parts
3402
3403    def to_column(self, copy: bool = True) -> Expression:
3404        parts = self.parts
3405        last_part = parts[-1]
3406
3407        if isinstance(last_part, Identifier):
3408            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3409        else:
3410            # This branch will be reached if a function or array is wrapped in a `Table`
3411            col = last_part
3412
3413        alias = self.args.get("alias")
3414        if alias:
3415            col = alias_(col, alias.this, copy=copy)
3416
3417        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
3366    @property
3367    def name(self) -> str:
3368        if not self.this or isinstance(self.this, Func):
3369            return ""
3370        return self.this.name
db: str
3372    @property
3373    def db(self) -> str:
3374        return self.text("db")
catalog: str
3376    @property
3377    def catalog(self) -> str:
3378        return self.text("catalog")
selects: List[Expression]
3380    @property
3381    def selects(self) -> t.List[Expression]:
3382        return []
named_selects: List[str]
3384    @property
3385    def named_selects(self) -> t.List[str]:
3386        return []
parts: List[Expression]
3388    @property
3389    def parts(self) -> t.List[Expression]:
3390        """Return the parts of a table in order catalog, db, table."""
3391        parts: t.List[Expression] = []
3392
3393        for arg in ("catalog", "db", "this"):
3394            part = self.args.get(arg)
3395
3396            if isinstance(part, Dot):
3397                parts.extend(part.flatten())
3398            elif isinstance(part, Expression):
3399                parts.append(part)
3400
3401        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3452    @property
3453    def is_star(self) -> bool:
3454        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3456    @property
3457    def selects(self) -> t.List[Expression]:
3458        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

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

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4374class Pivot(Expression):
4375    arg_types = {
4376        "this": False,
4377        "alias": False,
4378        "expressions": False,
4379        "fields": False,
4380        "unpivot": False,
4381        "using": False,
4382        "group": False,
4383        "columns": False,
4384        "include_nulls": False,
4385        "default_on_null": False,
4386        "into": False,
4387    }
4388
4389    @property
4390    def unpivot(self) -> bool:
4391        return bool(self.args.get("unpivot"))
4392
4393    @property
4394    def fields(self) -> t.List[Expression]:
4395        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
4389    @property
4390    def unpivot(self) -> bool:
4391        return bool(self.args.get("unpivot"))
fields: List[Expression]
4393    @property
4394    def fields(self) -> t.List[Expression]:
4395        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4400class UnpivotColumns(Expression):
4401    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4404class Window(Condition):
4405    arg_types = {
4406        "this": True,
4407        "partition_by": False,
4408        "order": False,
4409        "spec": False,
4410        "alias": False,
4411        "over": False,
4412        "first": False,
4413    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4416class WindowSpec(Expression):
4417    arg_types = {
4418        "kind": False,
4419        "start": False,
4420        "start_side": False,
4421        "end": False,
4422        "end_side": False,
4423    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4426class PreWhere(Expression):
4427    pass
key = 'prewhere'
class Where(Expression):
4430class Where(Expression):
4431    pass
key = 'where'
class Star(Expression):
4434class Star(Expression):
4435    arg_types = {"except": False, "replace": False, "rename": False}
4436
4437    @property
4438    def name(self) -> str:
4439        return "*"
4440
4441    @property
4442    def output_name(self) -> str:
4443        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4437    @property
4438    def name(self) -> str:
4439        return "*"
output_name: str
4441    @property
4442    def output_name(self) -> str:
4443        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):
4446class Parameter(Condition):
4447    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4450class SessionParameter(Condition):
4451    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4454class Placeholder(Condition):
4455    arg_types = {"this": False, "kind": False}
4456
4457    @property
4458    def name(self) -> str:
4459        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4457    @property
4458    def name(self) -> str:
4459        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4462class Null(Condition):
4463    arg_types: t.Dict[str, t.Any] = {}
4464
4465    @property
4466    def name(self) -> str:
4467        return "NULL"
4468
4469    def to_py(self) -> Lit[None]:
4470        return None
arg_types: Dict[str, Any] = {}
name: str
4465    @property
4466    def name(self) -> str:
4467        return "NULL"
def to_py(self) -> Literal[None]:
4469    def to_py(self) -> Lit[None]:
4470        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4473class Boolean(Condition):
4474    def to_py(self) -> bool:
4475        return self.this
def to_py(self) -> bool:
4474    def to_py(self) -> bool:
4475        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4478class DataTypeParam(Expression):
4479    arg_types = {"this": True, "expression": False}
4480
4481    @property
4482    def name(self) -> str:
4483        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4481    @property
4482    def name(self) -> str:
4483        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4488class DataType(Expression):
4489    arg_types = {
4490        "this": True,
4491        "expressions": False,
4492        "nested": False,
4493        "values": False,
4494        "prefix": False,
4495        "kind": False,
4496        "nullable": False,
4497    }
4498
4499    class Type(AutoName):
4500        ARRAY = auto()
4501        AGGREGATEFUNCTION = auto()
4502        SIMPLEAGGREGATEFUNCTION = auto()
4503        BIGDECIMAL = auto()
4504        BIGINT = auto()
4505        BIGSERIAL = auto()
4506        BINARY = auto()
4507        BIT = auto()
4508        BLOB = auto()
4509        BOOLEAN = auto()
4510        BPCHAR = auto()
4511        CHAR = auto()
4512        DATE = auto()
4513        DATE32 = auto()
4514        DATEMULTIRANGE = auto()
4515        DATERANGE = auto()
4516        DATETIME = auto()
4517        DATETIME2 = auto()
4518        DATETIME64 = auto()
4519        DECIMAL = auto()
4520        DECIMAL32 = auto()
4521        DECIMAL64 = auto()
4522        DECIMAL128 = auto()
4523        DECIMAL256 = auto()
4524        DOUBLE = auto()
4525        DYNAMIC = auto()
4526        ENUM = auto()
4527        ENUM8 = auto()
4528        ENUM16 = auto()
4529        FIXEDSTRING = auto()
4530        FLOAT = auto()
4531        GEOGRAPHY = auto()
4532        GEOMETRY = auto()
4533        POINT = auto()
4534        RING = auto()
4535        LINESTRING = auto()
4536        MULTILINESTRING = auto()
4537        POLYGON = auto()
4538        MULTIPOLYGON = auto()
4539        HLLSKETCH = auto()
4540        HSTORE = auto()
4541        IMAGE = auto()
4542        INET = auto()
4543        INT = auto()
4544        INT128 = auto()
4545        INT256 = auto()
4546        INT4MULTIRANGE = auto()
4547        INT4RANGE = auto()
4548        INT8MULTIRANGE = auto()
4549        INT8RANGE = auto()
4550        INTERVAL = auto()
4551        IPADDRESS = auto()
4552        IPPREFIX = auto()
4553        IPV4 = auto()
4554        IPV6 = auto()
4555        JSON = auto()
4556        JSONB = auto()
4557        LIST = auto()
4558        LONGBLOB = auto()
4559        LONGTEXT = auto()
4560        LOWCARDINALITY = auto()
4561        MAP = auto()
4562        MEDIUMBLOB = auto()
4563        MEDIUMINT = auto()
4564        MEDIUMTEXT = auto()
4565        MONEY = auto()
4566        NAME = auto()
4567        NCHAR = auto()
4568        NESTED = auto()
4569        NOTHING = auto()
4570        NULL = auto()
4571        NUMMULTIRANGE = auto()
4572        NUMRANGE = auto()
4573        NVARCHAR = auto()
4574        OBJECT = auto()
4575        RANGE = auto()
4576        ROWVERSION = auto()
4577        SERIAL = auto()
4578        SET = auto()
4579        SMALLDATETIME = auto()
4580        SMALLINT = auto()
4581        SMALLMONEY = auto()
4582        SMALLSERIAL = auto()
4583        STRUCT = auto()
4584        SUPER = auto()
4585        TEXT = auto()
4586        TINYBLOB = auto()
4587        TINYTEXT = auto()
4588        TIME = auto()
4589        TIMETZ = auto()
4590        TIMESTAMP = auto()
4591        TIMESTAMPNTZ = auto()
4592        TIMESTAMPLTZ = auto()
4593        TIMESTAMPTZ = auto()
4594        TIMESTAMP_S = auto()
4595        TIMESTAMP_MS = auto()
4596        TIMESTAMP_NS = auto()
4597        TINYINT = auto()
4598        TSMULTIRANGE = auto()
4599        TSRANGE = auto()
4600        TSTZMULTIRANGE = auto()
4601        TSTZRANGE = auto()
4602        UBIGINT = auto()
4603        UINT = auto()
4604        UINT128 = auto()
4605        UINT256 = auto()
4606        UMEDIUMINT = auto()
4607        UDECIMAL = auto()
4608        UDOUBLE = auto()
4609        UNION = auto()
4610        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4611        USERDEFINED = "USER-DEFINED"
4612        USMALLINT = auto()
4613        UTINYINT = auto()
4614        UUID = auto()
4615        VARBINARY = auto()
4616        VARCHAR = auto()
4617        VARIANT = auto()
4618        VECTOR = auto()
4619        XML = auto()
4620        YEAR = auto()
4621        TDIGEST = auto()
4622
4623    STRUCT_TYPES = {
4624        Type.NESTED,
4625        Type.OBJECT,
4626        Type.STRUCT,
4627        Type.UNION,
4628    }
4629
4630    ARRAY_TYPES = {
4631        Type.ARRAY,
4632        Type.LIST,
4633    }
4634
4635    NESTED_TYPES = {
4636        *STRUCT_TYPES,
4637        *ARRAY_TYPES,
4638        Type.MAP,
4639    }
4640
4641    TEXT_TYPES = {
4642        Type.CHAR,
4643        Type.NCHAR,
4644        Type.NVARCHAR,
4645        Type.TEXT,
4646        Type.VARCHAR,
4647        Type.NAME,
4648    }
4649
4650    SIGNED_INTEGER_TYPES = {
4651        Type.BIGINT,
4652        Type.INT,
4653        Type.INT128,
4654        Type.INT256,
4655        Type.MEDIUMINT,
4656        Type.SMALLINT,
4657        Type.TINYINT,
4658    }
4659
4660    UNSIGNED_INTEGER_TYPES = {
4661        Type.UBIGINT,
4662        Type.UINT,
4663        Type.UINT128,
4664        Type.UINT256,
4665        Type.UMEDIUMINT,
4666        Type.USMALLINT,
4667        Type.UTINYINT,
4668    }
4669
4670    INTEGER_TYPES = {
4671        *SIGNED_INTEGER_TYPES,
4672        *UNSIGNED_INTEGER_TYPES,
4673        Type.BIT,
4674    }
4675
4676    FLOAT_TYPES = {
4677        Type.DOUBLE,
4678        Type.FLOAT,
4679    }
4680
4681    REAL_TYPES = {
4682        *FLOAT_TYPES,
4683        Type.BIGDECIMAL,
4684        Type.DECIMAL,
4685        Type.DECIMAL32,
4686        Type.DECIMAL64,
4687        Type.DECIMAL128,
4688        Type.DECIMAL256,
4689        Type.MONEY,
4690        Type.SMALLMONEY,
4691        Type.UDECIMAL,
4692        Type.UDOUBLE,
4693    }
4694
4695    NUMERIC_TYPES = {
4696        *INTEGER_TYPES,
4697        *REAL_TYPES,
4698    }
4699
4700    TEMPORAL_TYPES = {
4701        Type.DATE,
4702        Type.DATE32,
4703        Type.DATETIME,
4704        Type.DATETIME2,
4705        Type.DATETIME64,
4706        Type.SMALLDATETIME,
4707        Type.TIME,
4708        Type.TIMESTAMP,
4709        Type.TIMESTAMPNTZ,
4710        Type.TIMESTAMPLTZ,
4711        Type.TIMESTAMPTZ,
4712        Type.TIMESTAMP_MS,
4713        Type.TIMESTAMP_NS,
4714        Type.TIMESTAMP_S,
4715        Type.TIMETZ,
4716    }
4717
4718    @classmethod
4719    def build(
4720        cls,
4721        dtype: DATA_TYPE,
4722        dialect: DialectType = None,
4723        udt: bool = False,
4724        copy: bool = True,
4725        **kwargs,
4726    ) -> DataType:
4727        """
4728        Constructs a DataType object.
4729
4730        Args:
4731            dtype: the data type of interest.
4732            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4733            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4734                DataType, thus creating a user-defined type.
4735            copy: whether to copy the data type.
4736            kwargs: additional arguments to pass in the constructor of DataType.
4737
4738        Returns:
4739            The constructed DataType object.
4740        """
4741        from sqlglot import parse_one
4742
4743        if isinstance(dtype, str):
4744            if dtype.upper() == "UNKNOWN":
4745                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4746
4747            try:
4748                data_type_exp = parse_one(
4749                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4750                )
4751            except ParseError:
4752                if udt:
4753                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4754                raise
4755        elif isinstance(dtype, DataType.Type):
4756            data_type_exp = DataType(this=dtype)
4757        elif isinstance(dtype, DataType):
4758            return maybe_copy(dtype, copy)
4759        else:
4760            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4761
4762        return DataType(**{**data_type_exp.args, **kwargs})
4763
4764    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4765        """
4766        Checks whether this DataType matches one of the provided data types. Nested types or precision
4767        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4768
4769        Args:
4770            dtypes: the data types to compare this DataType to.
4771            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4772                If false, it means that NULLABLE<INT> is equivalent to INT.
4773
4774        Returns:
4775            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4776        """
4777        self_is_nullable = self.args.get("nullable")
4778        for dtype in dtypes:
4779            other_type = DataType.build(dtype, copy=False, udt=True)
4780            other_is_nullable = other_type.args.get("nullable")
4781            if (
4782                other_type.expressions
4783                or (check_nullable and (self_is_nullable or other_is_nullable))
4784                or self.this == DataType.Type.USERDEFINED
4785                or other_type.this == DataType.Type.USERDEFINED
4786            ):
4787                matches = self == other_type
4788            else:
4789                matches = self.this == other_type.this
4790
4791            if matches:
4792                return True
4793        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.NESTED: 'NESTED'>, <Type.UNION: 'UNION'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>}
ARRAY_TYPES = {<Type.LIST: 'LIST'>, <Type.ARRAY: 'ARRAY'>}
NESTED_TYPES = {<Type.NESTED: 'NESTED'>, <Type.LIST: 'LIST'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.UNION: 'UNION'>, <Type.ARRAY: 'ARRAY'>, <Type.MAP: 'MAP'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>}
INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.BIT: 'BIT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UBIGINT: 'UBIGINT'>, <Type.INT: 'INT'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UINT128: 'UINT128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT: 'UINT'>, <Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>}
TEMPORAL_TYPES = {<Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE32: 'DATE32'>, <Type.DATE: 'DATE'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME2: 'DATETIME2'>}
@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:
4718    @classmethod
4719    def build(
4720        cls,
4721        dtype: DATA_TYPE,
4722        dialect: DialectType = None,
4723        udt: bool = False,
4724        copy: bool = True,
4725        **kwargs,
4726    ) -> DataType:
4727        """
4728        Constructs a DataType object.
4729
4730        Args:
4731            dtype: the data type of interest.
4732            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4733            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4734                DataType, thus creating a user-defined type.
4735            copy: whether to copy the data type.
4736            kwargs: additional arguments to pass in the constructor of DataType.
4737
4738        Returns:
4739            The constructed DataType object.
4740        """
4741        from sqlglot import parse_one
4742
4743        if isinstance(dtype, str):
4744            if dtype.upper() == "UNKNOWN":
4745                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4746
4747            try:
4748                data_type_exp = parse_one(
4749                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4750                )
4751            except ParseError:
4752                if udt:
4753                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4754                raise
4755        elif isinstance(dtype, DataType.Type):
4756            data_type_exp = DataType(this=dtype)
4757        elif isinstance(dtype, DataType):
4758            return maybe_copy(dtype, copy)
4759        else:
4760            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4761
4762        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:
4764    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4765        """
4766        Checks whether this DataType matches one of the provided data types. Nested types or precision
4767        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4768
4769        Args:
4770            dtypes: the data types to compare this DataType to.
4771            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4772                If false, it means that NULLABLE<INT> is equivalent to INT.
4773
4774        Returns:
4775            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4776        """
4777        self_is_nullable = self.args.get("nullable")
4778        for dtype in dtypes:
4779            other_type = DataType.build(dtype, copy=False, udt=True)
4780            other_is_nullable = other_type.args.get("nullable")
4781            if (
4782                other_type.expressions
4783                or (check_nullable and (self_is_nullable or other_is_nullable))
4784                or self.this == DataType.Type.USERDEFINED
4785                or other_type.this == DataType.Type.USERDEFINED
4786            ):
4787                matches = self == other_type
4788            else:
4789                matches = self.this == other_type.this
4790
4791            if matches:
4792                return True
4793        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):
4499    class Type(AutoName):
4500        ARRAY = auto()
4501        AGGREGATEFUNCTION = auto()
4502        SIMPLEAGGREGATEFUNCTION = auto()
4503        BIGDECIMAL = auto()
4504        BIGINT = auto()
4505        BIGSERIAL = auto()
4506        BINARY = auto()
4507        BIT = auto()
4508        BLOB = auto()
4509        BOOLEAN = auto()
4510        BPCHAR = auto()
4511        CHAR = auto()
4512        DATE = auto()
4513        DATE32 = auto()
4514        DATEMULTIRANGE = auto()
4515        DATERANGE = auto()
4516        DATETIME = auto()
4517        DATETIME2 = auto()
4518        DATETIME64 = auto()
4519        DECIMAL = auto()
4520        DECIMAL32 = auto()
4521        DECIMAL64 = auto()
4522        DECIMAL128 = auto()
4523        DECIMAL256 = auto()
4524        DOUBLE = auto()
4525        DYNAMIC = auto()
4526        ENUM = auto()
4527        ENUM8 = auto()
4528        ENUM16 = auto()
4529        FIXEDSTRING = auto()
4530        FLOAT = auto()
4531        GEOGRAPHY = auto()
4532        GEOMETRY = auto()
4533        POINT = auto()
4534        RING = auto()
4535        LINESTRING = auto()
4536        MULTILINESTRING = auto()
4537        POLYGON = auto()
4538        MULTIPOLYGON = auto()
4539        HLLSKETCH = auto()
4540        HSTORE = auto()
4541        IMAGE = auto()
4542        INET = auto()
4543        INT = auto()
4544        INT128 = auto()
4545        INT256 = auto()
4546        INT4MULTIRANGE = auto()
4547        INT4RANGE = auto()
4548        INT8MULTIRANGE = auto()
4549        INT8RANGE = auto()
4550        INTERVAL = auto()
4551        IPADDRESS = auto()
4552        IPPREFIX = auto()
4553        IPV4 = auto()
4554        IPV6 = auto()
4555        JSON = auto()
4556        JSONB = auto()
4557        LIST = auto()
4558        LONGBLOB = auto()
4559        LONGTEXT = auto()
4560        LOWCARDINALITY = auto()
4561        MAP = auto()
4562        MEDIUMBLOB = auto()
4563        MEDIUMINT = auto()
4564        MEDIUMTEXT = auto()
4565        MONEY = auto()
4566        NAME = auto()
4567        NCHAR = auto()
4568        NESTED = auto()
4569        NOTHING = auto()
4570        NULL = auto()
4571        NUMMULTIRANGE = auto()
4572        NUMRANGE = auto()
4573        NVARCHAR = auto()
4574        OBJECT = auto()
4575        RANGE = auto()
4576        ROWVERSION = auto()
4577        SERIAL = auto()
4578        SET = auto()
4579        SMALLDATETIME = auto()
4580        SMALLINT = auto()
4581        SMALLMONEY = auto()
4582        SMALLSERIAL = auto()
4583        STRUCT = auto()
4584        SUPER = auto()
4585        TEXT = auto()
4586        TINYBLOB = auto()
4587        TINYTEXT = auto()
4588        TIME = auto()
4589        TIMETZ = auto()
4590        TIMESTAMP = auto()
4591        TIMESTAMPNTZ = auto()
4592        TIMESTAMPLTZ = auto()
4593        TIMESTAMPTZ = auto()
4594        TIMESTAMP_S = auto()
4595        TIMESTAMP_MS = auto()
4596        TIMESTAMP_NS = auto()
4597        TINYINT = auto()
4598        TSMULTIRANGE = auto()
4599        TSRANGE = auto()
4600        TSTZMULTIRANGE = auto()
4601        TSTZRANGE = auto()
4602        UBIGINT = auto()
4603        UINT = auto()
4604        UINT128 = auto()
4605        UINT256 = auto()
4606        UMEDIUMINT = auto()
4607        UDECIMAL = auto()
4608        UDOUBLE = auto()
4609        UNION = auto()
4610        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4611        USERDEFINED = "USER-DEFINED"
4612        USMALLINT = auto()
4613        UTINYINT = auto()
4614        UUID = auto()
4615        VARBINARY = auto()
4616        VARCHAR = auto()
4617        VARIANT = auto()
4618        VECTOR = auto()
4619        XML = auto()
4620        YEAR = auto()
4621        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):
4800class PseudoType(DataType):
4801    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4805class ObjectIdentifier(DataType):
4806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4810class SubqueryPredicate(Predicate):
4811    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4814class All(SubqueryPredicate):
4815    pass
key = 'all'
class Any(SubqueryPredicate):
4818class Any(SubqueryPredicate):
4819    pass
key = 'any'
class Command(Expression):
4824class Command(Expression):
4825    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4828class Transaction(Expression):
4829    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4832class Commit(Expression):
4833    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4836class Rollback(Expression):
4837    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4840class Alter(Expression):
4841    arg_types = {
4842        "this": True,
4843        "kind": True,
4844        "actions": True,
4845        "exists": False,
4846        "only": False,
4847        "options": False,
4848        "cluster": False,
4849        "not_valid": False,
4850    }
4851
4852    @property
4853    def kind(self) -> t.Optional[str]:
4854        kind = self.args.get("kind")
4855        return kind and kind.upper()
4856
4857    @property
4858    def actions(self) -> t.List[Expression]:
4859        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]
4852    @property
4853    def kind(self) -> t.Optional[str]:
4854        kind = self.args.get("kind")
4855        return kind and kind.upper()
actions: List[Expression]
4857    @property
4858    def actions(self) -> t.List[Expression]:
4859        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4862class Analyze(Expression):
4863    arg_types = {
4864        "kind": False,
4865        "this": False,
4866        "options": False,
4867        "mode": False,
4868        "partition": False,
4869        "expression": False,
4870        "properties": False,
4871    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4874class AnalyzeStatistics(Expression):
4875    arg_types = {
4876        "kind": True,
4877        "option": False,
4878        "this": False,
4879        "expressions": False,
4880    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4883class AnalyzeHistogram(Expression):
4884    arg_types = {
4885        "this": True,
4886        "expressions": True,
4887        "expression": False,
4888        "update_options": False,
4889    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4892class AnalyzeSample(Expression):
4893    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4896class AnalyzeListChainedRows(Expression):
4897    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4900class AnalyzeDelete(Expression):
4901    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4904class AnalyzeWith(Expression):
4905    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4908class AnalyzeValidate(Expression):
4909    arg_types = {
4910        "kind": True,
4911        "this": False,
4912        "expression": False,
4913    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4916class AnalyzeColumns(Expression):
4917    pass
key = 'analyzecolumns'
class UsingData(Expression):
4920class UsingData(Expression):
4921    pass
key = 'usingdata'
class AddConstraint(Expression):
4924class AddConstraint(Expression):
4925    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4928class AttachOption(Expression):
4929    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4932class DropPartition(Expression):
4933    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4937class ReplacePartition(Expression):
4938    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4942class Binary(Condition):
4943    arg_types = {"this": True, "expression": True}
4944
4945    @property
4946    def left(self) -> Expression:
4947        return self.this
4948
4949    @property
4950    def right(self) -> Expression:
4951        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4945    @property
4946    def left(self) -> Expression:
4947        return self.this
right: Expression
4949    @property
4950    def right(self) -> Expression:
4951        return self.expression
key = 'binary'
class Add(Binary):
4954class Add(Binary):
4955    pass
key = 'add'
class Connector(Binary):
4958class Connector(Binary):
4959    pass
key = 'connector'
class BitwiseAnd(Binary):
4962class BitwiseAnd(Binary):
4963    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4966class BitwiseLeftShift(Binary):
4967    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4970class BitwiseOr(Binary):
4971    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4974class BitwiseRightShift(Binary):
4975    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4978class BitwiseXor(Binary):
4979    pass
key = 'bitwisexor'
class Div(Binary):
4982class Div(Binary):
4983    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):
4986class Overlaps(Binary):
4987    pass
key = 'overlaps'
class Dot(Binary):
4990class Dot(Binary):
4991    @property
4992    def is_star(self) -> bool:
4993        return self.expression.is_star
4994
4995    @property
4996    def name(self) -> str:
4997        return self.expression.name
4998
4999    @property
5000    def output_name(self) -> str:
5001        return self.name
5002
5003    @classmethod
5004    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5005        """Build a Dot object with a sequence of expressions."""
5006        if len(expressions) < 2:
5007            raise ValueError("Dot requires >= 2 expressions.")
5008
5009        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5010
5011    @property
5012    def parts(self) -> t.List[Expression]:
5013        """Return the parts of a table / column in order catalog, db, table."""
5014        this, *parts = self.flatten()
5015
5016        parts.reverse()
5017
5018        for arg in COLUMN_PARTS:
5019            part = this.args.get(arg)
5020
5021            if isinstance(part, Expression):
5022                parts.append(part)
5023
5024        parts.reverse()
5025        return parts
is_star: bool
4991    @property
4992    def is_star(self) -> bool:
4993        return self.expression.is_star

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
5028class DPipe(Binary):
5029    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5032class EQ(Binary, Predicate):
5033    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5036class NullSafeEQ(Binary, Predicate):
5037    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5040class NullSafeNEQ(Binary, Predicate):
5041    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5045class PropertyEQ(Binary):
5046    pass
key = 'propertyeq'
class Distance(Binary):
5049class Distance(Binary):
5050    pass
key = 'distance'
class Escape(Binary):
5053class Escape(Binary):
5054    pass
key = 'escape'
class Glob(Binary, Predicate):
5057class Glob(Binary, Predicate):
5058    pass
key = 'glob'
class GT(Binary, Predicate):
5061class GT(Binary, Predicate):
5062    pass
key = 'gt'
class GTE(Binary, Predicate):
5065class GTE(Binary, Predicate):
5066    pass
key = 'gte'
class ILike(Binary, Predicate):
5069class ILike(Binary, Predicate):
5070    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5073class ILikeAny(Binary, Predicate):
5074    pass
key = 'ilikeany'
class IntDiv(Binary):
5077class IntDiv(Binary):
5078    pass
key = 'intdiv'
class Is(Binary, Predicate):
5081class Is(Binary, Predicate):
5082    pass
key = 'is'
class Kwarg(Binary):
5085class Kwarg(Binary):
5086    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5089class Like(Binary, Predicate):
5090    pass
key = 'like'
class LikeAny(Binary, Predicate):
5093class LikeAny(Binary, Predicate):
5094    pass
key = 'likeany'
class LT(Binary, Predicate):
5097class LT(Binary, Predicate):
5098    pass
key = 'lt'
class LTE(Binary, Predicate):
5101class LTE(Binary, Predicate):
5102    pass
key = 'lte'
class Mod(Binary):
5105class Mod(Binary):
5106    pass
key = 'mod'
class Mul(Binary):
5109class Mul(Binary):
5110    pass
key = 'mul'
class NEQ(Binary, Predicate):
5113class NEQ(Binary, Predicate):
5114    pass
key = 'neq'
class Operator(Binary):
5118class Operator(Binary):
5119    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5122class SimilarTo(Binary, Predicate):
5123    pass
key = 'similarto'
class Slice(Binary):
5126class Slice(Binary):
5127    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5130class Sub(Binary):
5131    pass
key = 'sub'
class Unary(Condition):
5136class Unary(Condition):
5137    pass
key = 'unary'
class BitwiseNot(Unary):
5140class BitwiseNot(Unary):
5141    pass
key = 'bitwisenot'
class Not(Unary):
5144class Not(Unary):
5145    pass
key = 'not'
class Paren(Unary):
5148class Paren(Unary):
5149    @property
5150    def output_name(self) -> str:
5151        return self.this.name
output_name: str
5149    @property
5150    def output_name(self) -> str:
5151        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):
5154class Neg(Unary):
5155    def to_py(self) -> int | Decimal:
5156        if self.is_number:
5157            return self.this.to_py() * -1
5158        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5155    def to_py(self) -> int | Decimal:
5156        if self.is_number:
5157            return self.this.to_py() * -1
5158        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5161class Alias(Expression):
5162    arg_types = {"this": True, "alias": False}
5163
5164    @property
5165    def output_name(self) -> str:
5166        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5164    @property
5165    def output_name(self) -> str:
5166        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):
5171class PivotAlias(Alias):
5172    pass
key = 'pivotalias'
class PivotAny(Expression):
5177class PivotAny(Expression):
5178    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5181class Aliases(Expression):
5182    arg_types = {"this": True, "expressions": True}
5183
5184    @property
5185    def aliases(self):
5186        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5184    @property
5185    def aliases(self):
5186        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5190class AtIndex(Expression):
5191    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5194class AtTimeZone(Expression):
5195    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5198class FromTimeZone(Expression):
5199    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5202class Between(Predicate):
5203    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5206class Bracket(Condition):
5207    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5208    arg_types = {
5209        "this": True,
5210        "expressions": True,
5211        "offset": False,
5212        "safe": False,
5213        "returns_list_for_maps": False,
5214    }
5215
5216    @property
5217    def output_name(self) -> str:
5218        if len(self.expressions) == 1:
5219            return self.expressions[0].output_name
5220
5221        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5216    @property
5217    def output_name(self) -> str:
5218        if len(self.expressions) == 1:
5219            return self.expressions[0].output_name
5220
5221        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):
5224class Distinct(Expression):
5225    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5228class In(Predicate):
5229    arg_types = {
5230        "this": True,
5231        "expressions": False,
5232        "query": False,
5233        "unnest": False,
5234        "field": False,
5235        "is_global": False,
5236    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5240class ForIn(Expression):
5241    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5244class TimeUnit(Expression):
5245    """Automatically converts unit arg into a var."""
5246
5247    arg_types = {"unit": False}
5248
5249    UNABBREVIATED_UNIT_NAME = {
5250        "D": "DAY",
5251        "H": "HOUR",
5252        "M": "MINUTE",
5253        "MS": "MILLISECOND",
5254        "NS": "NANOSECOND",
5255        "Q": "QUARTER",
5256        "S": "SECOND",
5257        "US": "MICROSECOND",
5258        "W": "WEEK",
5259        "Y": "YEAR",
5260    }
5261
5262    VAR_LIKE = (Column, Literal, Var)
5263
5264    def __init__(self, **args):
5265        unit = args.get("unit")
5266        if isinstance(unit, self.VAR_LIKE):
5267            args["unit"] = Var(
5268                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5269            )
5270        elif isinstance(unit, Week):
5271            unit.set("this", Var(this=unit.this.name.upper()))
5272
5273        super().__init__(**args)
5274
5275    @property
5276    def unit(self) -> t.Optional[Var | IntervalSpan]:
5277        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5264    def __init__(self, **args):
5265        unit = args.get("unit")
5266        if isinstance(unit, self.VAR_LIKE):
5267            args["unit"] = Var(
5268                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5269            )
5270        elif isinstance(unit, Week):
5271            unit.set("this", Var(this=unit.this.name.upper()))
5272
5273        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]
5275    @property
5276    def unit(self) -> t.Optional[Var | IntervalSpan]:
5277        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5280class IntervalOp(TimeUnit):
5281    arg_types = {"unit": False, "expression": True}
5282
5283    def interval(self):
5284        return Interval(
5285            this=self.expression.copy(),
5286            unit=self.unit.copy() if self.unit else None,
5287        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5283    def interval(self):
5284        return Interval(
5285            this=self.expression.copy(),
5286            unit=self.unit.copy() if self.unit else None,
5287        )
key = 'intervalop'
class IntervalSpan(DataType):
5293class IntervalSpan(DataType):
5294    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5297class Interval(TimeUnit):
5298    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5301class IgnoreNulls(Expression):
5302    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5305class RespectNulls(Expression):
5306    pass
key = 'respectnulls'
class HavingMax(Expression):
5310class HavingMax(Expression):
5311    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5315class Func(Condition):
5316    """
5317    The base class for all function expressions.
5318
5319    Attributes:
5320        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5321            treated as a variable length argument and the argument's value will be stored as a list.
5322        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5323            function expression. These values are used to map this node to a name during parsing as
5324            well as to provide the function's name during SQL string generation. By default the SQL
5325            name is set to the expression's class name transformed to snake case.
5326    """
5327
5328    is_var_len_args = False
5329
5330    @classmethod
5331    def from_arg_list(cls, args):
5332        if cls.is_var_len_args:
5333            all_arg_keys = list(cls.arg_types)
5334            # If this function supports variable length argument treat the last argument as such.
5335            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5336            num_non_var = len(non_var_len_arg_keys)
5337
5338            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5339            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5340        else:
5341            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5342
5343        return cls(**args_dict)
5344
5345    @classmethod
5346    def sql_names(cls):
5347        if cls is Func:
5348            raise NotImplementedError(
5349                "SQL name is only supported by concrete function implementations"
5350            )
5351        if "_sql_names" not in cls.__dict__:
5352            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5353        return cls._sql_names
5354
5355    @classmethod
5356    def sql_name(cls):
5357        return cls.sql_names()[0]
5358
5359    @classmethod
5360    def default_parser_mappings(cls):
5361        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):
5330    @classmethod
5331    def from_arg_list(cls, args):
5332        if cls.is_var_len_args:
5333            all_arg_keys = list(cls.arg_types)
5334            # If this function supports variable length argument treat the last argument as such.
5335            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5336            num_non_var = len(non_var_len_arg_keys)
5337
5338            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5339            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5340        else:
5341            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5342
5343        return cls(**args_dict)
@classmethod
def sql_names(cls):
5345    @classmethod
5346    def sql_names(cls):
5347        if cls is Func:
5348            raise NotImplementedError(
5349                "SQL name is only supported by concrete function implementations"
5350            )
5351        if "_sql_names" not in cls.__dict__:
5352            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5353        return cls._sql_names
@classmethod
def sql_name(cls):
5355    @classmethod
5356    def sql_name(cls):
5357        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5359    @classmethod
5360    def default_parser_mappings(cls):
5361        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5364class AggFunc(Func):
5365    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5368class ParameterizedAgg(AggFunc):
5369    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5372class Abs(Func):
5373    pass
key = 'abs'
class ArgMax(AggFunc):
5376class ArgMax(AggFunc):
5377    arg_types = {"this": True, "expression": True, "count": False}
5378    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5381class ArgMin(AggFunc):
5382    arg_types = {"this": True, "expression": True, "count": False}
5383    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5386class ApproxTopK(AggFunc):
5387    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5390class Flatten(Func):
5391    pass
key = 'flatten'
class Transform(Func):
5395class Transform(Func):
5396    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5399class Anonymous(Func):
5400    arg_types = {"this": True, "expressions": False}
5401    is_var_len_args = True
5402
5403    @property
5404    def name(self) -> str:
5405        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
5403    @property
5404    def name(self) -> str:
5405        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5408class AnonymousAggFunc(AggFunc):
5409    arg_types = {"this": True, "expressions": False}
5410    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5414class CombinedAggFunc(AnonymousAggFunc):
5415    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5418class CombinedParameterizedAgg(ParameterizedAgg):
5419    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5424class Hll(AggFunc):
5425    arg_types = {"this": True, "expressions": False}
5426    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5429class ApproxDistinct(AggFunc):
5430    arg_types = {"this": True, "accuracy": False}
5431    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5434class Apply(Func):
5435    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5438class Array(Func):
5439    arg_types = {"expressions": False, "bracket_notation": False}
5440    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5444class ToArray(Func):
5445    pass
key = 'toarray'
class List(Func):
5449class List(Func):
5450    arg_types = {"expressions": False}
5451    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5455class Pad(Func):
5456    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):
5461class ToChar(Func):
5462    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5467class ToNumber(Func):
5468    arg_types = {
5469        "this": True,
5470        "format": False,
5471        "nlsparam": False,
5472        "precision": False,
5473        "scale": False,
5474    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5478class ToDouble(Func):
5479    arg_types = {
5480        "this": True,
5481        "format": False,
5482    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5485class Columns(Func):
5486    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5490class Convert(Func):
5491    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5494class ConvertTimezone(Func):
5495    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):
5498class GenerateSeries(Func):
5499    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):
5505class ExplodingGenerateSeries(GenerateSeries):
5506    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5509class ArrayAgg(AggFunc):
5510    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5513class ArrayUniqueAgg(AggFunc):
5514    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5517class ArrayAll(Func):
5518    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5522class ArrayAny(Func):
5523    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5526class ArrayConcat(Func):
5527    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5528    arg_types = {"this": True, "expressions": False}
5529    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5532class ArrayConstructCompact(Func):
5533    arg_types = {"expressions": True}
5534    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5537class ArrayContains(Binary, Func):
5538    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5541class ArrayContainsAll(Binary, Func):
5542    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5545class ArrayFilter(Func):
5546    arg_types = {"this": True, "expression": True}
5547    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5550class ArrayToString(Func):
5551    arg_types = {"this": True, "expression": True, "null": False}
5552    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5556class String(Func):
5557    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5560class StringToArray(Func):
5561    arg_types = {"this": True, "expression": True, "null": False}
5562    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5565class ArrayOverlaps(Binary, Func):
5566    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5569class ArraySize(Func):
5570    arg_types = {"this": True, "expression": False}
5571    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5574class ArraySort(Func):
5575    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5578class ArraySum(Func):
5579    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5582class ArrayUnionAgg(AggFunc):
5583    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5586class Avg(AggFunc):
5587    pass
key = 'avg'
class AnyValue(AggFunc):
5590class AnyValue(AggFunc):
5591    pass
key = 'anyvalue'
class Lag(AggFunc):
5594class Lag(AggFunc):
5595    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5598class Lead(AggFunc):
5599    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5604class First(AggFunc):
5605    pass
key = 'first'
class Last(AggFunc):
5608class Last(AggFunc):
5609    pass
key = 'last'
class FirstValue(AggFunc):
5612class FirstValue(AggFunc):
5613    pass
key = 'firstvalue'
class LastValue(AggFunc):
5616class LastValue(AggFunc):
5617    pass
key = 'lastvalue'
class NthValue(AggFunc):
5620class NthValue(AggFunc):
5621    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5624class Case(Func):
5625    arg_types = {"this": False, "ifs": True, "default": False}
5626
5627    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5628        instance = maybe_copy(self, copy)
5629        instance.append(
5630            "ifs",
5631            If(
5632                this=maybe_parse(condition, copy=copy, **opts),
5633                true=maybe_parse(then, copy=copy, **opts),
5634            ),
5635        )
5636        return instance
5637
5638    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5639        instance = maybe_copy(self, copy)
5640        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5641        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:
5627    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5628        instance = maybe_copy(self, copy)
5629        instance.append(
5630            "ifs",
5631            If(
5632                this=maybe_parse(condition, copy=copy, **opts),
5633                true=maybe_parse(then, copy=copy, **opts),
5634            ),
5635        )
5636        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5638    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5639        instance = maybe_copy(self, copy)
5640        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5641        return instance
key = 'case'
class Cast(Func):
5644class Cast(Func):
5645    arg_types = {
5646        "this": True,
5647        "to": True,
5648        "format": False,
5649        "safe": False,
5650        "action": False,
5651        "default": False,
5652    }
5653
5654    @property
5655    def name(self) -> str:
5656        return self.this.name
5657
5658    @property
5659    def to(self) -> DataType:
5660        return self.args["to"]
5661
5662    @property
5663    def output_name(self) -> str:
5664        return self.name
5665
5666    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5667        """
5668        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5669        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5670        array<int> != array<float>.
5671
5672        Args:
5673            dtypes: the data types to compare this Cast's DataType to.
5674
5675        Returns:
5676            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5677        """
5678        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5654    @property
5655    def name(self) -> str:
5656        return self.this.name
to: DataType
5658    @property
5659    def to(self) -> DataType:
5660        return self.args["to"]
output_name: str
5662    @property
5663    def output_name(self) -> str:
5664        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:
5666    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5667        """
5668        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5669        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5670        array<int> != array<float>.
5671
5672        Args:
5673            dtypes: the data types to compare this Cast's DataType to.
5674
5675        Returns:
5676            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5677        """
5678        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):
5681class TryCast(Cast):
5682    pass
key = 'trycast'
class JSONCast(Cast):
5686class JSONCast(Cast):
5687    pass
key = 'jsoncast'
class Try(Func):
5690class Try(Func):
5691    pass
key = 'try'
class CastToStrType(Func):
5694class CastToStrType(Func):
5695    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5698class Collate(Binary, Func):
5699    pass
key = 'collate'
class Ceil(Func):
5702class Ceil(Func):
5703    arg_types = {"this": True, "decimals": False, "to": False}
5704    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5707class Coalesce(Func):
5708    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5709    is_var_len_args = True
5710    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5713class Chr(Func):
5714    arg_types = {"expressions": True, "charset": False}
5715    is_var_len_args = True
5716    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5719class Concat(Func):
5720    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5721    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5724class ConcatWs(Concat):
5725    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5728class Contains(Func):
5729    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5733class ConnectByRoot(Func):
5734    pass
key = 'connectbyroot'
class Count(AggFunc):
5737class Count(AggFunc):
5738    arg_types = {"this": False, "expressions": False, "big_int": False}
5739    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5742class CountIf(AggFunc):
5743    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5747class Cbrt(Func):
5748    pass
key = 'cbrt'
class CurrentDate(Func):
5751class CurrentDate(Func):
5752    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5755class CurrentDatetime(Func):
5756    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5759class CurrentTime(Func):
5760    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5763class CurrentTimestamp(Func):
5764    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5767class CurrentSchema(Func):
5768    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5771class CurrentUser(Func):
5772    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5775class DateAdd(Func, IntervalOp):
5776    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5779class DateBin(Func, IntervalOp):
5780    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):
5783class DateSub(Func, IntervalOp):
5784    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5787class DateDiff(Func, TimeUnit):
5788    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5789    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):
5792class DateTrunc(Func):
5793    arg_types = {"unit": True, "this": True, "zone": False}
5794
5795    def __init__(self, **args):
5796        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5797        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5798        unabbreviate = args.pop("unabbreviate", True)
5799
5800        unit = args.get("unit")
5801        if isinstance(unit, TimeUnit.VAR_LIKE):
5802            unit_name = unit.name.upper()
5803            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5804                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5805
5806            args["unit"] = Literal.string(unit_name)
5807        elif isinstance(unit, Week):
5808            unit.set("this", Literal.string(unit.this.name.upper()))
5809
5810        super().__init__(**args)
5811
5812    @property
5813    def unit(self) -> Expression:
5814        return self.args["unit"]
DateTrunc(**args)
5795    def __init__(self, **args):
5796        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5797        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5798        unabbreviate = args.pop("unabbreviate", True)
5799
5800        unit = args.get("unit")
5801        if isinstance(unit, TimeUnit.VAR_LIKE):
5802            unit_name = unit.name.upper()
5803            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5804                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5805
5806            args["unit"] = Literal.string(unit_name)
5807        elif isinstance(unit, Week):
5808            unit.set("this", Literal.string(unit.this.name.upper()))
5809
5810        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5812    @property
5813    def unit(self) -> Expression:
5814        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5819class Datetime(Func):
5820    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5823class DatetimeAdd(Func, IntervalOp):
5824    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5827class DatetimeSub(Func, IntervalOp):
5828    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5831class DatetimeDiff(Func, TimeUnit):
5832    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5835class DatetimeTrunc(Func, TimeUnit):
5836    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5839class DayOfWeek(Func):
5840    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5845class DayOfWeekIso(Func):
5846    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5849class DayOfMonth(Func):
5850    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5853class DayOfYear(Func):
5854    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5857class ToDays(Func):
5858    pass
key = 'todays'
class WeekOfYear(Func):
5861class WeekOfYear(Func):
5862    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5865class MonthsBetween(Func):
5866    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5869class MakeInterval(Func):
5870    arg_types = {
5871        "year": False,
5872        "month": False,
5873        "day": False,
5874        "hour": False,
5875        "minute": False,
5876        "second": False,
5877    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5880class LastDay(Func, TimeUnit):
5881    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5882    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5885class Extract(Func):
5886    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5889class Exists(Func, SubqueryPredicate):
5890    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5893class Timestamp(Func):
5894    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5897class TimestampAdd(Func, TimeUnit):
5898    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5901class TimestampSub(Func, TimeUnit):
5902    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5905class TimestampDiff(Func, TimeUnit):
5906    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5907    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5910class TimestampTrunc(Func, TimeUnit):
5911    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5914class TimeAdd(Func, TimeUnit):
5915    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5918class TimeSub(Func, TimeUnit):
5919    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5922class TimeDiff(Func, TimeUnit):
5923    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5926class TimeTrunc(Func, TimeUnit):
5927    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5930class DateFromParts(Func):
5931    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5932    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5935class TimeFromParts(Func):
5936    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5937    arg_types = {
5938        "hour": True,
5939        "min": True,
5940        "sec": True,
5941        "nano": False,
5942        "fractions": False,
5943        "precision": False,
5944    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5947class DateStrToDate(Func):
5948    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5951class DateToDateStr(Func):
5952    pass
key = 'datetodatestr'
class DateToDi(Func):
5955class DateToDi(Func):
5956    pass
key = 'datetodi'
class Date(Func):
5960class Date(Func):
5961    arg_types = {"this": False, "zone": False, "expressions": False}
5962    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5965class Day(Func):
5966    pass
key = 'day'
class Decode(Func):
5969class Decode(Func):
5970    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5973class DiToDate(Func):
5974    pass
key = 'ditodate'
class Encode(Func):
5977class Encode(Func):
5978    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5981class Exp(Func):
5982    pass
key = 'exp'
class Explode(Func, UDTF):
5986class Explode(Func, UDTF):
5987    arg_types = {"this": True, "expressions": False}
5988    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5992class Inline(Func):
5993    pass
key = 'inline'
class ExplodeOuter(Explode):
5996class ExplodeOuter(Explode):
5997    pass
key = 'explodeouter'
class Posexplode(Explode):
6000class Posexplode(Explode):
6001    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6004class PosexplodeOuter(Posexplode, ExplodeOuter):
6005    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
6008class Unnest(Func, UDTF):
6009    arg_types = {
6010        "expressions": True,
6011        "alias": False,
6012        "offset": False,
6013        "explode_array": False,
6014    }
6015
6016    @property
6017    def selects(self) -> t.List[Expression]:
6018        columns = super().selects
6019        offset = self.args.get("offset")
6020        if offset:
6021            columns = columns + [to_identifier("offset") if offset is True else offset]
6022        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6016    @property
6017    def selects(self) -> t.List[Expression]:
6018        columns = super().selects
6019        offset = self.args.get("offset")
6020        if offset:
6021            columns = columns + [to_identifier("offset") if offset is True else offset]
6022        return columns
key = 'unnest'
class Floor(Func):
6025class Floor(Func):
6026    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6029class FromBase64(Func):
6030    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6033class FeaturesAtTime(Func):
6034    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):
6037class ToBase64(Func):
6038    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6042class FromISO8601Timestamp(Func):
6043    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6046class GapFill(Func):
6047    arg_types = {
6048        "this": True,
6049        "ts_column": True,
6050        "bucket_width": True,
6051        "partitioning_columns": False,
6052        "value_columns": False,
6053        "origin": False,
6054        "ignore_nulls": False,
6055    }
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):
6059class GenerateDateArray(Func):
6060    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6064class GenerateTimestampArray(Func):
6065    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6068class Greatest(Func):
6069    arg_types = {"this": True, "expressions": False}
6070    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6075class OverflowTruncateBehavior(Expression):
6076    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6079class GroupConcat(AggFunc):
6080    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6083class Hex(Func):
6084    pass
key = 'hex'
class LowerHex(Hex):
6087class LowerHex(Hex):
6088    pass
key = 'lowerhex'
class And(Connector, Func):
6091class And(Connector, Func):
6092    pass
key = 'and'
class Or(Connector, Func):
6095class Or(Connector, Func):
6096    pass
key = 'or'
class Xor(Connector, Func):
6099class Xor(Connector, Func):
6100    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6103class If(Func):
6104    arg_types = {"this": True, "true": True, "false": False}
6105    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6108class Nullif(Func):
6109    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6112class Initcap(Func):
6113    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6116class IsAscii(Func):
6117    pass
key = 'isascii'
class IsNan(Func):
6120class IsNan(Func):
6121    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6125class Int64(Func):
6126    pass
key = 'int64'
class IsInf(Func):
6129class IsInf(Func):
6130    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6134class JSON(Expression):
6135    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6138class JSONPath(Expression):
6139    arg_types = {"expressions": True, "escape": False}
6140
6141    @property
6142    def output_name(self) -> str:
6143        last_segment = self.expressions[-1].this
6144        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6141    @property
6142    def output_name(self) -> str:
6143        last_segment = self.expressions[-1].this
6144        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):
6147class JSONPathPart(Expression):
6148    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6151class JSONPathFilter(JSONPathPart):
6152    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6155class JSONPathKey(JSONPathPart):
6156    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6159class JSONPathRecursive(JSONPathPart):
6160    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6163class JSONPathRoot(JSONPathPart):
6164    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6167class JSONPathScript(JSONPathPart):
6168    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6171class JSONPathSlice(JSONPathPart):
6172    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6175class JSONPathSelector(JSONPathPart):
6176    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6179class JSONPathSubscript(JSONPathPart):
6180    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6183class JSONPathUnion(JSONPathPart):
6184    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6187class JSONPathWildcard(JSONPathPart):
6188    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6191class FormatJson(Expression):
6192    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6195class JSONKeyValue(Expression):
6196    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6199class JSONObject(Func):
6200    arg_types = {
6201        "expressions": False,
6202        "null_handling": False,
6203        "unique_keys": False,
6204        "return_type": False,
6205        "encoding": False,
6206    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6209class JSONObjectAgg(AggFunc):
6210    arg_types = {
6211        "expressions": False,
6212        "null_handling": False,
6213        "unique_keys": False,
6214        "return_type": False,
6215        "encoding": False,
6216    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6220class JSONBObjectAgg(AggFunc):
6221    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6225class JSONArray(Func):
6226    arg_types = {
6227        "expressions": True,
6228        "null_handling": False,
6229        "return_type": False,
6230        "strict": False,
6231    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6235class JSONArrayAgg(Func):
6236    arg_types = {
6237        "this": True,
6238        "order": False,
6239        "null_handling": False,
6240        "return_type": False,
6241        "strict": False,
6242    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6245class JSONExists(Func):
6246    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):
6251class JSONColumnDef(Expression):
6252    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):
6255class JSONSchema(Expression):
6256    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6260class JSONValue(Expression):
6261    arg_types = {
6262        "this": True,
6263        "path": True,
6264        "returning": False,
6265        "on_condition": False,
6266    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6269class JSONValueArray(Func):
6270    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6274class JSONTable(Func):
6275    arg_types = {
6276        "this": True,
6277        "schema": True,
6278        "path": False,
6279        "error_handling": False,
6280        "empty_handling": False,
6281    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6285class ObjectInsert(Func):
6286    arg_types = {
6287        "this": True,
6288        "key": True,
6289        "value": True,
6290        "update_flag": False,
6291    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6294class OpenJSONColumnDef(Expression):
6295    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):
6298class OpenJSON(Func):
6299    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6302class JSONBContains(Binary, Func):
6303    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6306class JSONBExists(Func):
6307    arg_types = {"this": True, "path": True}
6308    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6311class JSONExtract(Binary, Func):
6312    arg_types = {
6313        "this": True,
6314        "expression": True,
6315        "only_json_types": False,
6316        "expressions": False,
6317        "variant_extract": False,
6318        "json_query": False,
6319        "option": False,
6320        "quote": False,
6321        "on_condition": False,
6322    }
6323    _sql_names = ["JSON_EXTRACT"]
6324    is_var_len_args = True
6325
6326    @property
6327    def output_name(self) -> str:
6328        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
6326    @property
6327    def output_name(self) -> str:
6328        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):
6332class JSONExtractQuote(Expression):
6333    arg_types = {
6334        "option": True,
6335        "scalar": False,
6336    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6339class JSONExtractArray(Func):
6340    arg_types = {"this": True, "expression": False}
6341    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6344class JSONExtractScalar(Binary, Func):
6345    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6346    _sql_names = ["JSON_EXTRACT_SCALAR"]
6347    is_var_len_args = True
6348
6349    @property
6350    def output_name(self) -> str:
6351        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
6349    @property
6350    def output_name(self) -> str:
6351        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):
6354class JSONBExtract(Binary, Func):
6355    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6358class JSONBExtractScalar(Binary, Func):
6359    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6362class JSONFormat(Func):
6363    arg_types = {"this": False, "options": False, "is_json": False}
6364    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6368class JSONArrayContains(Binary, Predicate, Func):
6369    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6372class ParseJSON(Func):
6373    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6374    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6375    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6376    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6379class Least(Func):
6380    arg_types = {"this": True, "expressions": False}
6381    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6384class Left(Func):
6385    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6392class Length(Func):
6393    arg_types = {"this": True, "binary": False, "encoding": False}
6394    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6397class Levenshtein(Func):
6398    arg_types = {
6399        "this": True,
6400        "expression": False,
6401        "ins_cost": False,
6402        "del_cost": False,
6403        "sub_cost": False,
6404        "max_dist": False,
6405    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6408class Ln(Func):
6409    pass
key = 'ln'
class Log(Func):
6412class Log(Func):
6413    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6416class LogicalOr(AggFunc):
6417    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6420class LogicalAnd(AggFunc):
6421    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6424class Lower(Func):
6425    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6428class Map(Func):
6429    arg_types = {"keys": False, "values": False}
6430
6431    @property
6432    def keys(self) -> t.List[Expression]:
6433        keys = self.args.get("keys")
6434        return keys.expressions if keys else []
6435
6436    @property
6437    def values(self) -> t.List[Expression]:
6438        values = self.args.get("values")
6439        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6431    @property
6432    def keys(self) -> t.List[Expression]:
6433        keys = self.args.get("keys")
6434        return keys.expressions if keys else []
values: List[Expression]
6436    @property
6437    def values(self) -> t.List[Expression]:
6438        values = self.args.get("values")
6439        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6443class ToMap(Func):
6444    pass
key = 'tomap'
class MapFromEntries(Func):
6447class MapFromEntries(Func):
6448    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6452class ScopeResolution(Expression):
6453    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6456class Stream(Expression):
6457    pass
key = 'stream'
class StarMap(Func):
6460class StarMap(Func):
6461    pass
key = 'starmap'
class VarMap(Func):
6464class VarMap(Func):
6465    arg_types = {"keys": True, "values": True}
6466    is_var_len_args = True
6467
6468    @property
6469    def keys(self) -> t.List[Expression]:
6470        return self.args["keys"].expressions
6471
6472    @property
6473    def values(self) -> t.List[Expression]:
6474        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6468    @property
6469    def keys(self) -> t.List[Expression]:
6470        return self.args["keys"].expressions
values: List[Expression]
6472    @property
6473    def values(self) -> t.List[Expression]:
6474        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6478class MatchAgainst(Func):
6479    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6482class Max(AggFunc):
6483    arg_types = {"this": True, "expressions": False}
6484    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6487class MD5(Func):
6488    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6492class MD5Digest(Func):
6493    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6496class Median(AggFunc):
6497    pass
key = 'median'
class Min(AggFunc):
6500class Min(AggFunc):
6501    arg_types = {"this": True, "expressions": False}
6502    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6505class Month(Func):
6506    pass
key = 'month'
class AddMonths(Func):
6509class AddMonths(Func):
6510    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6513class Nvl2(Func):
6514    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6517class Normalize(Func):
6518    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6521class Overlay(Func):
6522    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):
6526class Predict(Func):
6527    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6530class Pow(Binary, Func):
6531    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6534class PercentileCont(AggFunc):
6535    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6538class PercentileDisc(AggFunc):
6539    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6542class Quantile(AggFunc):
6543    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6546class ApproxQuantile(Quantile):
6547    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):
6550class Quarter(Func):
6551    pass
key = 'quarter'
class Rand(Func):
6556class Rand(Func):
6557    _sql_names = ["RAND", "RANDOM"]
6558    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6561class Randn(Func):
6562    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6565class RangeN(Func):
6566    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6569class ReadCSV(Func):
6570    _sql_names = ["READ_CSV"]
6571    is_var_len_args = True
6572    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6575class Reduce(Func):
6576    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):
6579class RegexpExtract(Func):
6580    arg_types = {
6581        "this": True,
6582        "expression": True,
6583        "position": False,
6584        "occurrence": False,
6585        "parameters": False,
6586        "group": False,
6587    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6590class RegexpExtractAll(Func):
6591    arg_types = {
6592        "this": True,
6593        "expression": True,
6594        "position": False,
6595        "occurrence": False,
6596        "parameters": False,
6597        "group": False,
6598    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6601class RegexpReplace(Func):
6602    arg_types = {
6603        "this": True,
6604        "expression": True,
6605        "replacement": False,
6606        "position": False,
6607        "occurrence": False,
6608        "modifiers": False,
6609    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6612class RegexpLike(Binary, Func):
6613    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6616class RegexpILike(Binary, Func):
6617    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6622class RegexpSplit(Func):
6623    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6626class Repeat(Func):
6627    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6632class Round(Func):
6633    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6636class RowNumber(Func):
6637    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6640class SafeDivide(Func):
6641    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6644class SHA(Func):
6645    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6648class SHA2(Func):
6649    _sql_names = ["SHA2"]
6650    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6653class Sign(Func):
6654    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6657class SortArray(Func):
6658    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6661class Split(Func):
6662    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6666class SplitPart(Func):
6667    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6672class Substring(Func):
6673    _sql_names = ["SUBSTRING", "SUBSTR"]
6674    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6677class StandardHash(Func):
6678    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6681class StartsWith(Func):
6682    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6683    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6686class StrPosition(Func):
6687    arg_types = {
6688        "this": True,
6689        "substr": True,
6690        "position": False,
6691        "occurrence": False,
6692    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6695class StrToDate(Func):
6696    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6699class StrToTime(Func):
6700    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):
6705class StrToUnix(Func):
6706    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6711class StrToMap(Func):
6712    arg_types = {
6713        "this": True,
6714        "pair_delim": False,
6715        "key_value_delim": False,
6716        "duplicate_resolution_callback": False,
6717    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6720class NumberToStr(Func):
6721    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6724class FromBase(Func):
6725    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6728class Struct(Func):
6729    arg_types = {"expressions": False}
6730    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6733class StructExtract(Func):
6734    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6739class Stuff(Func):
6740    _sql_names = ["STUFF", "INSERT"]
6741    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):
6744class Sum(AggFunc):
6745    pass
key = 'sum'
class Sqrt(Func):
6748class Sqrt(Func):
6749    pass
key = 'sqrt'
class Stddev(AggFunc):
6752class Stddev(AggFunc):
6753    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6756class StddevPop(AggFunc):
6757    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6760class StddevSamp(AggFunc):
6761    pass
key = 'stddevsamp'
class Time(Func):
6765class Time(Func):
6766    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6769class TimeToStr(Func):
6770    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):
6773class TimeToTimeStr(Func):
6774    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6777class TimeToUnix(Func):
6778    pass
key = 'timetounix'
class TimeStrToDate(Func):
6781class TimeStrToDate(Func):
6782    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6785class TimeStrToTime(Func):
6786    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6789class TimeStrToUnix(Func):
6790    pass
key = 'timestrtounix'
class Trim(Func):
6793class Trim(Func):
6794    arg_types = {
6795        "this": True,
6796        "expression": False,
6797        "position": False,
6798        "collation": False,
6799    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6802class TsOrDsAdd(Func, TimeUnit):
6803    # return_type is used to correctly cast the arguments of this expression when transpiling it
6804    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6805
6806    @property
6807    def return_type(self) -> DataType:
6808        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
6806    @property
6807    def return_type(self) -> DataType:
6808        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6811class TsOrDsDiff(Func, TimeUnit):
6812    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6815class TsOrDsToDateStr(Func):
6816    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6819class TsOrDsToDate(Func):
6820    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6823class TsOrDsToDatetime(Func):
6824    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6827class TsOrDsToTime(Func):
6828    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6831class TsOrDsToTimestamp(Func):
6832    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6835class TsOrDiToDi(Func):
6836    pass
key = 'tsorditodi'
class Unhex(Func):
6839class Unhex(Func):
6840    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6843class Unicode(Func):
6844    pass
key = 'unicode'
class UnixDate(Func):
6848class UnixDate(Func):
6849    pass
key = 'unixdate'
class UnixToStr(Func):
6852class UnixToStr(Func):
6853    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6858class UnixToTime(Func):
6859    arg_types = {
6860        "this": True,
6861        "scale": False,
6862        "zone": False,
6863        "hours": False,
6864        "minutes": False,
6865        "format": False,
6866    }
6867
6868    SECONDS = Literal.number(0)
6869    DECIS = Literal.number(1)
6870    CENTIS = Literal.number(2)
6871    MILLIS = Literal.number(3)
6872    DECIMILLIS = Literal.number(4)
6873    CENTIMILLIS = Literal.number(5)
6874    MICROS = Literal.number(6)
6875    DECIMICROS = Literal.number(7)
6876    CENTIMICROS = Literal.number(8)
6877    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):
6880class UnixToTimeStr(Func):
6881    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6884class UnixSeconds(Func):
6885    pass
key = 'unixseconds'
class Uuid(Func):
6888class Uuid(Func):
6889    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6890
6891    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6894class TimestampFromParts(Func):
6895    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6896    arg_types = {
6897        "year": True,
6898        "month": True,
6899        "day": True,
6900        "hour": True,
6901        "min": True,
6902        "sec": True,
6903        "nano": False,
6904        "zone": False,
6905        "milli": False,
6906    }
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):
6909class Upper(Func):
6910    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6913class Corr(Binary, AggFunc):
6914    pass
key = 'corr'
class Variance(AggFunc):
6917class Variance(AggFunc):
6918    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6921class VariancePop(AggFunc):
6922    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6925class CovarSamp(Binary, AggFunc):
6926    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6929class CovarPop(Binary, AggFunc):
6930    pass
key = 'covarpop'
class Week(Func):
6933class Week(Func):
6934    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6937class XMLElement(Func):
6938    _sql_names = ["XMLELEMENT"]
6939    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6942class XMLTable(Func):
6943    arg_types = {
6944        "this": True,
6945        "namespaces": False,
6946        "passing": False,
6947        "columns": False,
6948        "by_ref": False,
6949    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6952class XMLNamespace(Expression):
6953    pass
key = 'xmlnamespace'
class Year(Func):
6956class Year(Func):
6957    pass
key = 'year'
class Use(Expression):
6960class Use(Expression):
6961    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6964class Merge(DML):
6965    arg_types = {
6966        "this": True,
6967        "using": True,
6968        "on": True,
6969        "whens": True,
6970        "with": False,
6971        "returning": False,
6972    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6975class When(Expression):
6976    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):
6979class Whens(Expression):
6980    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6981
6982    arg_types = {"expressions": True}

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

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

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

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

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

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

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:
8215def values(
8216    values: t.Iterable[t.Tuple[t.Any, ...]],
8217    alias: t.Optional[str] = None,
8218    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8219) -> Values:
8220    """Build VALUES statement.
8221
8222    Example:
8223        >>> values([(1, '2')]).sql()
8224        "VALUES (1, '2')"
8225
8226    Args:
8227        values: values statements that will be converted to SQL
8228        alias: optional alias
8229        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8230         If either are provided then an alias is also required.
8231
8232    Returns:
8233        Values: the Values expression object
8234    """
8235    if columns and not alias:
8236        raise ValueError("Alias is required when providing columns")
8237
8238    return Values(
8239        expressions=[convert(tup) for tup in values],
8240        alias=(
8241            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8242            if columns
8243            else (TableAlias(this=to_identifier(alias)) if alias else None)
8244        ),
8245    )

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:
8248def var(name: t.Optional[ExpOrStr]) -> Var:
8249    """Build a SQL variable.
8250
8251    Example:
8252        >>> repr(var('x'))
8253        'Var(this=x)'
8254
8255        >>> repr(var(column('x', table='y')))
8256        'Var(this=x)'
8257
8258    Args:
8259        name: The name of the var or an expression who's name will become the var.
8260
8261    Returns:
8262        The new variable node.
8263    """
8264    if not name:
8265        raise ValueError("Cannot convert empty name into var.")
8266
8267    if isinstance(name, Expression):
8268        name = name.name
8269    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:
8272def rename_table(
8273    old_name: str | Table,
8274    new_name: str | Table,
8275    dialect: DialectType = None,
8276) -> Alter:
8277    """Build ALTER TABLE... RENAME... expression
8278
8279    Args:
8280        old_name: The old name of the table
8281        new_name: The new name of the table
8282        dialect: The dialect to parse the table.
8283
8284    Returns:
8285        Alter table expression
8286    """
8287    old_table = to_table(old_name, dialect=dialect)
8288    new_table = to_table(new_name, dialect=dialect)
8289    return Alter(
8290        this=old_table,
8291        kind="TABLE",
8292        actions=[
8293            AlterRename(this=new_table),
8294        ],
8295    )

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:
8298def rename_column(
8299    table_name: str | Table,
8300    old_column_name: str | Column,
8301    new_column_name: str | Column,
8302    exists: t.Optional[bool] = None,
8303    dialect: DialectType = None,
8304) -> Alter:
8305    """Build ALTER TABLE... RENAME COLUMN... expression
8306
8307    Args:
8308        table_name: Name of the table
8309        old_column: The old name of the column
8310        new_column: The new name of the column
8311        exists: Whether to add the `IF EXISTS` clause
8312        dialect: The dialect to parse the table/column.
8313
8314    Returns:
8315        Alter table expression
8316    """
8317    table = to_table(table_name, dialect=dialect)
8318    old_column = to_column(old_column_name, dialect=dialect)
8319    new_column = to_column(new_column_name, dialect=dialect)
8320    return Alter(
8321        this=table,
8322        kind="TABLE",
8323        actions=[
8324            RenameColumn(this=old_column, to=new_column, exists=exists),
8325        ],
8326    )

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

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:
8463def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8464    """Get the full name of a table as a string.
8465
8466    Args:
8467        table: Table expression node or string.
8468        dialect: The dialect to generate the table name for.
8469        identify: Determines when an identifier should be quoted. Possible values are:
8470            False (default): Never quote, except in cases where it's mandatory by the dialect.
8471            True: Always quote.
8472
8473    Examples:
8474        >>> from sqlglot import exp, parse_one
8475        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8476        'a.b.c'
8477
8478    Returns:
8479        The table name.
8480    """
8481
8482    table = maybe_parse(table, into=Table, dialect=dialect)
8483
8484    if not table:
8485        raise ValueError(f"Cannot parse {table}")
8486
8487    return ".".join(
8488        (
8489            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8490            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8491            else part.name
8492        )
8493        for part in table.parts
8494    )

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:
8497def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8498    """Returns a case normalized table name without quotes.
8499
8500    Args:
8501        table: the table to normalize
8502        dialect: the dialect to use for normalization rules
8503        copy: whether to copy the expression.
8504
8505    Examples:
8506        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8507        'A-B.c'
8508    """
8509    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8510
8511    return ".".join(
8512        p.name
8513        for p in normalize_identifiers(
8514            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8515        ).parts
8516    )

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

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:
8752def tuple_(
8753    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8754) -> Tuple:
8755    """
8756    Returns an tuple.
8757
8758    Examples:
8759        >>> tuple_(1, 'x').sql()
8760        '(1, x)'
8761
8762    Args:
8763        expressions: the expressions to add to the tuple.
8764        copy: whether to copy the argument expressions.
8765        dialect: the source dialect.
8766        kwargs: the kwargs used to instantiate the function of interest.
8767
8768    Returns:
8769        A tuple expression.
8770    """
8771    return Tuple(
8772        expressions=[
8773            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8774            for expression in expressions
8775        ]
8776    )

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:
8779def true() -> Boolean:
8780    """
8781    Returns a true Boolean expression.
8782    """
8783    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8786def false() -> Boolean:
8787    """
8788    Returns a false Boolean expression.
8789    """
8790    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8793def null() -> Null:
8794    """
8795    Returns a Null expression.
8796    """
8797    return Null()

Returns a Null expression.

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