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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

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

Returns a deep copy of the expression.

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

Returns the depth of this tree.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
764    @classmethod
765    def load(cls, obj):
766        """
767        Load a dict (as returned by `Expression.dump`) into an Expression instance.
768        """
769        from sqlglot.serde import load
770
771        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
773    def and_(
774        self,
775        *expressions: t.Optional[ExpOrStr],
776        dialect: DialectType = None,
777        copy: bool = True,
778        wrap: bool = True,
779        **opts,
780    ) -> Condition:
781        """
782        AND this condition with one or multiple expressions.
783
784        Example:
785            >>> condition("x=1").and_("y=1").sql()
786            'x = 1 AND y = 1'
787
788        Args:
789            *expressions: the SQL code strings to parse.
790                If an `Expression` instance is passed, it will be used as-is.
791            dialect: the dialect used to parse the input expression.
792            copy: whether to copy the involved expressions (only applies to Expressions).
793            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
794                precedence issues, but can be turned off when the produced AST is too deep and
795                causes recursion-related issues.
796            opts: other options to use to parse the input expressions.
797
798        Returns:
799            The new And condition.
800        """
801        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
803    def or_(
804        self,
805        *expressions: t.Optional[ExpOrStr],
806        dialect: DialectType = None,
807        copy: bool = True,
808        wrap: bool = True,
809        **opts,
810    ) -> Condition:
811        """
812        OR this condition with one or multiple expressions.
813
814        Example:
815            >>> condition("x=1").or_("y=1").sql()
816            'x = 1 OR y = 1'
817
818        Args:
819            *expressions: the SQL code strings to parse.
820                If an `Expression` instance is passed, it will be used as-is.
821            dialect: the dialect used to parse the input expression.
822            copy: whether to copy the involved expressions (only applies to Expressions).
823            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
824                precedence issues, but can be turned off when the produced AST is too deep and
825                causes recursion-related issues.
826            opts: other options to use to parse the input expressions.
827
828        Returns:
829            The new Or condition.
830        """
831        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):
833    def not_(self, copy: bool = True):
834        """
835        Wrap this condition with NOT.
836
837        Example:
838            >>> condition("x=1").not_().sql()
839            'NOT x = 1'
840
841        Args:
842            copy: whether to copy this object.
843
844        Returns:
845            The new Not instance.
846        """
847        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 as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
849    def as_(
850        self,
851        alias: str | Identifier,
852        quoted: t.Optional[bool] = None,
853        dialect: DialectType = None,
854        copy: bool = True,
855        **opts,
856    ) -> Alias:
857        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:
882    def isin(
883        self,
884        *expressions: t.Any,
885        query: t.Optional[ExpOrStr] = None,
886        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
887        copy: bool = True,
888        **opts,
889    ) -> In:
890        subquery = maybe_parse(query, copy=copy, **opts) if query else None
891        if subquery and not isinstance(subquery, Subquery):
892            subquery = subquery.subquery(copy=False)
893
894        return In(
895            this=maybe_copy(self, copy),
896            expressions=[convert(e, copy=copy) for e in expressions],
897            query=subquery,
898            unnest=(
899                Unnest(
900                    expressions=[
901                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
902                        for e in ensure_list(unnest)
903                    ]
904                )
905                if unnest
906                else None
907            ),
908        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
910    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
911        return Between(
912            this=maybe_copy(self, copy),
913            low=convert(low, copy=copy, **opts),
914            high=convert(high, copy=copy, **opts),
915        )
def is_( self, other: Union[str, Expression]) -> Is:
917    def is_(self, other: ExpOrStr) -> Is:
918        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
920    def like(self, other: ExpOrStr) -> Like:
921        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
923    def ilike(self, other: ExpOrStr) -> ILike:
924        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
926    def eq(self, other: t.Any) -> EQ:
927        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
929    def neq(self, other: t.Any) -> NEQ:
930        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
932    def rlike(self, other: ExpOrStr) -> RegexpLike:
933        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
935    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
936        div = self._binop(Div, other)
937        div.args["typed"] = typed
938        div.args["safe"] = safe
939        return div
def asc(self, nulls_first: bool = True) -> Ordered:
941    def asc(self, nulls_first: bool = True) -> Ordered:
942        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
944    def desc(self, nulls_first: bool = False) -> Ordered:
945        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):
1028class Condition(Expression):
1029    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1100    def offset(
1101        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1102    ) -> Q:
1103        """
1104        Set the OFFSET expression.
1105
1106        Example:
1107            >>> Select().from_("tbl").select("x").offset(10).sql()
1108            'SELECT x FROM tbl OFFSET 10'
1109
1110        Args:
1111            expression: the SQL code string to parse.
1112                This can also be an integer.
1113                If a `Offset` instance is passed, this is used as-is.
1114                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1115            dialect: the dialect used to parse the input expression.
1116            copy: if `False`, modify this expression instance in-place.
1117            opts: other options to use to parse the input expressions.
1118
1119        Returns:
1120            The modified Select expression.
1121        """
1122        return _apply_builder(
1123            expression=expression,
1124            instance=self,
1125            arg="offset",
1126            into=Offset,
1127            prefix="OFFSET",
1128            dialect=dialect,
1129            copy=copy,
1130            into_arg="expression",
1131            **opts,
1132        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1134    def order_by(
1135        self: Q,
1136        *expressions: t.Optional[ExpOrStr],
1137        append: bool = True,
1138        dialect: DialectType = None,
1139        copy: bool = True,
1140        **opts,
1141    ) -> Q:
1142        """
1143        Set the ORDER BY expression.
1144
1145        Example:
1146            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1147            'SELECT x FROM tbl ORDER BY x DESC'
1148
1149        Args:
1150            *expressions: the SQL code strings to parse.
1151                If a `Group` instance is passed, this is used as-is.
1152                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1153            append: if `True`, add to any existing expressions.
1154                Otherwise, this flattens all the `Order` expression into a single expression.
1155            dialect: the dialect used to parse the input expression.
1156            copy: if `False`, modify this expression instance in-place.
1157            opts: other options to use to parse the input expressions.
1158
1159        Returns:
1160            The modified Select expression.
1161        """
1162        return _apply_child_list_builder(
1163            *expressions,
1164            instance=self,
1165            arg="order",
1166            append=append,
1167            copy=copy,
1168            prefix="ORDER BY",
1169            into=Order,
1170            dialect=dialect,
1171            **opts,
1172        )

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

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

selects: List[Expression]
1180    @property
1181    def selects(self) -> t.List[Expression]:
1182        """Returns the query's projections."""
1183        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1185    @property
1186    def named_selects(self) -> t.List[str]:
1187        """Returns the output names of the query's projections."""
1188        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1190    def select(
1191        self: Q,
1192        *expressions: t.Optional[ExpOrStr],
1193        append: bool = True,
1194        dialect: DialectType = None,
1195        copy: bool = True,
1196        **opts,
1197    ) -> Q:
1198        """
1199        Append to or set the SELECT expressions.
1200
1201        Example:
1202            >>> Select().select("x", "y").sql()
1203            'SELECT x, y'
1204
1205        Args:
1206            *expressions: the SQL code strings to parse.
1207                If an `Expression` instance is passed, it will be used as-is.
1208            append: if `True`, add to any existing expressions.
1209                Otherwise, this resets the expressions.
1210            dialect: the dialect used to parse the input expressions.
1211            copy: if `False`, modify this expression instance in-place.
1212            opts: other options to use to parse the input expressions.
1213
1214        Returns:
1215            The modified Query expression.
1216        """
1217        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1219    def with_(
1220        self: Q,
1221        alias: ExpOrStr,
1222        as_: ExpOrStr,
1223        recursive: t.Optional[bool] = None,
1224        materialized: t.Optional[bool] = None,
1225        append: bool = True,
1226        dialect: DialectType = None,
1227        copy: bool = True,
1228        **opts,
1229    ) -> Q:
1230        """
1231        Append to or set the common table expressions.
1232
1233        Example:
1234            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1235            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1236
1237        Args:
1238            alias: the SQL code string to parse as the table name.
1239                If an `Expression` instance is passed, this is used as-is.
1240            as_: the SQL code string to parse as the table expression.
1241                If an `Expression` instance is passed, it will be used as-is.
1242            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1243            materialized: set the MATERIALIZED part of the expression.
1244            append: if `True`, add to any existing expressions.
1245                Otherwise, this resets the expressions.
1246            dialect: the dialect used to parse the input expression.
1247            copy: if `False`, modify this expression instance in-place.
1248            opts: other options to use to parse the input expressions.
1249
1250        Returns:
1251            The modified expression.
1252        """
1253        return _apply_cte_builder(
1254            self,
1255            alias,
1256            as_,
1257            recursive=recursive,
1258            materialized=materialized,
1259            append=append,
1260            dialect=dialect,
1261            copy=copy,
1262            **opts,
1263        )

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.
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1265    def union(
1266        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1267    ) -> Union:
1268        """
1269        Builds a UNION expression.
1270
1271        Example:
1272            >>> import sqlglot
1273            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1274            'SELECT * FROM foo UNION SELECT * FROM bla'
1275
1276        Args:
1277            expressions: the SQL code strings.
1278                If `Expression` instances are passed, they will be used as-is.
1279            distinct: set the DISTINCT flag if and only if this is true.
1280            dialect: the dialect used to parse the input expression.
1281            opts: other options to use to parse the input expressions.
1282
1283        Returns:
1284            The new Union expression.
1285        """
1286        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1288    def intersect(
1289        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1290    ) -> Intersect:
1291        """
1292        Builds an INTERSECT expression.
1293
1294        Example:
1295            >>> import sqlglot
1296            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1297            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1298
1299        Args:
1300            expressions: the SQL code strings.
1301                If `Expression` instances are passed, they will be used as-is.
1302            distinct: set the DISTINCT flag if and only if this is true.
1303            dialect: the dialect used to parse the input expression.
1304            opts: other options to use to parse the input expressions.
1305
1306        Returns:
1307            The new Intersect expression.
1308        """
1309        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1311    def except_(
1312        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1313    ) -> Except:
1314        """
1315        Builds an EXCEPT expression.
1316
1317        Example:
1318            >>> import sqlglot
1319            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1320            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1321
1322        Args:
1323            expressions: the SQL code strings.
1324                If `Expression` instance are passed, they will be used as-is.
1325            distinct: set the DISTINCT flag if and only if this is true.
1326            dialect: the dialect used to parse the input expression.
1327            opts: other options to use to parse the input expressions.
1328
1329        Returns:
1330            The new Except expression.
1331        """
1332        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):
1335class UDTF(DerivedTable):
1336    @property
1337    def selects(self) -> t.List[Expression]:
1338        alias = self.args.get("alias")
1339        return alias.columns if alias else []
selects: List[Expression]
1336    @property
1337    def selects(self) -> t.List[Expression]:
1338        alias = self.args.get("alias")
1339        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1342class Cache(Expression):
1343    arg_types = {
1344        "this": True,
1345        "lazy": False,
1346        "options": False,
1347        "expression": False,
1348    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1351class Uncache(Expression):
1352    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1355class Refresh(Expression):
1356    pass
key = 'refresh'
class DDL(Expression):
1359class DDL(Expression):
1360    @property
1361    def ctes(self) -> t.List[CTE]:
1362        """Returns a list of all the CTEs attached to this statement."""
1363        with_ = self.args.get("with")
1364        return with_.expressions if with_ else []
1365
1366    @property
1367    def selects(self) -> t.List[Expression]:
1368        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1369        return self.expression.selects if isinstance(self.expression, Query) else []
1370
1371    @property
1372    def named_selects(self) -> t.List[str]:
1373        """
1374        If this statement contains a query (e.g. a CTAS), this returns the output
1375        names of the query's projections.
1376        """
1377        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1360    @property
1361    def ctes(self) -> t.List[CTE]:
1362        """Returns a list of all the CTEs attached to this statement."""
1363        with_ = self.args.get("with")
1364        return with_.expressions if with_ else []

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

selects: List[Expression]
1366    @property
1367    def selects(self) -> t.List[Expression]:
1368        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1369        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]
1371    @property
1372    def named_selects(self) -> t.List[str]:
1373        """
1374        If this statement contains a query (e.g. a CTAS), this returns the output
1375        names of the query's projections.
1376        """
1377        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):
1380class DML(Expression):
1381    def returning(
1382        self,
1383        expression: ExpOrStr,
1384        dialect: DialectType = None,
1385        copy: bool = True,
1386        **opts,
1387    ) -> "Self":
1388        """
1389        Set the RETURNING expression. Not supported by all dialects.
1390
1391        Example:
1392            >>> delete("tbl").returning("*", dialect="postgres").sql()
1393            'DELETE FROM tbl RETURNING *'
1394
1395        Args:
1396            expression: the SQL code strings to parse.
1397                If an `Expression` instance is passed, it will be used as-is.
1398            dialect: the dialect used to parse the input expressions.
1399            copy: if `False`, modify this expression instance in-place.
1400            opts: other options to use to parse the input expressions.
1401
1402        Returns:
1403            Delete: the modified expression.
1404        """
1405        return _apply_builder(
1406            expression=expression,
1407            instance=self,
1408            arg="returning",
1409            prefix="RETURNING",
1410            dialect=dialect,
1411            copy=copy,
1412            into=Returning,
1413            **opts,
1414        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1381    def returning(
1382        self,
1383        expression: ExpOrStr,
1384        dialect: DialectType = None,
1385        copy: bool = True,
1386        **opts,
1387    ) -> "Self":
1388        """
1389        Set the RETURNING expression. Not supported by all dialects.
1390
1391        Example:
1392            >>> delete("tbl").returning("*", dialect="postgres").sql()
1393            'DELETE FROM tbl RETURNING *'
1394
1395        Args:
1396            expression: the SQL code strings to parse.
1397                If an `Expression` instance is passed, it will be used as-is.
1398            dialect: the dialect used to parse the input expressions.
1399            copy: if `False`, modify this expression instance in-place.
1400            opts: other options to use to parse the input expressions.
1401
1402        Returns:
1403            Delete: the modified expression.
1404        """
1405        return _apply_builder(
1406            expression=expression,
1407            instance=self,
1408            arg="returning",
1409            prefix="RETURNING",
1410            dialect=dialect,
1411            copy=copy,
1412            into=Returning,
1413            **opts,
1414        )

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):
1417class Create(DDL):
1418    arg_types = {
1419        "with": False,
1420        "this": True,
1421        "kind": True,
1422        "expression": False,
1423        "exists": False,
1424        "properties": False,
1425        "replace": False,
1426        "refresh": False,
1427        "unique": False,
1428        "indexes": False,
1429        "no_schema_binding": False,
1430        "begin": False,
1431        "end": False,
1432        "clone": False,
1433        "concurrently": False,
1434        "clustered": False,
1435    }
1436
1437    @property
1438    def kind(self) -> t.Optional[str]:
1439        kind = self.args.get("kind")
1440        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]
1437    @property
1438    def kind(self) -> t.Optional[str]:
1439        kind = self.args.get("kind")
1440        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1443class SequenceProperties(Expression):
1444    arg_types = {
1445        "increment": False,
1446        "minvalue": False,
1447        "maxvalue": False,
1448        "cache": False,
1449        "start": False,
1450        "owned": False,
1451        "options": False,
1452    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1455class TruncateTable(Expression):
1456    arg_types = {
1457        "expressions": True,
1458        "is_database": False,
1459        "exists": False,
1460        "only": False,
1461        "cluster": False,
1462        "identity": False,
1463        "option": False,
1464        "partition": False,
1465    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1471class Clone(Expression):
1472    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1475class Describe(Expression):
1476    arg_types = {
1477        "this": True,
1478        "style": False,
1479        "kind": False,
1480        "expressions": False,
1481        "partition": False,
1482        "format": False,
1483    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1487class Attach(Expression):
1488    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1492class Detach(Expression):
1493    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1497class Summarize(Expression):
1498    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1501class Kill(Expression):
1502    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1505class Pragma(Expression):
1506    pass
key = 'pragma'
class Declare(Expression):
1509class Declare(Expression):
1510    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1513class DeclareItem(Expression):
1514    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1517class Set(Expression):
1518    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1521class Heredoc(Expression):
1522    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1525class SetItem(Expression):
1526    arg_types = {
1527        "this": False,
1528        "expressions": False,
1529        "kind": False,
1530        "collate": False,  # MySQL SET NAMES statement
1531        "global": False,
1532    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1535class Show(Expression):
1536    arg_types = {
1537        "this": True,
1538        "history": False,
1539        "terse": False,
1540        "target": False,
1541        "offset": False,
1542        "starts_with": False,
1543        "limit": False,
1544        "from": False,
1545        "like": False,
1546        "where": False,
1547        "db": False,
1548        "scope": False,
1549        "scope_kind": False,
1550        "full": False,
1551        "mutex": False,
1552        "query": False,
1553        "channel": False,
1554        "global": False,
1555        "log": False,
1556        "position": False,
1557        "types": False,
1558    }
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}
key = 'show'
class UserDefinedFunction(Expression):
1561class UserDefinedFunction(Expression):
1562    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1565class CharacterSet(Expression):
1566    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1569class With(Expression):
1570    arg_types = {"expressions": True, "recursive": False}
1571
1572    @property
1573    def recursive(self) -> bool:
1574        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1572    @property
1573    def recursive(self) -> bool:
1574        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1577class WithinGroup(Expression):
1578    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1583class CTE(DerivedTable):
1584    arg_types = {
1585        "this": True,
1586        "alias": True,
1587        "scalar": False,
1588        "materialized": False,
1589    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1592class ProjectionDef(Expression):
1593    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1596class TableAlias(Expression):
1597    arg_types = {"this": False, "columns": False}
1598
1599    @property
1600    def columns(self):
1601        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1599    @property
1600    def columns(self):
1601        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1604class BitString(Condition):
1605    pass
key = 'bitstring'
class HexString(Condition):
1608class HexString(Condition):
1609    pass
key = 'hexstring'
class ByteString(Condition):
1612class ByteString(Condition):
1613    pass
key = 'bytestring'
class RawString(Condition):
1616class RawString(Condition):
1617    pass
key = 'rawstring'
class UnicodeString(Condition):
1620class UnicodeString(Condition):
1621    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1624class Column(Condition):
1625    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1626
1627    @property
1628    def table(self) -> str:
1629        return self.text("table")
1630
1631    @property
1632    def db(self) -> str:
1633        return self.text("db")
1634
1635    @property
1636    def catalog(self) -> str:
1637        return self.text("catalog")
1638
1639    @property
1640    def output_name(self) -> str:
1641        return self.name
1642
1643    @property
1644    def parts(self) -> t.List[Identifier]:
1645        """Return the parts of a column in order catalog, db, table, name."""
1646        return [
1647            t.cast(Identifier, self.args[part])
1648            for part in ("catalog", "db", "table", "this")
1649            if self.args.get(part)
1650        ]
1651
1652    def to_dot(self) -> Dot | Identifier:
1653        """Converts the column into a dot expression."""
1654        parts = self.parts
1655        parent = self.parent
1656
1657        while parent:
1658            if isinstance(parent, Dot):
1659                parts.append(parent.expression)
1660            parent = parent.parent
1661
1662        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
1627    @property
1628    def table(self) -> str:
1629        return self.text("table")
db: str
1631    @property
1632    def db(self) -> str:
1633        return self.text("db")
catalog: str
1635    @property
1636    def catalog(self) -> str:
1637        return self.text("catalog")
output_name: str
1639    @property
1640    def output_name(self) -> str:
1641        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]
1643    @property
1644    def parts(self) -> t.List[Identifier]:
1645        """Return the parts of a column in order catalog, db, table, name."""
1646        return [
1647            t.cast(Identifier, self.args[part])
1648            for part in ("catalog", "db", "table", "this")
1649            if self.args.get(part)
1650        ]

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

def to_dot(self) -> Dot | Identifier:
1652    def to_dot(self) -> Dot | Identifier:
1653        """Converts the column into a dot expression."""
1654        parts = self.parts
1655        parent = self.parent
1656
1657        while parent:
1658            if isinstance(parent, Dot):
1659                parts.append(parent.expression)
1660            parent = parent.parent
1661
1662        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1665class ColumnPosition(Expression):
1666    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1669class ColumnDef(Expression):
1670    arg_types = {
1671        "this": True,
1672        "kind": False,
1673        "constraints": False,
1674        "exists": False,
1675        "position": False,
1676    }
1677
1678    @property
1679    def constraints(self) -> t.List[ColumnConstraint]:
1680        return self.args.get("constraints") or []
1681
1682    @property
1683    def kind(self) -> t.Optional[DataType]:
1684        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1678    @property
1679    def constraints(self) -> t.List[ColumnConstraint]:
1680        return self.args.get("constraints") or []
kind: Optional[DataType]
1682    @property
1683    def kind(self) -> t.Optional[DataType]:
1684        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1687class AlterColumn(Expression):
1688    arg_types = {
1689        "this": True,
1690        "dtype": False,
1691        "collate": False,
1692        "using": False,
1693        "default": False,
1694        "drop": False,
1695        "comment": False,
1696        "allow_null": False,
1697    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1701class AlterDistStyle(Expression):
1702    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1705class AlterSortKey(Expression):
1706    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1709class AlterSet(Expression):
1710    arg_types = {
1711        "expressions": False,
1712        "option": False,
1713        "tablespace": False,
1714        "access_method": False,
1715        "file_format": False,
1716        "copy_options": False,
1717        "tag": False,
1718        "location": False,
1719        "serde": False,
1720    }
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):
1723class RenameColumn(Expression):
1724    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1727class AlterRename(Expression):
1728    pass
key = 'alterrename'
class SwapTable(Expression):
1731class SwapTable(Expression):
1732    pass
key = 'swaptable'
class Comment(Expression):
1735class Comment(Expression):
1736    arg_types = {
1737        "this": True,
1738        "kind": True,
1739        "expression": True,
1740        "exists": False,
1741        "materialized": False,
1742    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1745class Comprehension(Expression):
1746    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):
1750class MergeTreeTTLAction(Expression):
1751    arg_types = {
1752        "this": True,
1753        "delete": False,
1754        "recompress": False,
1755        "to_disk": False,
1756        "to_volume": False,
1757    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1761class MergeTreeTTL(Expression):
1762    arg_types = {
1763        "expressions": True,
1764        "where": False,
1765        "group": False,
1766        "aggregates": False,
1767    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1771class IndexConstraintOption(Expression):
1772    arg_types = {
1773        "key_block_size": False,
1774        "using": False,
1775        "parser": False,
1776        "comment": False,
1777        "visible": False,
1778        "engine_attr": False,
1779        "secondary_engine_attr": False,
1780    }
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):
1783class ColumnConstraint(Expression):
1784    arg_types = {"this": False, "kind": True}
1785
1786    @property
1787    def kind(self) -> ColumnConstraintKind:
1788        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1786    @property
1787    def kind(self) -> ColumnConstraintKind:
1788        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1791class ColumnConstraintKind(Expression):
1792    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1795class AutoIncrementColumnConstraint(ColumnConstraintKind):
1796    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1799class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1800    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1803class CaseSpecificColumnConstraint(ColumnConstraintKind):
1804    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1807class CharacterSetColumnConstraint(ColumnConstraintKind):
1808    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1811class CheckColumnConstraint(ColumnConstraintKind):
1812    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1815class ClusteredColumnConstraint(ColumnConstraintKind):
1816    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1819class CollateColumnConstraint(ColumnConstraintKind):
1820    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1823class CommentColumnConstraint(ColumnConstraintKind):
1824    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1827class CompressColumnConstraint(ColumnConstraintKind):
1828    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1831class DateFormatColumnConstraint(ColumnConstraintKind):
1832    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1835class DefaultColumnConstraint(ColumnConstraintKind):
1836    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1839class EncodeColumnConstraint(ColumnConstraintKind):
1840    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1844class ExcludeColumnConstraint(ColumnConstraintKind):
1845    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1848class EphemeralColumnConstraint(ColumnConstraintKind):
1849    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1852class WithOperator(Expression):
1853    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1856class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1857    # this: True -> ALWAYS, this: False -> BY DEFAULT
1858    arg_types = {
1859        "this": False,
1860        "expression": False,
1861        "on_null": False,
1862        "start": False,
1863        "increment": False,
1864        "minvalue": False,
1865        "maxvalue": False,
1866        "cycle": False,
1867    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1870class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1871    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1876class IndexColumnConstraint(ColumnConstraintKind):
1877    arg_types = {
1878        "this": False,
1879        "expressions": False,
1880        "kind": False,
1881        "index_type": False,
1882        "options": False,
1883        "expression": False,  # Clickhouse
1884        "granularity": False,
1885    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1888class InlineLengthColumnConstraint(ColumnConstraintKind):
1889    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1892class NonClusteredColumnConstraint(ColumnConstraintKind):
1893    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1896class NotForReplicationColumnConstraint(ColumnConstraintKind):
1897    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1901class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1902    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1905class NotNullColumnConstraint(ColumnConstraintKind):
1906    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1910class OnUpdateColumnConstraint(ColumnConstraintKind):
1911    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1915class TransformColumnConstraint(ColumnConstraintKind):
1916    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1919class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1920    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1923class TitleColumnConstraint(ColumnConstraintKind):
1924    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1927class UniqueColumnConstraint(ColumnConstraintKind):
1928    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1931class UppercaseColumnConstraint(ColumnConstraintKind):
1932    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1936class WatermarkColumnConstraint(Expression):
1937    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1940class PathColumnConstraint(ColumnConstraintKind):
1941    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1945class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1946    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1951class ComputedColumnConstraint(ColumnConstraintKind):
1952    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1955class Constraint(Expression):
1956    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1959class Delete(DML):
1960    arg_types = {
1961        "with": False,
1962        "this": False,
1963        "using": False,
1964        "where": False,
1965        "returning": False,
1966        "limit": False,
1967        "tables": False,  # Multiple-Table Syntax (MySQL)
1968        "cluster": False,  # Clickhouse
1969    }
1970
1971    def delete(
1972        self,
1973        table: ExpOrStr,
1974        dialect: DialectType = None,
1975        copy: bool = True,
1976        **opts,
1977    ) -> Delete:
1978        """
1979        Create a DELETE expression or replace the table on an existing DELETE expression.
1980
1981        Example:
1982            >>> delete("tbl").sql()
1983            'DELETE FROM tbl'
1984
1985        Args:
1986            table: the table from which to delete.
1987            dialect: the dialect used to parse the input expression.
1988            copy: if `False`, modify this expression instance in-place.
1989            opts: other options to use to parse the input expressions.
1990
1991        Returns:
1992            Delete: the modified expression.
1993        """
1994        return _apply_builder(
1995            expression=table,
1996            instance=self,
1997            arg="this",
1998            dialect=dialect,
1999            into=Table,
2000            copy=copy,
2001            **opts,
2002        )
2003
2004    def where(
2005        self,
2006        *expressions: t.Optional[ExpOrStr],
2007        append: bool = True,
2008        dialect: DialectType = None,
2009        copy: bool = True,
2010        **opts,
2011    ) -> Delete:
2012        """
2013        Append to or set the WHERE expressions.
2014
2015        Example:
2016            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2017            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2018
2019        Args:
2020            *expressions: the SQL code strings to parse.
2021                If an `Expression` instance is passed, it will be used as-is.
2022                Multiple expressions are combined with an AND operator.
2023            append: if `True`, AND the new expressions to any existing expression.
2024                Otherwise, this resets the expression.
2025            dialect: the dialect used to parse the input expressions.
2026            copy: if `False`, modify this expression instance in-place.
2027            opts: other options to use to parse the input expressions.
2028
2029        Returns:
2030            Delete: the modified expression.
2031        """
2032        return _apply_conjunction_builder(
2033            *expressions,
2034            instance=self,
2035            arg="where",
2036            append=append,
2037            into=Where,
2038            dialect=dialect,
2039            copy=copy,
2040            **opts,
2041        )
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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1971    def delete(
1972        self,
1973        table: ExpOrStr,
1974        dialect: DialectType = None,
1975        copy: bool = True,
1976        **opts,
1977    ) -> Delete:
1978        """
1979        Create a DELETE expression or replace the table on an existing DELETE expression.
1980
1981        Example:
1982            >>> delete("tbl").sql()
1983            'DELETE FROM tbl'
1984
1985        Args:
1986            table: the table from which to delete.
1987            dialect: the dialect used to parse the input expression.
1988            copy: if `False`, modify this expression instance in-place.
1989            opts: other options to use to parse the input expressions.
1990
1991        Returns:
1992            Delete: the modified expression.
1993        """
1994        return _apply_builder(
1995            expression=table,
1996            instance=self,
1997            arg="this",
1998            dialect=dialect,
1999            into=Table,
2000            copy=copy,
2001            **opts,
2002        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2004    def where(
2005        self,
2006        *expressions: t.Optional[ExpOrStr],
2007        append: bool = True,
2008        dialect: DialectType = None,
2009        copy: bool = True,
2010        **opts,
2011    ) -> Delete:
2012        """
2013        Append to or set the WHERE expressions.
2014
2015        Example:
2016            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2017            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2018
2019        Args:
2020            *expressions: the SQL code strings to parse.
2021                If an `Expression` instance is passed, it will be used as-is.
2022                Multiple expressions are combined with an AND operator.
2023            append: if `True`, AND the new expressions to any existing expression.
2024                Otherwise, this resets the expression.
2025            dialect: the dialect used to parse the input expressions.
2026            copy: if `False`, modify this expression instance in-place.
2027            opts: other options to use to parse the input expressions.
2028
2029        Returns:
2030            Delete: the modified expression.
2031        """
2032        return _apply_conjunction_builder(
2033            *expressions,
2034            instance=self,
2035            arg="where",
2036            append=append,
2037            into=Where,
2038            dialect=dialect,
2039            copy=copy,
2040            **opts,
2041        )

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):
2044class Drop(Expression):
2045    arg_types = {
2046        "this": False,
2047        "kind": False,
2048        "expressions": False,
2049        "exists": False,
2050        "temporary": False,
2051        "materialized": False,
2052        "cascade": False,
2053        "constraints": False,
2054        "purge": False,
2055        "cluster": False,
2056        "concurrently": False,
2057    }
2058
2059    @property
2060    def kind(self) -> t.Optional[str]:
2061        kind = self.args.get("kind")
2062        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]
2059    @property
2060    def kind(self) -> t.Optional[str]:
2061        kind = self.args.get("kind")
2062        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2065class Filter(Expression):
2066    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2069class Check(Expression):
2070    pass
key = 'check'
class Changes(Expression):
2073class Changes(Expression):
2074    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2078class Connect(Expression):
2079    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2082class CopyParameter(Expression):
2083    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2086class Copy(DML):
2087    arg_types = {
2088        "this": True,
2089        "kind": True,
2090        "files": True,
2091        "credentials": False,
2092        "format": False,
2093        "params": False,
2094    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2097class Credentials(Expression):
2098    arg_types = {
2099        "credentials": False,
2100        "encryption": False,
2101        "storage": False,
2102        "iam_role": False,
2103        "region": False,
2104    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2107class Prior(Expression):
2108    pass
key = 'prior'
class Directory(Expression):
2111class Directory(Expression):
2112    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2113    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2116class ForeignKey(Expression):
2117    arg_types = {
2118        "expressions": False,
2119        "reference": False,
2120        "delete": False,
2121        "update": False,
2122    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2125class ColumnPrefix(Expression):
2126    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2129class PrimaryKey(Expression):
2130    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2135class Into(Expression):
2136    arg_types = {
2137        "this": False,
2138        "temporary": False,
2139        "unlogged": False,
2140        "bulk_collect": False,
2141        "expressions": False,
2142    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2145class From(Expression):
2146    @property
2147    def name(self) -> str:
2148        return self.this.name
2149
2150    @property
2151    def alias_or_name(self) -> str:
2152        return self.this.alias_or_name
name: str
2146    @property
2147    def name(self) -> str:
2148        return self.this.name
alias_or_name: str
2150    @property
2151    def alias_or_name(self) -> str:
2152        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2155class Having(Expression):
2156    pass
key = 'having'
class Hint(Expression):
2159class Hint(Expression):
2160    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2163class JoinHint(Expression):
2164    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2167class Identifier(Expression):
2168    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2169
2170    @property
2171    def quoted(self) -> bool:
2172        return bool(self.args.get("quoted"))
2173
2174    @property
2175    def hashable_args(self) -> t.Any:
2176        return (self.this, self.quoted)
2177
2178    @property
2179    def output_name(self) -> str:
2180        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2170    @property
2171    def quoted(self) -> bool:
2172        return bool(self.args.get("quoted"))
hashable_args: Any
2174    @property
2175    def hashable_args(self) -> t.Any:
2176        return (self.this, self.quoted)
output_name: str
2178    @property
2179    def output_name(self) -> str:
2180        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):
2184class Opclass(Expression):
2185    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2188class Index(Expression):
2189    arg_types = {
2190        "this": False,
2191        "table": False,
2192        "unique": False,
2193        "primary": False,
2194        "amp": False,  # teradata
2195        "params": False,
2196    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2199class IndexParameters(Expression):
2200    arg_types = {
2201        "using": False,
2202        "include": False,
2203        "columns": False,
2204        "with_storage": False,
2205        "partition_by": False,
2206        "tablespace": False,
2207        "where": False,
2208        "on": False,
2209    }
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):
2212class Insert(DDL, DML):
2213    arg_types = {
2214        "hint": False,
2215        "with": False,
2216        "is_function": False,
2217        "this": False,
2218        "expression": False,
2219        "conflict": False,
2220        "returning": False,
2221        "overwrite": False,
2222        "exists": False,
2223        "alternative": False,
2224        "where": False,
2225        "ignore": False,
2226        "by_name": False,
2227        "stored": False,
2228        "partition": False,
2229        "settings": False,
2230        "source": False,
2231    }
2232
2233    def with_(
2234        self,
2235        alias: ExpOrStr,
2236        as_: ExpOrStr,
2237        recursive: t.Optional[bool] = None,
2238        materialized: t.Optional[bool] = None,
2239        append: bool = True,
2240        dialect: DialectType = None,
2241        copy: bool = True,
2242        **opts,
2243    ) -> Insert:
2244        """
2245        Append to or set the common table expressions.
2246
2247        Example:
2248            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2249            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2250
2251        Args:
2252            alias: the SQL code string to parse as the table name.
2253                If an `Expression` instance is passed, this is used as-is.
2254            as_: the SQL code string to parse as the table expression.
2255                If an `Expression` instance is passed, it will be used as-is.
2256            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2257            materialized: set the MATERIALIZED part of the expression.
2258            append: if `True`, add to any existing expressions.
2259                Otherwise, this resets the expressions.
2260            dialect: the dialect used to parse the input expression.
2261            copy: if `False`, modify this expression instance in-place.
2262            opts: other options to use to parse the input expressions.
2263
2264        Returns:
2265            The modified expression.
2266        """
2267        return _apply_cte_builder(
2268            self,
2269            alias,
2270            as_,
2271            recursive=recursive,
2272            materialized=materialized,
2273            append=append,
2274            dialect=dialect,
2275            copy=copy,
2276            **opts,
2277        )
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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2233    def with_(
2234        self,
2235        alias: ExpOrStr,
2236        as_: ExpOrStr,
2237        recursive: t.Optional[bool] = None,
2238        materialized: t.Optional[bool] = None,
2239        append: bool = True,
2240        dialect: DialectType = None,
2241        copy: bool = True,
2242        **opts,
2243    ) -> Insert:
2244        """
2245        Append to or set the common table expressions.
2246
2247        Example:
2248            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2249            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2250
2251        Args:
2252            alias: the SQL code string to parse as the table name.
2253                If an `Expression` instance is passed, this is used as-is.
2254            as_: the SQL code string to parse as the table expression.
2255                If an `Expression` instance is passed, it will be used as-is.
2256            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2257            materialized: set the MATERIALIZED part of the expression.
2258            append: if `True`, add to any existing expressions.
2259                Otherwise, this resets the expressions.
2260            dialect: the dialect used to parse the input expression.
2261            copy: if `False`, modify this expression instance in-place.
2262            opts: other options to use to parse the input expressions.
2263
2264        Returns:
2265            The modified expression.
2266        """
2267        return _apply_cte_builder(
2268            self,
2269            alias,
2270            as_,
2271            recursive=recursive,
2272            materialized=materialized,
2273            append=append,
2274            dialect=dialect,
2275            copy=copy,
2276            **opts,
2277        )

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):
2280class ConditionalInsert(Expression):
2281    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2284class MultitableInserts(Expression):
2285    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2288class OnConflict(Expression):
2289    arg_types = {
2290        "duplicate": False,
2291        "expressions": False,
2292        "action": False,
2293        "conflict_keys": False,
2294        "constraint": False,
2295        "where": False,
2296    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2299class OnCondition(Expression):
2300    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2303class Returning(Expression):
2304    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2308class Introducer(Expression):
2309    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2313class National(Expression):
2314    pass
key = 'national'
class LoadData(Expression):
2317class LoadData(Expression):
2318    arg_types = {
2319        "this": True,
2320        "local": False,
2321        "overwrite": False,
2322        "inpath": True,
2323        "partition": False,
2324        "input_format": False,
2325        "serde": False,
2326    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2329class Partition(Expression):
2330    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2333class PartitionRange(Expression):
2334    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2338class PartitionId(Expression):
2339    pass
key = 'partitionid'
class Fetch(Expression):
2342class Fetch(Expression):
2343    arg_types = {
2344        "direction": False,
2345        "count": False,
2346        "percent": False,
2347        "with_ties": False,
2348    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2351class Grant(Expression):
2352    arg_types = {
2353        "privileges": True,
2354        "kind": False,
2355        "securable": True,
2356        "principals": True,
2357        "grant_option": False,
2358    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2361class Group(Expression):
2362    arg_types = {
2363        "expressions": False,
2364        "grouping_sets": False,
2365        "cube": False,
2366        "rollup": False,
2367        "totals": False,
2368        "all": False,
2369    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2372class Cube(Expression):
2373    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2376class Rollup(Expression):
2377    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2380class GroupingSets(Expression):
2381    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2384class Lambda(Expression):
2385    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2388class Limit(Expression):
2389    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2392class Literal(Condition):
2393    arg_types = {"this": True, "is_string": True}
2394
2395    @property
2396    def hashable_args(self) -> t.Any:
2397        return (self.this, self.args.get("is_string"))
2398
2399    @classmethod
2400    def number(cls, number) -> Literal:
2401        return cls(this=str(number), is_string=False)
2402
2403    @classmethod
2404    def string(cls, string) -> Literal:
2405        return cls(this=str(string), is_string=True)
2406
2407    @property
2408    def output_name(self) -> str:
2409        return self.name
2410
2411    def to_py(self) -> int | str | Decimal:
2412        if self.is_number:
2413            try:
2414                return int(self.this)
2415            except ValueError:
2416                return Decimal(self.this)
2417        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2395    @property
2396    def hashable_args(self) -> t.Any:
2397        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2399    @classmethod
2400    def number(cls, number) -> Literal:
2401        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2403    @classmethod
2404    def string(cls, string) -> Literal:
2405        return cls(this=str(string), is_string=True)
output_name: str
2407    @property
2408    def output_name(self) -> str:
2409        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:
2411    def to_py(self) -> int | str | Decimal:
2412        if self.is_number:
2413            try:
2414                return int(self.this)
2415            except ValueError:
2416                return Decimal(self.this)
2417        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2420class Join(Expression):
2421    arg_types = {
2422        "this": True,
2423        "on": False,
2424        "side": False,
2425        "kind": False,
2426        "using": False,
2427        "method": False,
2428        "global": False,
2429        "hint": False,
2430        "match_condition": False,  # Snowflake
2431        "expressions": False,
2432    }
2433
2434    @property
2435    def method(self) -> str:
2436        return self.text("method").upper()
2437
2438    @property
2439    def kind(self) -> str:
2440        return self.text("kind").upper()
2441
2442    @property
2443    def side(self) -> str:
2444        return self.text("side").upper()
2445
2446    @property
2447    def hint(self) -> str:
2448        return self.text("hint").upper()
2449
2450    @property
2451    def alias_or_name(self) -> str:
2452        return self.this.alias_or_name
2453
2454    def on(
2455        self,
2456        *expressions: t.Optional[ExpOrStr],
2457        append: bool = True,
2458        dialect: DialectType = None,
2459        copy: bool = True,
2460        **opts,
2461    ) -> Join:
2462        """
2463        Append to or set the ON expressions.
2464
2465        Example:
2466            >>> import sqlglot
2467            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2468            'JOIN x ON y = 1'
2469
2470        Args:
2471            *expressions: the SQL code strings to parse.
2472                If an `Expression` instance is passed, it will be used as-is.
2473                Multiple expressions are combined with an AND operator.
2474            append: if `True`, AND the new expressions to any existing expression.
2475                Otherwise, this resets the expression.
2476            dialect: the dialect used to parse the input expressions.
2477            copy: if `False`, modify this expression instance in-place.
2478            opts: other options to use to parse the input expressions.
2479
2480        Returns:
2481            The modified Join expression.
2482        """
2483        join = _apply_conjunction_builder(
2484            *expressions,
2485            instance=self,
2486            arg="on",
2487            append=append,
2488            dialect=dialect,
2489            copy=copy,
2490            **opts,
2491        )
2492
2493        if join.kind == "CROSS":
2494            join.set("kind", None)
2495
2496        return join
2497
2498    def using(
2499        self,
2500        *expressions: t.Optional[ExpOrStr],
2501        append: bool = True,
2502        dialect: DialectType = None,
2503        copy: bool = True,
2504        **opts,
2505    ) -> Join:
2506        """
2507        Append to or set the USING expressions.
2508
2509        Example:
2510            >>> import sqlglot
2511            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2512            'JOIN x USING (foo, bla)'
2513
2514        Args:
2515            *expressions: the SQL code strings to parse.
2516                If an `Expression` instance is passed, it will be used as-is.
2517            append: if `True`, concatenate the new expressions to the existing "using" list.
2518                Otherwise, this resets the expression.
2519            dialect: the dialect used to parse the input expressions.
2520            copy: if `False`, modify this expression instance in-place.
2521            opts: other options to use to parse the input expressions.
2522
2523        Returns:
2524            The modified Join expression.
2525        """
2526        join = _apply_list_builder(
2527            *expressions,
2528            instance=self,
2529            arg="using",
2530            append=append,
2531            dialect=dialect,
2532            copy=copy,
2533            **opts,
2534        )
2535
2536        if join.kind == "CROSS":
2537            join.set("kind", None)
2538
2539        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
2434    @property
2435    def method(self) -> str:
2436        return self.text("method").upper()
kind: str
2438    @property
2439    def kind(self) -> str:
2440        return self.text("kind").upper()
side: str
2442    @property
2443    def side(self) -> str:
2444        return self.text("side").upper()
hint: str
2446    @property
2447    def hint(self) -> str:
2448        return self.text("hint").upper()
alias_or_name: str
2450    @property
2451    def alias_or_name(self) -> str:
2452        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2454    def on(
2455        self,
2456        *expressions: t.Optional[ExpOrStr],
2457        append: bool = True,
2458        dialect: DialectType = None,
2459        copy: bool = True,
2460        **opts,
2461    ) -> Join:
2462        """
2463        Append to or set the ON expressions.
2464
2465        Example:
2466            >>> import sqlglot
2467            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2468            'JOIN x ON y = 1'
2469
2470        Args:
2471            *expressions: the SQL code strings to parse.
2472                If an `Expression` instance is passed, it will be used as-is.
2473                Multiple expressions are combined with an AND operator.
2474            append: if `True`, AND the new expressions to any existing expression.
2475                Otherwise, this resets the expression.
2476            dialect: the dialect used to parse the input expressions.
2477            copy: if `False`, modify this expression instance in-place.
2478            opts: other options to use to parse the input expressions.
2479
2480        Returns:
2481            The modified Join expression.
2482        """
2483        join = _apply_conjunction_builder(
2484            *expressions,
2485            instance=self,
2486            arg="on",
2487            append=append,
2488            dialect=dialect,
2489            copy=copy,
2490            **opts,
2491        )
2492
2493        if join.kind == "CROSS":
2494            join.set("kind", None)
2495
2496        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2498    def using(
2499        self,
2500        *expressions: t.Optional[ExpOrStr],
2501        append: bool = True,
2502        dialect: DialectType = None,
2503        copy: bool = True,
2504        **opts,
2505    ) -> Join:
2506        """
2507        Append to or set the USING expressions.
2508
2509        Example:
2510            >>> import sqlglot
2511            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2512            'JOIN x USING (foo, bla)'
2513
2514        Args:
2515            *expressions: the SQL code strings to parse.
2516                If an `Expression` instance is passed, it will be used as-is.
2517            append: if `True`, concatenate the new expressions to the existing "using" list.
2518                Otherwise, this resets the expression.
2519            dialect: the dialect used to parse the input expressions.
2520            copy: if `False`, modify this expression instance in-place.
2521            opts: other options to use to parse the input expressions.
2522
2523        Returns:
2524            The modified Join expression.
2525        """
2526        join = _apply_list_builder(
2527            *expressions,
2528            instance=self,
2529            arg="using",
2530            append=append,
2531            dialect=dialect,
2532            copy=copy,
2533            **opts,
2534        )
2535
2536        if join.kind == "CROSS":
2537            join.set("kind", None)
2538
2539        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):
2542class Lateral(UDTF):
2543    arg_types = {
2544        "this": True,
2545        "view": False,
2546        "outer": False,
2547        "alias": False,
2548        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2549    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2552class MatchRecognizeMeasure(Expression):
2553    arg_types = {
2554        "this": True,
2555        "window_frame": False,
2556    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2559class MatchRecognize(Expression):
2560    arg_types = {
2561        "partition_by": False,
2562        "order": False,
2563        "measures": False,
2564        "rows": False,
2565        "after": False,
2566        "pattern": False,
2567        "define": False,
2568        "alias": False,
2569    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2574class Final(Expression):
2575    pass
key = 'final'
class Offset(Expression):
2578class Offset(Expression):
2579    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2582class Order(Expression):
2583    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2587class WithFill(Expression):
2588    arg_types = {
2589        "from": False,
2590        "to": False,
2591        "step": False,
2592        "interpolate": False,
2593    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2598class Cluster(Order):
2599    pass
key = 'cluster'
class Distribute(Order):
2602class Distribute(Order):
2603    pass
key = 'distribute'
class Sort(Order):
2606class Sort(Order):
2607    pass
key = 'sort'
class Ordered(Expression):
2610class Ordered(Expression):
2611    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2614class Property(Expression):
2615    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2618class GrantPrivilege(Expression):
2619    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2622class GrantPrincipal(Expression):
2623    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2626class AllowedValuesProperty(Expression):
2627    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2630class AlgorithmProperty(Property):
2631    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2634class AutoIncrementProperty(Property):
2635    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2639class AutoRefreshProperty(Property):
2640    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2643class BackupProperty(Property):
2644    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2647class BlockCompressionProperty(Property):
2648    arg_types = {
2649        "autotemp": False,
2650        "always": False,
2651        "default": False,
2652        "manual": False,
2653        "never": False,
2654    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2657class CharacterSetProperty(Property):
2658    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2661class ChecksumProperty(Property):
2662    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2665class CollateProperty(Property):
2666    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2669class CopyGrantsProperty(Property):
2670    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2673class DataBlocksizeProperty(Property):
2674    arg_types = {
2675        "size": False,
2676        "units": False,
2677        "minimum": False,
2678        "maximum": False,
2679        "default": False,
2680    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2683class DataDeletionProperty(Property):
2684    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):
2687class DefinerProperty(Property):
2688    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2691class DistKeyProperty(Property):
2692    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2697class DistributedByProperty(Property):
2698    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):
2701class DistStyleProperty(Property):
2702    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2705class DuplicateKeyProperty(Property):
2706    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2709class EngineProperty(Property):
2710    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2713class HeapProperty(Property):
2714    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2717class ToTableProperty(Property):
2718    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2721class ExecuteAsProperty(Property):
2722    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2725class ExternalProperty(Property):
2726    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2729class FallbackProperty(Property):
2730    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2733class FileFormatProperty(Property):
2734    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2737class FreespaceProperty(Property):
2738    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2741class GlobalProperty(Property):
2742    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2745class IcebergProperty(Property):
2746    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2749class InheritsProperty(Property):
2750    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2753class InputModelProperty(Property):
2754    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2757class OutputModelProperty(Property):
2758    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2761class IsolatedLoadingProperty(Property):
2762    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2765class JournalProperty(Property):
2766    arg_types = {
2767        "no": False,
2768        "dual": False,
2769        "before": False,
2770        "local": False,
2771        "after": False,
2772    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2775class LanguageProperty(Property):
2776    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2780class ClusteredByProperty(Property):
2781    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2784class DictProperty(Property):
2785    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2788class DictSubProperty(Property):
2789    pass
key = 'dictsubproperty'
class DictRange(Property):
2792class DictRange(Property):
2793    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2796class DynamicProperty(Property):
2797    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2802class OnCluster(Property):
2803    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2807class EmptyProperty(Property):
2808    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2811class LikeProperty(Property):
2812    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2815class LocationProperty(Property):
2816    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2819class LockProperty(Property):
2820    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2823class LockingProperty(Property):
2824    arg_types = {
2825        "this": False,
2826        "kind": True,
2827        "for_or_in": False,
2828        "lock_type": True,
2829        "override": False,
2830    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2833class LogProperty(Property):
2834    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2837class MaterializedProperty(Property):
2838    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2841class MergeBlockRatioProperty(Property):
2842    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):
2845class NoPrimaryIndexProperty(Property):
2846    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2849class OnProperty(Property):
2850    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2853class OnCommitProperty(Property):
2854    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2857class PartitionedByProperty(Property):
2858    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionByRangeProperty(Property):
2862class PartitionByRangeProperty(Property):
2863    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2867class PartitionByRangePropertyDynamic(Expression):
2868    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):
2872class UniqueKeyProperty(Property):
2873    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2877class PartitionBoundSpec(Expression):
2878    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2879    arg_types = {
2880        "this": False,
2881        "expression": False,
2882        "from_expressions": False,
2883        "to_expressions": False,
2884    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2887class PartitionedOfProperty(Property):
2888    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2889    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2892class StreamingTableProperty(Property):
2893    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2896class RemoteWithConnectionModelProperty(Property):
2897    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2900class ReturnsProperty(Property):
2901    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):
2904class StrictProperty(Property):
2905    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2908class RowFormatProperty(Property):
2909    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2912class RowFormatDelimitedProperty(Property):
2913    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2914    arg_types = {
2915        "fields": False,
2916        "escaped": False,
2917        "collection_items": False,
2918        "map_keys": False,
2919        "lines": False,
2920        "null": False,
2921        "serde": False,
2922    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2925class RowFormatSerdeProperty(Property):
2926    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2930class QueryTransform(Expression):
2931    arg_types = {
2932        "expressions": True,
2933        "command_script": True,
2934        "schema": False,
2935        "row_format_before": False,
2936        "record_writer": False,
2937        "row_format_after": False,
2938        "record_reader": False,
2939    }
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):
2942class SampleProperty(Property):
2943    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2947class SecurityProperty(Property):
2948    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2951class SchemaCommentProperty(Property):
2952    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2955class SerdeProperties(Property):
2956    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2959class SetProperty(Property):
2960    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2963class SharingProperty(Property):
2964    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2967class SetConfigProperty(Property):
2968    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2971class SettingsProperty(Property):
2972    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2975class SortKeyProperty(Property):
2976    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2979class SqlReadWriteProperty(Property):
2980    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2983class SqlSecurityProperty(Property):
2984    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2987class StabilityProperty(Property):
2988    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2991class TemporaryProperty(Property):
2992    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2995class SecureProperty(Property):
2996    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3000class Tags(ColumnConstraintKind, Property):
3001    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3004class TransformModelProperty(Property):
3005    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3008class TransientProperty(Property):
3009    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3012class UnloggedProperty(Property):
3013    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
3017class ViewAttributeProperty(Property):
3018    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3021class VolatileProperty(Property):
3022    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3025class WithDataProperty(Property):
3026    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3029class WithJournalTableProperty(Property):
3030    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3033class WithSchemaBindingProperty(Property):
3034    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3037class WithSystemVersioningProperty(Property):
3038    arg_types = {
3039        "on": False,
3040        "this": False,
3041        "data_consistency": False,
3042        "retention_period": False,
3043        "with": True,
3044    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3047class WithProcedureOptions(Property):
3048    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3051class EncodeProperty(Property):
3052    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3055class IncludeProperty(Property):
3056    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class Properties(Expression):
3059class Properties(Expression):
3060    arg_types = {"expressions": True}
3061
3062    NAME_TO_PROPERTY = {
3063        "ALGORITHM": AlgorithmProperty,
3064        "AUTO_INCREMENT": AutoIncrementProperty,
3065        "CHARACTER SET": CharacterSetProperty,
3066        "CLUSTERED_BY": ClusteredByProperty,
3067        "COLLATE": CollateProperty,
3068        "COMMENT": SchemaCommentProperty,
3069        "DEFINER": DefinerProperty,
3070        "DISTKEY": DistKeyProperty,
3071        "DISTRIBUTED_BY": DistributedByProperty,
3072        "DISTSTYLE": DistStyleProperty,
3073        "ENGINE": EngineProperty,
3074        "EXECUTE AS": ExecuteAsProperty,
3075        "FORMAT": FileFormatProperty,
3076        "LANGUAGE": LanguageProperty,
3077        "LOCATION": LocationProperty,
3078        "LOCK": LockProperty,
3079        "PARTITIONED_BY": PartitionedByProperty,
3080        "RETURNS": ReturnsProperty,
3081        "ROW_FORMAT": RowFormatProperty,
3082        "SORTKEY": SortKeyProperty,
3083        "ENCODE": EncodeProperty,
3084        "INCLUDE": IncludeProperty,
3085    }
3086
3087    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3088
3089    # CREATE property locations
3090    # Form: schema specified
3091    #   create [POST_CREATE]
3092    #     table a [POST_NAME]
3093    #     (b int) [POST_SCHEMA]
3094    #     with ([POST_WITH])
3095    #     index (b) [POST_INDEX]
3096    #
3097    # Form: alias selection
3098    #   create [POST_CREATE]
3099    #     table a [POST_NAME]
3100    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3101    #     index (c) [POST_INDEX]
3102    class Location(AutoName):
3103        POST_CREATE = auto()
3104        POST_NAME = auto()
3105        POST_SCHEMA = auto()
3106        POST_WITH = auto()
3107        POST_ALIAS = auto()
3108        POST_EXPRESSION = auto()
3109        POST_INDEX = auto()
3110        UNSUPPORTED = auto()
3111
3112    @classmethod
3113    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3114        expressions = []
3115        for key, value in properties_dict.items():
3116            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3117            if property_cls:
3118                expressions.append(property_cls(this=convert(value)))
3119            else:
3120                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3121
3122        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'>, '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 '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:
3112    @classmethod
3113    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3114        expressions = []
3115        for key, value in properties_dict.items():
3116            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3117            if property_cls:
3118                expressions.append(property_cls(this=convert(value)))
3119            else:
3120                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3121
3122        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3102    class Location(AutoName):
3103        POST_CREATE = auto()
3104        POST_NAME = auto()
3105        POST_SCHEMA = auto()
3106        POST_WITH = auto()
3107        POST_ALIAS = auto()
3108        POST_EXPRESSION = auto()
3109        POST_INDEX = auto()
3110        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):
3125class Qualify(Expression):
3126    pass
key = 'qualify'
class InputOutputFormat(Expression):
3129class InputOutputFormat(Expression):
3130    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3134class Return(Expression):
3135    pass
key = 'return'
class Reference(Expression):
3138class Reference(Expression):
3139    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3142class Tuple(Expression):
3143    arg_types = {"expressions": False}
3144
3145    def isin(
3146        self,
3147        *expressions: t.Any,
3148        query: t.Optional[ExpOrStr] = None,
3149        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3150        copy: bool = True,
3151        **opts,
3152    ) -> In:
3153        return In(
3154            this=maybe_copy(self, copy),
3155            expressions=[convert(e, copy=copy) for e in expressions],
3156            query=maybe_parse(query, copy=copy, **opts) if query else None,
3157            unnest=(
3158                Unnest(
3159                    expressions=[
3160                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3161                        for e in ensure_list(unnest)
3162                    ]
3163                )
3164                if unnest
3165                else None
3166            ),
3167        )
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:
3145    def isin(
3146        self,
3147        *expressions: t.Any,
3148        query: t.Optional[ExpOrStr] = None,
3149        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3150        copy: bool = True,
3151        **opts,
3152    ) -> In:
3153        return In(
3154            this=maybe_copy(self, copy),
3155            expressions=[convert(e, copy=copy) for e in expressions],
3156            query=maybe_parse(query, copy=copy, **opts) if query else None,
3157            unnest=(
3158                Unnest(
3159                    expressions=[
3160                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3161                        for e in ensure_list(unnest)
3162                    ]
3163                )
3164                if unnest
3165                else None
3166            ),
3167        )
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):
3198class QueryOption(Expression):
3199    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3203class WithTableHint(Expression):
3204    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3208class IndexTableHint(Expression):
3209    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3213class HistoricalData(Expression):
3214    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3217class Table(Expression):
3218    arg_types = {
3219        "this": False,
3220        "alias": False,
3221        "db": False,
3222        "catalog": False,
3223        "laterals": False,
3224        "joins": False,
3225        "pivots": False,
3226        "hints": False,
3227        "system_time": False,
3228        "version": False,
3229        "format": False,
3230        "pattern": False,
3231        "ordinality": False,
3232        "when": False,
3233        "only": False,
3234        "partition": False,
3235        "changes": False,
3236        "rows_from": False,
3237        "sample": False,
3238    }
3239
3240    @property
3241    def name(self) -> str:
3242        if isinstance(self.this, Func):
3243            return ""
3244        return self.this.name
3245
3246    @property
3247    def db(self) -> str:
3248        return self.text("db")
3249
3250    @property
3251    def catalog(self) -> str:
3252        return self.text("catalog")
3253
3254    @property
3255    def selects(self) -> t.List[Expression]:
3256        return []
3257
3258    @property
3259    def named_selects(self) -> t.List[str]:
3260        return []
3261
3262    @property
3263    def parts(self) -> t.List[Expression]:
3264        """Return the parts of a table in order catalog, db, table."""
3265        parts: t.List[Expression] = []
3266
3267        for arg in ("catalog", "db", "this"):
3268            part = self.args.get(arg)
3269
3270            if isinstance(part, Dot):
3271                parts.extend(part.flatten())
3272            elif isinstance(part, Expression):
3273                parts.append(part)
3274
3275        return parts
3276
3277    def to_column(self, copy: bool = True) -> Expression:
3278        parts = self.parts
3279        last_part = parts[-1]
3280
3281        if isinstance(last_part, Identifier):
3282            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3283        else:
3284            # This branch will be reached if a function or array is wrapped in a `Table`
3285            col = last_part
3286
3287        alias = self.args.get("alias")
3288        if alias:
3289            col = alias_(col, alias.this, copy=copy)
3290
3291        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
3240    @property
3241    def name(self) -> str:
3242        if isinstance(self.this, Func):
3243            return ""
3244        return self.this.name
db: str
3246    @property
3247    def db(self) -> str:
3248        return self.text("db")
catalog: str
3250    @property
3251    def catalog(self) -> str:
3252        return self.text("catalog")
selects: List[Expression]
3254    @property
3255    def selects(self) -> t.List[Expression]:
3256        return []
named_selects: List[str]
3258    @property
3259    def named_selects(self) -> t.List[str]:
3260        return []
parts: List[Expression]
3262    @property
3263    def parts(self) -> t.List[Expression]:
3264        """Return the parts of a table in order catalog, db, table."""
3265        parts: t.List[Expression] = []
3266
3267        for arg in ("catalog", "db", "this"):
3268            part = self.args.get(arg)
3269
3270            if isinstance(part, Dot):
3271                parts.extend(part.flatten())
3272            elif isinstance(part, Expression):
3273                parts.append(part)
3274
3275        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3277    def to_column(self, copy: bool = True) -> Expression:
3278        parts = self.parts
3279        last_part = parts[-1]
3280
3281        if isinstance(last_part, Identifier):
3282            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3283        else:
3284            # This branch will be reached if a function or array is wrapped in a `Table`
3285            col = last_part
3286
3287        alias = self.args.get("alias")
3288        if alias:
3289            col = alias_(col, alias.this, copy=copy)
3290
3291        return col
key = 'table'
class SetOperation(Query):
3294class SetOperation(Query):
3295    arg_types = {
3296        "with": False,
3297        "this": True,
3298        "expression": True,
3299        "distinct": False,
3300        "by_name": False,
3301        **QUERY_MODIFIERS,
3302    }
3303
3304    def select(
3305        self: S,
3306        *expressions: t.Optional[ExpOrStr],
3307        append: bool = True,
3308        dialect: DialectType = None,
3309        copy: bool = True,
3310        **opts,
3311    ) -> S:
3312        this = maybe_copy(self, copy)
3313        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3314        this.expression.unnest().select(
3315            *expressions, append=append, dialect=dialect, copy=False, **opts
3316        )
3317        return this
3318
3319    @property
3320    def named_selects(self) -> t.List[str]:
3321        return self.this.unnest().named_selects
3322
3323    @property
3324    def is_star(self) -> bool:
3325        return self.this.is_star or self.expression.is_star
3326
3327    @property
3328    def selects(self) -> t.List[Expression]:
3329        return self.this.unnest().selects
3330
3331    @property
3332    def left(self) -> Query:
3333        return self.this
3334
3335    @property
3336    def right(self) -> Query:
3337        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3304    def select(
3305        self: S,
3306        *expressions: t.Optional[ExpOrStr],
3307        append: bool = True,
3308        dialect: DialectType = None,
3309        copy: bool = True,
3310        **opts,
3311    ) -> S:
3312        this = maybe_copy(self, copy)
3313        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3314        this.expression.unnest().select(
3315            *expressions, append=append, dialect=dialect, copy=False, **opts
3316        )
3317        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]
3319    @property
3320    def named_selects(self) -> t.List[str]:
3321        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3323    @property
3324    def is_star(self) -> bool:
3325        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3327    @property
3328    def selects(self) -> t.List[Expression]:
3329        return self.this.unnest().selects

Returns the query's projections.

left: Query
3331    @property
3332    def left(self) -> Query:
3333        return self.this
right: Query
3335    @property
3336    def right(self) -> Query:
3337        return self.expression
key = 'setoperation'
class Union(SetOperation):
3340class Union(SetOperation):
3341    pass
key = 'union'
class Except(SetOperation):
3344class Except(SetOperation):
3345    pass
key = 'except'
class Intersect(SetOperation):
3348class Intersect(SetOperation):
3349    pass
key = 'intersect'
class Update(DML):
3352class Update(DML):
3353    arg_types = {
3354        "with": False,
3355        "this": False,
3356        "expressions": True,
3357        "from": False,
3358        "where": False,
3359        "returning": False,
3360        "order": False,
3361        "limit": False,
3362    }
3363
3364    def table(
3365        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3366    ) -> Update:
3367        """
3368        Set the table to update.
3369
3370        Example:
3371            >>> Update().table("my_table").set_("x = 1").sql()
3372            'UPDATE my_table SET x = 1'
3373
3374        Args:
3375            expression : the SQL code strings to parse.
3376                If a `Table` instance is passed, this is used as-is.
3377                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3378            dialect: the dialect used to parse the input expression.
3379            copy: if `False`, modify this expression instance in-place.
3380            opts: other options to use to parse the input expressions.
3381
3382        Returns:
3383            The modified Update expression.
3384        """
3385        return _apply_builder(
3386            expression=expression,
3387            instance=self,
3388            arg="this",
3389            into=Table,
3390            prefix=None,
3391            dialect=dialect,
3392            copy=copy,
3393            **opts,
3394        )
3395
3396    def set_(
3397        self,
3398        *expressions: ExpOrStr,
3399        append: bool = True,
3400        dialect: DialectType = None,
3401        copy: bool = True,
3402        **opts,
3403    ) -> Update:
3404        """
3405        Append to or set the SET expressions.
3406
3407        Example:
3408            >>> Update().table("my_table").set_("x = 1").sql()
3409            'UPDATE my_table SET x = 1'
3410
3411        Args:
3412            *expressions: the SQL code strings to parse.
3413                If `Expression` instance(s) are passed, they will be used as-is.
3414                Multiple expressions are combined with a comma.
3415            append: if `True`, add the new expressions to any existing SET expressions.
3416                Otherwise, this resets the expressions.
3417            dialect: the dialect used to parse the input expressions.
3418            copy: if `False`, modify this expression instance in-place.
3419            opts: other options to use to parse the input expressions.
3420        """
3421        return _apply_list_builder(
3422            *expressions,
3423            instance=self,
3424            arg="expressions",
3425            append=append,
3426            into=Expression,
3427            prefix=None,
3428            dialect=dialect,
3429            copy=copy,
3430            **opts,
3431        )
3432
3433    def where(
3434        self,
3435        *expressions: t.Optional[ExpOrStr],
3436        append: bool = True,
3437        dialect: DialectType = None,
3438        copy: bool = True,
3439        **opts,
3440    ) -> Select:
3441        """
3442        Append to or set the WHERE expressions.
3443
3444        Example:
3445            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3446            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3447
3448        Args:
3449            *expressions: the SQL code strings to parse.
3450                If an `Expression` instance is passed, it will be used as-is.
3451                Multiple expressions are combined with an AND operator.
3452            append: if `True`, AND the new expressions to any existing expression.
3453                Otherwise, this resets the expression.
3454            dialect: the dialect used to parse the input expressions.
3455            copy: if `False`, modify this expression instance in-place.
3456            opts: other options to use to parse the input expressions.
3457
3458        Returns:
3459            Select: the modified expression.
3460        """
3461        return _apply_conjunction_builder(
3462            *expressions,
3463            instance=self,
3464            arg="where",
3465            append=append,
3466            into=Where,
3467            dialect=dialect,
3468            copy=copy,
3469            **opts,
3470        )
3471
3472    def from_(
3473        self,
3474        expression: t.Optional[ExpOrStr] = None,
3475        dialect: DialectType = None,
3476        copy: bool = True,
3477        **opts,
3478    ) -> Update:
3479        """
3480        Set the FROM expression.
3481
3482        Example:
3483            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3484            'UPDATE my_table SET x = 1 FROM baz'
3485
3486        Args:
3487            expression : the SQL code strings to parse.
3488                If a `From` instance is passed, this is used as-is.
3489                If another `Expression` instance is passed, it will be wrapped in a `From`.
3490                If nothing is passed in then a from is not applied to the expression
3491            dialect: the dialect used to parse the input expression.
3492            copy: if `False`, modify this expression instance in-place.
3493            opts: other options to use to parse the input expressions.
3494
3495        Returns:
3496            The modified Update expression.
3497        """
3498        if not expression:
3499            return maybe_copy(self, copy)
3500
3501        return _apply_builder(
3502            expression=expression,
3503            instance=self,
3504            arg="from",
3505            into=From,
3506            prefix="FROM",
3507            dialect=dialect,
3508            copy=copy,
3509            **opts,
3510        )
3511
3512    def with_(
3513        self,
3514        alias: ExpOrStr,
3515        as_: ExpOrStr,
3516        recursive: t.Optional[bool] = None,
3517        materialized: t.Optional[bool] = None,
3518        append: bool = True,
3519        dialect: DialectType = None,
3520        copy: bool = True,
3521        **opts,
3522    ) -> Update:
3523        """
3524        Append to or set the common table expressions.
3525
3526        Example:
3527            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3528            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3529
3530        Args:
3531            alias: the SQL code string to parse as the table name.
3532                If an `Expression` instance is passed, this is used as-is.
3533            as_: the SQL code string to parse as the table expression.
3534                If an `Expression` instance is passed, it will be used as-is.
3535            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3536            materialized: set the MATERIALIZED part of the expression.
3537            append: if `True`, add to any existing expressions.
3538                Otherwise, this resets the expressions.
3539            dialect: the dialect used to parse the input expression.
3540            copy: if `False`, modify this expression instance in-place.
3541            opts: other options to use to parse the input expressions.
3542
3543        Returns:
3544            The modified expression.
3545        """
3546        return _apply_cte_builder(
3547            self,
3548            alias,
3549            as_,
3550            recursive=recursive,
3551            materialized=materialized,
3552            append=append,
3553            dialect=dialect,
3554            copy=copy,
3555            **opts,
3556        )
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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3364    def table(
3365        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3366    ) -> Update:
3367        """
3368        Set the table to update.
3369
3370        Example:
3371            >>> Update().table("my_table").set_("x = 1").sql()
3372            'UPDATE my_table SET x = 1'
3373
3374        Args:
3375            expression : the SQL code strings to parse.
3376                If a `Table` instance is passed, this is used as-is.
3377                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3378            dialect: the dialect used to parse the input expression.
3379            copy: if `False`, modify this expression instance in-place.
3380            opts: other options to use to parse the input expressions.
3381
3382        Returns:
3383            The modified Update expression.
3384        """
3385        return _apply_builder(
3386            expression=expression,
3387            instance=self,
3388            arg="this",
3389            into=Table,
3390            prefix=None,
3391            dialect=dialect,
3392            copy=copy,
3393            **opts,
3394        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3396    def set_(
3397        self,
3398        *expressions: ExpOrStr,
3399        append: bool = True,
3400        dialect: DialectType = None,
3401        copy: bool = True,
3402        **opts,
3403    ) -> Update:
3404        """
3405        Append to or set the SET expressions.
3406
3407        Example:
3408            >>> Update().table("my_table").set_("x = 1").sql()
3409            'UPDATE my_table SET x = 1'
3410
3411        Args:
3412            *expressions: the SQL code strings to parse.
3413                If `Expression` instance(s) are passed, they will be used as-is.
3414                Multiple expressions are combined with a comma.
3415            append: if `True`, add the new expressions to any existing SET expressions.
3416                Otherwise, this resets the expressions.
3417            dialect: the dialect used to parse the input expressions.
3418            copy: if `False`, modify this expression instance in-place.
3419            opts: other options to use to parse the input expressions.
3420        """
3421        return _apply_list_builder(
3422            *expressions,
3423            instance=self,
3424            arg="expressions",
3425            append=append,
3426            into=Expression,
3427            prefix=None,
3428            dialect=dialect,
3429            copy=copy,
3430            **opts,
3431        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3433    def where(
3434        self,
3435        *expressions: t.Optional[ExpOrStr],
3436        append: bool = True,
3437        dialect: DialectType = None,
3438        copy: bool = True,
3439        **opts,
3440    ) -> Select:
3441        """
3442        Append to or set the WHERE expressions.
3443
3444        Example:
3445            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3446            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3447
3448        Args:
3449            *expressions: the SQL code strings to parse.
3450                If an `Expression` instance is passed, it will be used as-is.
3451                Multiple expressions are combined with an AND operator.
3452            append: if `True`, AND the new expressions to any existing expression.
3453                Otherwise, this resets the expression.
3454            dialect: the dialect used to parse the input expressions.
3455            copy: if `False`, modify this expression instance in-place.
3456            opts: other options to use to parse the input expressions.
3457
3458        Returns:
3459            Select: the modified expression.
3460        """
3461        return _apply_conjunction_builder(
3462            *expressions,
3463            instance=self,
3464            arg="where",
3465            append=append,
3466            into=Where,
3467            dialect=dialect,
3468            copy=copy,
3469            **opts,
3470        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3472    def from_(
3473        self,
3474        expression: t.Optional[ExpOrStr] = None,
3475        dialect: DialectType = None,
3476        copy: bool = True,
3477        **opts,
3478    ) -> Update:
3479        """
3480        Set the FROM expression.
3481
3482        Example:
3483            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3484            'UPDATE my_table SET x = 1 FROM baz'
3485
3486        Args:
3487            expression : the SQL code strings to parse.
3488                If a `From` instance is passed, this is used as-is.
3489                If another `Expression` instance is passed, it will be wrapped in a `From`.
3490                If nothing is passed in then a from is not applied to the expression
3491            dialect: the dialect used to parse the input expression.
3492            copy: if `False`, modify this expression instance in-place.
3493            opts: other options to use to parse the input expressions.
3494
3495        Returns:
3496            The modified Update expression.
3497        """
3498        if not expression:
3499            return maybe_copy(self, copy)
3500
3501        return _apply_builder(
3502            expression=expression,
3503            instance=self,
3504            arg="from",
3505            into=From,
3506            prefix="FROM",
3507            dialect=dialect,
3508            copy=copy,
3509            **opts,
3510        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3512    def with_(
3513        self,
3514        alias: ExpOrStr,
3515        as_: ExpOrStr,
3516        recursive: t.Optional[bool] = None,
3517        materialized: t.Optional[bool] = None,
3518        append: bool = True,
3519        dialect: DialectType = None,
3520        copy: bool = True,
3521        **opts,
3522    ) -> Update:
3523        """
3524        Append to or set the common table expressions.
3525
3526        Example:
3527            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3528            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3529
3530        Args:
3531            alias: the SQL code string to parse as the table name.
3532                If an `Expression` instance is passed, this is used as-is.
3533            as_: the SQL code string to parse as the table expression.
3534                If an `Expression` instance is passed, it will be used as-is.
3535            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3536            materialized: set the MATERIALIZED part of the expression.
3537            append: if `True`, add to any existing expressions.
3538                Otherwise, this resets the expressions.
3539            dialect: the dialect used to parse the input expression.
3540            copy: if `False`, modify this expression instance in-place.
3541            opts: other options to use to parse the input expressions.
3542
3543        Returns:
3544            The modified expression.
3545        """
3546        return _apply_cte_builder(
3547            self,
3548            alias,
3549            as_,
3550            recursive=recursive,
3551            materialized=materialized,
3552            append=append,
3553            dialect=dialect,
3554            copy=copy,
3555            **opts,
3556        )

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):
3559class Values(UDTF):
3560    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3563class Var(Expression):
3564    pass
key = 'var'
class Version(Expression):
3567class Version(Expression):
3568    """
3569    Time travel, iceberg, bigquery etc
3570    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3571    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3572    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3573    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3574    this is either TIMESTAMP or VERSION
3575    kind is ("AS OF", "BETWEEN")
3576    """
3577
3578    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3581class Schema(Expression):
3582    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3587class Lock(Expression):
3588    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3591class Select(Query):
3592    arg_types = {
3593        "with": False,
3594        "kind": False,
3595        "expressions": False,
3596        "hint": False,
3597        "distinct": False,
3598        "into": False,
3599        "from": False,
3600        "operation_modifiers": False,
3601        **QUERY_MODIFIERS,
3602    }
3603
3604    def from_(
3605        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3606    ) -> Select:
3607        """
3608        Set the FROM expression.
3609
3610        Example:
3611            >>> Select().from_("tbl").select("x").sql()
3612            'SELECT x FROM tbl'
3613
3614        Args:
3615            expression : the SQL code strings to parse.
3616                If a `From` instance is passed, this is used as-is.
3617                If another `Expression` instance is passed, it will be wrapped in a `From`.
3618            dialect: the dialect used to parse the input expression.
3619            copy: if `False`, modify this expression instance in-place.
3620            opts: other options to use to parse the input expressions.
3621
3622        Returns:
3623            The modified Select expression.
3624        """
3625        return _apply_builder(
3626            expression=expression,
3627            instance=self,
3628            arg="from",
3629            into=From,
3630            prefix="FROM",
3631            dialect=dialect,
3632            copy=copy,
3633            **opts,
3634        )
3635
3636    def group_by(
3637        self,
3638        *expressions: t.Optional[ExpOrStr],
3639        append: bool = True,
3640        dialect: DialectType = None,
3641        copy: bool = True,
3642        **opts,
3643    ) -> Select:
3644        """
3645        Set the GROUP BY expression.
3646
3647        Example:
3648            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3649            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3650
3651        Args:
3652            *expressions: the SQL code strings to parse.
3653                If a `Group` instance is passed, this is used as-is.
3654                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3655                If nothing is passed in then a group by is not applied to the expression
3656            append: if `True`, add to any existing expressions.
3657                Otherwise, this flattens all the `Group` expression into a single expression.
3658            dialect: the dialect used to parse the input expression.
3659            copy: if `False`, modify this expression instance in-place.
3660            opts: other options to use to parse the input expressions.
3661
3662        Returns:
3663            The modified Select expression.
3664        """
3665        if not expressions:
3666            return self if not copy else self.copy()
3667
3668        return _apply_child_list_builder(
3669            *expressions,
3670            instance=self,
3671            arg="group",
3672            append=append,
3673            copy=copy,
3674            prefix="GROUP BY",
3675            into=Group,
3676            dialect=dialect,
3677            **opts,
3678        )
3679
3680    def sort_by(
3681        self,
3682        *expressions: t.Optional[ExpOrStr],
3683        append: bool = True,
3684        dialect: DialectType = None,
3685        copy: bool = True,
3686        **opts,
3687    ) -> Select:
3688        """
3689        Set the SORT BY expression.
3690
3691        Example:
3692            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3693            'SELECT x FROM tbl SORT BY x DESC'
3694
3695        Args:
3696            *expressions: the SQL code strings to parse.
3697                If a `Group` instance is passed, this is used as-is.
3698                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3699            append: if `True`, add to any existing expressions.
3700                Otherwise, this flattens all the `Order` expression into a single expression.
3701            dialect: the dialect used to parse the input expression.
3702            copy: if `False`, modify this expression instance in-place.
3703            opts: other options to use to parse the input expressions.
3704
3705        Returns:
3706            The modified Select expression.
3707        """
3708        return _apply_child_list_builder(
3709            *expressions,
3710            instance=self,
3711            arg="sort",
3712            append=append,
3713            copy=copy,
3714            prefix="SORT BY",
3715            into=Sort,
3716            dialect=dialect,
3717            **opts,
3718        )
3719
3720    def cluster_by(
3721        self,
3722        *expressions: t.Optional[ExpOrStr],
3723        append: bool = True,
3724        dialect: DialectType = None,
3725        copy: bool = True,
3726        **opts,
3727    ) -> Select:
3728        """
3729        Set the CLUSTER BY expression.
3730
3731        Example:
3732            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3733            'SELECT x FROM tbl CLUSTER BY x DESC'
3734
3735        Args:
3736            *expressions: the SQL code strings to parse.
3737                If a `Group` instance is passed, this is used as-is.
3738                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3739            append: if `True`, add to any existing expressions.
3740                Otherwise, this flattens all the `Order` expression into a single expression.
3741            dialect: the dialect used to parse the input expression.
3742            copy: if `False`, modify this expression instance in-place.
3743            opts: other options to use to parse the input expressions.
3744
3745        Returns:
3746            The modified Select expression.
3747        """
3748        return _apply_child_list_builder(
3749            *expressions,
3750            instance=self,
3751            arg="cluster",
3752            append=append,
3753            copy=copy,
3754            prefix="CLUSTER BY",
3755            into=Cluster,
3756            dialect=dialect,
3757            **opts,
3758        )
3759
3760    def select(
3761        self,
3762        *expressions: t.Optional[ExpOrStr],
3763        append: bool = True,
3764        dialect: DialectType = None,
3765        copy: bool = True,
3766        **opts,
3767    ) -> Select:
3768        return _apply_list_builder(
3769            *expressions,
3770            instance=self,
3771            arg="expressions",
3772            append=append,
3773            dialect=dialect,
3774            into=Expression,
3775            copy=copy,
3776            **opts,
3777        )
3778
3779    def lateral(
3780        self,
3781        *expressions: t.Optional[ExpOrStr],
3782        append: bool = True,
3783        dialect: DialectType = None,
3784        copy: bool = True,
3785        **opts,
3786    ) -> Select:
3787        """
3788        Append to or set the LATERAL expressions.
3789
3790        Example:
3791            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3792            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3793
3794        Args:
3795            *expressions: the SQL code strings to parse.
3796                If an `Expression` instance is passed, it will be used as-is.
3797            append: if `True`, add to any existing expressions.
3798                Otherwise, this resets the expressions.
3799            dialect: the dialect used to parse the input expressions.
3800            copy: if `False`, modify this expression instance in-place.
3801            opts: other options to use to parse the input expressions.
3802
3803        Returns:
3804            The modified Select expression.
3805        """
3806        return _apply_list_builder(
3807            *expressions,
3808            instance=self,
3809            arg="laterals",
3810            append=append,
3811            into=Lateral,
3812            prefix="LATERAL VIEW",
3813            dialect=dialect,
3814            copy=copy,
3815            **opts,
3816        )
3817
3818    def join(
3819        self,
3820        expression: ExpOrStr,
3821        on: t.Optional[ExpOrStr] = None,
3822        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3823        append: bool = True,
3824        join_type: t.Optional[str] = None,
3825        join_alias: t.Optional[Identifier | str] = None,
3826        dialect: DialectType = None,
3827        copy: bool = True,
3828        **opts,
3829    ) -> Select:
3830        """
3831        Append to or set the JOIN expressions.
3832
3833        Example:
3834            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3835            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3836
3837            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3838            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3839
3840            Use `join_type` to change the type of join:
3841
3842            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3843            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3844
3845        Args:
3846            expression: the SQL code string to parse.
3847                If an `Expression` instance is passed, it will be used as-is.
3848            on: optionally specify the join "on" criteria as a SQL string.
3849                If an `Expression` instance is passed, it will be used as-is.
3850            using: optionally specify the join "using" criteria as a SQL string.
3851                If an `Expression` instance is passed, it will be used as-is.
3852            append: if `True`, add to any existing expressions.
3853                Otherwise, this resets the expressions.
3854            join_type: if set, alter the parsed join type.
3855            join_alias: an optional alias for the joined source.
3856            dialect: the dialect used to parse the input expressions.
3857            copy: if `False`, modify this expression instance in-place.
3858            opts: other options to use to parse the input expressions.
3859
3860        Returns:
3861            Select: the modified expression.
3862        """
3863        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3864
3865        try:
3866            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3867        except ParseError:
3868            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3869
3870        join = expression if isinstance(expression, Join) else Join(this=expression)
3871
3872        if isinstance(join.this, Select):
3873            join.this.replace(join.this.subquery())
3874
3875        if join_type:
3876            method: t.Optional[Token]
3877            side: t.Optional[Token]
3878            kind: t.Optional[Token]
3879
3880            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3881
3882            if method:
3883                join.set("method", method.text)
3884            if side:
3885                join.set("side", side.text)
3886            if kind:
3887                join.set("kind", kind.text)
3888
3889        if on:
3890            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3891            join.set("on", on)
3892
3893        if using:
3894            join = _apply_list_builder(
3895                *ensure_list(using),
3896                instance=join,
3897                arg="using",
3898                append=append,
3899                copy=copy,
3900                into=Identifier,
3901                **opts,
3902            )
3903
3904        if join_alias:
3905            join.set("this", alias_(join.this, join_alias, table=True))
3906
3907        return _apply_list_builder(
3908            join,
3909            instance=self,
3910            arg="joins",
3911            append=append,
3912            copy=copy,
3913            **opts,
3914        )
3915
3916    def where(
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 WHERE expressions.
3926
3927        Example:
3928            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3929            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
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                Multiple expressions are combined with an AND operator.
3935            append: if `True`, AND the new expressions to any existing expression.
3936                Otherwise, this resets the expression.
3937            dialect: the dialect used to parse the input expressions.
3938            copy: if `False`, modify this expression instance in-place.
3939            opts: other options to use to parse the input expressions.
3940
3941        Returns:
3942            Select: the modified expression.
3943        """
3944        return _apply_conjunction_builder(
3945            *expressions,
3946            instance=self,
3947            arg="where",
3948            append=append,
3949            into=Where,
3950            dialect=dialect,
3951            copy=copy,
3952            **opts,
3953        )
3954
3955    def having(
3956        self,
3957        *expressions: t.Optional[ExpOrStr],
3958        append: bool = True,
3959        dialect: DialectType = None,
3960        copy: bool = True,
3961        **opts,
3962    ) -> Select:
3963        """
3964        Append to or set the HAVING expressions.
3965
3966        Example:
3967            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3968            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3969
3970        Args:
3971            *expressions: the SQL code strings to parse.
3972                If an `Expression` instance is passed, it will be used as-is.
3973                Multiple expressions are combined with an AND operator.
3974            append: if `True`, AND the new expressions to any existing expression.
3975                Otherwise, this resets the expression.
3976            dialect: the dialect used to parse the input expressions.
3977            copy: if `False`, modify this expression instance in-place.
3978            opts: other options to use to parse the input expressions.
3979
3980        Returns:
3981            The modified Select expression.
3982        """
3983        return _apply_conjunction_builder(
3984            *expressions,
3985            instance=self,
3986            arg="having",
3987            append=append,
3988            into=Having,
3989            dialect=dialect,
3990            copy=copy,
3991            **opts,
3992        )
3993
3994    def window(
3995        self,
3996        *expressions: t.Optional[ExpOrStr],
3997        append: bool = True,
3998        dialect: DialectType = None,
3999        copy: bool = True,
4000        **opts,
4001    ) -> Select:
4002        return _apply_list_builder(
4003            *expressions,
4004            instance=self,
4005            arg="windows",
4006            append=append,
4007            into=Window,
4008            dialect=dialect,
4009            copy=copy,
4010            **opts,
4011        )
4012
4013    def qualify(
4014        self,
4015        *expressions: t.Optional[ExpOrStr],
4016        append: bool = True,
4017        dialect: DialectType = None,
4018        copy: bool = True,
4019        **opts,
4020    ) -> Select:
4021        return _apply_conjunction_builder(
4022            *expressions,
4023            instance=self,
4024            arg="qualify",
4025            append=append,
4026            into=Qualify,
4027            dialect=dialect,
4028            copy=copy,
4029            **opts,
4030        )
4031
4032    def distinct(
4033        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4034    ) -> Select:
4035        """
4036        Set the OFFSET expression.
4037
4038        Example:
4039            >>> Select().from_("tbl").select("x").distinct().sql()
4040            'SELECT DISTINCT x FROM tbl'
4041
4042        Args:
4043            ons: the expressions to distinct on
4044            distinct: whether the Select should be distinct
4045            copy: if `False`, modify this expression instance in-place.
4046
4047        Returns:
4048            Select: the modified expression.
4049        """
4050        instance = maybe_copy(self, copy)
4051        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4052        instance.set("distinct", Distinct(on=on) if distinct else None)
4053        return instance
4054
4055    def ctas(
4056        self,
4057        table: ExpOrStr,
4058        properties: t.Optional[t.Dict] = None,
4059        dialect: DialectType = None,
4060        copy: bool = True,
4061        **opts,
4062    ) -> Create:
4063        """
4064        Convert this expression to a CREATE TABLE AS statement.
4065
4066        Example:
4067            >>> Select().select("*").from_("tbl").ctas("x").sql()
4068            'CREATE TABLE x AS SELECT * FROM tbl'
4069
4070        Args:
4071            table: the SQL code string to parse as the table name.
4072                If another `Expression` instance is passed, it will be used as-is.
4073            properties: an optional mapping of table properties
4074            dialect: the dialect used to parse the input table.
4075            copy: if `False`, modify this expression instance in-place.
4076            opts: other options to use to parse the input table.
4077
4078        Returns:
4079            The new Create expression.
4080        """
4081        instance = maybe_copy(self, copy)
4082        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4083
4084        properties_expression = None
4085        if properties:
4086            properties_expression = Properties.from_dict(properties)
4087
4088        return Create(
4089            this=table_expression,
4090            kind="TABLE",
4091            expression=instance,
4092            properties=properties_expression,
4093        )
4094
4095    def lock(self, update: bool = True, copy: bool = True) -> Select:
4096        """
4097        Set the locking read mode for this expression.
4098
4099        Examples:
4100            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4101            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4102
4103            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4104            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4105
4106        Args:
4107            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4108            copy: if `False`, modify this expression instance in-place.
4109
4110        Returns:
4111            The modified expression.
4112        """
4113        inst = maybe_copy(self, copy)
4114        inst.set("locks", [Lock(update=update)])
4115
4116        return inst
4117
4118    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4119        """
4120        Set hints for this expression.
4121
4122        Examples:
4123            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4124            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4125
4126        Args:
4127            hints: The SQL code strings to parse as the hints.
4128                If an `Expression` instance is passed, it will be used as-is.
4129            dialect: The dialect used to parse the hints.
4130            copy: If `False`, modify this expression instance in-place.
4131
4132        Returns:
4133            The modified expression.
4134        """
4135        inst = maybe_copy(self, copy)
4136        inst.set(
4137            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4138        )
4139
4140        return inst
4141
4142    @property
4143    def named_selects(self) -> t.List[str]:
4144        return [e.output_name for e in self.expressions if e.alias_or_name]
4145
4146    @property
4147    def is_star(self) -> bool:
4148        return any(expression.is_star for expression in self.expressions)
4149
4150    @property
4151    def selects(self) -> t.List[Expression]:
4152        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3604    def from_(
3605        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3606    ) -> Select:
3607        """
3608        Set the FROM expression.
3609
3610        Example:
3611            >>> Select().from_("tbl").select("x").sql()
3612            'SELECT x FROM tbl'
3613
3614        Args:
3615            expression : the SQL code strings to parse.
3616                If a `From` instance is passed, this is used as-is.
3617                If another `Expression` instance is passed, it will be wrapped in a `From`.
3618            dialect: the dialect used to parse the input expression.
3619            copy: if `False`, modify this expression instance in-place.
3620            opts: other options to use to parse the input expressions.
3621
3622        Returns:
3623            The modified Select expression.
3624        """
3625        return _apply_builder(
3626            expression=expression,
3627            instance=self,
3628            arg="from",
3629            into=From,
3630            prefix="FROM",
3631            dialect=dialect,
3632            copy=copy,
3633            **opts,
3634        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3636    def group_by(
3637        self,
3638        *expressions: t.Optional[ExpOrStr],
3639        append: bool = True,
3640        dialect: DialectType = None,
3641        copy: bool = True,
3642        **opts,
3643    ) -> Select:
3644        """
3645        Set the GROUP BY expression.
3646
3647        Example:
3648            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3649            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3650
3651        Args:
3652            *expressions: the SQL code strings to parse.
3653                If a `Group` instance is passed, this is used as-is.
3654                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3655                If nothing is passed in then a group by is not applied to the expression
3656            append: if `True`, add to any existing expressions.
3657                Otherwise, this flattens all the `Group` expression into a single expression.
3658            dialect: the dialect used to parse the input expression.
3659            copy: if `False`, modify this expression instance in-place.
3660            opts: other options to use to parse the input expressions.
3661
3662        Returns:
3663            The modified Select expression.
3664        """
3665        if not expressions:
3666            return self if not copy else self.copy()
3667
3668        return _apply_child_list_builder(
3669            *expressions,
3670            instance=self,
3671            arg="group",
3672            append=append,
3673            copy=copy,
3674            prefix="GROUP BY",
3675            into=Group,
3676            dialect=dialect,
3677            **opts,
3678        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3680    def sort_by(
3681        self,
3682        *expressions: t.Optional[ExpOrStr],
3683        append: bool = True,
3684        dialect: DialectType = None,
3685        copy: bool = True,
3686        **opts,
3687    ) -> Select:
3688        """
3689        Set the SORT BY expression.
3690
3691        Example:
3692            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3693            'SELECT x FROM tbl SORT BY x DESC'
3694
3695        Args:
3696            *expressions: the SQL code strings to parse.
3697                If a `Group` instance is passed, this is used as-is.
3698                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3699            append: if `True`, add to any existing expressions.
3700                Otherwise, this flattens all the `Order` expression into a single expression.
3701            dialect: the dialect used to parse the input expression.
3702            copy: if `False`, modify this expression instance in-place.
3703            opts: other options to use to parse the input expressions.
3704
3705        Returns:
3706            The modified Select expression.
3707        """
3708        return _apply_child_list_builder(
3709            *expressions,
3710            instance=self,
3711            arg="sort",
3712            append=append,
3713            copy=copy,
3714            prefix="SORT BY",
3715            into=Sort,
3716            dialect=dialect,
3717            **opts,
3718        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3720    def cluster_by(
3721        self,
3722        *expressions: t.Optional[ExpOrStr],
3723        append: bool = True,
3724        dialect: DialectType = None,
3725        copy: bool = True,
3726        **opts,
3727    ) -> Select:
3728        """
3729        Set the CLUSTER BY expression.
3730
3731        Example:
3732            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3733            'SELECT x FROM tbl CLUSTER BY x DESC'
3734
3735        Args:
3736            *expressions: the SQL code strings to parse.
3737                If a `Group` instance is passed, this is used as-is.
3738                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3739            append: if `True`, add to any existing expressions.
3740                Otherwise, this flattens all the `Order` expression into a single expression.
3741            dialect: the dialect used to parse the input expression.
3742            copy: if `False`, modify this expression instance in-place.
3743            opts: other options to use to parse the input expressions.
3744
3745        Returns:
3746            The modified Select expression.
3747        """
3748        return _apply_child_list_builder(
3749            *expressions,
3750            instance=self,
3751            arg="cluster",
3752            append=append,
3753            copy=copy,
3754            prefix="CLUSTER BY",
3755            into=Cluster,
3756            dialect=dialect,
3757            **opts,
3758        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3760    def select(
3761        self,
3762        *expressions: t.Optional[ExpOrStr],
3763        append: bool = True,
3764        dialect: DialectType = None,
3765        copy: bool = True,
3766        **opts,
3767    ) -> Select:
3768        return _apply_list_builder(
3769            *expressions,
3770            instance=self,
3771            arg="expressions",
3772            append=append,
3773            dialect=dialect,
3774            into=Expression,
3775            copy=copy,
3776            **opts,
3777        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3779    def lateral(
3780        self,
3781        *expressions: t.Optional[ExpOrStr],
3782        append: bool = True,
3783        dialect: DialectType = None,
3784        copy: bool = True,
3785        **opts,
3786    ) -> Select:
3787        """
3788        Append to or set the LATERAL expressions.
3789
3790        Example:
3791            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3792            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3793
3794        Args:
3795            *expressions: the SQL code strings to parse.
3796                If an `Expression` instance is passed, it will be used as-is.
3797            append: if `True`, add to any existing expressions.
3798                Otherwise, this resets the expressions.
3799            dialect: the dialect used to parse the input expressions.
3800            copy: if `False`, modify this expression instance in-place.
3801            opts: other options to use to parse the input expressions.
3802
3803        Returns:
3804            The modified Select expression.
3805        """
3806        return _apply_list_builder(
3807            *expressions,
3808            instance=self,
3809            arg="laterals",
3810            append=append,
3811            into=Lateral,
3812            prefix="LATERAL VIEW",
3813            dialect=dialect,
3814            copy=copy,
3815            **opts,
3816        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3818    def join(
3819        self,
3820        expression: ExpOrStr,
3821        on: t.Optional[ExpOrStr] = None,
3822        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3823        append: bool = True,
3824        join_type: t.Optional[str] = None,
3825        join_alias: t.Optional[Identifier | str] = None,
3826        dialect: DialectType = None,
3827        copy: bool = True,
3828        **opts,
3829    ) -> Select:
3830        """
3831        Append to or set the JOIN expressions.
3832
3833        Example:
3834            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3835            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3836
3837            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3838            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3839
3840            Use `join_type` to change the type of join:
3841
3842            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3843            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3844
3845        Args:
3846            expression: the SQL code string to parse.
3847                If an `Expression` instance is passed, it will be used as-is.
3848            on: optionally specify the join "on" criteria as a SQL string.
3849                If an `Expression` instance is passed, it will be used as-is.
3850            using: optionally specify the join "using" criteria as a SQL string.
3851                If an `Expression` instance is passed, it will be used as-is.
3852            append: if `True`, add to any existing expressions.
3853                Otherwise, this resets the expressions.
3854            join_type: if set, alter the parsed join type.
3855            join_alias: an optional alias for the joined source.
3856            dialect: the dialect used to parse the input expressions.
3857            copy: if `False`, modify this expression instance in-place.
3858            opts: other options to use to parse the input expressions.
3859
3860        Returns:
3861            Select: the modified expression.
3862        """
3863        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3864
3865        try:
3866            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3867        except ParseError:
3868            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3869
3870        join = expression if isinstance(expression, Join) else Join(this=expression)
3871
3872        if isinstance(join.this, Select):
3873            join.this.replace(join.this.subquery())
3874
3875        if join_type:
3876            method: t.Optional[Token]
3877            side: t.Optional[Token]
3878            kind: t.Optional[Token]
3879
3880            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3881
3882            if method:
3883                join.set("method", method.text)
3884            if side:
3885                join.set("side", side.text)
3886            if kind:
3887                join.set("kind", kind.text)
3888
3889        if on:
3890            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3891            join.set("on", on)
3892
3893        if using:
3894            join = _apply_list_builder(
3895                *ensure_list(using),
3896                instance=join,
3897                arg="using",
3898                append=append,
3899                copy=copy,
3900                into=Identifier,
3901                **opts,
3902            )
3903
3904        if join_alias:
3905            join.set("this", alias_(join.this, join_alias, table=True))
3906
3907        return _apply_list_builder(
3908            join,
3909            instance=self,
3910            arg="joins",
3911            append=append,
3912            copy=copy,
3913            **opts,
3914        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3916    def where(
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 WHERE expressions.
3926
3927        Example:
3928            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3929            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
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                Multiple expressions are combined with an AND operator.
3935            append: if `True`, AND the new expressions to any existing expression.
3936                Otherwise, this resets the expression.
3937            dialect: the dialect used to parse the input expressions.
3938            copy: if `False`, modify this expression instance in-place.
3939            opts: other options to use to parse the input expressions.
3940
3941        Returns:
3942            Select: the modified expression.
3943        """
3944        return _apply_conjunction_builder(
3945            *expressions,
3946            instance=self,
3947            arg="where",
3948            append=append,
3949            into=Where,
3950            dialect=dialect,
3951            copy=copy,
3952            **opts,
3953        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3955    def having(
3956        self,
3957        *expressions: t.Optional[ExpOrStr],
3958        append: bool = True,
3959        dialect: DialectType = None,
3960        copy: bool = True,
3961        **opts,
3962    ) -> Select:
3963        """
3964        Append to or set the HAVING expressions.
3965
3966        Example:
3967            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3968            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3969
3970        Args:
3971            *expressions: the SQL code strings to parse.
3972                If an `Expression` instance is passed, it will be used as-is.
3973                Multiple expressions are combined with an AND operator.
3974            append: if `True`, AND the new expressions to any existing expression.
3975                Otherwise, this resets the expression.
3976            dialect: the dialect used to parse the input expressions.
3977            copy: if `False`, modify this expression instance in-place.
3978            opts: other options to use to parse the input expressions.
3979
3980        Returns:
3981            The modified Select expression.
3982        """
3983        return _apply_conjunction_builder(
3984            *expressions,
3985            instance=self,
3986            arg="having",
3987            append=append,
3988            into=Having,
3989            dialect=dialect,
3990            copy=copy,
3991            **opts,
3992        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3994    def window(
3995        self,
3996        *expressions: t.Optional[ExpOrStr],
3997        append: bool = True,
3998        dialect: DialectType = None,
3999        copy: bool = True,
4000        **opts,
4001    ) -> Select:
4002        return _apply_list_builder(
4003            *expressions,
4004            instance=self,
4005            arg="windows",
4006            append=append,
4007            into=Window,
4008            dialect=dialect,
4009            copy=copy,
4010            **opts,
4011        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4013    def qualify(
4014        self,
4015        *expressions: t.Optional[ExpOrStr],
4016        append: bool = True,
4017        dialect: DialectType = None,
4018        copy: bool = True,
4019        **opts,
4020    ) -> Select:
4021        return _apply_conjunction_builder(
4022            *expressions,
4023            instance=self,
4024            arg="qualify",
4025            append=append,
4026            into=Qualify,
4027            dialect=dialect,
4028            copy=copy,
4029            **opts,
4030        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4032    def distinct(
4033        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4034    ) -> Select:
4035        """
4036        Set the OFFSET expression.
4037
4038        Example:
4039            >>> Select().from_("tbl").select("x").distinct().sql()
4040            'SELECT DISTINCT x FROM tbl'
4041
4042        Args:
4043            ons: the expressions to distinct on
4044            distinct: whether the Select should be distinct
4045            copy: if `False`, modify this expression instance in-place.
4046
4047        Returns:
4048            Select: the modified expression.
4049        """
4050        instance = maybe_copy(self, copy)
4051        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4052        instance.set("distinct", Distinct(on=on) if distinct else None)
4053        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4055    def ctas(
4056        self,
4057        table: ExpOrStr,
4058        properties: t.Optional[t.Dict] = None,
4059        dialect: DialectType = None,
4060        copy: bool = True,
4061        **opts,
4062    ) -> Create:
4063        """
4064        Convert this expression to a CREATE TABLE AS statement.
4065
4066        Example:
4067            >>> Select().select("*").from_("tbl").ctas("x").sql()
4068            'CREATE TABLE x AS SELECT * FROM tbl'
4069
4070        Args:
4071            table: the SQL code string to parse as the table name.
4072                If another `Expression` instance is passed, it will be used as-is.
4073            properties: an optional mapping of table properties
4074            dialect: the dialect used to parse the input table.
4075            copy: if `False`, modify this expression instance in-place.
4076            opts: other options to use to parse the input table.
4077
4078        Returns:
4079            The new Create expression.
4080        """
4081        instance = maybe_copy(self, copy)
4082        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4083
4084        properties_expression = None
4085        if properties:
4086            properties_expression = Properties.from_dict(properties)
4087
4088        return Create(
4089            this=table_expression,
4090            kind="TABLE",
4091            expression=instance,
4092            properties=properties_expression,
4093        )

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:
4095    def lock(self, update: bool = True, copy: bool = True) -> Select:
4096        """
4097        Set the locking read mode for this expression.
4098
4099        Examples:
4100            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4101            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4102
4103            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4104            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4105
4106        Args:
4107            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4108            copy: if `False`, modify this expression instance in-place.
4109
4110        Returns:
4111            The modified expression.
4112        """
4113        inst = maybe_copy(self, copy)
4114        inst.set("locks", [Lock(update=update)])
4115
4116        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
4118    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4119        """
4120        Set hints for this expression.
4121
4122        Examples:
4123            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4124            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4125
4126        Args:
4127            hints: The SQL code strings to parse as the hints.
4128                If an `Expression` instance is passed, it will be used as-is.
4129            dialect: The dialect used to parse the hints.
4130            copy: If `False`, modify this expression instance in-place.
4131
4132        Returns:
4133            The modified expression.
4134        """
4135        inst = maybe_copy(self, copy)
4136        inst.set(
4137            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4138        )
4139
4140        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]
4142    @property
4143    def named_selects(self) -> t.List[str]:
4144        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
4146    @property
4147    def is_star(self) -> bool:
4148        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4150    @property
4151    def selects(self) -> t.List[Expression]:
4152        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4158class Subquery(DerivedTable, Query):
4159    arg_types = {
4160        "this": True,
4161        "alias": False,
4162        "with": False,
4163        **QUERY_MODIFIERS,
4164    }
4165
4166    def unnest(self):
4167        """Returns the first non subquery."""
4168        expression = self
4169        while isinstance(expression, Subquery):
4170            expression = expression.this
4171        return expression
4172
4173    def unwrap(self) -> Subquery:
4174        expression = self
4175        while expression.same_parent and expression.is_wrapper:
4176            expression = t.cast(Subquery, expression.parent)
4177        return expression
4178
4179    def select(
4180        self,
4181        *expressions: t.Optional[ExpOrStr],
4182        append: bool = True,
4183        dialect: DialectType = None,
4184        copy: bool = True,
4185        **opts,
4186    ) -> Subquery:
4187        this = maybe_copy(self, copy)
4188        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4189        return this
4190
4191    @property
4192    def is_wrapper(self) -> bool:
4193        """
4194        Whether this Subquery acts as a simple wrapper around another expression.
4195
4196        SELECT * FROM (((SELECT * FROM t)))
4197                      ^
4198                      This corresponds to a "wrapper" Subquery node
4199        """
4200        return all(v is None for k, v in self.args.items() if k != "this")
4201
4202    @property
4203    def is_star(self) -> bool:
4204        return self.this.is_star
4205
4206    @property
4207    def output_name(self) -> str:
4208        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):
4166    def unnest(self):
4167        """Returns the first non subquery."""
4168        expression = self
4169        while isinstance(expression, Subquery):
4170            expression = expression.this
4171        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4173    def unwrap(self) -> Subquery:
4174        expression = self
4175        while expression.same_parent and expression.is_wrapper:
4176            expression = t.cast(Subquery, expression.parent)
4177        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4179    def select(
4180        self,
4181        *expressions: t.Optional[ExpOrStr],
4182        append: bool = True,
4183        dialect: DialectType = None,
4184        copy: bool = True,
4185        **opts,
4186    ) -> Subquery:
4187        this = maybe_copy(self, copy)
4188        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4189        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
4191    @property
4192    def is_wrapper(self) -> bool:
4193        """
4194        Whether this Subquery acts as a simple wrapper around another expression.
4195
4196        SELECT * FROM (((SELECT * FROM t)))
4197                      ^
4198                      This corresponds to a "wrapper" Subquery node
4199        """
4200        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
4202    @property
4203    def is_star(self) -> bool:
4204        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4206    @property
4207    def output_name(self) -> str:
4208        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):
4211class TableSample(Expression):
4212    arg_types = {
4213        "expressions": False,
4214        "method": False,
4215        "bucket_numerator": False,
4216        "bucket_denominator": False,
4217        "bucket_field": False,
4218        "percent": False,
4219        "rows": False,
4220        "size": False,
4221        "seed": False,
4222    }
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):
4225class Tag(Expression):
4226    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4227
4228    arg_types = {
4229        "this": False,
4230        "prefix": False,
4231        "postfix": False,
4232    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4237class Pivot(Expression):
4238    arg_types = {
4239        "this": False,
4240        "alias": False,
4241        "expressions": False,
4242        "field": False,
4243        "unpivot": False,
4244        "using": False,
4245        "group": False,
4246        "columns": False,
4247        "include_nulls": False,
4248        "default_on_null": False,
4249        "into": False,
4250    }
4251
4252    @property
4253    def unpivot(self) -> bool:
4254        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4252    @property
4253    def unpivot(self) -> bool:
4254        return bool(self.args.get("unpivot"))
key = 'pivot'
class UnpivotColumns(Expression):
4259class UnpivotColumns(Expression):
4260    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4263class Window(Condition):
4264    arg_types = {
4265        "this": True,
4266        "partition_by": False,
4267        "order": False,
4268        "spec": False,
4269        "alias": False,
4270        "over": False,
4271        "first": False,
4272    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4275class WindowSpec(Expression):
4276    arg_types = {
4277        "kind": False,
4278        "start": False,
4279        "start_side": False,
4280        "end": False,
4281        "end_side": False,
4282    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4285class PreWhere(Expression):
4286    pass
key = 'prewhere'
class Where(Expression):
4289class Where(Expression):
4290    pass
key = 'where'
class Star(Expression):
4293class Star(Expression):
4294    arg_types = {"except": False, "replace": False, "rename": False}
4295
4296    @property
4297    def name(self) -> str:
4298        return "*"
4299
4300    @property
4301    def output_name(self) -> str:
4302        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4296    @property
4297    def name(self) -> str:
4298        return "*"
output_name: str
4300    @property
4301    def output_name(self) -> str:
4302        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):
4305class Parameter(Condition):
4306    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4309class SessionParameter(Condition):
4310    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4313class Placeholder(Condition):
4314    arg_types = {"this": False, "kind": False}
4315
4316    @property
4317    def name(self) -> str:
4318        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4316    @property
4317    def name(self) -> str:
4318        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4321class Null(Condition):
4322    arg_types: t.Dict[str, t.Any] = {}
4323
4324    @property
4325    def name(self) -> str:
4326        return "NULL"
4327
4328    def to_py(self) -> Lit[None]:
4329        return None
arg_types: Dict[str, Any] = {}
name: str
4324    @property
4325    def name(self) -> str:
4326        return "NULL"
def to_py(self) -> Literal[None]:
4328    def to_py(self) -> Lit[None]:
4329        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4332class Boolean(Condition):
4333    def to_py(self) -> bool:
4334        return self.this
def to_py(self) -> bool:
4333    def to_py(self) -> bool:
4334        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4337class DataTypeParam(Expression):
4338    arg_types = {"this": True, "expression": False}
4339
4340    @property
4341    def name(self) -> str:
4342        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4340    @property
4341    def name(self) -> str:
4342        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4347class DataType(Expression):
4348    arg_types = {
4349        "this": True,
4350        "expressions": False,
4351        "nested": False,
4352        "values": False,
4353        "prefix": False,
4354        "kind": False,
4355        "nullable": False,
4356    }
4357
4358    class Type(AutoName):
4359        ARRAY = auto()
4360        AGGREGATEFUNCTION = auto()
4361        SIMPLEAGGREGATEFUNCTION = auto()
4362        BIGDECIMAL = auto()
4363        BIGINT = auto()
4364        BIGSERIAL = auto()
4365        BINARY = auto()
4366        BIT = auto()
4367        BOOLEAN = auto()
4368        BPCHAR = auto()
4369        CHAR = auto()
4370        DATE = auto()
4371        DATE32 = auto()
4372        DATEMULTIRANGE = auto()
4373        DATERANGE = auto()
4374        DATETIME = auto()
4375        DATETIME2 = auto()
4376        DATETIME64 = auto()
4377        DECIMAL = auto()
4378        DECIMAL32 = auto()
4379        DECIMAL64 = auto()
4380        DECIMAL128 = auto()
4381        DECIMAL256 = auto()
4382        DOUBLE = auto()
4383        ENUM = auto()
4384        ENUM8 = auto()
4385        ENUM16 = auto()
4386        FIXEDSTRING = auto()
4387        FLOAT = auto()
4388        GEOGRAPHY = auto()
4389        GEOMETRY = auto()
4390        POINT = auto()
4391        RING = auto()
4392        LINESTRING = auto()
4393        MULTILINESTRING = auto()
4394        POLYGON = auto()
4395        MULTIPOLYGON = auto()
4396        HLLSKETCH = auto()
4397        HSTORE = auto()
4398        IMAGE = auto()
4399        INET = auto()
4400        INT = auto()
4401        INT128 = auto()
4402        INT256 = auto()
4403        INT4MULTIRANGE = auto()
4404        INT4RANGE = auto()
4405        INT8MULTIRANGE = auto()
4406        INT8RANGE = auto()
4407        INTERVAL = auto()
4408        IPADDRESS = auto()
4409        IPPREFIX = auto()
4410        IPV4 = auto()
4411        IPV6 = auto()
4412        JSON = auto()
4413        JSONB = auto()
4414        LIST = auto()
4415        LONGBLOB = auto()
4416        LONGTEXT = auto()
4417        LOWCARDINALITY = auto()
4418        MAP = auto()
4419        MEDIUMBLOB = auto()
4420        MEDIUMINT = auto()
4421        MEDIUMTEXT = auto()
4422        MONEY = auto()
4423        NAME = auto()
4424        NCHAR = auto()
4425        NESTED = auto()
4426        NULL = auto()
4427        NUMMULTIRANGE = auto()
4428        NUMRANGE = auto()
4429        NVARCHAR = auto()
4430        OBJECT = auto()
4431        RANGE = auto()
4432        ROWVERSION = auto()
4433        SERIAL = auto()
4434        SET = auto()
4435        SMALLDATETIME = auto()
4436        SMALLINT = auto()
4437        SMALLMONEY = auto()
4438        SMALLSERIAL = auto()
4439        STRUCT = auto()
4440        SUPER = auto()
4441        TEXT = auto()
4442        TINYBLOB = auto()
4443        TINYTEXT = auto()
4444        TIME = auto()
4445        TIMETZ = auto()
4446        TIMESTAMP = auto()
4447        TIMESTAMPNTZ = auto()
4448        TIMESTAMPLTZ = auto()
4449        TIMESTAMPTZ = auto()
4450        TIMESTAMP_S = auto()
4451        TIMESTAMP_MS = auto()
4452        TIMESTAMP_NS = auto()
4453        TINYINT = auto()
4454        TSMULTIRANGE = auto()
4455        TSRANGE = auto()
4456        TSTZMULTIRANGE = auto()
4457        TSTZRANGE = auto()
4458        UBIGINT = auto()
4459        UINT = auto()
4460        UINT128 = auto()
4461        UINT256 = auto()
4462        UMEDIUMINT = auto()
4463        UDECIMAL = auto()
4464        UNION = auto()
4465        UNIQUEIDENTIFIER = auto()
4466        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4467        USERDEFINED = "USER-DEFINED"
4468        USMALLINT = auto()
4469        UTINYINT = auto()
4470        UUID = auto()
4471        VARBINARY = auto()
4472        VARCHAR = auto()
4473        VARIANT = auto()
4474        VECTOR = auto()
4475        XML = auto()
4476        YEAR = auto()
4477        TDIGEST = auto()
4478
4479    STRUCT_TYPES = {
4480        Type.NESTED,
4481        Type.OBJECT,
4482        Type.STRUCT,
4483        Type.UNION,
4484    }
4485
4486    ARRAY_TYPES = {
4487        Type.ARRAY,
4488        Type.LIST,
4489    }
4490
4491    NESTED_TYPES = {
4492        *STRUCT_TYPES,
4493        *ARRAY_TYPES,
4494        Type.MAP,
4495    }
4496
4497    TEXT_TYPES = {
4498        Type.CHAR,
4499        Type.NCHAR,
4500        Type.NVARCHAR,
4501        Type.TEXT,
4502        Type.VARCHAR,
4503        Type.NAME,
4504    }
4505
4506    SIGNED_INTEGER_TYPES = {
4507        Type.BIGINT,
4508        Type.INT,
4509        Type.INT128,
4510        Type.INT256,
4511        Type.MEDIUMINT,
4512        Type.SMALLINT,
4513        Type.TINYINT,
4514    }
4515
4516    UNSIGNED_INTEGER_TYPES = {
4517        Type.UBIGINT,
4518        Type.UINT,
4519        Type.UINT128,
4520        Type.UINT256,
4521        Type.UMEDIUMINT,
4522        Type.USMALLINT,
4523        Type.UTINYINT,
4524    }
4525
4526    INTEGER_TYPES = {
4527        *SIGNED_INTEGER_TYPES,
4528        *UNSIGNED_INTEGER_TYPES,
4529        Type.BIT,
4530    }
4531
4532    FLOAT_TYPES = {
4533        Type.DOUBLE,
4534        Type.FLOAT,
4535    }
4536
4537    REAL_TYPES = {
4538        *FLOAT_TYPES,
4539        Type.BIGDECIMAL,
4540        Type.DECIMAL,
4541        Type.DECIMAL32,
4542        Type.DECIMAL64,
4543        Type.DECIMAL128,
4544        Type.DECIMAL256,
4545        Type.MONEY,
4546        Type.SMALLMONEY,
4547        Type.UDECIMAL,
4548    }
4549
4550    NUMERIC_TYPES = {
4551        *INTEGER_TYPES,
4552        *REAL_TYPES,
4553    }
4554
4555    TEMPORAL_TYPES = {
4556        Type.DATE,
4557        Type.DATE32,
4558        Type.DATETIME,
4559        Type.DATETIME2,
4560        Type.DATETIME64,
4561        Type.SMALLDATETIME,
4562        Type.TIME,
4563        Type.TIMESTAMP,
4564        Type.TIMESTAMPNTZ,
4565        Type.TIMESTAMPLTZ,
4566        Type.TIMESTAMPTZ,
4567        Type.TIMESTAMP_MS,
4568        Type.TIMESTAMP_NS,
4569        Type.TIMESTAMP_S,
4570        Type.TIMETZ,
4571    }
4572
4573    @classmethod
4574    def build(
4575        cls,
4576        dtype: DATA_TYPE,
4577        dialect: DialectType = None,
4578        udt: bool = False,
4579        copy: bool = True,
4580        **kwargs,
4581    ) -> DataType:
4582        """
4583        Constructs a DataType object.
4584
4585        Args:
4586            dtype: the data type of interest.
4587            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4588            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4589                DataType, thus creating a user-defined type.
4590            copy: whether to copy the data type.
4591            kwargs: additional arguments to pass in the constructor of DataType.
4592
4593        Returns:
4594            The constructed DataType object.
4595        """
4596        from sqlglot import parse_one
4597
4598        if isinstance(dtype, str):
4599            if dtype.upper() == "UNKNOWN":
4600                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4601
4602            try:
4603                data_type_exp = parse_one(
4604                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4605                )
4606            except ParseError:
4607                if udt:
4608                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4609                raise
4610        elif isinstance(dtype, DataType.Type):
4611            data_type_exp = DataType(this=dtype)
4612        elif isinstance(dtype, DataType):
4613            return maybe_copy(dtype, copy)
4614        else:
4615            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4616
4617        return DataType(**{**data_type_exp.args, **kwargs})
4618
4619    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4620        """
4621        Checks whether this DataType matches one of the provided data types. Nested types or precision
4622        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4623
4624        Args:
4625            dtypes: the data types to compare this DataType to.
4626            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4627                If false, it means that NULLABLE<INT> is equivalent to INT.
4628
4629        Returns:
4630            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4631        """
4632        self_is_nullable = self.args.get("nullable")
4633        for dtype in dtypes:
4634            other_type = DataType.build(dtype, copy=False, udt=True)
4635            other_is_nullable = other_type.args.get("nullable")
4636            if (
4637                other_type.expressions
4638                or (check_nullable and (self_is_nullable or other_is_nullable))
4639                or self.this == DataType.Type.USERDEFINED
4640                or other_type.this == DataType.Type.USERDEFINED
4641            ):
4642                matches = self == other_type
4643            else:
4644                matches = self.this == other_type.this
4645
4646            if matches:
4647                return True
4648        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.ARRAY: 'ARRAY'>, <Type.MAP: 'MAP'>, <Type.UNION: 'UNION'>, <Type.LIST: 'LIST'>, <Type.NESTED: 'NESTED'>}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.NAME: 'NAME'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT128: 'UINT128'>}
INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL256: 'DECIMAL256'>}
NUMERIC_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT128: 'UINT128'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.MONEY: 'MONEY'>, <Type.INT: 'INT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.BIT: 'BIT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIME: 'TIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATE32: 'DATE32'>, <Type.DATE: 'DATE'>, <Type.DATETIME2: 'DATETIME2'>, <Type.DATETIME: 'DATETIME'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4573    @classmethod
4574    def build(
4575        cls,
4576        dtype: DATA_TYPE,
4577        dialect: DialectType = None,
4578        udt: bool = False,
4579        copy: bool = True,
4580        **kwargs,
4581    ) -> DataType:
4582        """
4583        Constructs a DataType object.
4584
4585        Args:
4586            dtype: the data type of interest.
4587            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4588            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4589                DataType, thus creating a user-defined type.
4590            copy: whether to copy the data type.
4591            kwargs: additional arguments to pass in the constructor of DataType.
4592
4593        Returns:
4594            The constructed DataType object.
4595        """
4596        from sqlglot import parse_one
4597
4598        if isinstance(dtype, str):
4599            if dtype.upper() == "UNKNOWN":
4600                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4601
4602            try:
4603                data_type_exp = parse_one(
4604                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4605                )
4606            except ParseError:
4607                if udt:
4608                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4609                raise
4610        elif isinstance(dtype, DataType.Type):
4611            data_type_exp = DataType(this=dtype)
4612        elif isinstance(dtype, DataType):
4613            return maybe_copy(dtype, copy)
4614        else:
4615            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4616
4617        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:
4619    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4620        """
4621        Checks whether this DataType matches one of the provided data types. Nested types or precision
4622        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4623
4624        Args:
4625            dtypes: the data types to compare this DataType to.
4626            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4627                If false, it means that NULLABLE<INT> is equivalent to INT.
4628
4629        Returns:
4630            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4631        """
4632        self_is_nullable = self.args.get("nullable")
4633        for dtype in dtypes:
4634            other_type = DataType.build(dtype, copy=False, udt=True)
4635            other_is_nullable = other_type.args.get("nullable")
4636            if (
4637                other_type.expressions
4638                or (check_nullable and (self_is_nullable or other_is_nullable))
4639                or self.this == DataType.Type.USERDEFINED
4640                or other_type.this == DataType.Type.USERDEFINED
4641            ):
4642                matches = self == other_type
4643            else:
4644                matches = self.this == other_type.this
4645
4646            if matches:
4647                return True
4648        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):
4358    class Type(AutoName):
4359        ARRAY = auto()
4360        AGGREGATEFUNCTION = auto()
4361        SIMPLEAGGREGATEFUNCTION = auto()
4362        BIGDECIMAL = auto()
4363        BIGINT = auto()
4364        BIGSERIAL = auto()
4365        BINARY = auto()
4366        BIT = auto()
4367        BOOLEAN = auto()
4368        BPCHAR = auto()
4369        CHAR = auto()
4370        DATE = auto()
4371        DATE32 = auto()
4372        DATEMULTIRANGE = auto()
4373        DATERANGE = auto()
4374        DATETIME = auto()
4375        DATETIME2 = auto()
4376        DATETIME64 = auto()
4377        DECIMAL = auto()
4378        DECIMAL32 = auto()
4379        DECIMAL64 = auto()
4380        DECIMAL128 = auto()
4381        DECIMAL256 = auto()
4382        DOUBLE = auto()
4383        ENUM = auto()
4384        ENUM8 = auto()
4385        ENUM16 = auto()
4386        FIXEDSTRING = auto()
4387        FLOAT = auto()
4388        GEOGRAPHY = auto()
4389        GEOMETRY = auto()
4390        POINT = auto()
4391        RING = auto()
4392        LINESTRING = auto()
4393        MULTILINESTRING = auto()
4394        POLYGON = auto()
4395        MULTIPOLYGON = auto()
4396        HLLSKETCH = auto()
4397        HSTORE = auto()
4398        IMAGE = auto()
4399        INET = auto()
4400        INT = auto()
4401        INT128 = auto()
4402        INT256 = auto()
4403        INT4MULTIRANGE = auto()
4404        INT4RANGE = auto()
4405        INT8MULTIRANGE = auto()
4406        INT8RANGE = auto()
4407        INTERVAL = auto()
4408        IPADDRESS = auto()
4409        IPPREFIX = auto()
4410        IPV4 = auto()
4411        IPV6 = auto()
4412        JSON = auto()
4413        JSONB = auto()
4414        LIST = auto()
4415        LONGBLOB = auto()
4416        LONGTEXT = auto()
4417        LOWCARDINALITY = auto()
4418        MAP = auto()
4419        MEDIUMBLOB = auto()
4420        MEDIUMINT = auto()
4421        MEDIUMTEXT = auto()
4422        MONEY = auto()
4423        NAME = auto()
4424        NCHAR = auto()
4425        NESTED = auto()
4426        NULL = auto()
4427        NUMMULTIRANGE = auto()
4428        NUMRANGE = auto()
4429        NVARCHAR = auto()
4430        OBJECT = auto()
4431        RANGE = auto()
4432        ROWVERSION = auto()
4433        SERIAL = auto()
4434        SET = auto()
4435        SMALLDATETIME = auto()
4436        SMALLINT = auto()
4437        SMALLMONEY = auto()
4438        SMALLSERIAL = auto()
4439        STRUCT = auto()
4440        SUPER = auto()
4441        TEXT = auto()
4442        TINYBLOB = auto()
4443        TINYTEXT = auto()
4444        TIME = auto()
4445        TIMETZ = auto()
4446        TIMESTAMP = auto()
4447        TIMESTAMPNTZ = auto()
4448        TIMESTAMPLTZ = auto()
4449        TIMESTAMPTZ = auto()
4450        TIMESTAMP_S = auto()
4451        TIMESTAMP_MS = auto()
4452        TIMESTAMP_NS = auto()
4453        TINYINT = auto()
4454        TSMULTIRANGE = auto()
4455        TSRANGE = auto()
4456        TSTZMULTIRANGE = auto()
4457        TSTZRANGE = auto()
4458        UBIGINT = auto()
4459        UINT = auto()
4460        UINT128 = auto()
4461        UINT256 = auto()
4462        UMEDIUMINT = auto()
4463        UDECIMAL = auto()
4464        UNION = auto()
4465        UNIQUEIDENTIFIER = auto()
4466        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4467        USERDEFINED = "USER-DEFINED"
4468        USMALLINT = auto()
4469        UTINYINT = auto()
4470        UUID = auto()
4471        VARBINARY = auto()
4472        VARCHAR = auto()
4473        VARIANT = auto()
4474        VECTOR = auto()
4475        XML = auto()
4476        YEAR = auto()
4477        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'>
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'>
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'>
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'>
UNION = <Type.UNION: 'UNION'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
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):
4655class PseudoType(DataType):
4656    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4660class ObjectIdentifier(DataType):
4661    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4665class SubqueryPredicate(Predicate):
4666    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4669class All(SubqueryPredicate):
4670    pass
key = 'all'
class Any(SubqueryPredicate):
4673class Any(SubqueryPredicate):
4674    pass
key = 'any'
class Command(Expression):
4679class Command(Expression):
4680    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4683class Transaction(Expression):
4684    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4687class Commit(Expression):
4688    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4691class Rollback(Expression):
4692    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4695class Alter(Expression):
4696    arg_types = {
4697        "this": True,
4698        "kind": True,
4699        "actions": True,
4700        "exists": False,
4701        "only": False,
4702        "options": False,
4703        "cluster": False,
4704        "not_valid": False,
4705    }
4706
4707    @property
4708    def kind(self) -> t.Optional[str]:
4709        kind = self.args.get("kind")
4710        return kind and kind.upper()
4711
4712    @property
4713    def actions(self) -> t.List[Expression]:
4714        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]
4707    @property
4708    def kind(self) -> t.Optional[str]:
4709        kind = self.args.get("kind")
4710        return kind and kind.upper()
actions: List[Expression]
4712    @property
4713    def actions(self) -> t.List[Expression]:
4714        return self.args.get("actions") or []
key = 'alter'
class AddConstraint(Expression):
4717class AddConstraint(Expression):
4718    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4721class AttachOption(Expression):
4722    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4725class DropPartition(Expression):
4726    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4730class ReplacePartition(Expression):
4731    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4735class Binary(Condition):
4736    arg_types = {"this": True, "expression": True}
4737
4738    @property
4739    def left(self) -> Expression:
4740        return self.this
4741
4742    @property
4743    def right(self) -> Expression:
4744        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4738    @property
4739    def left(self) -> Expression:
4740        return self.this
right: Expression
4742    @property
4743    def right(self) -> Expression:
4744        return self.expression
key = 'binary'
class Add(Binary):
4747class Add(Binary):
4748    pass
key = 'add'
class Connector(Binary):
4751class Connector(Binary):
4752    pass
key = 'connector'
class And(Connector):
4755class And(Connector):
4756    pass
key = 'and'
class Or(Connector):
4759class Or(Connector):
4760    pass
key = 'or'
class BitwiseAnd(Binary):
4763class BitwiseAnd(Binary):
4764    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4767class BitwiseLeftShift(Binary):
4768    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4771class BitwiseOr(Binary):
4772    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4775class BitwiseRightShift(Binary):
4776    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4779class BitwiseXor(Binary):
4780    pass
key = 'bitwisexor'
class Div(Binary):
4783class Div(Binary):
4784    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):
4787class Overlaps(Binary):
4788    pass
key = 'overlaps'
class Dot(Binary):
4791class Dot(Binary):
4792    @property
4793    def is_star(self) -> bool:
4794        return self.expression.is_star
4795
4796    @property
4797    def name(self) -> str:
4798        return self.expression.name
4799
4800    @property
4801    def output_name(self) -> str:
4802        return self.name
4803
4804    @classmethod
4805    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4806        """Build a Dot object with a sequence of expressions."""
4807        if len(expressions) < 2:
4808            raise ValueError("Dot requires >= 2 expressions.")
4809
4810        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4811
4812    @property
4813    def parts(self) -> t.List[Expression]:
4814        """Return the parts of a table / column in order catalog, db, table."""
4815        this, *parts = self.flatten()
4816
4817        parts.reverse()
4818
4819        for arg in COLUMN_PARTS:
4820            part = this.args.get(arg)
4821
4822            if isinstance(part, Expression):
4823                parts.append(part)
4824
4825        parts.reverse()
4826        return parts
is_star: bool
4792    @property
4793    def is_star(self) -> bool:
4794        return self.expression.is_star

Checks whether an expression is a star.

name: str
4796    @property
4797    def name(self) -> str:
4798        return self.expression.name
output_name: str
4800    @property
4801    def output_name(self) -> str:
4802        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:
4804    @classmethod
4805    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4806        """Build a Dot object with a sequence of expressions."""
4807        if len(expressions) < 2:
4808            raise ValueError("Dot requires >= 2 expressions.")
4809
4810        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]
4812    @property
4813    def parts(self) -> t.List[Expression]:
4814        """Return the parts of a table / column in order catalog, db, table."""
4815        this, *parts = self.flatten()
4816
4817        parts.reverse()
4818
4819        for arg in COLUMN_PARTS:
4820            part = this.args.get(arg)
4821
4822            if isinstance(part, Expression):
4823                parts.append(part)
4824
4825        parts.reverse()
4826        return parts

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

key = 'dot'
class DPipe(Binary):
4829class DPipe(Binary):
4830    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4833class EQ(Binary, Predicate):
4834    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4837class NullSafeEQ(Binary, Predicate):
4838    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4841class NullSafeNEQ(Binary, Predicate):
4842    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4846class PropertyEQ(Binary):
4847    pass
key = 'propertyeq'
class Distance(Binary):
4850class Distance(Binary):
4851    pass
key = 'distance'
class Escape(Binary):
4854class Escape(Binary):
4855    pass
key = 'escape'
class Glob(Binary, Predicate):
4858class Glob(Binary, Predicate):
4859    pass
key = 'glob'
class GT(Binary, Predicate):
4862class GT(Binary, Predicate):
4863    pass
key = 'gt'
class GTE(Binary, Predicate):
4866class GTE(Binary, Predicate):
4867    pass
key = 'gte'
class ILike(Binary, Predicate):
4870class ILike(Binary, Predicate):
4871    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4874class ILikeAny(Binary, Predicate):
4875    pass
key = 'ilikeany'
class IntDiv(Binary):
4878class IntDiv(Binary):
4879    pass
key = 'intdiv'
class Is(Binary, Predicate):
4882class Is(Binary, Predicate):
4883    pass
key = 'is'
class Kwarg(Binary):
4886class Kwarg(Binary):
4887    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4890class Like(Binary, Predicate):
4891    pass
key = 'like'
class LikeAny(Binary, Predicate):
4894class LikeAny(Binary, Predicate):
4895    pass
key = 'likeany'
class LT(Binary, Predicate):
4898class LT(Binary, Predicate):
4899    pass
key = 'lt'
class LTE(Binary, Predicate):
4902class LTE(Binary, Predicate):
4903    pass
key = 'lte'
class Mod(Binary):
4906class Mod(Binary):
4907    pass
key = 'mod'
class Mul(Binary):
4910class Mul(Binary):
4911    pass
key = 'mul'
class NEQ(Binary, Predicate):
4914class NEQ(Binary, Predicate):
4915    pass
key = 'neq'
class Operator(Binary):
4919class Operator(Binary):
4920    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4923class SimilarTo(Binary, Predicate):
4924    pass
key = 'similarto'
class Slice(Binary):
4927class Slice(Binary):
4928    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4931class Sub(Binary):
4932    pass
key = 'sub'
class Unary(Condition):
4937class Unary(Condition):
4938    pass
key = 'unary'
class BitwiseNot(Unary):
4941class BitwiseNot(Unary):
4942    pass
key = 'bitwisenot'
class Not(Unary):
4945class Not(Unary):
4946    pass
key = 'not'
class Paren(Unary):
4949class Paren(Unary):
4950    @property
4951    def output_name(self) -> str:
4952        return self.this.name
output_name: str
4950    @property
4951    def output_name(self) -> str:
4952        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):
4955class Neg(Unary):
4956    def to_py(self) -> int | Decimal:
4957        if self.is_number:
4958            return self.this.to_py() * -1
4959        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4956    def to_py(self) -> int | Decimal:
4957        if self.is_number:
4958            return self.this.to_py() * -1
4959        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4962class Alias(Expression):
4963    arg_types = {"this": True, "alias": False}
4964
4965    @property
4966    def output_name(self) -> str:
4967        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4965    @property
4966    def output_name(self) -> str:
4967        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):
4972class PivotAlias(Alias):
4973    pass
key = 'pivotalias'
class PivotAny(Expression):
4978class PivotAny(Expression):
4979    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4982class Aliases(Expression):
4983    arg_types = {"this": True, "expressions": True}
4984
4985    @property
4986    def aliases(self):
4987        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4985    @property
4986    def aliases(self):
4987        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4991class AtIndex(Expression):
4992    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4995class AtTimeZone(Expression):
4996    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4999class FromTimeZone(Expression):
5000    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5003class Between(Predicate):
5004    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5007class Bracket(Condition):
5008    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5009    arg_types = {
5010        "this": True,
5011        "expressions": True,
5012        "offset": False,
5013        "safe": False,
5014        "returns_list_for_maps": False,
5015    }
5016
5017    @property
5018    def output_name(self) -> str:
5019        if len(self.expressions) == 1:
5020            return self.expressions[0].output_name
5021
5022        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5017    @property
5018    def output_name(self) -> str:
5019        if len(self.expressions) == 1:
5020            return self.expressions[0].output_name
5021
5022        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):
5025class Distinct(Expression):
5026    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5029class In(Predicate):
5030    arg_types = {
5031        "this": True,
5032        "expressions": False,
5033        "query": False,
5034        "unnest": False,
5035        "field": False,
5036        "is_global": False,
5037    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5041class ForIn(Expression):
5042    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5045class TimeUnit(Expression):
5046    """Automatically converts unit arg into a var."""
5047
5048    arg_types = {"unit": False}
5049
5050    UNABBREVIATED_UNIT_NAME = {
5051        "D": "DAY",
5052        "H": "HOUR",
5053        "M": "MINUTE",
5054        "MS": "MILLISECOND",
5055        "NS": "NANOSECOND",
5056        "Q": "QUARTER",
5057        "S": "SECOND",
5058        "US": "MICROSECOND",
5059        "W": "WEEK",
5060        "Y": "YEAR",
5061    }
5062
5063    VAR_LIKE = (Column, Literal, Var)
5064
5065    def __init__(self, **args):
5066        unit = args.get("unit")
5067        if isinstance(unit, self.VAR_LIKE):
5068            args["unit"] = Var(
5069                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5070            )
5071        elif isinstance(unit, Week):
5072            unit.set("this", Var(this=unit.this.name.upper()))
5073
5074        super().__init__(**args)
5075
5076    @property
5077    def unit(self) -> t.Optional[Var | IntervalSpan]:
5078        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5065    def __init__(self, **args):
5066        unit = args.get("unit")
5067        if isinstance(unit, self.VAR_LIKE):
5068            args["unit"] = Var(
5069                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5070            )
5071        elif isinstance(unit, Week):
5072            unit.set("this", Var(this=unit.this.name.upper()))
5073
5074        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]
5076    @property
5077    def unit(self) -> t.Optional[Var | IntervalSpan]:
5078        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5081class IntervalOp(TimeUnit):
5082    arg_types = {"unit": False, "expression": True}
5083
5084    def interval(self):
5085        return Interval(
5086            this=self.expression.copy(),
5087            unit=self.unit.copy() if self.unit else None,
5088        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5084    def interval(self):
5085        return Interval(
5086            this=self.expression.copy(),
5087            unit=self.unit.copy() if self.unit else None,
5088        )
key = 'intervalop'
class IntervalSpan(DataType):
5094class IntervalSpan(DataType):
5095    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5098class Interval(TimeUnit):
5099    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5102class IgnoreNulls(Expression):
5103    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5106class RespectNulls(Expression):
5107    pass
key = 'respectnulls'
class HavingMax(Expression):
5111class HavingMax(Expression):
5112    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5116class Func(Condition):
5117    """
5118    The base class for all function expressions.
5119
5120    Attributes:
5121        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5122            treated as a variable length argument and the argument's value will be stored as a list.
5123        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5124            function expression. These values are used to map this node to a name during parsing as
5125            well as to provide the function's name during SQL string generation. By default the SQL
5126            name is set to the expression's class name transformed to snake case.
5127    """
5128
5129    is_var_len_args = False
5130
5131    @classmethod
5132    def from_arg_list(cls, args):
5133        if cls.is_var_len_args:
5134            all_arg_keys = list(cls.arg_types)
5135            # If this function supports variable length argument treat the last argument as such.
5136            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5137            num_non_var = len(non_var_len_arg_keys)
5138
5139            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5140            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5141        else:
5142            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5143
5144        return cls(**args_dict)
5145
5146    @classmethod
5147    def sql_names(cls):
5148        if cls is Func:
5149            raise NotImplementedError(
5150                "SQL name is only supported by concrete function implementations"
5151            )
5152        if "_sql_names" not in cls.__dict__:
5153            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5154        return cls._sql_names
5155
5156    @classmethod
5157    def sql_name(cls):
5158        return cls.sql_names()[0]
5159
5160    @classmethod
5161    def default_parser_mappings(cls):
5162        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):
5131    @classmethod
5132    def from_arg_list(cls, args):
5133        if cls.is_var_len_args:
5134            all_arg_keys = list(cls.arg_types)
5135            # If this function supports variable length argument treat the last argument as such.
5136            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5137            num_non_var = len(non_var_len_arg_keys)
5138
5139            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5140            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5141        else:
5142            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5143
5144        return cls(**args_dict)
@classmethod
def sql_names(cls):
5146    @classmethod
5147    def sql_names(cls):
5148        if cls is Func:
5149            raise NotImplementedError(
5150                "SQL name is only supported by concrete function implementations"
5151            )
5152        if "_sql_names" not in cls.__dict__:
5153            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5154        return cls._sql_names
@classmethod
def sql_name(cls):
5156    @classmethod
5157    def sql_name(cls):
5158        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5160    @classmethod
5161    def default_parser_mappings(cls):
5162        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5165class AggFunc(Func):
5166    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5169class ParameterizedAgg(AggFunc):
5170    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5173class Abs(Func):
5174    pass
key = 'abs'
class ArgMax(AggFunc):
5177class ArgMax(AggFunc):
5178    arg_types = {"this": True, "expression": True, "count": False}
5179    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5182class ArgMin(AggFunc):
5183    arg_types = {"this": True, "expression": True, "count": False}
5184    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5187class ApproxTopK(AggFunc):
5188    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5191class Flatten(Func):
5192    pass
key = 'flatten'
class Transform(Func):
5196class Transform(Func):
5197    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5200class Anonymous(Func):
5201    arg_types = {"this": True, "expressions": False}
5202    is_var_len_args = True
5203
5204    @property
5205    def name(self) -> str:
5206        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
5204    @property
5205    def name(self) -> str:
5206        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5209class AnonymousAggFunc(AggFunc):
5210    arg_types = {"this": True, "expressions": False}
5211    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5215class CombinedAggFunc(AnonymousAggFunc):
5216    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5219class CombinedParameterizedAgg(ParameterizedAgg):
5220    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5225class Hll(AggFunc):
5226    arg_types = {"this": True, "expressions": False}
5227    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5230class ApproxDistinct(AggFunc):
5231    arg_types = {"this": True, "accuracy": False}
5232    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5235class Apply(Func):
5236    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5239class Array(Func):
5240    arg_types = {"expressions": False, "bracket_notation": False}
5241    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5245class ToArray(Func):
5246    pass
key = 'toarray'
class List(Func):
5250class List(Func):
5251    arg_types = {"expressions": False}
5252    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5256class Pad(Func):
5257    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):
5262class ToChar(Func):
5263    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5268class ToNumber(Func):
5269    arg_types = {
5270        "this": True,
5271        "format": False,
5272        "nlsparam": False,
5273        "precision": False,
5274        "scale": False,
5275    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5279class ToDouble(Func):
5280    arg_types = {
5281        "this": True,
5282        "format": False,
5283    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5286class Columns(Func):
5287    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5291class Convert(Func):
5292    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5295class ConvertTimezone(Func):
5296    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):
5299class GenerateSeries(Func):
5300    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):
5306class ExplodingGenerateSeries(GenerateSeries):
5307    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5310class ArrayAgg(AggFunc):
5311    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5314class ArrayUniqueAgg(AggFunc):
5315    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5318class ArrayAll(Func):
5319    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5323class ArrayAny(Func):
5324    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5327class ArrayConcat(Func):
5328    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5329    arg_types = {"this": True, "expressions": False}
5330    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5333class ArrayConstructCompact(Func):
5334    arg_types = {"expressions": True}
5335    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5338class ArrayContains(Binary, Func):
5339    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5342class ArrayContainsAll(Binary, Func):
5343    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5346class ArrayFilter(Func):
5347    arg_types = {"this": True, "expression": True}
5348    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5351class ArrayToString(Func):
5352    arg_types = {"this": True, "expression": True, "null": False}
5353    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5357class String(Func):
5358    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5361class StringToArray(Func):
5362    arg_types = {"this": True, "expression": True, "null": False}
5363    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5366class ArrayOverlaps(Binary, Func):
5367    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5370class ArraySize(Func):
5371    arg_types = {"this": True, "expression": False}
5372    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5375class ArraySort(Func):
5376    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5379class ArraySum(Func):
5380    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5383class ArrayUnionAgg(AggFunc):
5384    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5387class Avg(AggFunc):
5388    pass
key = 'avg'
class AnyValue(AggFunc):
5391class AnyValue(AggFunc):
5392    pass
key = 'anyvalue'
class Lag(AggFunc):
5395class Lag(AggFunc):
5396    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5399class Lead(AggFunc):
5400    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5405class First(AggFunc):
5406    pass
key = 'first'
class Last(AggFunc):
5409class Last(AggFunc):
5410    pass
key = 'last'
class FirstValue(AggFunc):
5413class FirstValue(AggFunc):
5414    pass
key = 'firstvalue'
class LastValue(AggFunc):
5417class LastValue(AggFunc):
5418    pass
key = 'lastvalue'
class NthValue(AggFunc):
5421class NthValue(AggFunc):
5422    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5425class Case(Func):
5426    arg_types = {"this": False, "ifs": True, "default": False}
5427
5428    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5429        instance = maybe_copy(self, copy)
5430        instance.append(
5431            "ifs",
5432            If(
5433                this=maybe_parse(condition, copy=copy, **opts),
5434                true=maybe_parse(then, copy=copy, **opts),
5435            ),
5436        )
5437        return instance
5438
5439    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5440        instance = maybe_copy(self, copy)
5441        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5442        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:
5428    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5429        instance = maybe_copy(self, copy)
5430        instance.append(
5431            "ifs",
5432            If(
5433                this=maybe_parse(condition, copy=copy, **opts),
5434                true=maybe_parse(then, copy=copy, **opts),
5435            ),
5436        )
5437        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5439    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5440        instance = maybe_copy(self, copy)
5441        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5442        return instance
key = 'case'
class Cast(Func):
5445class Cast(Func):
5446    arg_types = {
5447        "this": True,
5448        "to": True,
5449        "format": False,
5450        "safe": False,
5451        "action": False,
5452    }
5453
5454    @property
5455    def name(self) -> str:
5456        return self.this.name
5457
5458    @property
5459    def to(self) -> DataType:
5460        return self.args["to"]
5461
5462    @property
5463    def output_name(self) -> str:
5464        return self.name
5465
5466    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5467        """
5468        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5469        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5470        array<int> != array<float>.
5471
5472        Args:
5473            dtypes: the data types to compare this Cast's DataType to.
5474
5475        Returns:
5476            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5477        """
5478        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5454    @property
5455    def name(self) -> str:
5456        return self.this.name
to: DataType
5458    @property
5459    def to(self) -> DataType:
5460        return self.args["to"]
output_name: str
5462    @property
5463    def output_name(self) -> str:
5464        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:
5466    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5467        """
5468        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5469        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5470        array<int> != array<float>.
5471
5472        Args:
5473            dtypes: the data types to compare this Cast's DataType to.
5474
5475        Returns:
5476            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5477        """
5478        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):
5481class TryCast(Cast):
5482    pass
key = 'trycast'
class Try(Func):
5485class Try(Func):
5486    pass
key = 'try'
class CastToStrType(Func):
5489class CastToStrType(Func):
5490    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5493class Collate(Binary, Func):
5494    pass
key = 'collate'
class Ceil(Func):
5497class Ceil(Func):
5498    arg_types = {"this": True, "decimals": False}
5499    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5502class Coalesce(Func):
5503    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5504    is_var_len_args = True
5505    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5508class Chr(Func):
5509    arg_types = {"expressions": True, "charset": False}
5510    is_var_len_args = True
5511    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5514class Concat(Func):
5515    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5516    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5519class ConcatWs(Concat):
5520    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5523class Contains(Func):
5524    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5528class ConnectByRoot(Func):
5529    pass
key = 'connectbyroot'
class Count(AggFunc):
5532class Count(AggFunc):
5533    arg_types = {"this": False, "expressions": False, "big_int": False}
5534    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5537class CountIf(AggFunc):
5538    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5542class Cbrt(Func):
5543    pass
key = 'cbrt'
class CurrentDate(Func):
5546class CurrentDate(Func):
5547    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5550class CurrentDatetime(Func):
5551    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5554class CurrentTime(Func):
5555    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5558class CurrentTimestamp(Func):
5559    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5562class CurrentUser(Func):
5563    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5566class DateAdd(Func, IntervalOp):
5567    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5570class DateSub(Func, IntervalOp):
5571    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5574class DateDiff(Func, TimeUnit):
5575    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5576    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5579class DateTrunc(Func):
5580    arg_types = {"unit": True, "this": True, "zone": False}
5581
5582    def __init__(self, **args):
5583        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5584        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5585        unabbreviate = args.pop("unabbreviate", True)
5586
5587        unit = args.get("unit")
5588        if isinstance(unit, TimeUnit.VAR_LIKE):
5589            unit_name = unit.name.upper()
5590            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5591                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5592
5593            args["unit"] = Literal.string(unit_name)
5594        elif isinstance(unit, Week):
5595            unit.set("this", Literal.string(unit.this.name.upper()))
5596
5597        super().__init__(**args)
5598
5599    @property
5600    def unit(self) -> Expression:
5601        return self.args["unit"]
DateTrunc(**args)
5582    def __init__(self, **args):
5583        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5584        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5585        unabbreviate = args.pop("unabbreviate", True)
5586
5587        unit = args.get("unit")
5588        if isinstance(unit, TimeUnit.VAR_LIKE):
5589            unit_name = unit.name.upper()
5590            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5591                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5592
5593            args["unit"] = Literal.string(unit_name)
5594        elif isinstance(unit, Week):
5595            unit.set("this", Literal.string(unit.this.name.upper()))
5596
5597        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5599    @property
5600    def unit(self) -> Expression:
5601        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5606class Datetime(Func):
5607    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5610class DatetimeAdd(Func, IntervalOp):
5611    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5614class DatetimeSub(Func, IntervalOp):
5615    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5618class DatetimeDiff(Func, TimeUnit):
5619    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5622class DatetimeTrunc(Func, TimeUnit):
5623    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5626class DayOfWeek(Func):
5627    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5632class DayOfWeekIso(Func):
5633    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5636class DayOfMonth(Func):
5637    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5640class DayOfYear(Func):
5641    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5644class ToDays(Func):
5645    pass
key = 'todays'
class WeekOfYear(Func):
5648class WeekOfYear(Func):
5649    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5652class MonthsBetween(Func):
5653    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5656class MakeInterval(Func):
5657    arg_types = {
5658        "year": False,
5659        "month": False,
5660        "day": False,
5661        "hour": False,
5662        "minute": False,
5663        "second": False,
5664    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5667class LastDay(Func, TimeUnit):
5668    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5669    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5672class Extract(Func):
5673    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5676class Exists(Func, SubqueryPredicate):
5677    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5680class Timestamp(Func):
5681    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5684class TimestampAdd(Func, TimeUnit):
5685    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5688class TimestampSub(Func, TimeUnit):
5689    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5692class TimestampDiff(Func, TimeUnit):
5693    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5694    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5697class TimestampTrunc(Func, TimeUnit):
5698    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5701class TimeAdd(Func, TimeUnit):
5702    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5705class TimeSub(Func, TimeUnit):
5706    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5709class TimeDiff(Func, TimeUnit):
5710    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5713class TimeTrunc(Func, TimeUnit):
5714    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5717class DateFromParts(Func):
5718    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5719    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5722class TimeFromParts(Func):
5723    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5724    arg_types = {
5725        "hour": True,
5726        "min": True,
5727        "sec": True,
5728        "nano": False,
5729        "fractions": False,
5730        "precision": False,
5731    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5734class DateStrToDate(Func):
5735    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5738class DateToDateStr(Func):
5739    pass
key = 'datetodatestr'
class DateToDi(Func):
5742class DateToDi(Func):
5743    pass
key = 'datetodi'
class Date(Func):
5747class Date(Func):
5748    arg_types = {"this": False, "zone": False, "expressions": False}
5749    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5752class Day(Func):
5753    pass
key = 'day'
class Decode(Func):
5756class Decode(Func):
5757    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5760class DiToDate(Func):
5761    pass
key = 'ditodate'
class Encode(Func):
5764class Encode(Func):
5765    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5768class Exp(Func):
5769    pass
key = 'exp'
class Explode(Func, UDTF):
5773class Explode(Func, UDTF):
5774    arg_types = {"this": True, "expressions": False}
5775    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5779class Inline(Func):
5780    pass
key = 'inline'
class ExplodeOuter(Explode):
5783class ExplodeOuter(Explode):
5784    pass
key = 'explodeouter'
class Posexplode(Explode):
5787class Posexplode(Explode):
5788    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5791class PosexplodeOuter(Posexplode, ExplodeOuter):
5792    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5795class Unnest(Func, UDTF):
5796    arg_types = {
5797        "expressions": True,
5798        "alias": False,
5799        "offset": False,
5800        "explode_array": False,
5801    }
5802
5803    @property
5804    def selects(self) -> t.List[Expression]:
5805        columns = super().selects
5806        offset = self.args.get("offset")
5807        if offset:
5808            columns = columns + [to_identifier("offset") if offset is True else offset]
5809        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5803    @property
5804    def selects(self) -> t.List[Expression]:
5805        columns = super().selects
5806        offset = self.args.get("offset")
5807        if offset:
5808            columns = columns + [to_identifier("offset") if offset is True else offset]
5809        return columns
key = 'unnest'
class Floor(Func):
5812class Floor(Func):
5813    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5816class FromBase64(Func):
5817    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5820class FeaturesAtTime(Func):
5821    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):
5824class ToBase64(Func):
5825    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5829class FromISO8601Timestamp(Func):
5830    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5833class GapFill(Func):
5834    arg_types = {
5835        "this": True,
5836        "ts_column": True,
5837        "bucket_width": True,
5838        "partitioning_columns": False,
5839        "value_columns": False,
5840        "origin": False,
5841        "ignore_nulls": False,
5842    }
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):
5846class GenerateDateArray(Func):
5847    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5851class GenerateTimestampArray(Func):
5852    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5855class Greatest(Func):
5856    arg_types = {"this": True, "expressions": False}
5857    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5862class OverflowTruncateBehavior(Expression):
5863    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5866class GroupConcat(AggFunc):
5867    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5870class Hex(Func):
5871    pass
key = 'hex'
class LowerHex(Hex):
5874class LowerHex(Hex):
5875    pass
key = 'lowerhex'
class Xor(Connector, Func):
5878class Xor(Connector, Func):
5879    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5882class If(Func):
5883    arg_types = {"this": True, "true": True, "false": False}
5884    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5887class Nullif(Func):
5888    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5891class Initcap(Func):
5892    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
5895class IsAscii(Func):
5896    pass
key = 'isascii'
class IsNan(Func):
5899class IsNan(Func):
5900    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
5904class Int64(Func):
5905    pass
key = 'int64'
class IsInf(Func):
5908class IsInf(Func):
5909    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5913class JSON(Expression):
5914    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5917class JSONPath(Expression):
5918    arg_types = {"expressions": True, "escape": False}
5919
5920    @property
5921    def output_name(self) -> str:
5922        last_segment = self.expressions[-1].this
5923        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5920    @property
5921    def output_name(self) -> str:
5922        last_segment = self.expressions[-1].this
5923        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):
5926class JSONPathPart(Expression):
5927    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5930class JSONPathFilter(JSONPathPart):
5931    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5934class JSONPathKey(JSONPathPart):
5935    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5938class JSONPathRecursive(JSONPathPart):
5939    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5942class JSONPathRoot(JSONPathPart):
5943    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5946class JSONPathScript(JSONPathPart):
5947    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5950class JSONPathSlice(JSONPathPart):
5951    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5954class JSONPathSelector(JSONPathPart):
5955    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5958class JSONPathSubscript(JSONPathPart):
5959    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5962class JSONPathUnion(JSONPathPart):
5963    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5966class JSONPathWildcard(JSONPathPart):
5967    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5970class FormatJson(Expression):
5971    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5974class JSONKeyValue(Expression):
5975    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5978class JSONObject(Func):
5979    arg_types = {
5980        "expressions": False,
5981        "null_handling": False,
5982        "unique_keys": False,
5983        "return_type": False,
5984        "encoding": False,
5985    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5988class JSONObjectAgg(AggFunc):
5989    arg_types = {
5990        "expressions": False,
5991        "null_handling": False,
5992        "unique_keys": False,
5993        "return_type": False,
5994        "encoding": False,
5995    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5999class JSONArray(Func):
6000    arg_types = {
6001        "expressions": True,
6002        "null_handling": False,
6003        "return_type": False,
6004        "strict": False,
6005    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6009class JSONArrayAgg(Func):
6010    arg_types = {
6011        "this": True,
6012        "order": False,
6013        "null_handling": False,
6014        "return_type": False,
6015        "strict": False,
6016    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6019class JSONExists(Func):
6020    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):
6025class JSONColumnDef(Expression):
6026    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):
6029class JSONSchema(Expression):
6030    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6034class JSONValue(Expression):
6035    arg_types = {
6036        "this": True,
6037        "path": True,
6038        "returning": False,
6039        "on_condition": False,
6040    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6043class JSONValueArray(Func):
6044    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6048class JSONTable(Func):
6049    arg_types = {
6050        "this": True,
6051        "schema": True,
6052        "path": False,
6053        "error_handling": False,
6054        "empty_handling": False,
6055    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6059class ObjectInsert(Func):
6060    arg_types = {
6061        "this": True,
6062        "key": True,
6063        "value": True,
6064        "update_flag": False,
6065    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6068class OpenJSONColumnDef(Expression):
6069    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):
6072class OpenJSON(Func):
6073    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6076class JSONBContains(Binary, Func):
6077    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6080class JSONBExists(Func):
6081    arg_types = {"this": True, "path": True}
6082    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6085class JSONExtract(Binary, Func):
6086    arg_types = {
6087        "this": True,
6088        "expression": True,
6089        "only_json_types": False,
6090        "expressions": False,
6091        "variant_extract": False,
6092        "json_query": False,
6093        "option": False,
6094    }
6095    _sql_names = ["JSON_EXTRACT"]
6096    is_var_len_args = True
6097
6098    @property
6099    def output_name(self) -> str:
6100        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}
is_var_len_args = True
output_name: str
6098    @property
6099    def output_name(self) -> str:
6100        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 JSONExtractArray(Func):
6103class JSONExtractArray(Func):
6104    arg_types = {"this": True, "expression": False}
6105    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6108class JSONExtractScalar(Binary, Func):
6109    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6110    _sql_names = ["JSON_EXTRACT_SCALAR"]
6111    is_var_len_args = True
6112
6113    @property
6114    def output_name(self) -> str:
6115        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
6113    @property
6114    def output_name(self) -> str:
6115        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):
6118class JSONBExtract(Binary, Func):
6119    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6122class JSONBExtractScalar(Binary, Func):
6123    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6126class JSONFormat(Func):
6127    arg_types = {"this": False, "options": False}
6128    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6132class JSONArrayContains(Binary, Predicate, Func):
6133    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6136class ParseJSON(Func):
6137    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6138    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6139    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6140    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6143class Least(Func):
6144    arg_types = {"this": True, "expressions": False}
6145    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6148class Left(Func):
6149    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6156class Length(Func):
6157    arg_types = {"this": True, "binary": False, "encoding": False}
6158    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6161class Levenshtein(Func):
6162    arg_types = {
6163        "this": True,
6164        "expression": False,
6165        "ins_cost": False,
6166        "del_cost": False,
6167        "sub_cost": False,
6168        "max_dist": False,
6169    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6172class Ln(Func):
6173    pass
key = 'ln'
class Log(Func):
6176class Log(Func):
6177    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6180class LogicalOr(AggFunc):
6181    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6184class LogicalAnd(AggFunc):
6185    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6188class Lower(Func):
6189    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6192class Map(Func):
6193    arg_types = {"keys": False, "values": False}
6194
6195    @property
6196    def keys(self) -> t.List[Expression]:
6197        keys = self.args.get("keys")
6198        return keys.expressions if keys else []
6199
6200    @property
6201    def values(self) -> t.List[Expression]:
6202        values = self.args.get("values")
6203        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6195    @property
6196    def keys(self) -> t.List[Expression]:
6197        keys = self.args.get("keys")
6198        return keys.expressions if keys else []
values: List[Expression]
6200    @property
6201    def values(self) -> t.List[Expression]:
6202        values = self.args.get("values")
6203        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6207class ToMap(Func):
6208    pass
key = 'tomap'
class MapFromEntries(Func):
6211class MapFromEntries(Func):
6212    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6216class ScopeResolution(Expression):
6217    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6220class Stream(Expression):
6221    pass
key = 'stream'
class StarMap(Func):
6224class StarMap(Func):
6225    pass
key = 'starmap'
class VarMap(Func):
6228class VarMap(Func):
6229    arg_types = {"keys": True, "values": True}
6230    is_var_len_args = True
6231
6232    @property
6233    def keys(self) -> t.List[Expression]:
6234        return self.args["keys"].expressions
6235
6236    @property
6237    def values(self) -> t.List[Expression]:
6238        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6232    @property
6233    def keys(self) -> t.List[Expression]:
6234        return self.args["keys"].expressions
values: List[Expression]
6236    @property
6237    def values(self) -> t.List[Expression]:
6238        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6242class MatchAgainst(Func):
6243    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6246class Max(AggFunc):
6247    arg_types = {"this": True, "expressions": False}
6248    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6251class MD5(Func):
6252    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6256class MD5Digest(Func):
6257    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6260class Median(AggFunc):
6261    pass
key = 'median'
class Min(AggFunc):
6264class Min(AggFunc):
6265    arg_types = {"this": True, "expressions": False}
6266    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6269class Month(Func):
6270    pass
key = 'month'
class AddMonths(Func):
6273class AddMonths(Func):
6274    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6277class Nvl2(Func):
6278    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6281class Normalize(Func):
6282    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6285class Overlay(Func):
6286    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):
6290class Predict(Func):
6291    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6294class Pow(Binary, Func):
6295    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6298class PercentileCont(AggFunc):
6299    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6302class PercentileDisc(AggFunc):
6303    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6306class Quantile(AggFunc):
6307    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6310class ApproxQuantile(Quantile):
6311    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):
6314class Quarter(Func):
6315    pass
key = 'quarter'
class Rand(Func):
6320class Rand(Func):
6321    _sql_names = ["RAND", "RANDOM"]
6322    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6325class Randn(Func):
6326    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6329class RangeN(Func):
6330    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6333class ReadCSV(Func):
6334    _sql_names = ["READ_CSV"]
6335    is_var_len_args = True
6336    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6339class Reduce(Func):
6340    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):
6343class RegexpExtract(Func):
6344    arg_types = {
6345        "this": True,
6346        "expression": True,
6347        "position": False,
6348        "occurrence": False,
6349        "parameters": False,
6350        "group": False,
6351    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6354class RegexpExtractAll(Func):
6355    arg_types = {
6356        "this": True,
6357        "expression": True,
6358        "position": False,
6359        "occurrence": False,
6360        "parameters": False,
6361        "group": False,
6362    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6365class RegexpReplace(Func):
6366    arg_types = {
6367        "this": True,
6368        "expression": True,
6369        "replacement": False,
6370        "position": False,
6371        "occurrence": False,
6372        "modifiers": False,
6373    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6376class RegexpLike(Binary, Func):
6377    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6380class RegexpILike(Binary, Func):
6381    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6386class RegexpSplit(Func):
6387    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6390class Repeat(Func):
6391    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6396class Round(Func):
6397    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6400class RowNumber(Func):
6401    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6404class SafeDivide(Func):
6405    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6408class SHA(Func):
6409    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6412class SHA2(Func):
6413    _sql_names = ["SHA2"]
6414    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6417class Sign(Func):
6418    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6421class SortArray(Func):
6422    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6425class Split(Func):
6426    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6430class SplitPart(Func):
6431    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6436class Substring(Func):
6437    _sql_names = ["SUBSTRING", "SUBSTR"]
6438    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6441class StandardHash(Func):
6442    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6445class StartsWith(Func):
6446    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6447    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6450class StrPosition(Func):
6451    arg_types = {
6452        "this": True,
6453        "substr": True,
6454        "position": False,
6455        "instance": False,
6456    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6459class StrToDate(Func):
6460    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6463class StrToTime(Func):
6464    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):
6469class StrToUnix(Func):
6470    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6475class StrToMap(Func):
6476    arg_types = {
6477        "this": True,
6478        "pair_delim": False,
6479        "key_value_delim": False,
6480        "duplicate_resolution_callback": False,
6481    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6484class NumberToStr(Func):
6485    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6488class FromBase(Func):
6489    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6492class Struct(Func):
6493    arg_types = {"expressions": False}
6494    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6497class StructExtract(Func):
6498    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6503class Stuff(Func):
6504    _sql_names = ["STUFF", "INSERT"]
6505    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):
6508class Sum(AggFunc):
6509    pass
key = 'sum'
class Sqrt(Func):
6512class Sqrt(Func):
6513    pass
key = 'sqrt'
class Stddev(AggFunc):
6516class Stddev(AggFunc):
6517    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6520class StddevPop(AggFunc):
6521    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6524class StddevSamp(AggFunc):
6525    pass
key = 'stddevsamp'
class Time(Func):
6529class Time(Func):
6530    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6533class TimeToStr(Func):
6534    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):
6537class TimeToTimeStr(Func):
6538    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6541class TimeToUnix(Func):
6542    pass
key = 'timetounix'
class TimeStrToDate(Func):
6545class TimeStrToDate(Func):
6546    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6549class TimeStrToTime(Func):
6550    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6553class TimeStrToUnix(Func):
6554    pass
key = 'timestrtounix'
class Trim(Func):
6557class Trim(Func):
6558    arg_types = {
6559        "this": True,
6560        "expression": False,
6561        "position": False,
6562        "collation": False,
6563    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6566class TsOrDsAdd(Func, TimeUnit):
6567    # return_type is used to correctly cast the arguments of this expression when transpiling it
6568    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6569
6570    @property
6571    def return_type(self) -> DataType:
6572        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
6570    @property
6571    def return_type(self) -> DataType:
6572        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6575class TsOrDsDiff(Func, TimeUnit):
6576    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6579class TsOrDsToDateStr(Func):
6580    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6583class TsOrDsToDate(Func):
6584    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6587class TsOrDsToDatetime(Func):
6588    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6591class TsOrDsToTime(Func):
6592    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6595class TsOrDsToTimestamp(Func):
6596    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6599class TsOrDiToDi(Func):
6600    pass
key = 'tsorditodi'
class Unhex(Func):
6603class Unhex(Func):
6604    pass
key = 'unhex'
class Unicode(Func):
6607class Unicode(Func):
6608    pass
key = 'unicode'
class UnixDate(Func):
6612class UnixDate(Func):
6613    pass
key = 'unixdate'
class UnixToStr(Func):
6616class UnixToStr(Func):
6617    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6622class UnixToTime(Func):
6623    arg_types = {
6624        "this": True,
6625        "scale": False,
6626        "zone": False,
6627        "hours": False,
6628        "minutes": False,
6629        "format": False,
6630    }
6631
6632    SECONDS = Literal.number(0)
6633    DECIS = Literal.number(1)
6634    CENTIS = Literal.number(2)
6635    MILLIS = Literal.number(3)
6636    DECIMILLIS = Literal.number(4)
6637    CENTIMILLIS = Literal.number(5)
6638    MICROS = Literal.number(6)
6639    DECIMICROS = Literal.number(7)
6640    CENTIMICROS = Literal.number(8)
6641    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):
6644class UnixToTimeStr(Func):
6645    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6648class UnixSeconds(Func):
6649    pass
key = 'unixseconds'
class Uuid(Func):
6652class Uuid(Func):
6653    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6654
6655    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6658class TimestampFromParts(Func):
6659    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6660    arg_types = {
6661        "year": True,
6662        "month": True,
6663        "day": True,
6664        "hour": True,
6665        "min": True,
6666        "sec": True,
6667        "nano": False,
6668        "zone": False,
6669        "milli": False,
6670    }
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):
6673class Upper(Func):
6674    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6677class Corr(Binary, AggFunc):
6678    pass
key = 'corr'
class Variance(AggFunc):
6681class Variance(AggFunc):
6682    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6685class VariancePop(AggFunc):
6686    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6689class CovarSamp(Binary, AggFunc):
6690    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6693class CovarPop(Binary, AggFunc):
6694    pass
key = 'covarpop'
class Week(Func):
6697class Week(Func):
6698    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6701class XMLElement(Func):
6702    _sql_names = ["XMLELEMENT"]
6703    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6706class XMLTable(Func):
6707    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
arg_types = {'this': True, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class Year(Func):
6710class Year(Func):
6711    pass
key = 'year'
class Use(Expression):
6714class Use(Expression):
6715    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6718class Merge(DML):
6719    arg_types = {
6720        "this": True,
6721        "using": True,
6722        "on": True,
6723        "whens": True,
6724        "with": False,
6725        "returning": False,
6726    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6729class When(Expression):
6730    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):
6733class Whens(Expression):
6734    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6735
6736    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6741class NextValueFor(Func):
6742    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6747class Semicolon(Expression):
6748    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <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 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <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 '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 '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'>, '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_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, '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_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'>, '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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6788def maybe_parse(
6789    sql_or_expression: ExpOrStr,
6790    *,
6791    into: t.Optional[IntoType] = None,
6792    dialect: DialectType = None,
6793    prefix: t.Optional[str] = None,
6794    copy: bool = False,
6795    **opts,
6796) -> Expression:
6797    """Gracefully handle a possible string or expression.
6798
6799    Example:
6800        >>> maybe_parse("1")
6801        Literal(this=1, is_string=False)
6802        >>> maybe_parse(to_identifier("x"))
6803        Identifier(this=x, quoted=False)
6804
6805    Args:
6806        sql_or_expression: the SQL code string or an expression
6807        into: the SQLGlot Expression to parse into
6808        dialect: the dialect used to parse the input expressions (in the case that an
6809            input expression is a SQL string).
6810        prefix: a string to prefix the sql with before it gets parsed
6811            (automatically includes a space)
6812        copy: whether to copy the expression.
6813        **opts: other options to use to parse the input expressions (again, in the case
6814            that an input expression is a SQL string).
6815
6816    Returns:
6817        Expression: the parsed or given expression.
6818    """
6819    if isinstance(sql_or_expression, Expression):
6820        if copy:
6821            return sql_or_expression.copy()
6822        return sql_or_expression
6823
6824    if sql_or_expression is None:
6825        raise ParseError("SQL cannot be None")
6826
6827    import sqlglot
6828
6829    sql = str(sql_or_expression)
6830    if prefix:
6831        sql = f"{prefix} {sql}"
6832
6833    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):
6844def maybe_copy(instance, copy=True):
6845    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7089def union(
7090    *expressions: ExpOrStr,
7091    distinct: bool = True,
7092    dialect: DialectType = None,
7093    copy: bool = True,
7094    **opts,
7095) -> Union:
7096    """
7097    Initializes a syntax tree for the `UNION` operation.
7098
7099    Example:
7100        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7101        'SELECT * FROM foo UNION SELECT * FROM bla'
7102
7103    Args:
7104        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7105            If `Expression` instances are passed, they will be used as-is.
7106        distinct: set the DISTINCT flag if and only if this is true.
7107        dialect: the dialect used to parse the input expression.
7108        copy: whether to copy the expression.
7109        opts: other options to use to parse the input expressions.
7110
7111    Returns:
7112        The new Union instance.
7113    """
7114    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7115    return _apply_set_operation(
7116        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7117    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7120def intersect(
7121    *expressions: ExpOrStr,
7122    distinct: bool = True,
7123    dialect: DialectType = None,
7124    copy: bool = True,
7125    **opts,
7126) -> Intersect:
7127    """
7128    Initializes a syntax tree for the `INTERSECT` operation.
7129
7130    Example:
7131        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7132        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7133
7134    Args:
7135        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7136            If `Expression` instances are passed, they will be used as-is.
7137        distinct: set the DISTINCT flag if and only if this is true.
7138        dialect: the dialect used to parse the input expression.
7139        copy: whether to copy the expression.
7140        opts: other options to use to parse the input expressions.
7141
7142    Returns:
7143        The new Intersect instance.
7144    """
7145    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7146    return _apply_set_operation(
7147        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7148    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7151def except_(
7152    *expressions: ExpOrStr,
7153    distinct: bool = True,
7154    dialect: DialectType = None,
7155    copy: bool = True,
7156    **opts,
7157) -> Except:
7158    """
7159    Initializes a syntax tree for the `EXCEPT` operation.
7160
7161    Example:
7162        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7163        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7164
7165    Args:
7166        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7167            If `Expression` instances are passed, they will be used as-is.
7168        distinct: set the DISTINCT flag if and only if this is true.
7169        dialect: the dialect used to parse the input expression.
7170        copy: whether to copy the expression.
7171        opts: other options to use to parse the input expressions.
7172
7173    Returns:
7174        The new Except instance.
7175    """
7176    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7177    return _apply_set_operation(
7178        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7179    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7182def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7183    """
7184    Initializes a syntax tree from one or multiple SELECT expressions.
7185
7186    Example:
7187        >>> select("col1", "col2").from_("tbl").sql()
7188        'SELECT col1, col2 FROM tbl'
7189
7190    Args:
7191        *expressions: the SQL code string to parse as the expressions of a
7192            SELECT statement. If an Expression instance is passed, this is used as-is.
7193        dialect: the dialect used to parse the input expressions (in the case that an
7194            input expression is a SQL string).
7195        **opts: other options to use to parse the input expressions (again, in the case
7196            that an input expression is a SQL string).
7197
7198    Returns:
7199        Select: the syntax tree for the SELECT statement.
7200    """
7201    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7204def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7205    """
7206    Initializes a syntax tree from a FROM expression.
7207
7208    Example:
7209        >>> from_("tbl").select("col1", "col2").sql()
7210        'SELECT col1, col2 FROM tbl'
7211
7212    Args:
7213        *expression: the SQL code string to parse as the FROM expressions of a
7214            SELECT statement. If an Expression instance is passed, this is used as-is.
7215        dialect: the dialect used to parse the input expression (in the case that the
7216            input expression is a SQL string).
7217        **opts: other options to use to parse the input expressions (again, in the case
7218            that the input expression is a SQL string).
7219
7220    Returns:
7221        Select: the syntax tree for the SELECT statement.
7222    """
7223    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Update:
7226def update(
7227    table: str | Table,
7228    properties: t.Optional[dict] = None,
7229    where: t.Optional[ExpOrStr] = None,
7230    from_: t.Optional[ExpOrStr] = None,
7231    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7232    dialect: DialectType = None,
7233    **opts,
7234) -> Update:
7235    """
7236    Creates an update statement.
7237
7238    Example:
7239        >>> 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()
7240        "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"
7241
7242    Args:
7243        properties: dictionary of properties to SET which are
7244            auto converted to sql objects eg None -> NULL
7245        where: sql conditional parsed into a WHERE statement
7246        from_: sql statement parsed into a FROM statement
7247        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7248        dialect: the dialect used to parse the input expressions.
7249        **opts: other options to use to parse the input expressions.
7250
7251    Returns:
7252        Update: the syntax tree for the UPDATE statement.
7253    """
7254    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7255    if properties:
7256        update_expr.set(
7257            "expressions",
7258            [
7259                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7260                for k, v in properties.items()
7261            ],
7262        )
7263    if from_:
7264        update_expr.set(
7265            "from",
7266            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7267        )
7268    if isinstance(where, Condition):
7269        where = Where(this=where)
7270    if where:
7271        update_expr.set(
7272            "where",
7273            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7274        )
7275    if with_:
7276        cte_list = [
7277            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7278            for alias, qry in with_.items()
7279        ]
7280        update_expr.set(
7281            "with",
7282            With(expressions=cte_list),
7283        )
7284    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Delete:
7287def delete(
7288    table: ExpOrStr,
7289    where: t.Optional[ExpOrStr] = None,
7290    returning: t.Optional[ExpOrStr] = None,
7291    dialect: DialectType = None,
7292    **opts,
7293) -> Delete:
7294    """
7295    Builds a delete statement.
7296
7297    Example:
7298        >>> delete("my_table", where="id > 1").sql()
7299        'DELETE FROM my_table WHERE id > 1'
7300
7301    Args:
7302        where: sql conditional parsed into a WHERE statement
7303        returning: sql conditional parsed into a RETURNING statement
7304        dialect: the dialect used to parse the input expressions.
7305        **opts: other options to use to parse the input expressions.
7306
7307    Returns:
7308        Delete: the syntax tree for the DELETE statement.
7309    """
7310    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7311    if where:
7312        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7313    if returning:
7314        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7315    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7318def insert(
7319    expression: ExpOrStr,
7320    into: ExpOrStr,
7321    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7322    overwrite: t.Optional[bool] = None,
7323    returning: t.Optional[ExpOrStr] = None,
7324    dialect: DialectType = None,
7325    copy: bool = True,
7326    **opts,
7327) -> Insert:
7328    """
7329    Builds an INSERT statement.
7330
7331    Example:
7332        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7333        'INSERT INTO tbl VALUES (1, 2, 3)'
7334
7335    Args:
7336        expression: the sql string or expression of the INSERT statement
7337        into: the tbl to insert data to.
7338        columns: optionally the table's column names.
7339        overwrite: whether to INSERT OVERWRITE or not.
7340        returning: sql conditional parsed into a RETURNING statement
7341        dialect: the dialect used to parse the input expressions.
7342        copy: whether to copy the expression.
7343        **opts: other options to use to parse the input expressions.
7344
7345    Returns:
7346        Insert: the syntax tree for the INSERT statement.
7347    """
7348    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7349    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7350
7351    if columns:
7352        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7353
7354    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7355
7356    if returning:
7357        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7358
7359    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7362def merge(
7363    *when_exprs: ExpOrStr,
7364    into: ExpOrStr,
7365    using: ExpOrStr,
7366    on: ExpOrStr,
7367    returning: t.Optional[ExpOrStr] = None,
7368    dialect: DialectType = None,
7369    copy: bool = True,
7370    **opts,
7371) -> Merge:
7372    """
7373    Builds a MERGE statement.
7374
7375    Example:
7376        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7377        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7378        ...       into="my_table",
7379        ...       using="source_table",
7380        ...       on="my_table.id = source_table.id").sql()
7381        '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)'
7382
7383    Args:
7384        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7385        into: The target table to merge data into.
7386        using: The source table to merge data from.
7387        on: The join condition for the merge.
7388        returning: The columns to return from the merge.
7389        dialect: The dialect used to parse the input expressions.
7390        copy: Whether to copy the expression.
7391        **opts: Other options to use to parse the input expressions.
7392
7393    Returns:
7394        Merge: The syntax tree for the MERGE statement.
7395    """
7396    expressions: t.List[Expression] = []
7397    for when_expr in when_exprs:
7398        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7399        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7400
7401    merge = Merge(
7402        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7403        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7404        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7405        whens=Whens(expressions=expressions),
7406    )
7407    if returning:
7408        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7409
7410    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7413def condition(
7414    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7415) -> Condition:
7416    """
7417    Initialize a logical condition expression.
7418
7419    Example:
7420        >>> condition("x=1").sql()
7421        'x = 1'
7422
7423        This is helpful for composing larger logical syntax trees:
7424        >>> where = condition("x=1")
7425        >>> where = where.and_("y=1")
7426        >>> Select().from_("tbl").select("*").where(where).sql()
7427        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7428
7429    Args:
7430        *expression: the SQL code string to parse.
7431            If an Expression instance is passed, this is used as-is.
7432        dialect: the dialect used to parse the input expression (in the case that the
7433            input expression is a SQL string).
7434        copy: Whether to copy `expression` (only applies to expressions).
7435        **opts: other options to use to parse the input expressions (again, in the case
7436            that the input expression is a SQL string).
7437
7438    Returns:
7439        The new Condition instance
7440    """
7441    return maybe_parse(
7442        expression,
7443        into=Condition,
7444        dialect=dialect,
7445        copy=copy,
7446        **opts,
7447    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7450def and_(
7451    *expressions: t.Optional[ExpOrStr],
7452    dialect: DialectType = None,
7453    copy: bool = True,
7454    wrap: bool = True,
7455    **opts,
7456) -> Condition:
7457    """
7458    Combine multiple conditions with an AND logical operator.
7459
7460    Example:
7461        >>> and_("x=1", and_("y=1", "z=1")).sql()
7462        'x = 1 AND (y = 1 AND z = 1)'
7463
7464    Args:
7465        *expressions: the SQL code strings to parse.
7466            If an Expression instance is passed, this is used as-is.
7467        dialect: the dialect used to parse the input expression.
7468        copy: whether to copy `expressions` (only applies to Expressions).
7469        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7470            precedence issues, but can be turned off when the produced AST is too deep and
7471            causes recursion-related issues.
7472        **opts: other options to use to parse the input expressions.
7473
7474    Returns:
7475        The new condition
7476    """
7477    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7480def or_(
7481    *expressions: t.Optional[ExpOrStr],
7482    dialect: DialectType = None,
7483    copy: bool = True,
7484    wrap: bool = True,
7485    **opts,
7486) -> Condition:
7487    """
7488    Combine multiple conditions with an OR logical operator.
7489
7490    Example:
7491        >>> or_("x=1", or_("y=1", "z=1")).sql()
7492        'x = 1 OR (y = 1 OR z = 1)'
7493
7494    Args:
7495        *expressions: the SQL code strings to parse.
7496            If an Expression instance is passed, this is used as-is.
7497        dialect: the dialect used to parse the input expression.
7498        copy: whether to copy `expressions` (only applies to Expressions).
7499        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7500            precedence issues, but can be turned off when the produced AST is too deep and
7501            causes recursion-related issues.
7502        **opts: other options to use to parse the input expressions.
7503
7504    Returns:
7505        The new condition
7506    """
7507    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7510def xor(
7511    *expressions: t.Optional[ExpOrStr],
7512    dialect: DialectType = None,
7513    copy: bool = True,
7514    wrap: bool = True,
7515    **opts,
7516) -> Condition:
7517    """
7518    Combine multiple conditions with an XOR logical operator.
7519
7520    Example:
7521        >>> xor("x=1", xor("y=1", "z=1")).sql()
7522        'x = 1 XOR (y = 1 XOR z = 1)'
7523
7524    Args:
7525        *expressions: the SQL code strings to parse.
7526            If an Expression instance is passed, this is used as-is.
7527        dialect: the dialect used to parse the input expression.
7528        copy: whether to copy `expressions` (only applies to Expressions).
7529        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7530            precedence issues, but can be turned off when the produced AST is too deep and
7531            causes recursion-related issues.
7532        **opts: other options to use to parse the input expressions.
7533
7534    Returns:
7535        The new condition
7536    """
7537    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7540def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7541    """
7542    Wrap a condition with a NOT operator.
7543
7544    Example:
7545        >>> not_("this_suit='black'").sql()
7546        "NOT this_suit = 'black'"
7547
7548    Args:
7549        expression: the SQL code string to parse.
7550            If an Expression instance is passed, this is used as-is.
7551        dialect: the dialect used to parse the input expression.
7552        copy: whether to copy the expression or not.
7553        **opts: other options to use to parse the input expressions.
7554
7555    Returns:
7556        The new condition.
7557    """
7558    this = condition(
7559        expression,
7560        dialect=dialect,
7561        copy=copy,
7562        **opts,
7563    )
7564    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:
7567def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7568    """
7569    Wrap an expression in parentheses.
7570
7571    Example:
7572        >>> paren("5 + 3").sql()
7573        '(5 + 3)'
7574
7575    Args:
7576        expression: the SQL code string to parse.
7577            If an Expression instance is passed, this is used as-is.
7578        copy: whether to copy the expression or not.
7579
7580    Returns:
7581        The wrapped expression.
7582    """
7583    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):
7599def to_identifier(name, quoted=None, copy=True):
7600    """Builds an identifier.
7601
7602    Args:
7603        name: The name to turn into an identifier.
7604        quoted: Whether to force quote the identifier.
7605        copy: Whether to copy name if it's an Identifier.
7606
7607    Returns:
7608        The identifier ast node.
7609    """
7610
7611    if name is None:
7612        return None
7613
7614    if isinstance(name, Identifier):
7615        identifier = maybe_copy(name, copy)
7616    elif isinstance(name, str):
7617        identifier = Identifier(
7618            this=name,
7619            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7620        )
7621    else:
7622        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7623    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
7626def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7627    """
7628    Parses a given string into an identifier.
7629
7630    Args:
7631        name: The name to parse into an identifier.
7632        dialect: The dialect to parse against.
7633
7634    Returns:
7635        The identifier ast node.
7636    """
7637    try:
7638        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7639    except (ParseError, TokenError):
7640        expression = to_identifier(name)
7641
7642    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:
7648def to_interval(interval: str | Literal) -> Interval:
7649    """Builds an interval expression from a string like '1 day' or '5 months'."""
7650    if isinstance(interval, Literal):
7651        if not interval.is_string:
7652            raise ValueError("Invalid interval string.")
7653
7654        interval = interval.this
7655
7656    interval = maybe_parse(f"INTERVAL {interval}")
7657    assert isinstance(interval, Interval)
7658    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
7661def to_table(
7662    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7663) -> Table:
7664    """
7665    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7666    If a table is passed in then that table is returned.
7667
7668    Args:
7669        sql_path: a `[catalog].[schema].[table]` string.
7670        dialect: the source dialect according to which the table name will be parsed.
7671        copy: Whether to copy a table if it is passed in.
7672        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7673
7674    Returns:
7675        A table expression.
7676    """
7677    if isinstance(sql_path, Table):
7678        return maybe_copy(sql_path, copy=copy)
7679
7680    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7681
7682    for k, v in kwargs.items():
7683        table.set(k, v)
7684
7685    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
7688def to_column(
7689    sql_path: str | Column,
7690    quoted: t.Optional[bool] = None,
7691    dialect: DialectType = None,
7692    copy: bool = True,
7693    **kwargs,
7694) -> Column:
7695    """
7696    Create a column from a `[table].[column]` sql path. Table is optional.
7697    If a column is passed in then that column is returned.
7698
7699    Args:
7700        sql_path: a `[table].[column]` string.
7701        quoted: Whether or not to force quote identifiers.
7702        dialect: the source dialect according to which the column name will be parsed.
7703        copy: Whether to copy a column if it is passed in.
7704        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7705
7706    Returns:
7707        A column expression.
7708    """
7709    if isinstance(sql_path, Column):
7710        return maybe_copy(sql_path, copy=copy)
7711
7712    try:
7713        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7714    except ParseError:
7715        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7716
7717    for k, v in kwargs.items():
7718        col.set(k, v)
7719
7720    if quoted:
7721        for i in col.find_all(Identifier):
7722            i.set("quoted", True)
7723
7724    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
7727def alias_(
7728    expression: ExpOrStr,
7729    alias: t.Optional[str | Identifier],
7730    table: bool | t.Sequence[str | Identifier] = False,
7731    quoted: t.Optional[bool] = None,
7732    dialect: DialectType = None,
7733    copy: bool = True,
7734    **opts,
7735):
7736    """Create an Alias expression.
7737
7738    Example:
7739        >>> alias_('foo', 'bar').sql()
7740        'foo AS bar'
7741
7742        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7743        '(SELECT 1, 2) AS bar(a, b)'
7744
7745    Args:
7746        expression: the SQL code strings to parse.
7747            If an Expression instance is passed, this is used as-is.
7748        alias: the alias name to use. If the name has
7749            special characters it is quoted.
7750        table: Whether to create a table alias, can also be a list of columns.
7751        quoted: whether to quote the alias
7752        dialect: the dialect used to parse the input expression.
7753        copy: Whether to copy the expression.
7754        **opts: other options to use to parse the input expressions.
7755
7756    Returns:
7757        Alias: the aliased expression
7758    """
7759    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7760    alias = to_identifier(alias, quoted=quoted)
7761
7762    if table:
7763        table_alias = TableAlias(this=alias)
7764        exp.set("alias", table_alias)
7765
7766        if not isinstance(table, bool):
7767            for column in table:
7768                table_alias.append("columns", to_identifier(column, quoted=quoted))
7769
7770        return exp
7771
7772    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7773    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7774    # for the complete Window expression.
7775    #
7776    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7777
7778    if "alias" in exp.arg_types and not isinstance(exp, Window):
7779        exp.set("alias", alias)
7780        return exp
7781    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7784def subquery(
7785    expression: ExpOrStr,
7786    alias: t.Optional[Identifier | str] = None,
7787    dialect: DialectType = None,
7788    **opts,
7789) -> Select:
7790    """
7791    Build a subquery expression that's selected from.
7792
7793    Example:
7794        >>> subquery('select x from tbl', 'bar').select('x').sql()
7795        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7796
7797    Args:
7798        expression: the SQL code strings to parse.
7799            If an Expression instance is passed, this is used as-is.
7800        alias: the alias name to use.
7801        dialect: the dialect used to parse the input expression.
7802        **opts: other options to use to parse the input expressions.
7803
7804    Returns:
7805        A new Select instance with the subquery expression included.
7806    """
7807
7808    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7809    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):
7840def column(
7841    col,
7842    table=None,
7843    db=None,
7844    catalog=None,
7845    *,
7846    fields=None,
7847    quoted=None,
7848    copy=True,
7849):
7850    """
7851    Build a Column.
7852
7853    Args:
7854        col: Column name.
7855        table: Table name.
7856        db: Database name.
7857        catalog: Catalog name.
7858        fields: Additional fields using dots.
7859        quoted: Whether to force quotes on the column's identifiers.
7860        copy: Whether to copy identifiers if passed in.
7861
7862    Returns:
7863        The new Column instance.
7864    """
7865    this = Column(
7866        this=to_identifier(col, quoted=quoted, copy=copy),
7867        table=to_identifier(table, quoted=quoted, copy=copy),
7868        db=to_identifier(db, quoted=quoted, copy=copy),
7869        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7870    )
7871
7872    if fields:
7873        this = Dot.build(
7874            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7875        )
7876    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Cast:
7879def cast(
7880    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7881) -> Cast:
7882    """Cast an expression to a data type.
7883
7884    Example:
7885        >>> cast('x + 1', 'int').sql()
7886        'CAST(x + 1 AS INT)'
7887
7888    Args:
7889        expression: The expression to cast.
7890        to: The datatype to cast to.
7891        copy: Whether to copy the supplied expressions.
7892        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7893            - The expression to be cast is already a exp.Cast expression
7894            - The existing cast is to a type that is logically equivalent to new type
7895
7896            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7897            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7898            and instead just return the original expression `CAST(x as DATETIME)`.
7899
7900            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7901            mapping is applied in the target dialect generator.
7902
7903    Returns:
7904        The new Cast instance.
7905    """
7906    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7907    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7908
7909    # dont re-cast if the expression is already a cast to the correct type
7910    if isinstance(expr, Cast):
7911        from sqlglot.dialects.dialect import Dialect
7912
7913        target_dialect = Dialect.get_or_raise(dialect)
7914        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7915
7916        existing_cast_type: DataType.Type = expr.to.this
7917        new_cast_type: DataType.Type = data_type.this
7918        types_are_equivalent = type_mapping.get(
7919            existing_cast_type, existing_cast_type.value
7920        ) == type_mapping.get(new_cast_type, new_cast_type.value)
7921
7922        if expr.is_type(data_type) or types_are_equivalent:
7923            return expr
7924
7925    expr = Cast(this=expr, to=data_type)
7926    expr.type = data_type
7927
7928    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:
7931def table_(
7932    table: Identifier | str,
7933    db: t.Optional[Identifier | str] = None,
7934    catalog: t.Optional[Identifier | str] = None,
7935    quoted: t.Optional[bool] = None,
7936    alias: t.Optional[Identifier | str] = None,
7937) -> Table:
7938    """Build a Table.
7939
7940    Args:
7941        table: Table name.
7942        db: Database name.
7943        catalog: Catalog name.
7944        quote: Whether to force quotes on the table's identifiers.
7945        alias: Table's alias.
7946
7947    Returns:
7948        The new Table instance.
7949    """
7950    return Table(
7951        this=to_identifier(table, quoted=quoted) if table else None,
7952        db=to_identifier(db, quoted=quoted) if db else None,
7953        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7954        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7955    )

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:
7958def values(
7959    values: t.Iterable[t.Tuple[t.Any, ...]],
7960    alias: t.Optional[str] = None,
7961    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7962) -> Values:
7963    """Build VALUES statement.
7964
7965    Example:
7966        >>> values([(1, '2')]).sql()
7967        "VALUES (1, '2')"
7968
7969    Args:
7970        values: values statements that will be converted to SQL
7971        alias: optional alias
7972        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7973         If either are provided then an alias is also required.
7974
7975    Returns:
7976        Values: the Values expression object
7977    """
7978    if columns and not alias:
7979        raise ValueError("Alias is required when providing columns")
7980
7981    return Values(
7982        expressions=[convert(tup) for tup in values],
7983        alias=(
7984            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7985            if columns
7986            else (TableAlias(this=to_identifier(alias)) if alias else None)
7987        ),
7988    )

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:
7991def var(name: t.Optional[ExpOrStr]) -> Var:
7992    """Build a SQL variable.
7993
7994    Example:
7995        >>> repr(var('x'))
7996        'Var(this=x)'
7997
7998        >>> repr(var(column('x', table='y')))
7999        'Var(this=x)'
8000
8001    Args:
8002        name: The name of the var or an expression who's name will become the var.
8003
8004    Returns:
8005        The new variable node.
8006    """
8007    if not name:
8008        raise ValueError("Cannot convert empty name into var.")
8009
8010    if isinstance(name, Expression):
8011        name = name.name
8012    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
8015def rename_table(
8016    old_name: str | Table,
8017    new_name: str | Table,
8018    dialect: DialectType = None,
8019) -> Alter:
8020    """Build ALTER TABLE... RENAME... expression
8021
8022    Args:
8023        old_name: The old name of the table
8024        new_name: The new name of the table
8025        dialect: The dialect to parse the table.
8026
8027    Returns:
8028        Alter table expression
8029    """
8030    old_table = to_table(old_name, dialect=dialect)
8031    new_table = to_table(new_name, dialect=dialect)
8032    return Alter(
8033        this=old_table,
8034        kind="TABLE",
8035        actions=[
8036            AlterRename(this=new_table),
8037        ],
8038    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
8041def rename_column(
8042    table_name: str | Table,
8043    old_column_name: str | Column,
8044    new_column_name: str | Column,
8045    exists: t.Optional[bool] = None,
8046    dialect: DialectType = None,
8047) -> Alter:
8048    """Build ALTER TABLE... RENAME COLUMN... expression
8049
8050    Args:
8051        table_name: Name of the table
8052        old_column: The old name of the column
8053        new_column: The new name of the column
8054        exists: Whether to add the `IF EXISTS` clause
8055        dialect: The dialect to parse the table/column.
8056
8057    Returns:
8058        Alter table expression
8059    """
8060    table = to_table(table_name, dialect=dialect)
8061    old_column = to_column(old_column_name, dialect=dialect)
8062    new_column = to_column(new_column_name, dialect=dialect)
8063    return Alter(
8064        this=table,
8065        kind="TABLE",
8066        actions=[
8067            RenameColumn(this=old_column, to=new_column, exists=exists),
8068        ],
8069    )

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:
8072def convert(value: t.Any, copy: bool = False) -> Expression:
8073    """Convert a python value into an expression object.
8074
8075    Raises an error if a conversion is not possible.
8076
8077    Args:
8078        value: A python object.
8079        copy: Whether to copy `value` (only applies to Expressions and collections).
8080
8081    Returns:
8082        The equivalent expression object.
8083    """
8084    if isinstance(value, Expression):
8085        return maybe_copy(value, copy)
8086    if isinstance(value, str):
8087        return Literal.string(value)
8088    if isinstance(value, bool):
8089        return Boolean(this=value)
8090    if value is None or (isinstance(value, float) and math.isnan(value)):
8091        return null()
8092    if isinstance(value, numbers.Number):
8093        return Literal.number(value)
8094    if isinstance(value, bytes):
8095        return HexString(this=value.hex())
8096    if isinstance(value, datetime.datetime):
8097        datetime_literal = Literal.string(value.isoformat(sep=" "))
8098
8099        tz = None
8100        if value.tzinfo:
8101            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8102            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8103            tz = Literal.string(str(value.tzinfo))
8104
8105        return TimeStrToTime(this=datetime_literal, zone=tz)
8106    if isinstance(value, datetime.date):
8107        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8108        return DateStrToDate(this=date_literal)
8109    if isinstance(value, tuple):
8110        if hasattr(value, "_fields"):
8111            return Struct(
8112                expressions=[
8113                    PropertyEQ(
8114                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8115                    )
8116                    for k in value._fields
8117                ]
8118            )
8119        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8120    if isinstance(value, list):
8121        return Array(expressions=[convert(v, copy=copy) for v in value])
8122    if isinstance(value, dict):
8123        return Map(
8124            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8125            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8126        )
8127    if hasattr(value, "__dict__"):
8128        return Struct(
8129            expressions=[
8130                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8131                for k, v in value.__dict__.items()
8132            ]
8133        )
8134    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:
8137def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8138    """
8139    Replace children of an expression with the result of a lambda fun(child) -> exp.
8140    """
8141    for k, v in tuple(expression.args.items()):
8142        is_list_arg = type(v) is list
8143
8144        child_nodes = v if is_list_arg else [v]
8145        new_child_nodes = []
8146
8147        for cn in child_nodes:
8148            if isinstance(cn, Expression):
8149                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8150                    new_child_nodes.append(child_node)
8151            else:
8152                new_child_nodes.append(cn)
8153
8154        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:
8157def replace_tree(
8158    expression: Expression,
8159    fun: t.Callable,
8160    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8161) -> Expression:
8162    """
8163    Replace an entire tree with the result of function calls on each node.
8164
8165    This will be traversed in reverse dfs, so leaves first.
8166    If new nodes are created as a result of function calls, they will also be traversed.
8167    """
8168    stack = list(expression.dfs(prune=prune))
8169
8170    while stack:
8171        node = stack.pop()
8172        new_node = fun(node)
8173
8174        if new_node is not node:
8175            node.replace(new_node)
8176
8177            if isinstance(new_node, Expression):
8178                stack.append(new_node)
8179
8180    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]:
8183def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8184    """
8185    Return all table names referenced through columns in an expression.
8186
8187    Example:
8188        >>> import sqlglot
8189        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8190        ['a', 'c']
8191
8192    Args:
8193        expression: expression to find table names.
8194        exclude: a table name to exclude
8195
8196    Returns:
8197        A list of unique names.
8198    """
8199    return {
8200        table
8201        for table in (column.table for column in expression.find_all(Column))
8202        if table and table != exclude
8203    }

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
8206def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8207    """Get the full name of a table as a string.
8208
8209    Args:
8210        table: Table expression node or string.
8211        dialect: The dialect to generate the table name for.
8212        identify: Determines when an identifier should be quoted. Possible values are:
8213            False (default): Never quote, except in cases where it's mandatory by the dialect.
8214            True: Always quote.
8215
8216    Examples:
8217        >>> from sqlglot import exp, parse_one
8218        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8219        'a.b.c'
8220
8221    Returns:
8222        The table name.
8223    """
8224
8225    table = maybe_parse(table, into=Table, dialect=dialect)
8226
8227    if not table:
8228        raise ValueError(f"Cannot parse {table}")
8229
8230    return ".".join(
8231        (
8232            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8233            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8234            else part.name
8235        )
8236        for part in table.parts
8237    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
8240def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8241    """Returns a case normalized table name without quotes.
8242
8243    Args:
8244        table: the table to normalize
8245        dialect: the dialect to use for normalization rules
8246        copy: whether to copy the expression.
8247
8248    Examples:
8249        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8250        'A-B.c'
8251    """
8252    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8253
8254    return ".".join(
8255        p.name
8256        for p in normalize_identifiers(
8257            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8258        ).parts
8259    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8262def replace_tables(
8263    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8264) -> E:
8265    """Replace all tables in expression according to the mapping.
8266
8267    Args:
8268        expression: expression node to be transformed and replaced.
8269        mapping: mapping of table names.
8270        dialect: the dialect of the mapping table
8271        copy: whether to copy the expression.
8272
8273    Examples:
8274        >>> from sqlglot import exp, parse_one
8275        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8276        'SELECT * FROM c /* a.b */'
8277
8278    Returns:
8279        The mapped expression.
8280    """
8281
8282    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8283
8284    def _replace_tables(node: Expression) -> Expression:
8285        if isinstance(node, Table) and node.meta.get("replace") is not False:
8286            original = normalize_table_name(node, dialect=dialect)
8287            new_name = mapping.get(original)
8288
8289            if new_name:
8290                table = to_table(
8291                    new_name,
8292                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8293                    dialect=dialect,
8294                )
8295                table.add_comments([original])
8296                return table
8297        return node
8298
8299    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:
8302def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8303    """Replace placeholders in an expression.
8304
8305    Args:
8306        expression: expression node to be transformed and replaced.
8307        args: positional names that will substitute unnamed placeholders in the given order.
8308        kwargs: keyword arguments that will substitute named placeholders.
8309
8310    Examples:
8311        >>> from sqlglot import exp, parse_one
8312        >>> replace_placeholders(
8313        ...     parse_one("select * from :tbl where ? = ?"),
8314        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8315        ... ).sql()
8316        "SELECT * FROM foo WHERE str_col = 'b'"
8317
8318    Returns:
8319        The mapped expression.
8320    """
8321
8322    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8323        if isinstance(node, Placeholder):
8324            if node.this:
8325                new_name = kwargs.get(node.this)
8326                if new_name is not None:
8327                    return convert(new_name)
8328            else:
8329                try:
8330                    return convert(next(args))
8331                except StopIteration:
8332                    pass
8333        return node
8334
8335    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, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8338def expand(
8339    expression: Expression,
8340    sources: t.Dict[str, Query],
8341    dialect: DialectType = None,
8342    copy: bool = True,
8343) -> Expression:
8344    """Transforms an expression by expanding all referenced sources into subqueries.
8345
8346    Examples:
8347        >>> from sqlglot import parse_one
8348        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8349        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8350
8351        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8352        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8353
8354    Args:
8355        expression: The expression to expand.
8356        sources: A dictionary of name to Queries.
8357        dialect: The dialect of the sources dict.
8358        copy: Whether to copy the expression during transformation. Defaults to True.
8359
8360    Returns:
8361        The transformed expression.
8362    """
8363    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8364
8365    def _expand(node: Expression):
8366        if isinstance(node, Table):
8367            name = normalize_table_name(node, dialect=dialect)
8368            source = sources.get(name)
8369            if source:
8370                subquery = source.subquery(node.alias or name)
8371                subquery.comments = [f"source: {name}"]
8372                return subquery.transform(_expand, copy=False)
8373        return node
8374
8375    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 dictionary of name to Queries.
  • dialect: The dialect of the sources dict.
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
8378def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8379    """
8380    Returns a Func expression.
8381
8382    Examples:
8383        >>> func("abs", 5).sql()
8384        'ABS(5)'
8385
8386        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8387        'CAST(5 AS DOUBLE)'
8388
8389    Args:
8390        name: the name of the function to build.
8391        args: the args used to instantiate the function of interest.
8392        copy: whether to copy the argument expressions.
8393        dialect: the source dialect.
8394        kwargs: the kwargs used to instantiate the function of interest.
8395
8396    Note:
8397        The arguments `args` and `kwargs` are mutually exclusive.
8398
8399    Returns:
8400        An instance of the function of interest, or an anonymous function, if `name` doesn't
8401        correspond to an existing `sqlglot.expressions.Func` class.
8402    """
8403    if args and kwargs:
8404        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8405
8406    from sqlglot.dialects.dialect import Dialect
8407
8408    dialect = Dialect.get_or_raise(dialect)
8409
8410    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8411    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8412
8413    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8414    if constructor:
8415        if converted:
8416            if "dialect" in constructor.__code__.co_varnames:
8417                function = constructor(converted, dialect=dialect)
8418            else:
8419                function = constructor(converted)
8420        elif constructor.__name__ == "from_arg_list":
8421            function = constructor.__self__(**kwargs)  # type: ignore
8422        else:
8423            constructor = FUNCTION_BY_NAME.get(name.upper())
8424            if constructor:
8425                function = constructor(**kwargs)
8426            else:
8427                raise ValueError(
8428                    f"Unable to convert '{name}' into a Func. Either manually construct "
8429                    "the Func expression of interest or parse the function call."
8430                )
8431    else:
8432        kwargs = kwargs or {"expressions": converted}
8433        function = Anonymous(this=name, **kwargs)
8434
8435    for error_message in function.error_messages(converted):
8436        raise ValueError(error_message)
8437
8438    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:
8441def case(
8442    expression: t.Optional[ExpOrStr] = None,
8443    **opts,
8444) -> Case:
8445    """
8446    Initialize a CASE statement.
8447
8448    Example:
8449        case().when("a = 1", "foo").else_("bar")
8450
8451    Args:
8452        expression: Optionally, the input expression (not all dialects support this)
8453        **opts: Extra keyword arguments for parsing `expression`
8454    """
8455    if expression is not None:
8456        this = maybe_parse(expression, **opts)
8457    else:
8458        this = None
8459    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
8462def array(
8463    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8464) -> Array:
8465    """
8466    Returns an array.
8467
8468    Examples:
8469        >>> array(1, 'x').sql()
8470        'ARRAY(1, x)'
8471
8472    Args:
8473        expressions: the expressions to add to the array.
8474        copy: whether to copy the argument expressions.
8475        dialect: the source dialect.
8476        kwargs: the kwargs used to instantiate the function of interest.
8477
8478    Returns:
8479        An array expression.
8480    """
8481    return Array(
8482        expressions=[
8483            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8484            for expression in expressions
8485        ]
8486    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
8489def tuple_(
8490    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8491) -> Tuple:
8492    """
8493    Returns an tuple.
8494
8495    Examples:
8496        >>> tuple_(1, 'x').sql()
8497        '(1, x)'
8498
8499    Args:
8500        expressions: the expressions to add to the tuple.
8501        copy: whether to copy the argument expressions.
8502        dialect: the source dialect.
8503        kwargs: the kwargs used to instantiate the function of interest.
8504
8505    Returns:
8506        A tuple expression.
8507    """
8508    return Tuple(
8509        expressions=[
8510            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8511            for expression in expressions
8512        ]
8513    )

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:
8516def true() -> Boolean:
8517    """
8518    Returns a true Boolean expression.
8519    """
8520    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8523def false() -> Boolean:
8524    """
8525    Returns a false Boolean expression.
8526    """
8527    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8530def null() -> Null:
8531    """
8532    Returns a Null expression.
8533    """
8534    return Null()

Returns a Null expression.

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