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

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)
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)
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
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        )
this: Any
133    @property
134    def this(self) -> t.Any:
135        """
136        Retrieves the argument with key "this".
137        """
138        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

expressions: List[Any]
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 []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
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 ""

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
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"]

Checks whether a Literal expression is a string.

is_number: bool
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        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
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.")

Returns a Python object equivalent of the SQL node.

is_int: bool
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)

Checks whether an expression is an integer.

is_star: bool
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))

Checks whether an expression is a star.

alias: str
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")

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

alias_column_names: List[str]
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 []]
name: str
218    @property
219    def name(self) -> str:
220        return self.text("this")
alias_or_name: str
222    @property
223    def alias_or_name(self) -> str:
224        return self.alias or self.name
output_name: str
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 ""

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]
244    @property
245    def type(self) -> t.Optional[DataType]:
246        return self._type
def is_type(self, *dtypes) -> bool:
254    def is_type(self, *dtypes) -> bool:
255        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
257    def is_leaf(self) -> bool:
258        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
260    @property
261    def meta(self) -> t.Dict[str, t.Any]:
262        if self._meta is None:
263            self._meta = {}
264        return self._meta
def copy(self) -> typing_extensions.Self:
300    def copy(self) -> Self:
301        """
302        Returns a deep copy of the expression.
303        """
304        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
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
def pop_comments(self) -> List[str]:
325    def pop_comments(self) -> t.List[str]:
326        comments = self.comments or []
327        self.comments = None
328        return comments
def append(self, arg_key: str, value: Any) -> None:
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)

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

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

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
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

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
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)

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

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

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

same_parent: bool
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__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
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

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
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)

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

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

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

Returns:

The generator object.

def unnest(self):
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

Returns the first non parenthesis child or self.

def unalias(self):
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

Returns the inner expression if this is an Alias.

def unnest_operands(self):
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())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
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

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

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

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

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

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

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
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

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

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
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)

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

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

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

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:
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)
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:
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        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
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        )
def is_( self, other: Union[str, Expression]) -> Is:
916    def is_(self, other: ExpOrStr) -> Is:
917        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
919    def like(self, other: ExpOrStr) -> Like:
920        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
922    def ilike(self, other: ExpOrStr) -> ILike:
923        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
925    def eq(self, other: t.Any) -> EQ:
926        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
928    def neq(self, other: t.Any) -> NEQ:
929        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
931    def rlike(self, other: ExpOrStr) -> RegexpLike:
932        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
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
def asc(self, nulls_first: bool = True) -> Ordered:
940    def asc(self, nulls_first: bool = True) -> Ordered:
941        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
943    def desc(self, nulls_first: bool = False) -> Ordered:
944        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):
1027class Condition(Expression):
1028    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
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]
selects: List[Expression]
1036    @property
1037    def selects(self) -> t.List[Expression]:
1038        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1040    @property
1041    def named_selects(self) -> t.List[str]:
1042        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
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)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
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)

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

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

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

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]
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 []

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

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

Returns the query's projections.

named_selects: List[str]
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`")

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:
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`")

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

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

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

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

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):
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 []
selects: List[Expression]
1335    @property
1336    def selects(self) -> t.List[Expression]:
1337        alias = self.args.get("alias")
1338        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1341class Cache(Expression):
1342    arg_types = {
1343        "this": True,
1344        "lazy": False,
1345        "options": False,
1346        "expression": False,
1347    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1350class Uncache(Expression):
1351    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1354class Refresh(Expression):
1355    pass
key = 'refresh'
class DDL(Expression):
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 []
ctes: List[CTE]
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 []

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

selects: List[Expression]
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 []

If this statement contains a query (e.g. a CTAS), this returns the query's projections.

named_selects: List[str]
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 []

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

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):
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()
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]
1436    @property
1437    def kind(self) -> t.Optional[str]:
1438        kind = self.args.get("kind")
1439        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
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    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
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    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1470class Clone(Expression):
1471    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
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    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1486class Attach(Expression):
1487    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1491class Detach(Expression):
1492    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1496class Summarize(Expression):
1497    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1500class Kill(Expression):
1501    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1504class Pragma(Expression):
1505    pass
key = 'pragma'
class Declare(Expression):
1508class Declare(Expression):
1509    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1512class DeclareItem(Expression):
1513    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1516class Set(Expression):
1517    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1520class Heredoc(Expression):
1521    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
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    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
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    }
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):
1560class UserDefinedFunction(Expression):
1561    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1564class CharacterSet(Expression):
1565    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
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"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1571    @property
1572    def recursive(self) -> bool:
1573        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1576class WithinGroup(Expression):
1577    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1582class CTE(DerivedTable):
1583    arg_types = {
1584        "this": True,
1585        "alias": True,
1586        "scalar": False,
1587        "materialized": False,
1588    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1591class ProjectionDef(Expression):
1592    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1595class TableAlias(Expression):
1596    arg_types = {"this": False, "columns": False}
1597
1598    @property
1599    def columns(self):
1600        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1598    @property
1599    def columns(self):
1600        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1603class BitString(Condition):
1604    pass
key = 'bitstring'
class HexString(Condition):
1607class HexString(Condition):
1608    pass
key = 'hexstring'
class ByteString(Condition):
1611class ByteString(Condition):
1612    pass
key = 'bytestring'
class RawString(Condition):
1615class RawString(Condition):
1616    pass
key = 'rawstring'
class UnicodeString(Condition):
1619class UnicodeString(Condition):
1620    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
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]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1626    @property
1627    def table(self) -> str:
1628        return self.text("table")
db: str
1630    @property
1631    def db(self) -> str:
1632        return self.text("db")
catalog: str
1634    @property
1635    def catalog(self) -> str:
1636        return self.text("catalog")
output_name: str
1638    @property
1639    def output_name(self) -> str:
1640        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]
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        ]

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

def to_dot(self) -> Dot | Identifier:
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]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1664class ColumnPosition(Expression):
1665    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
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")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1677    @property
1678    def constraints(self) -> t.List[ColumnConstraint]:
1679        return self.args.get("constraints") or []
kind: Optional[DataType]
1681    @property
1682    def kind(self) -> t.Optional[DataType]:
1683        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
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    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1700class AlterDistStyle(Expression):
1701    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1704class AlterSortKey(Expression):
1705    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
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    }
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):
1722class RenameColumn(Expression):
1723    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1726class AlterRename(Expression):
1727    pass
key = 'alterrename'
class SwapTable(Expression):
1730class SwapTable(Expression):
1731    pass
key = 'swaptable'
class Comment(Expression):
1734class Comment(Expression):
1735    arg_types = {
1736        "this": True,
1737        "kind": True,
1738        "expression": True,
1739        "exists": False,
1740        "materialized": False,
1741    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1744class Comprehension(Expression):
1745    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):
1749class MergeTreeTTLAction(Expression):
1750    arg_types = {
1751        "this": True,
1752        "delete": False,
1753        "recompress": False,
1754        "to_disk": False,
1755        "to_volume": False,
1756    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1760class MergeTreeTTL(Expression):
1761    arg_types = {
1762        "expressions": True,
1763        "where": False,
1764        "group": False,
1765        "aggregates": False,
1766    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
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    }
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):
1782class ColumnConstraint(Expression):
1783    arg_types = {"this": False, "kind": True}
1784
1785    @property
1786    def kind(self) -> ColumnConstraintKind:
1787        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1785    @property
1786    def kind(self) -> ColumnConstraintKind:
1787        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1790class ColumnConstraintKind(Expression):
1791    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1794class AutoIncrementColumnConstraint(ColumnConstraintKind):
1795    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1798class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1799    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1802class CaseSpecificColumnConstraint(ColumnConstraintKind):
1803    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1806class CharacterSetColumnConstraint(ColumnConstraintKind):
1807    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1810class CheckColumnConstraint(ColumnConstraintKind):
1811    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1814class ClusteredColumnConstraint(ColumnConstraintKind):
1815    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1818class CollateColumnConstraint(ColumnConstraintKind):
1819    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1822class CommentColumnConstraint(ColumnConstraintKind):
1823    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1826class CompressColumnConstraint(ColumnConstraintKind):
1827    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1830class DateFormatColumnConstraint(ColumnConstraintKind):
1831    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1834class DefaultColumnConstraint(ColumnConstraintKind):
1835    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1838class EncodeColumnConstraint(ColumnConstraintKind):
1839    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1843class ExcludeColumnConstraint(ColumnConstraintKind):
1844    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1847class EphemeralColumnConstraint(ColumnConstraintKind):
1848    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1851class WithOperator(Expression):
1852    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
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    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1869class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1870    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
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    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1887class InlineLengthColumnConstraint(ColumnConstraintKind):
1888    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1891class NonClusteredColumnConstraint(ColumnConstraintKind):
1892    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1895class NotForReplicationColumnConstraint(ColumnConstraintKind):
1896    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1900class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1901    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1904class NotNullColumnConstraint(ColumnConstraintKind):
1905    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1909class OnUpdateColumnConstraint(ColumnConstraintKind):
1910    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1914class TransformColumnConstraint(ColumnConstraintKind):
1915    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1918class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1919    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1922class TitleColumnConstraint(ColumnConstraintKind):
1923    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1926class UniqueColumnConstraint(ColumnConstraintKind):
1927    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):
1930class UppercaseColumnConstraint(ColumnConstraintKind):
1931    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1935class WatermarkColumnConstraint(Expression):
1936    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1939class PathColumnConstraint(ColumnConstraintKind):
1940    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1944class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1945    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1950class ComputedColumnConstraint(ColumnConstraintKind):
1951    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1954class Constraint(Expression):
1955    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
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        )
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:
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        )

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

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):
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()
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]
2058    @property
2059    def kind(self) -> t.Optional[str]:
2060        kind = self.args.get("kind")
2061        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2064class Filter(Expression):
2065    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2068class Check(Expression):
2069    pass
key = 'check'
class Changes(Expression):
2072class Changes(Expression):
2073    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2077class Connect(Expression):
2078    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2081class CopyParameter(Expression):
2082    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
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    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2096class Credentials(Expression):
2097    arg_types = {
2098        "credentials": False,
2099        "encryption": False,
2100        "storage": False,
2101        "iam_role": False,
2102        "region": False,
2103    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2106class Prior(Expression):
2107    pass
key = 'prior'
class Directory(Expression):
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}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2115class ForeignKey(Expression):
2116    arg_types = {
2117        "expressions": False,
2118        "reference": False,
2119        "delete": False,
2120        "update": False,
2121    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2124class ColumnPrefix(Expression):
2125    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2128class PrimaryKey(Expression):
2129    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2134class Into(Expression):
2135    arg_types = {
2136        "this": False,
2137        "temporary": False,
2138        "unlogged": False,
2139        "bulk_collect": False,
2140        "expressions": False,
2141    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
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
name: str
2145    @property
2146    def name(self) -> str:
2147        return self.this.name
alias_or_name: str
2149    @property
2150    def alias_or_name(self) -> str:
2151        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2154class Having(Expression):
2155    pass
key = 'having'
class Hint(Expression):
2158class Hint(Expression):
2159    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2162class JoinHint(Expression):
2163    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
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
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2169    @property
2170    def quoted(self) -> bool:
2171        return bool(self.args.get("quoted"))
hashable_args: Any
2173    @property
2174    def hashable_args(self) -> t.Any:
2175        return (self.this, self.quoted)
output_name: str
2177    @property
2178    def output_name(self) -> str:
2179        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):
2183class Opclass(Expression):
2184    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
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    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
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    }
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):
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        )
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:
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        )

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):
2279class ConditionalInsert(Expression):
2280    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2283class MultitableInserts(Expression):
2284    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2287class OnConflict(Expression):
2288    arg_types = {
2289        "duplicate": False,
2290        "expressions": False,
2291        "action": False,
2292        "conflict_keys": False,
2293        "constraint": False,
2294    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2297class OnCondition(Expression):
2298    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2301class Returning(Expression):
2302    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2306class Introducer(Expression):
2307    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2311class National(Expression):
2312    pass
key = 'national'
class LoadData(Expression):
2315class LoadData(Expression):
2316    arg_types = {
2317        "this": True,
2318        "local": False,
2319        "overwrite": False,
2320        "inpath": True,
2321        "partition": False,
2322        "input_format": False,
2323        "serde": False,
2324    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2327class Partition(Expression):
2328    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2331class PartitionRange(Expression):
2332    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2336class PartitionId(Expression):
2337    pass
key = 'partitionid'
class Fetch(Expression):
2340class Fetch(Expression):
2341    arg_types = {
2342        "direction": False,
2343        "count": False,
2344        "percent": False,
2345        "with_ties": False,
2346    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2349class Grant(Expression):
2350    arg_types = {
2351        "privileges": True,
2352        "kind": False,
2353        "securable": True,
2354        "principals": True,
2355        "grant_option": False,
2356    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2359class Group(Expression):
2360    arg_types = {
2361        "expressions": False,
2362        "grouping_sets": False,
2363        "cube": False,
2364        "rollup": False,
2365        "totals": False,
2366        "all": False,
2367    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2370class Cube(Expression):
2371    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2374class Rollup(Expression):
2375    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2378class GroupingSets(Expression):
2379    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2382class Lambda(Expression):
2383    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2386class Limit(Expression):
2387    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):
2390class Literal(Condition):
2391    arg_types = {"this": True, "is_string": True}
2392
2393    @property
2394    def hashable_args(self) -> t.Any:
2395        return (self.this, self.args.get("is_string"))
2396
2397    @classmethod
2398    def number(cls, number) -> Literal:
2399        return cls(this=str(number), is_string=False)
2400
2401    @classmethod
2402    def string(cls, string) -> Literal:
2403        return cls(this=str(string), is_string=True)
2404
2405    @property
2406    def output_name(self) -> str:
2407        return self.name
2408
2409    def to_py(self) -> int | str | Decimal:
2410        if self.is_number:
2411            try:
2412                return int(self.this)
2413            except ValueError:
2414                return Decimal(self.this)
2415        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2393    @property
2394    def hashable_args(self) -> t.Any:
2395        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2397    @classmethod
2398    def number(cls, number) -> Literal:
2399        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2401    @classmethod
2402    def string(cls, string) -> Literal:
2403        return cls(this=str(string), is_string=True)
output_name: str
2405    @property
2406    def output_name(self) -> str:
2407        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:
2409    def to_py(self) -> int | str | Decimal:
2410        if self.is_number:
2411            try:
2412                return int(self.this)
2413            except ValueError:
2414                return Decimal(self.this)
2415        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2418class Join(Expression):
2419    arg_types = {
2420        "this": True,
2421        "on": False,
2422        "side": False,
2423        "kind": False,
2424        "using": False,
2425        "method": False,
2426        "global": False,
2427        "hint": False,
2428        "match_condition": False,  # Snowflake
2429        "expressions": False,
2430    }
2431
2432    @property
2433    def method(self) -> str:
2434        return self.text("method").upper()
2435
2436    @property
2437    def kind(self) -> str:
2438        return self.text("kind").upper()
2439
2440    @property
2441    def side(self) -> str:
2442        return self.text("side").upper()
2443
2444    @property
2445    def hint(self) -> str:
2446        return self.text("hint").upper()
2447
2448    @property
2449    def alias_or_name(self) -> str:
2450        return self.this.alias_or_name
2451
2452    def on(
2453        self,
2454        *expressions: t.Optional[ExpOrStr],
2455        append: bool = True,
2456        dialect: DialectType = None,
2457        copy: bool = True,
2458        **opts,
2459    ) -> Join:
2460        """
2461        Append to or set the ON expressions.
2462
2463        Example:
2464            >>> import sqlglot
2465            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2466            'JOIN x ON y = 1'
2467
2468        Args:
2469            *expressions: the SQL code strings to parse.
2470                If an `Expression` instance is passed, it will be used as-is.
2471                Multiple expressions are combined with an AND operator.
2472            append: if `True`, AND the new expressions to any existing expression.
2473                Otherwise, this resets the expression.
2474            dialect: the dialect used to parse the input expressions.
2475            copy: if `False`, modify this expression instance in-place.
2476            opts: other options to use to parse the input expressions.
2477
2478        Returns:
2479            The modified Join expression.
2480        """
2481        join = _apply_conjunction_builder(
2482            *expressions,
2483            instance=self,
2484            arg="on",
2485            append=append,
2486            dialect=dialect,
2487            copy=copy,
2488            **opts,
2489        )
2490
2491        if join.kind == "CROSS":
2492            join.set("kind", None)
2493
2494        return join
2495
2496    def using(
2497        self,
2498        *expressions: t.Optional[ExpOrStr],
2499        append: bool = True,
2500        dialect: DialectType = None,
2501        copy: bool = True,
2502        **opts,
2503    ) -> Join:
2504        """
2505        Append to or set the USING expressions.
2506
2507        Example:
2508            >>> import sqlglot
2509            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2510            'JOIN x USING (foo, bla)'
2511
2512        Args:
2513            *expressions: the SQL code strings to parse.
2514                If an `Expression` instance is passed, it will be used as-is.
2515            append: if `True`, concatenate the new expressions to the existing "using" list.
2516                Otherwise, this resets the expression.
2517            dialect: the dialect used to parse the input expressions.
2518            copy: if `False`, modify this expression instance in-place.
2519            opts: other options to use to parse the input expressions.
2520
2521        Returns:
2522            The modified Join expression.
2523        """
2524        join = _apply_list_builder(
2525            *expressions,
2526            instance=self,
2527            arg="using",
2528            append=append,
2529            dialect=dialect,
2530            copy=copy,
2531            **opts,
2532        )
2533
2534        if join.kind == "CROSS":
2535            join.set("kind", None)
2536
2537        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
2432    @property
2433    def method(self) -> str:
2434        return self.text("method").upper()
kind: str
2436    @property
2437    def kind(self) -> str:
2438        return self.text("kind").upper()
side: str
2440    @property
2441    def side(self) -> str:
2442        return self.text("side").upper()
hint: str
2444    @property
2445    def hint(self) -> str:
2446        return self.text("hint").upper()
alias_or_name: str
2448    @property
2449    def alias_or_name(self) -> str:
2450        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:
2452    def on(
2453        self,
2454        *expressions: t.Optional[ExpOrStr],
2455        append: bool = True,
2456        dialect: DialectType = None,
2457        copy: bool = True,
2458        **opts,
2459    ) -> Join:
2460        """
2461        Append to or set the ON expressions.
2462
2463        Example:
2464            >>> import sqlglot
2465            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2466            'JOIN x ON y = 1'
2467
2468        Args:
2469            *expressions: the SQL code strings to parse.
2470                If an `Expression` instance is passed, it will be used as-is.
2471                Multiple expressions are combined with an AND operator.
2472            append: if `True`, AND the new expressions to any existing expression.
2473                Otherwise, this resets the expression.
2474            dialect: the dialect used to parse the input expressions.
2475            copy: if `False`, modify this expression instance in-place.
2476            opts: other options to use to parse the input expressions.
2477
2478        Returns:
2479            The modified Join expression.
2480        """
2481        join = _apply_conjunction_builder(
2482            *expressions,
2483            instance=self,
2484            arg="on",
2485            append=append,
2486            dialect=dialect,
2487            copy=copy,
2488            **opts,
2489        )
2490
2491        if join.kind == "CROSS":
2492            join.set("kind", None)
2493
2494        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:
2496    def using(
2497        self,
2498        *expressions: t.Optional[ExpOrStr],
2499        append: bool = True,
2500        dialect: DialectType = None,
2501        copy: bool = True,
2502        **opts,
2503    ) -> Join:
2504        """
2505        Append to or set the USING expressions.
2506
2507        Example:
2508            >>> import sqlglot
2509            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2510            'JOIN x USING (foo, bla)'
2511
2512        Args:
2513            *expressions: the SQL code strings to parse.
2514                If an `Expression` instance is passed, it will be used as-is.
2515            append: if `True`, concatenate the new expressions to the existing "using" list.
2516                Otherwise, this resets the expression.
2517            dialect: the dialect used to parse the input expressions.
2518            copy: if `False`, modify this expression instance in-place.
2519            opts: other options to use to parse the input expressions.
2520
2521        Returns:
2522            The modified Join expression.
2523        """
2524        join = _apply_list_builder(
2525            *expressions,
2526            instance=self,
2527            arg="using",
2528            append=append,
2529            dialect=dialect,
2530            copy=copy,
2531            **opts,
2532        )
2533
2534        if join.kind == "CROSS":
2535            join.set("kind", None)
2536
2537        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):
2540class Lateral(UDTF):
2541    arg_types = {
2542        "this": True,
2543        "view": False,
2544        "outer": False,
2545        "alias": False,
2546        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2547    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2550class MatchRecognizeMeasure(Expression):
2551    arg_types = {
2552        "this": True,
2553        "window_frame": False,
2554    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2557class MatchRecognize(Expression):
2558    arg_types = {
2559        "partition_by": False,
2560        "order": False,
2561        "measures": False,
2562        "rows": False,
2563        "after": False,
2564        "pattern": False,
2565        "define": False,
2566        "alias": False,
2567    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2572class Final(Expression):
2573    pass
key = 'final'
class Offset(Expression):
2576class Offset(Expression):
2577    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2580class Order(Expression):
2581    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2585class WithFill(Expression):
2586    arg_types = {
2587        "from": False,
2588        "to": False,
2589        "step": False,
2590        "interpolate": False,
2591    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2596class Cluster(Order):
2597    pass
key = 'cluster'
class Distribute(Order):
2600class Distribute(Order):
2601    pass
key = 'distribute'
class Sort(Order):
2604class Sort(Order):
2605    pass
key = 'sort'
class Ordered(Expression):
2608class Ordered(Expression):
2609    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):
2612class Property(Expression):
2613    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2616class GrantPrivilege(Expression):
2617    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2620class GrantPrincipal(Expression):
2621    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2624class AllowedValuesProperty(Expression):
2625    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2628class AlgorithmProperty(Property):
2629    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2632class AutoIncrementProperty(Property):
2633    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2637class AutoRefreshProperty(Property):
2638    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2641class BackupProperty(Property):
2642    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2645class BlockCompressionProperty(Property):
2646    arg_types = {
2647        "autotemp": False,
2648        "always": False,
2649        "default": False,
2650        "manual": False,
2651        "never": False,
2652    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2655class CharacterSetProperty(Property):
2656    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2659class ChecksumProperty(Property):
2660    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2663class CollateProperty(Property):
2664    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2667class CopyGrantsProperty(Property):
2668    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2671class DataBlocksizeProperty(Property):
2672    arg_types = {
2673        "size": False,
2674        "units": False,
2675        "minimum": False,
2676        "maximum": False,
2677        "default": False,
2678    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2681class DataDeletionProperty(Property):
2682    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):
2685class DefinerProperty(Property):
2686    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2689class DistKeyProperty(Property):
2690    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2695class DistributedByProperty(Property):
2696    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):
2699class DistStyleProperty(Property):
2700    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2703class DuplicateKeyProperty(Property):
2704    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2707class EngineProperty(Property):
2708    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2711class HeapProperty(Property):
2712    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2715class ToTableProperty(Property):
2716    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2719class ExecuteAsProperty(Property):
2720    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2723class ExternalProperty(Property):
2724    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2727class FallbackProperty(Property):
2728    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2731class FileFormatProperty(Property):
2732    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2735class FreespaceProperty(Property):
2736    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2739class GlobalProperty(Property):
2740    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2743class IcebergProperty(Property):
2744    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2747class InheritsProperty(Property):
2748    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2751class InputModelProperty(Property):
2752    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2755class OutputModelProperty(Property):
2756    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2759class IsolatedLoadingProperty(Property):
2760    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2763class JournalProperty(Property):
2764    arg_types = {
2765        "no": False,
2766        "dual": False,
2767        "before": False,
2768        "local": False,
2769        "after": False,
2770    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2773class LanguageProperty(Property):
2774    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2778class ClusteredByProperty(Property):
2779    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2782class DictProperty(Property):
2783    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2786class DictSubProperty(Property):
2787    pass
key = 'dictsubproperty'
class DictRange(Property):
2790class DictRange(Property):
2791    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2794class DynamicProperty(Property):
2795    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2800class OnCluster(Property):
2801    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2805class EmptyProperty(Property):
2806    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2809class LikeProperty(Property):
2810    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2813class LocationProperty(Property):
2814    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2817class LockProperty(Property):
2818    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2821class LockingProperty(Property):
2822    arg_types = {
2823        "this": False,
2824        "kind": True,
2825        "for_or_in": False,
2826        "lock_type": True,
2827        "override": False,
2828    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2831class LogProperty(Property):
2832    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2835class MaterializedProperty(Property):
2836    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2839class MergeBlockRatioProperty(Property):
2840    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):
2843class NoPrimaryIndexProperty(Property):
2844    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2847class OnProperty(Property):
2848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2851class OnCommitProperty(Property):
2852    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2855class PartitionedByProperty(Property):
2856    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2860class PartitionBoundSpec(Expression):
2861    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2862    arg_types = {
2863        "this": False,
2864        "expression": False,
2865        "from_expressions": False,
2866        "to_expressions": False,
2867    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2870class PartitionedOfProperty(Property):
2871    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2872    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2875class StreamingTableProperty(Property):
2876    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2879class RemoteWithConnectionModelProperty(Property):
2880    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2883class ReturnsProperty(Property):
2884    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):
2887class StrictProperty(Property):
2888    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2891class RowFormatProperty(Property):
2892    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2895class RowFormatDelimitedProperty(Property):
2896    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2897    arg_types = {
2898        "fields": False,
2899        "escaped": False,
2900        "collection_items": False,
2901        "map_keys": False,
2902        "lines": False,
2903        "null": False,
2904        "serde": False,
2905    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2908class RowFormatSerdeProperty(Property):
2909    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2913class QueryTransform(Expression):
2914    arg_types = {
2915        "expressions": True,
2916        "command_script": True,
2917        "schema": False,
2918        "row_format_before": False,
2919        "record_writer": False,
2920        "row_format_after": False,
2921        "record_reader": False,
2922    }
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):
2925class SampleProperty(Property):
2926    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2930class SecurityProperty(Property):
2931    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2934class SchemaCommentProperty(Property):
2935    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2938class SerdeProperties(Property):
2939    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2942class SetProperty(Property):
2943    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2946class SharingProperty(Property):
2947    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2950class SetConfigProperty(Property):
2951    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2954class SettingsProperty(Property):
2955    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2958class SortKeyProperty(Property):
2959    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2962class SqlReadWriteProperty(Property):
2963    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2966class SqlSecurityProperty(Property):
2967    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2970class StabilityProperty(Property):
2971    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2974class TemporaryProperty(Property):
2975    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2978class SecureProperty(Property):
2979    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
2983class Tags(ColumnConstraintKind, Property):
2984    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
2987class TransformModelProperty(Property):
2988    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2991class TransientProperty(Property):
2992    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2995class UnloggedProperty(Property):
2996    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
3000class ViewAttributeProperty(Property):
3001    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3004class VolatileProperty(Property):
3005    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3008class WithDataProperty(Property):
3009    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3012class WithJournalTableProperty(Property):
3013    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3016class WithSchemaBindingProperty(Property):
3017    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3020class WithSystemVersioningProperty(Property):
3021    arg_types = {
3022        "on": False,
3023        "this": False,
3024        "data_consistency": False,
3025        "retention_period": False,
3026        "with": True,
3027    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3030class WithProcedureOptions(Property):
3031    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3034class EncodeProperty(Property):
3035    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3038class IncludeProperty(Property):
3039    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class Properties(Expression):
3042class Properties(Expression):
3043    arg_types = {"expressions": True}
3044
3045    NAME_TO_PROPERTY = {
3046        "ALGORITHM": AlgorithmProperty,
3047        "AUTO_INCREMENT": AutoIncrementProperty,
3048        "CHARACTER SET": CharacterSetProperty,
3049        "CLUSTERED_BY": ClusteredByProperty,
3050        "COLLATE": CollateProperty,
3051        "COMMENT": SchemaCommentProperty,
3052        "DEFINER": DefinerProperty,
3053        "DISTKEY": DistKeyProperty,
3054        "DISTRIBUTED_BY": DistributedByProperty,
3055        "DISTSTYLE": DistStyleProperty,
3056        "ENGINE": EngineProperty,
3057        "EXECUTE AS": ExecuteAsProperty,
3058        "FORMAT": FileFormatProperty,
3059        "LANGUAGE": LanguageProperty,
3060        "LOCATION": LocationProperty,
3061        "LOCK": LockProperty,
3062        "PARTITIONED_BY": PartitionedByProperty,
3063        "RETURNS": ReturnsProperty,
3064        "ROW_FORMAT": RowFormatProperty,
3065        "SORTKEY": SortKeyProperty,
3066        "ENCODE": EncodeProperty,
3067        "INCLUDE": IncludeProperty,
3068    }
3069
3070    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3071
3072    # CREATE property locations
3073    # Form: schema specified
3074    #   create [POST_CREATE]
3075    #     table a [POST_NAME]
3076    #     (b int) [POST_SCHEMA]
3077    #     with ([POST_WITH])
3078    #     index (b) [POST_INDEX]
3079    #
3080    # Form: alias selection
3081    #   create [POST_CREATE]
3082    #     table a [POST_NAME]
3083    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3084    #     index (c) [POST_INDEX]
3085    class Location(AutoName):
3086        POST_CREATE = auto()
3087        POST_NAME = auto()
3088        POST_SCHEMA = auto()
3089        POST_WITH = auto()
3090        POST_ALIAS = auto()
3091        POST_EXPRESSION = auto()
3092        POST_INDEX = auto()
3093        UNSUPPORTED = auto()
3094
3095    @classmethod
3096    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3097        expressions = []
3098        for key, value in properties_dict.items():
3099            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3100            if property_cls:
3101                expressions.append(property_cls(this=convert(value)))
3102            else:
3103                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3104
3105        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:
3095    @classmethod
3096    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3097        expressions = []
3098        for key, value in properties_dict.items():
3099            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3100            if property_cls:
3101                expressions.append(property_cls(this=convert(value)))
3102            else:
3103                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3104
3105        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3085    class Location(AutoName):
3086        POST_CREATE = auto()
3087        POST_NAME = auto()
3088        POST_SCHEMA = auto()
3089        POST_WITH = auto()
3090        POST_ALIAS = auto()
3091        POST_EXPRESSION = auto()
3092        POST_INDEX = auto()
3093        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):
3108class Qualify(Expression):
3109    pass
key = 'qualify'
class InputOutputFormat(Expression):
3112class InputOutputFormat(Expression):
3113    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3117class Return(Expression):
3118    pass
key = 'return'
class Reference(Expression):
3121class Reference(Expression):
3122    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3125class Tuple(Expression):
3126    arg_types = {"expressions": False}
3127
3128    def isin(
3129        self,
3130        *expressions: t.Any,
3131        query: t.Optional[ExpOrStr] = None,
3132        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3133        copy: bool = True,
3134        **opts,
3135    ) -> In:
3136        return In(
3137            this=maybe_copy(self, copy),
3138            expressions=[convert(e, copy=copy) for e in expressions],
3139            query=maybe_parse(query, copy=copy, **opts) if query else None,
3140            unnest=(
3141                Unnest(
3142                    expressions=[
3143                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3144                        for e in ensure_list(unnest)
3145                    ]
3146                )
3147                if unnest
3148                else None
3149            ),
3150        )
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:
3128    def isin(
3129        self,
3130        *expressions: t.Any,
3131        query: t.Optional[ExpOrStr] = None,
3132        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3133        copy: bool = True,
3134        **opts,
3135    ) -> In:
3136        return In(
3137            this=maybe_copy(self, copy),
3138            expressions=[convert(e, copy=copy) for e in expressions],
3139            query=maybe_parse(query, copy=copy, **opts) if query else None,
3140            unnest=(
3141                Unnest(
3142                    expressions=[
3143                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3144                        for e in ensure_list(unnest)
3145                    ]
3146                )
3147                if unnest
3148                else None
3149            ),
3150        )
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):
3181class QueryOption(Expression):
3182    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3186class WithTableHint(Expression):
3187    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3191class IndexTableHint(Expression):
3192    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3196class HistoricalData(Expression):
3197    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3200class Table(Expression):
3201    arg_types = {
3202        "this": False,
3203        "alias": False,
3204        "db": False,
3205        "catalog": False,
3206        "laterals": False,
3207        "joins": False,
3208        "pivots": False,
3209        "hints": False,
3210        "system_time": False,
3211        "version": False,
3212        "format": False,
3213        "pattern": False,
3214        "ordinality": False,
3215        "when": False,
3216        "only": False,
3217        "partition": False,
3218        "changes": False,
3219        "rows_from": False,
3220        "sample": False,
3221    }
3222
3223    @property
3224    def name(self) -> str:
3225        if isinstance(self.this, Func):
3226            return ""
3227        return self.this.name
3228
3229    @property
3230    def db(self) -> str:
3231        return self.text("db")
3232
3233    @property
3234    def catalog(self) -> str:
3235        return self.text("catalog")
3236
3237    @property
3238    def selects(self) -> t.List[Expression]:
3239        return []
3240
3241    @property
3242    def named_selects(self) -> t.List[str]:
3243        return []
3244
3245    @property
3246    def parts(self) -> t.List[Expression]:
3247        """Return the parts of a table in order catalog, db, table."""
3248        parts: t.List[Expression] = []
3249
3250        for arg in ("catalog", "db", "this"):
3251            part = self.args.get(arg)
3252
3253            if isinstance(part, Dot):
3254                parts.extend(part.flatten())
3255            elif isinstance(part, Expression):
3256                parts.append(part)
3257
3258        return parts
3259
3260    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3261        parts = self.parts
3262        last_part = parts[-1]
3263
3264        if isinstance(last_part, Identifier):
3265            col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3266        else:
3267            # This branch will be reached if a function or array is wrapped in a `Table`
3268            col = last_part
3269
3270        alias = self.args.get("alias")
3271        if alias:
3272            col = alias_(col, alias.this, copy=copy)
3273
3274        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
3223    @property
3224    def name(self) -> str:
3225        if isinstance(self.this, Func):
3226            return ""
3227        return self.this.name
db: str
3229    @property
3230    def db(self) -> str:
3231        return self.text("db")
catalog: str
3233    @property
3234    def catalog(self) -> str:
3235        return self.text("catalog")
selects: List[Expression]
3237    @property
3238    def selects(self) -> t.List[Expression]:
3239        return []
named_selects: List[str]
3241    @property
3242    def named_selects(self) -> t.List[str]:
3243        return []
parts: List[Expression]
3245    @property
3246    def parts(self) -> t.List[Expression]:
3247        """Return the parts of a table in order catalog, db, table."""
3248        parts: t.List[Expression] = []
3249
3250        for arg in ("catalog", "db", "this"):
3251            part = self.args.get(arg)
3252
3253            if isinstance(part, Dot):
3254                parts.extend(part.flatten())
3255            elif isinstance(part, Expression):
3256                parts.append(part)
3257
3258        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3260    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3261        parts = self.parts
3262        last_part = parts[-1]
3263
3264        if isinstance(last_part, Identifier):
3265            col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3266        else:
3267            # This branch will be reached if a function or array is wrapped in a `Table`
3268            col = last_part
3269
3270        alias = self.args.get("alias")
3271        if alias:
3272            col = alias_(col, alias.this, copy=copy)
3273
3274        return col
key = 'table'
class SetOperation(Query):
3277class SetOperation(Query):
3278    arg_types = {
3279        "with": False,
3280        "this": True,
3281        "expression": True,
3282        "distinct": False,
3283        "by_name": False,
3284        **QUERY_MODIFIERS,
3285    }
3286
3287    def select(
3288        self: S,
3289        *expressions: t.Optional[ExpOrStr],
3290        append: bool = True,
3291        dialect: DialectType = None,
3292        copy: bool = True,
3293        **opts,
3294    ) -> S:
3295        this = maybe_copy(self, copy)
3296        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3297        this.expression.unnest().select(
3298            *expressions, append=append, dialect=dialect, copy=False, **opts
3299        )
3300        return this
3301
3302    @property
3303    def named_selects(self) -> t.List[str]:
3304        return self.this.unnest().named_selects
3305
3306    @property
3307    def is_star(self) -> bool:
3308        return self.this.is_star or self.expression.is_star
3309
3310    @property
3311    def selects(self) -> t.List[Expression]:
3312        return self.this.unnest().selects
3313
3314    @property
3315    def left(self) -> Query:
3316        return self.this
3317
3318    @property
3319    def right(self) -> Query:
3320        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:
3287    def select(
3288        self: S,
3289        *expressions: t.Optional[ExpOrStr],
3290        append: bool = True,
3291        dialect: DialectType = None,
3292        copy: bool = True,
3293        **opts,
3294    ) -> S:
3295        this = maybe_copy(self, copy)
3296        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3297        this.expression.unnest().select(
3298            *expressions, append=append, dialect=dialect, copy=False, **opts
3299        )
3300        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]
3302    @property
3303    def named_selects(self) -> t.List[str]:
3304        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3306    @property
3307    def is_star(self) -> bool:
3308        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3310    @property
3311    def selects(self) -> t.List[Expression]:
3312        return self.this.unnest().selects

Returns the query's projections.

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

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:
3379    def set_(
3380        self,
3381        *expressions: ExpOrStr,
3382        append: bool = True,
3383        dialect: DialectType = None,
3384        copy: bool = True,
3385        **opts,
3386    ) -> Update:
3387        """
3388        Append to or set the SET expressions.
3389
3390        Example:
3391            >>> Update().table("my_table").set_("x = 1").sql()
3392            'UPDATE my_table SET x = 1'
3393
3394        Args:
3395            *expressions: the SQL code strings to parse.
3396                If `Expression` instance(s) are passed, they will be used as-is.
3397                Multiple expressions are combined with a comma.
3398            append: if `True`, add the new expressions to any existing SET expressions.
3399                Otherwise, this resets the expressions.
3400            dialect: the dialect used to parse the input expressions.
3401            copy: if `False`, modify this expression instance in-place.
3402            opts: other options to use to parse the input expressions.
3403        """
3404        return _apply_list_builder(
3405            *expressions,
3406            instance=self,
3407            arg="expressions",
3408            append=append,
3409            into=Expression,
3410            prefix=None,
3411            dialect=dialect,
3412            copy=copy,
3413            **opts,
3414        )

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:
3416    def where(
3417        self,
3418        *expressions: t.Optional[ExpOrStr],
3419        append: bool = True,
3420        dialect: DialectType = None,
3421        copy: bool = True,
3422        **opts,
3423    ) -> Select:
3424        """
3425        Append to or set the WHERE expressions.
3426
3427        Example:
3428            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3429            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3430
3431        Args:
3432            *expressions: the SQL code strings to parse.
3433                If an `Expression` instance is passed, it will be used as-is.
3434                Multiple expressions are combined with an AND operator.
3435            append: if `True`, AND the new expressions to any existing expression.
3436                Otherwise, this resets the expression.
3437            dialect: the dialect used to parse the input expressions.
3438            copy: if `False`, modify this expression instance in-place.
3439            opts: other options to use to parse the input expressions.
3440
3441        Returns:
3442            Select: the modified expression.
3443        """
3444        return _apply_conjunction_builder(
3445            *expressions,
3446            instance=self,
3447            arg="where",
3448            append=append,
3449            into=Where,
3450            dialect=dialect,
3451            copy=copy,
3452            **opts,
3453        )

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:
3455    def from_(
3456        self,
3457        expression: t.Optional[ExpOrStr] = None,
3458        dialect: DialectType = None,
3459        copy: bool = True,
3460        **opts,
3461    ) -> Update:
3462        """
3463        Set the FROM expression.
3464
3465        Example:
3466            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3467            'UPDATE my_table SET x = 1 FROM baz'
3468
3469        Args:
3470            expression : the SQL code strings to parse.
3471                If a `From` instance is passed, this is used as-is.
3472                If another `Expression` instance is passed, it will be wrapped in a `From`.
3473                If nothing is passed in then a from is not applied to the expression
3474            dialect: the dialect used to parse the input expression.
3475            copy: if `False`, modify this expression instance in-place.
3476            opts: other options to use to parse the input expressions.
3477
3478        Returns:
3479            The modified Update expression.
3480        """
3481        if not expression:
3482            return maybe_copy(self, copy)
3483
3484        return _apply_builder(
3485            expression=expression,
3486            instance=self,
3487            arg="from",
3488            into=From,
3489            prefix="FROM",
3490            dialect=dialect,
3491            copy=copy,
3492            **opts,
3493        )

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:
3495    def with_(
3496        self,
3497        alias: ExpOrStr,
3498        as_: ExpOrStr,
3499        recursive: t.Optional[bool] = None,
3500        materialized: t.Optional[bool] = None,
3501        append: bool = True,
3502        dialect: DialectType = None,
3503        copy: bool = True,
3504        **opts,
3505    ) -> Update:
3506        """
3507        Append to or set the common table expressions.
3508
3509        Example:
3510            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3511            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3512
3513        Args:
3514            alias: the SQL code string to parse as the table name.
3515                If an `Expression` instance is passed, this is used as-is.
3516            as_: the SQL code string to parse as the table expression.
3517                If an `Expression` instance is passed, it will be used as-is.
3518            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3519            materialized: set the MATERIALIZED part of the expression.
3520            append: if `True`, add to any existing expressions.
3521                Otherwise, this resets the expressions.
3522            dialect: the dialect used to parse the input expression.
3523            copy: if `False`, modify this expression instance in-place.
3524            opts: other options to use to parse the input expressions.
3525
3526        Returns:
3527            The modified expression.
3528        """
3529        return _apply_cte_builder(
3530            self,
3531            alias,
3532            as_,
3533            recursive=recursive,
3534            materialized=materialized,
3535            append=append,
3536            dialect=dialect,
3537            copy=copy,
3538            **opts,
3539        )

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

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:
3619    def group_by(
3620        self,
3621        *expressions: t.Optional[ExpOrStr],
3622        append: bool = True,
3623        dialect: DialectType = None,
3624        copy: bool = True,
3625        **opts,
3626    ) -> Select:
3627        """
3628        Set the GROUP BY expression.
3629
3630        Example:
3631            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3632            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3633
3634        Args:
3635            *expressions: the SQL code strings to parse.
3636                If a `Group` instance is passed, this is used as-is.
3637                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3638                If nothing is passed in then a group by is not applied to the expression
3639            append: if `True`, add to any existing expressions.
3640                Otherwise, this flattens all the `Group` expression into a single expression.
3641            dialect: the dialect used to parse the input expression.
3642            copy: if `False`, modify this expression instance in-place.
3643            opts: other options to use to parse the input expressions.
3644
3645        Returns:
3646            The modified Select expression.
3647        """
3648        if not expressions:
3649            return self if not copy else self.copy()
3650
3651        return _apply_child_list_builder(
3652            *expressions,
3653            instance=self,
3654            arg="group",
3655            append=append,
3656            copy=copy,
3657            prefix="GROUP BY",
3658            into=Group,
3659            dialect=dialect,
3660            **opts,
3661        )

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:
3663    def sort_by(
3664        self,
3665        *expressions: t.Optional[ExpOrStr],
3666        append: bool = True,
3667        dialect: DialectType = None,
3668        copy: bool = True,
3669        **opts,
3670    ) -> Select:
3671        """
3672        Set the SORT BY expression.
3673
3674        Example:
3675            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3676            'SELECT x FROM tbl SORT BY x DESC'
3677
3678        Args:
3679            *expressions: the SQL code strings to parse.
3680                If a `Group` instance is passed, this is used as-is.
3681                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3682            append: if `True`, add to any existing expressions.
3683                Otherwise, this flattens all the `Order` expression into a single expression.
3684            dialect: the dialect used to parse the input expression.
3685            copy: if `False`, modify this expression instance in-place.
3686            opts: other options to use to parse the input expressions.
3687
3688        Returns:
3689            The modified Select expression.
3690        """
3691        return _apply_child_list_builder(
3692            *expressions,
3693            instance=self,
3694            arg="sort",
3695            append=append,
3696            copy=copy,
3697            prefix="SORT BY",
3698            into=Sort,
3699            dialect=dialect,
3700            **opts,
3701        )

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:
3703    def cluster_by(
3704        self,
3705        *expressions: t.Optional[ExpOrStr],
3706        append: bool = True,
3707        dialect: DialectType = None,
3708        copy: bool = True,
3709        **opts,
3710    ) -> Select:
3711        """
3712        Set the CLUSTER BY expression.
3713
3714        Example:
3715            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3716            'SELECT x FROM tbl CLUSTER BY x DESC'
3717
3718        Args:
3719            *expressions: the SQL code strings to parse.
3720                If a `Group` instance is passed, this is used as-is.
3721                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3722            append: if `True`, add to any existing expressions.
3723                Otherwise, this flattens all the `Order` expression into a single expression.
3724            dialect: the dialect used to parse the input expression.
3725            copy: if `False`, modify this expression instance in-place.
3726            opts: other options to use to parse the input expressions.
3727
3728        Returns:
3729            The modified Select expression.
3730        """
3731        return _apply_child_list_builder(
3732            *expressions,
3733            instance=self,
3734            arg="cluster",
3735            append=append,
3736            copy=copy,
3737            prefix="CLUSTER BY",
3738            into=Cluster,
3739            dialect=dialect,
3740            **opts,
3741        )

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:
3743    def select(
3744        self,
3745        *expressions: t.Optional[ExpOrStr],
3746        append: bool = True,
3747        dialect: DialectType = None,
3748        copy: bool = True,
3749        **opts,
3750    ) -> Select:
3751        return _apply_list_builder(
3752            *expressions,
3753            instance=self,
3754            arg="expressions",
3755            append=append,
3756            dialect=dialect,
3757            into=Expression,
3758            copy=copy,
3759            **opts,
3760        )

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:
3762    def lateral(
3763        self,
3764        *expressions: t.Optional[ExpOrStr],
3765        append: bool = True,
3766        dialect: DialectType = None,
3767        copy: bool = True,
3768        **opts,
3769    ) -> Select:
3770        """
3771        Append to or set the LATERAL expressions.
3772
3773        Example:
3774            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3775            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3776
3777        Args:
3778            *expressions: the SQL code strings to parse.
3779                If an `Expression` instance is passed, it will be used as-is.
3780            append: if `True`, add to any existing expressions.
3781                Otherwise, this resets the expressions.
3782            dialect: the dialect used to parse the input expressions.
3783            copy: if `False`, modify this expression instance in-place.
3784            opts: other options to use to parse the input expressions.
3785
3786        Returns:
3787            The modified Select expression.
3788        """
3789        return _apply_list_builder(
3790            *expressions,
3791            instance=self,
3792            arg="laterals",
3793            append=append,
3794            into=Lateral,
3795            prefix="LATERAL VIEW",
3796            dialect=dialect,
3797            copy=copy,
3798            **opts,
3799        )

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

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:
3899    def where(
3900        self,
3901        *expressions: t.Optional[ExpOrStr],
3902        append: bool = True,
3903        dialect: DialectType = None,
3904        copy: bool = True,
3905        **opts,
3906    ) -> Select:
3907        """
3908        Append to or set the WHERE expressions.
3909
3910        Example:
3911            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3912            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3913
3914        Args:
3915            *expressions: the SQL code strings to parse.
3916                If an `Expression` instance is passed, it will be used as-is.
3917                Multiple expressions are combined with an AND operator.
3918            append: if `True`, AND the new expressions to any existing expression.
3919                Otherwise, this resets the expression.
3920            dialect: the dialect used to parse the input expressions.
3921            copy: if `False`, modify this expression instance in-place.
3922            opts: other options to use to parse the input expressions.
3923
3924        Returns:
3925            Select: the modified expression.
3926        """
3927        return _apply_conjunction_builder(
3928            *expressions,
3929            instance=self,
3930            arg="where",
3931            append=append,
3932            into=Where,
3933            dialect=dialect,
3934            copy=copy,
3935            **opts,
3936        )

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:
3938    def having(
3939        self,
3940        *expressions: t.Optional[ExpOrStr],
3941        append: bool = True,
3942        dialect: DialectType = None,
3943        copy: bool = True,
3944        **opts,
3945    ) -> Select:
3946        """
3947        Append to or set the HAVING expressions.
3948
3949        Example:
3950            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3951            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3952
3953        Args:
3954            *expressions: the SQL code strings to parse.
3955                If an `Expression` instance is passed, it will be used as-is.
3956                Multiple expressions are combined with an AND operator.
3957            append: if `True`, AND the new expressions to any existing expression.
3958                Otherwise, this resets the expression.
3959            dialect: the dialect used to parse the input expressions.
3960            copy: if `False`, modify this expression instance in-place.
3961            opts: other options to use to parse the input expressions.
3962
3963        Returns:
3964            The modified Select expression.
3965        """
3966        return _apply_conjunction_builder(
3967            *expressions,
3968            instance=self,
3969            arg="having",
3970            append=append,
3971            into=Having,
3972            dialect=dialect,
3973            copy=copy,
3974            **opts,
3975        )

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

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:
4078    def lock(self, update: bool = True, copy: bool = True) -> Select:
4079        """
4080        Set the locking read mode for this expression.
4081
4082        Examples:
4083            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4084            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4085
4086            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4087            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4088
4089        Args:
4090            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4091            copy: if `False`, modify this expression instance in-place.
4092
4093        Returns:
4094            The modified expression.
4095        """
4096        inst = maybe_copy(self, copy)
4097        inst.set("locks", [Lock(update=update)])
4098
4099        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:
4101    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4102        """
4103        Set hints for this expression.
4104
4105        Examples:
4106            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4107            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4108
4109        Args:
4110            hints: The SQL code strings to parse as the hints.
4111                If an `Expression` instance is passed, it will be used as-is.
4112            dialect: The dialect used to parse the hints.
4113            copy: If `False`, modify this expression instance in-place.
4114
4115        Returns:
4116            The modified expression.
4117        """
4118        inst = maybe_copy(self, copy)
4119        inst.set(
4120            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4121        )
4122
4123        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]
4125    @property
4126    def named_selects(self) -> t.List[str]:
4127        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
4129    @property
4130    def is_star(self) -> bool:
4131        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4133    @property
4134    def selects(self) -> t.List[Expression]:
4135        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4141class Subquery(DerivedTable, Query):
4142    arg_types = {
4143        "this": True,
4144        "alias": False,
4145        "with": False,
4146        **QUERY_MODIFIERS,
4147    }
4148
4149    def unnest(self):
4150        """Returns the first non subquery."""
4151        expression = self
4152        while isinstance(expression, Subquery):
4153            expression = expression.this
4154        return expression
4155
4156    def unwrap(self) -> Subquery:
4157        expression = self
4158        while expression.same_parent and expression.is_wrapper:
4159            expression = t.cast(Subquery, expression.parent)
4160        return expression
4161
4162    def select(
4163        self,
4164        *expressions: t.Optional[ExpOrStr],
4165        append: bool = True,
4166        dialect: DialectType = None,
4167        copy: bool = True,
4168        **opts,
4169    ) -> Subquery:
4170        this = maybe_copy(self, copy)
4171        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4172        return this
4173
4174    @property
4175    def is_wrapper(self) -> bool:
4176        """
4177        Whether this Subquery acts as a simple wrapper around another expression.
4178
4179        SELECT * FROM (((SELECT * FROM t)))
4180                      ^
4181                      This corresponds to a "wrapper" Subquery node
4182        """
4183        return all(v is None for k, v in self.args.items() if k != "this")
4184
4185    @property
4186    def is_star(self) -> bool:
4187        return self.this.is_star
4188
4189    @property
4190    def output_name(self) -> str:
4191        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):
4149    def unnest(self):
4150        """Returns the first non subquery."""
4151        expression = self
4152        while isinstance(expression, Subquery):
4153            expression = expression.this
4154        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4156    def unwrap(self) -> Subquery:
4157        expression = self
4158        while expression.same_parent and expression.is_wrapper:
4159            expression = t.cast(Subquery, expression.parent)
4160        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:
4162    def select(
4163        self,
4164        *expressions: t.Optional[ExpOrStr],
4165        append: bool = True,
4166        dialect: DialectType = None,
4167        copy: bool = True,
4168        **opts,
4169    ) -> Subquery:
4170        this = maybe_copy(self, copy)
4171        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4172        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
4174    @property
4175    def is_wrapper(self) -> bool:
4176        """
4177        Whether this Subquery acts as a simple wrapper around another expression.
4178
4179        SELECT * FROM (((SELECT * FROM t)))
4180                      ^
4181                      This corresponds to a "wrapper" Subquery node
4182        """
4183        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
4185    @property
4186    def is_star(self) -> bool:
4187        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4189    @property
4190    def output_name(self) -> str:
4191        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):
4194class TableSample(Expression):
4195    arg_types = {
4196        "expressions": False,
4197        "method": False,
4198        "bucket_numerator": False,
4199        "bucket_denominator": False,
4200        "bucket_field": False,
4201        "percent": False,
4202        "rows": False,
4203        "size": False,
4204        "seed": False,
4205    }
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):
4208class Tag(Expression):
4209    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4210
4211    arg_types = {
4212        "this": False,
4213        "prefix": False,
4214        "postfix": False,
4215    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4220class Pivot(Expression):
4221    arg_types = {
4222        "this": False,
4223        "alias": False,
4224        "expressions": False,
4225        "field": False,
4226        "unpivot": False,
4227        "using": False,
4228        "group": False,
4229        "columns": False,
4230        "include_nulls": False,
4231        "default_on_null": False,
4232    }
4233
4234    @property
4235    def unpivot(self) -> bool:
4236        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}
unpivot: bool
4234    @property
4235    def unpivot(self) -> bool:
4236        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
4239class Window(Condition):
4240    arg_types = {
4241        "this": True,
4242        "partition_by": False,
4243        "order": False,
4244        "spec": False,
4245        "alias": False,
4246        "over": False,
4247        "first": False,
4248    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4251class WindowSpec(Expression):
4252    arg_types = {
4253        "kind": False,
4254        "start": False,
4255        "start_side": False,
4256        "end": False,
4257        "end_side": False,
4258    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4261class PreWhere(Expression):
4262    pass
key = 'prewhere'
class Where(Expression):
4265class Where(Expression):
4266    pass
key = 'where'
class Star(Expression):
4269class Star(Expression):
4270    arg_types = {"except": False, "replace": False, "rename": False}
4271
4272    @property
4273    def name(self) -> str:
4274        return "*"
4275
4276    @property
4277    def output_name(self) -> str:
4278        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4272    @property
4273    def name(self) -> str:
4274        return "*"
output_name: str
4276    @property
4277    def output_name(self) -> str:
4278        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):
4281class Parameter(Condition):
4282    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4285class SessionParameter(Condition):
4286    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4289class Placeholder(Condition):
4290    arg_types = {"this": False, "kind": False}
4291
4292    @property
4293    def name(self) -> str:
4294        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4292    @property
4293    def name(self) -> str:
4294        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4297class Null(Condition):
4298    arg_types: t.Dict[str, t.Any] = {}
4299
4300    @property
4301    def name(self) -> str:
4302        return "NULL"
4303
4304    def to_py(self) -> Lit[None]:
4305        return None
arg_types: Dict[str, Any] = {}
name: str
4300    @property
4301    def name(self) -> str:
4302        return "NULL"
def to_py(self) -> Literal[None]:
4304    def to_py(self) -> Lit[None]:
4305        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4308class Boolean(Condition):
4309    def to_py(self) -> bool:
4310        return self.this
def to_py(self) -> bool:
4309    def to_py(self) -> bool:
4310        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
4772    @property
4773    def name(self) -> str:
4774        return self.expression.name
output_name: str
4776    @property
4777    def output_name(self) -> str:
4778        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:
4780    @classmethod
4781    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4782        """Build a Dot object with a sequence of expressions."""
4783        if len(expressions) < 2:
4784            raise ValueError("Dot requires >= 2 expressions.")
4785
4786        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]
4788    @property
4789    def parts(self) -> t.List[Expression]:
4790        """Return the parts of a table / column in order catalog, db, table."""
4791        this, *parts = self.flatten()
4792
4793        parts.reverse()
4794
4795        for arg in COLUMN_PARTS:
4796            part = this.args.get(arg)
4797
4798            if isinstance(part, Expression):
4799                parts.append(part)
4800
4801        parts.reverse()
4802        return parts

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

key = 'dot'
class DPipe(Binary):
4805class DPipe(Binary):
4806    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4809class EQ(Binary, Predicate):
4810    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4813class NullSafeEQ(Binary, Predicate):
4814    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4817class NullSafeNEQ(Binary, Predicate):
4818    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4822class PropertyEQ(Binary):
4823    pass
key = 'propertyeq'
class Distance(Binary):
4826class Distance(Binary):
4827    pass
key = 'distance'
class Escape(Binary):
4830class Escape(Binary):
4831    pass
key = 'escape'
class Glob(Binary, Predicate):
4834class Glob(Binary, Predicate):
4835    pass
key = 'glob'
class GT(Binary, Predicate):
4838class GT(Binary, Predicate):
4839    pass
key = 'gt'
class GTE(Binary, Predicate):
4842class GTE(Binary, Predicate):
4843    pass
key = 'gte'
class ILike(Binary, Predicate):
4846class ILike(Binary, Predicate):
4847    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4850class ILikeAny(Binary, Predicate):
4851    pass
key = 'ilikeany'
class IntDiv(Binary):
4854class IntDiv(Binary):
4855    pass
key = 'intdiv'
class Is(Binary, Predicate):
4858class Is(Binary, Predicate):
4859    pass
key = 'is'
class Kwarg(Binary):
4862class Kwarg(Binary):
4863    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4866class Like(Binary, Predicate):
4867    pass
key = 'like'
class LikeAny(Binary, Predicate):
4870class LikeAny(Binary, Predicate):
4871    pass
key = 'likeany'
class LT(Binary, Predicate):
4874class LT(Binary, Predicate):
4875    pass
key = 'lt'
class LTE(Binary, Predicate):
4878class LTE(Binary, Predicate):
4879    pass
key = 'lte'
class Mod(Binary):
4882class Mod(Binary):
4883    pass
key = 'mod'
class Mul(Binary):
4886class Mul(Binary):
4887    pass
key = 'mul'
class NEQ(Binary, Predicate):
4890class NEQ(Binary, Predicate):
4891    pass
key = 'neq'
class Operator(Binary):
4895class Operator(Binary):
4896    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4899class SimilarTo(Binary, Predicate):
4900    pass
key = 'similarto'
class Slice(Binary):
4903class Slice(Binary):
4904    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4907class Sub(Binary):
4908    pass
key = 'sub'
class Unary(Condition):
4913class Unary(Condition):
4914    pass
key = 'unary'
class BitwiseNot(Unary):
4917class BitwiseNot(Unary):
4918    pass
key = 'bitwisenot'
class Not(Unary):
4921class Not(Unary):
4922    pass
key = 'not'
class Paren(Unary):
4925class Paren(Unary):
4926    @property
4927    def output_name(self) -> str:
4928        return self.this.name
output_name: str
4926    @property
4927    def output_name(self) -> str:
4928        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):
4931class Neg(Unary):
4932    def to_py(self) -> int | Decimal:
4933        if self.is_number:
4934            return self.this.to_py() * -1
4935        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4932    def to_py(self) -> int | Decimal:
4933        if self.is_number:
4934            return self.this.to_py() * -1
4935        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4938class Alias(Expression):
4939    arg_types = {"this": True, "alias": False}
4940
4941    @property
4942    def output_name(self) -> str:
4943        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4941    @property
4942    def output_name(self) -> str:
4943        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):
4948class PivotAlias(Alias):
4949    pass
key = 'pivotalias'
class PivotAny(Expression):
4954class PivotAny(Expression):
4955    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4958class Aliases(Expression):
4959    arg_types = {"this": True, "expressions": True}
4960
4961    @property
4962    def aliases(self):
4963        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4961    @property
4962    def aliases(self):
4963        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4967class AtIndex(Expression):
4968    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4971class AtTimeZone(Expression):
4972    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4975class FromTimeZone(Expression):
4976    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4979class Between(Predicate):
4980    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4983class Bracket(Condition):
4984    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4985    arg_types = {
4986        "this": True,
4987        "expressions": True,
4988        "offset": False,
4989        "safe": False,
4990        "returns_list_for_maps": False,
4991    }
4992
4993    @property
4994    def output_name(self) -> str:
4995        if len(self.expressions) == 1:
4996            return self.expressions[0].output_name
4997
4998        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4993    @property
4994    def output_name(self) -> str:
4995        if len(self.expressions) == 1:
4996            return self.expressions[0].output_name
4997
4998        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):
5001class Distinct(Expression):
5002    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5005class In(Predicate):
5006    arg_types = {
5007        "this": True,
5008        "expressions": False,
5009        "query": False,
5010        "unnest": False,
5011        "field": False,
5012        "is_global": False,
5013    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5017class ForIn(Expression):
5018    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5021class TimeUnit(Expression):
5022    """Automatically converts unit arg into a var."""
5023
5024    arg_types = {"unit": False}
5025
5026    UNABBREVIATED_UNIT_NAME = {
5027        "D": "DAY",
5028        "H": "HOUR",
5029        "M": "MINUTE",
5030        "MS": "MILLISECOND",
5031        "NS": "NANOSECOND",
5032        "Q": "QUARTER",
5033        "S": "SECOND",
5034        "US": "MICROSECOND",
5035        "W": "WEEK",
5036        "Y": "YEAR",
5037    }
5038
5039    VAR_LIKE = (Column, Literal, Var)
5040
5041    def __init__(self, **args):
5042        unit = args.get("unit")
5043        if isinstance(unit, self.VAR_LIKE):
5044            args["unit"] = Var(
5045                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5046            )
5047        elif isinstance(unit, Week):
5048            unit.set("this", Var(this=unit.this.name.upper()))
5049
5050        super().__init__(**args)
5051
5052    @property
5053    def unit(self) -> t.Optional[Var | IntervalSpan]:
5054        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5041    def __init__(self, **args):
5042        unit = args.get("unit")
5043        if isinstance(unit, self.VAR_LIKE):
5044            args["unit"] = Var(
5045                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5046            )
5047        elif isinstance(unit, Week):
5048            unit.set("this", Var(this=unit.this.name.upper()))
5049
5050        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]
5052    @property
5053    def unit(self) -> t.Optional[Var | IntervalSpan]:
5054        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5057class IntervalOp(TimeUnit):
5058    arg_types = {"unit": False, "expression": True}
5059
5060    def interval(self):
5061        return Interval(
5062            this=self.expression.copy(),
5063            unit=self.unit.copy() if self.unit else None,
5064        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5060    def interval(self):
5061        return Interval(
5062            this=self.expression.copy(),
5063            unit=self.unit.copy() if self.unit else None,
5064        )
key = 'intervalop'
class IntervalSpan(DataType):
5070class IntervalSpan(DataType):
5071    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5074class Interval(TimeUnit):
5075    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5078class IgnoreNulls(Expression):
5079    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5082class RespectNulls(Expression):
5083    pass
key = 'respectnulls'
class HavingMax(Expression):
5087class HavingMax(Expression):
5088    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5092class Func(Condition):
5093    """
5094    The base class for all function expressions.
5095
5096    Attributes:
5097        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5098            treated as a variable length argument and the argument's value will be stored as a list.
5099        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5100            function expression. These values are used to map this node to a name during parsing as
5101            well as to provide the function's name during SQL string generation. By default the SQL
5102            name is set to the expression's class name transformed to snake case.
5103    """
5104
5105    is_var_len_args = False
5106
5107    @classmethod
5108    def from_arg_list(cls, args):
5109        if cls.is_var_len_args:
5110            all_arg_keys = list(cls.arg_types)
5111            # If this function supports variable length argument treat the last argument as such.
5112            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5113            num_non_var = len(non_var_len_arg_keys)
5114
5115            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5116            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5117        else:
5118            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5119
5120        return cls(**args_dict)
5121
5122    @classmethod
5123    def sql_names(cls):
5124        if cls is Func:
5125            raise NotImplementedError(
5126                "SQL name is only supported by concrete function implementations"
5127            )
5128        if "_sql_names" not in cls.__dict__:
5129            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5130        return cls._sql_names
5131
5132    @classmethod
5133    def sql_name(cls):
5134        return cls.sql_names()[0]
5135
5136    @classmethod
5137    def default_parser_mappings(cls):
5138        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):
5107    @classmethod
5108    def from_arg_list(cls, args):
5109        if cls.is_var_len_args:
5110            all_arg_keys = list(cls.arg_types)
5111            # If this function supports variable length argument treat the last argument as such.
5112            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5113            num_non_var = len(non_var_len_arg_keys)
5114
5115            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5116            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5117        else:
5118            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5119
5120        return cls(**args_dict)
@classmethod
def sql_names(cls):
5122    @classmethod
5123    def sql_names(cls):
5124        if cls is Func:
5125            raise NotImplementedError(
5126                "SQL name is only supported by concrete function implementations"
5127            )
5128        if "_sql_names" not in cls.__dict__:
5129            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5130        return cls._sql_names
@classmethod
def sql_name(cls):
5132    @classmethod
5133    def sql_name(cls):
5134        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5136    @classmethod
5137    def default_parser_mappings(cls):
5138        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5141class AggFunc(Func):
5142    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5145class ParameterizedAgg(AggFunc):
5146    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5149class Abs(Func):
5150    pass
key = 'abs'
class ArgMax(AggFunc):
5153class ArgMax(AggFunc):
5154    arg_types = {"this": True, "expression": True, "count": False}
5155    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5158class ArgMin(AggFunc):
5159    arg_types = {"this": True, "expression": True, "count": False}
5160    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5163class ApproxTopK(AggFunc):
5164    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5167class Flatten(Func):
5168    pass
key = 'flatten'
class Transform(Func):
5172class Transform(Func):
5173    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5176class Anonymous(Func):
5177    arg_types = {"this": True, "expressions": False}
5178    is_var_len_args = True
5179
5180    @property
5181    def name(self) -> str:
5182        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
5180    @property
5181    def name(self) -> str:
5182        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5185class AnonymousAggFunc(AggFunc):
5186    arg_types = {"this": True, "expressions": False}
5187    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5191class CombinedAggFunc(AnonymousAggFunc):
5192    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5195class CombinedParameterizedAgg(ParameterizedAgg):
5196    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):
5201class Hll(AggFunc):
5202    arg_types = {"this": True, "expressions": False}
5203    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5206class ApproxDistinct(AggFunc):
5207    arg_types = {"this": True, "accuracy": False}
5208    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5211class Apply(Func):
5212    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5215class Array(Func):
5216    arg_types = {"expressions": False, "bracket_notation": False}
5217    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5221class ToArray(Func):
5222    pass
key = 'toarray'
class List(Func):
5226class List(Func):
5227    arg_types = {"expressions": False}
5228    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5232class Pad(Func):
5233    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):
5238class ToChar(Func):
5239    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5244class ToNumber(Func):
5245    arg_types = {
5246        "this": True,
5247        "format": False,
5248        "nlsparam": False,
5249        "precision": False,
5250        "scale": False,
5251    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5255class ToDouble(Func):
5256    arg_types = {
5257        "this": True,
5258        "format": False,
5259    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5262class Columns(Func):
5263    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5267class Convert(Func):
5268    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5271class ConvertTimezone(Func):
5272    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):
5275class GenerateSeries(Func):
5276    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):
5282class ExplodingGenerateSeries(GenerateSeries):
5283    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5286class ArrayAgg(AggFunc):
5287    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5290class ArrayUniqueAgg(AggFunc):
5291    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5294class ArrayAll(Func):
5295    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5299class ArrayAny(Func):
5300    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5303class ArrayConcat(Func):
5304    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5305    arg_types = {"this": True, "expressions": False}
5306    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5309class ArrayConstructCompact(Func):
5310    arg_types = {"expressions": True}
5311    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5314class ArrayContains(Binary, Func):
5315    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5318class ArrayContainsAll(Binary, Func):
5319    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5322class ArrayFilter(Func):
5323    arg_types = {"this": True, "expression": True}
5324    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5327class ArrayToString(Func):
5328    arg_types = {"this": True, "expression": True, "null": False}
5329    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5333class String(Func):
5334    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5337class StringToArray(Func):
5338    arg_types = {"this": True, "expression": True, "null": False}
5339    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5342class ArrayOverlaps(Binary, Func):
5343    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5346class ArraySize(Func):
5347    arg_types = {"this": True, "expression": False}
5348    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5351class ArraySort(Func):
5352    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5355class ArraySum(Func):
5356    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5359class ArrayUnionAgg(AggFunc):
5360    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5363class Avg(AggFunc):
5364    pass
key = 'avg'
class AnyValue(AggFunc):
5367class AnyValue(AggFunc):
5368    pass
key = 'anyvalue'
class Lag(AggFunc):
5371class Lag(AggFunc):
5372    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5375class Lead(AggFunc):
5376    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5381class First(AggFunc):
5382    pass
key = 'first'
class Last(AggFunc):
5385class Last(AggFunc):
5386    pass
key = 'last'
class FirstValue(AggFunc):
5389class FirstValue(AggFunc):
5390    pass
key = 'firstvalue'
class LastValue(AggFunc):
5393class LastValue(AggFunc):
5394    pass
key = 'lastvalue'
class NthValue(AggFunc):
5397class NthValue(AggFunc):
5398    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5401class Case(Func):
5402    arg_types = {"this": False, "ifs": True, "default": False}
5403
5404    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5405        instance = maybe_copy(self, copy)
5406        instance.append(
5407            "ifs",
5408            If(
5409                this=maybe_parse(condition, copy=copy, **opts),
5410                true=maybe_parse(then, copy=copy, **opts),
5411            ),
5412        )
5413        return instance
5414
5415    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5416        instance = maybe_copy(self, copy)
5417        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5418        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:
5404    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5405        instance = maybe_copy(self, copy)
5406        instance.append(
5407            "ifs",
5408            If(
5409                this=maybe_parse(condition, copy=copy, **opts),
5410                true=maybe_parse(then, copy=copy, **opts),
5411            ),
5412        )
5413        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5415    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5416        instance = maybe_copy(self, copy)
5417        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5418        return instance
key = 'case'
class Cast(Func):
5421class Cast(Func):
5422    arg_types = {
5423        "this": True,
5424        "to": True,
5425        "format": False,
5426        "safe": False,
5427        "action": False,
5428    }
5429
5430    @property
5431    def name(self) -> str:
5432        return self.this.name
5433
5434    @property
5435    def to(self) -> DataType:
5436        return self.args["to"]
5437
5438    @property
5439    def output_name(self) -> str:
5440        return self.name
5441
5442    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5443        """
5444        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5445        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5446        array<int> != array<float>.
5447
5448        Args:
5449            dtypes: the data types to compare this Cast's DataType to.
5450
5451        Returns:
5452            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5453        """
5454        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5430    @property
5431    def name(self) -> str:
5432        return self.this.name
to: DataType
5434    @property
5435    def to(self) -> DataType:
5436        return self.args["to"]
output_name: str
5438    @property
5439    def output_name(self) -> str:
5440        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:
5442    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5443        """
5444        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5445        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5446        array<int> != array<float>.
5447
5448        Args:
5449            dtypes: the data types to compare this Cast's DataType to.
5450
5451        Returns:
5452            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5453        """
5454        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):
5457class TryCast(Cast):
5458    pass
key = 'trycast'
class Try(Func):
5461class Try(Func):
5462    pass
key = 'try'
class CastToStrType(Func):
5465class CastToStrType(Func):
5466    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5469class Collate(Binary, Func):
5470    pass
key = 'collate'
class Ceil(Func):
5473class Ceil(Func):
5474    arg_types = {"this": True, "decimals": False}
5475    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5478class Coalesce(Func):
5479    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5480    is_var_len_args = True
5481    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5484class Chr(Func):
5485    arg_types = {"expressions": True, "charset": False}
5486    is_var_len_args = True
5487    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5490class Concat(Func):
5491    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5492    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5495class ConcatWs(Concat):
5496    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5499class Contains(Func):
5500    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5504class ConnectByRoot(Func):
5505    pass
key = 'connectbyroot'
class Count(AggFunc):
5508class Count(AggFunc):
5509    arg_types = {"this": False, "expressions": False, "big_int": False}
5510    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5513class CountIf(AggFunc):
5514    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5518class Cbrt(Func):
5519    pass
key = 'cbrt'
class CurrentDate(Func):
5522class CurrentDate(Func):
5523    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5526class CurrentDatetime(Func):
5527    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5530class CurrentTime(Func):
5531    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5534class CurrentTimestamp(Func):
5535    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5538class CurrentUser(Func):
5539    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5542class DateAdd(Func, IntervalOp):
5543    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5546class DateSub(Func, IntervalOp):
5547    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5550class DateDiff(Func, TimeUnit):
5551    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5552    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5555class DateTrunc(Func):
5556    arg_types = {"unit": True, "this": True, "zone": False}
5557
5558    def __init__(self, **args):
5559        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5560        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5561        unabbreviate = args.pop("unabbreviate", True)
5562
5563        unit = args.get("unit")
5564        if isinstance(unit, TimeUnit.VAR_LIKE):
5565            unit_name = unit.name.upper()
5566            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5567                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5568
5569            args["unit"] = Literal.string(unit_name)
5570        elif isinstance(unit, Week):
5571            unit.set("this", Literal.string(unit.this.name.upper()))
5572
5573        super().__init__(**args)
5574
5575    @property
5576    def unit(self) -> Expression:
5577        return self.args["unit"]
DateTrunc(**args)
5558    def __init__(self, **args):
5559        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5560        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5561        unabbreviate = args.pop("unabbreviate", True)
5562
5563        unit = args.get("unit")
5564        if isinstance(unit, TimeUnit.VAR_LIKE):
5565            unit_name = unit.name.upper()
5566            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5567                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5568
5569            args["unit"] = Literal.string(unit_name)
5570        elif isinstance(unit, Week):
5571            unit.set("this", Literal.string(unit.this.name.upper()))
5572
5573        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5575    @property
5576    def unit(self) -> Expression:
5577        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5582class Datetime(Func):
5583    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5586class DatetimeAdd(Func, IntervalOp):
5587    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5590class DatetimeSub(Func, IntervalOp):
5591    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5594class DatetimeDiff(Func, TimeUnit):
5595    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5598class DatetimeTrunc(Func, TimeUnit):
5599    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5602class DayOfWeek(Func):
5603    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5608class DayOfWeekIso(Func):
5609    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5612class DayOfMonth(Func):
5613    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5616class DayOfYear(Func):
5617    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5620class ToDays(Func):
5621    pass
key = 'todays'
class WeekOfYear(Func):
5624class WeekOfYear(Func):
5625    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5628class MonthsBetween(Func):
5629    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5632class MakeInterval(Func):
5633    arg_types = {
5634        "year": False,
5635        "month": False,
5636        "day": False,
5637        "hour": False,
5638        "minute": False,
5639        "second": False,
5640    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5643class LastDay(Func, TimeUnit):
5644    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5645    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5648class Extract(Func):
5649    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5652class Exists(Func, SubqueryPredicate):
5653    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5656class Timestamp(Func):
5657    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5660class TimestampAdd(Func, TimeUnit):
5661    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5664class TimestampSub(Func, TimeUnit):
5665    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5668class TimestampDiff(Func, TimeUnit):
5669    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5670    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5673class TimestampTrunc(Func, TimeUnit):
5674    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5677class TimeAdd(Func, TimeUnit):
5678    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5681class TimeSub(Func, TimeUnit):
5682    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5685class TimeDiff(Func, TimeUnit):
5686    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5689class TimeTrunc(Func, TimeUnit):
5690    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5693class DateFromParts(Func):
5694    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5695    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5698class TimeFromParts(Func):
5699    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5700    arg_types = {
5701        "hour": True,
5702        "min": True,
5703        "sec": True,
5704        "nano": False,
5705        "fractions": False,
5706        "precision": False,
5707    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5710class DateStrToDate(Func):
5711    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5714class DateToDateStr(Func):
5715    pass
key = 'datetodatestr'
class DateToDi(Func):
5718class DateToDi(Func):
5719    pass
key = 'datetodi'
class Date(Func):
5723class Date(Func):
5724    arg_types = {"this": False, "zone": False, "expressions": False}
5725    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5728class Day(Func):
5729    pass
key = 'day'
class Decode(Func):
5732class Decode(Func):
5733    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5736class DiToDate(Func):
5737    pass
key = 'ditodate'
class Encode(Func):
5740class Encode(Func):
5741    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5744class Exp(Func):
5745    pass
key = 'exp'
class Explode(Func, UDTF):
5749class Explode(Func, UDTF):
5750    arg_types = {"this": True, "expressions": False}
5751    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5755class Inline(Func):
5756    pass
key = 'inline'
class ExplodeOuter(Explode):
5759class ExplodeOuter(Explode):
5760    pass
key = 'explodeouter'
class Posexplode(Explode):
5763class Posexplode(Explode):
5764    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5767class PosexplodeOuter(Posexplode, ExplodeOuter):
5768    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5771class Unnest(Func, UDTF):
5772    arg_types = {
5773        "expressions": True,
5774        "alias": False,
5775        "offset": False,
5776        "explode_array": False,
5777    }
5778
5779    @property
5780    def selects(self) -> t.List[Expression]:
5781        columns = super().selects
5782        offset = self.args.get("offset")
5783        if offset:
5784            columns = columns + [to_identifier("offset") if offset is True else offset]
5785        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5779    @property
5780    def selects(self) -> t.List[Expression]:
5781        columns = super().selects
5782        offset = self.args.get("offset")
5783        if offset:
5784            columns = columns + [to_identifier("offset") if offset is True else offset]
5785        return columns
key = 'unnest'
class Floor(Func):
5788class Floor(Func):
5789    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5792class FromBase64(Func):
5793    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5796class FeaturesAtTime(Func):
5797    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):
5800class ToBase64(Func):
5801    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5805class FromISO8601Timestamp(Func):
5806    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5809class GapFill(Func):
5810    arg_types = {
5811        "this": True,
5812        "ts_column": True,
5813        "bucket_width": True,
5814        "partitioning_columns": False,
5815        "value_columns": False,
5816        "origin": False,
5817        "ignore_nulls": False,
5818    }
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):
5822class GenerateDateArray(Func):
5823    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5827class GenerateTimestampArray(Func):
5828    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5831class Greatest(Func):
5832    arg_types = {"this": True, "expressions": False}
5833    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5838class OverflowTruncateBehavior(Expression):
5839    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5842class GroupConcat(AggFunc):
5843    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5846class Hex(Func):
5847    pass
key = 'hex'
class LowerHex(Hex):
5850class LowerHex(Hex):
5851    pass
key = 'lowerhex'
class Xor(Connector, Func):
5854class Xor(Connector, Func):
5855    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5858class If(Func):
5859    arg_types = {"this": True, "true": True, "false": False}
5860    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5863class Nullif(Func):
5864    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5867class Initcap(Func):
5868    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5871class IsNan(Func):
5872    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
5876class Int64(Func):
5877    pass
key = 'int64'
class IsInf(Func):
5880class IsInf(Func):
5881    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5885class JSON(Expression):
5886    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5889class JSONPath(Expression):
5890    arg_types = {"expressions": True, "escape": False}
5891
5892    @property
5893    def output_name(self) -> str:
5894        last_segment = self.expressions[-1].this
5895        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5892    @property
5893    def output_name(self) -> str:
5894        last_segment = self.expressions[-1].this
5895        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):
5898class JSONPathPart(Expression):
5899    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5902class JSONPathFilter(JSONPathPart):
5903    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5906class JSONPathKey(JSONPathPart):
5907    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5910class JSONPathRecursive(JSONPathPart):
5911    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5914class JSONPathRoot(JSONPathPart):
5915    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5918class JSONPathScript(JSONPathPart):
5919    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5922class JSONPathSlice(JSONPathPart):
5923    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5926class JSONPathSelector(JSONPathPart):
5927    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5930class JSONPathSubscript(JSONPathPart):
5931    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5934class JSONPathUnion(JSONPathPart):
5935    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5938class JSONPathWildcard(JSONPathPart):
5939    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5942class FormatJson(Expression):
5943    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5946class JSONKeyValue(Expression):
5947    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5950class JSONObject(Func):
5951    arg_types = {
5952        "expressions": False,
5953        "null_handling": False,
5954        "unique_keys": False,
5955        "return_type": False,
5956        "encoding": False,
5957    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5960class JSONObjectAgg(AggFunc):
5961    arg_types = {
5962        "expressions": False,
5963        "null_handling": False,
5964        "unique_keys": False,
5965        "return_type": False,
5966        "encoding": False,
5967    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5971class JSONArray(Func):
5972    arg_types = {
5973        "expressions": True,
5974        "null_handling": False,
5975        "return_type": False,
5976        "strict": False,
5977    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5981class JSONArrayAgg(Func):
5982    arg_types = {
5983        "this": True,
5984        "order": False,
5985        "null_handling": False,
5986        "return_type": False,
5987        "strict": False,
5988    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5991class JSONExists(Func):
5992    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):
5997class JSONColumnDef(Expression):
5998    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):
6001class JSONSchema(Expression):
6002    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6006class JSONValue(Expression):
6007    arg_types = {
6008        "this": True,
6009        "path": True,
6010        "returning": False,
6011        "on_condition": False,
6012    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6015class JSONValueArray(Func):
6016    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6020class JSONTable(Func):
6021    arg_types = {
6022        "this": True,
6023        "schema": True,
6024        "path": False,
6025        "error_handling": False,
6026        "empty_handling": False,
6027    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6031class ObjectInsert(Func):
6032    arg_types = {
6033        "this": True,
6034        "key": True,
6035        "value": True,
6036        "update_flag": False,
6037    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6040class OpenJSONColumnDef(Expression):
6041    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):
6044class OpenJSON(Func):
6045    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6048class JSONBContains(Binary, Func):
6049    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6052class JSONBExists(Func):
6053    arg_types = {"this": True, "path": True}
6054    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6057class JSONExtract(Binary, Func):
6058    arg_types = {
6059        "this": True,
6060        "expression": True,
6061        "only_json_types": False,
6062        "expressions": False,
6063        "variant_extract": False,
6064        "json_query": False,
6065        "option": False,
6066    }
6067    _sql_names = ["JSON_EXTRACT"]
6068    is_var_len_args = True
6069
6070    @property
6071    def output_name(self) -> str:
6072        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
6070    @property
6071    def output_name(self) -> str:
6072        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):
6075class JSONExtractArray(Func):
6076    arg_types = {"this": True, "expression": False}
6077    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6080class JSONExtractScalar(Binary, Func):
6081    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6082    _sql_names = ["JSON_EXTRACT_SCALAR"]
6083    is_var_len_args = True
6084
6085    @property
6086    def output_name(self) -> str:
6087        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
6085    @property
6086    def output_name(self) -> str:
6087        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):
6090class JSONBExtract(Binary, Func):
6091    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6094class JSONBExtractScalar(Binary, Func):
6095    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6098class JSONFormat(Func):
6099    arg_types = {"this": False, "options": False}
6100    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6104class JSONArrayContains(Binary, Predicate, Func):
6105    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6108class ParseJSON(Func):
6109    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6110    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6111    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6112    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6115class Least(Func):
6116    arg_types = {"this": True, "expressions": False}
6117    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6120class Left(Func):
6121    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6128class Length(Func):
6129    arg_types = {"this": True, "binary": False}
6130    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
6133class Levenshtein(Func):
6134    arg_types = {
6135        "this": True,
6136        "expression": False,
6137        "ins_cost": False,
6138        "del_cost": False,
6139        "sub_cost": False,
6140        "max_dist": False,
6141    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6144class Ln(Func):
6145    pass
key = 'ln'
class Log(Func):
6148class Log(Func):
6149    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6152class LogicalOr(AggFunc):
6153    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6156class LogicalAnd(AggFunc):
6157    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6160class Lower(Func):
6161    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6164class Map(Func):
6165    arg_types = {"keys": False, "values": False}
6166
6167    @property
6168    def keys(self) -> t.List[Expression]:
6169        keys = self.args.get("keys")
6170        return keys.expressions if keys else []
6171
6172    @property
6173    def values(self) -> t.List[Expression]:
6174        values = self.args.get("values")
6175        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6167    @property
6168    def keys(self) -> t.List[Expression]:
6169        keys = self.args.get("keys")
6170        return keys.expressions if keys else []
values: List[Expression]
6172    @property
6173    def values(self) -> t.List[Expression]:
6174        values = self.args.get("values")
6175        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6179class ToMap(Func):
6180    pass
key = 'tomap'
class MapFromEntries(Func):
6183class MapFromEntries(Func):
6184    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6188class ScopeResolution(Expression):
6189    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6192class Stream(Expression):
6193    pass
key = 'stream'
class StarMap(Func):
6196class StarMap(Func):
6197    pass
key = 'starmap'
class VarMap(Func):
6200class VarMap(Func):
6201    arg_types = {"keys": True, "values": True}
6202    is_var_len_args = True
6203
6204    @property
6205    def keys(self) -> t.List[Expression]:
6206        return self.args["keys"].expressions
6207
6208    @property
6209    def values(self) -> t.List[Expression]:
6210        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6204    @property
6205    def keys(self) -> t.List[Expression]:
6206        return self.args["keys"].expressions
values: List[Expression]
6208    @property
6209    def values(self) -> t.List[Expression]:
6210        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6214class MatchAgainst(Func):
6215    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6218class Max(AggFunc):
6219    arg_types = {"this": True, "expressions": False}
6220    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6223class MD5(Func):
6224    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6228class MD5Digest(Func):
6229    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6232class Median(AggFunc):
6233    pass
key = 'median'
class Min(AggFunc):
6236class Min(AggFunc):
6237    arg_types = {"this": True, "expressions": False}
6238    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6241class Month(Func):
6242    pass
key = 'month'
class AddMonths(Func):
6245class AddMonths(Func):
6246    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6249class Nvl2(Func):
6250    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6253class Normalize(Func):
6254    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6257class Overlay(Func):
6258    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):
6262class Predict(Func):
6263    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6266class Pow(Binary, Func):
6267    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6270class PercentileCont(AggFunc):
6271    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6274class PercentileDisc(AggFunc):
6275    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6278class Quantile(AggFunc):
6279    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6282class ApproxQuantile(Quantile):
6283    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):
6286class Quarter(Func):
6287    pass
key = 'quarter'
class Rand(Func):
6292class Rand(Func):
6293    _sql_names = ["RAND", "RANDOM"]
6294    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6297class Randn(Func):
6298    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6301class RangeN(Func):
6302    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6305class ReadCSV(Func):
6306    _sql_names = ["READ_CSV"]
6307    is_var_len_args = True
6308    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6311class Reduce(Func):
6312    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):
6315class RegexpExtract(Func):
6316    arg_types = {
6317        "this": True,
6318        "expression": True,
6319        "position": False,
6320        "occurrence": False,
6321        "parameters": False,
6322        "group": False,
6323    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6326class RegexpExtractAll(Func):
6327    arg_types = {
6328        "this": True,
6329        "expression": True,
6330        "position": False,
6331        "occurrence": False,
6332        "parameters": False,
6333        "group": False,
6334    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6337class RegexpReplace(Func):
6338    arg_types = {
6339        "this": True,
6340        "expression": True,
6341        "replacement": False,
6342        "position": False,
6343        "occurrence": False,
6344        "modifiers": False,
6345    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6348class RegexpLike(Binary, Func):
6349    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6352class RegexpILike(Binary, Func):
6353    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6358class RegexpSplit(Func):
6359    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6362class Repeat(Func):
6363    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6368class Round(Func):
6369    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6372class RowNumber(Func):
6373    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6376class SafeDivide(Func):
6377    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6380class SHA(Func):
6381    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6384class SHA2(Func):
6385    _sql_names = ["SHA2"]
6386    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6389class Sign(Func):
6390    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6393class SortArray(Func):
6394    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6397class Split(Func):
6398    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6402class SplitPart(Func):
6403    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6408class Substring(Func):
6409    _sql_names = ["SUBSTRING", "SUBSTR"]
6410    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6413class StandardHash(Func):
6414    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6417class StartsWith(Func):
6418    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6419    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6422class StrPosition(Func):
6423    arg_types = {
6424        "this": True,
6425        "substr": True,
6426        "position": False,
6427        "instance": False,
6428    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6431class StrToDate(Func):
6432    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6435class StrToTime(Func):
6436    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):
6441class StrToUnix(Func):
6442    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6447class StrToMap(Func):
6448    arg_types = {
6449        "this": True,
6450        "pair_delim": False,
6451        "key_value_delim": False,
6452        "duplicate_resolution_callback": False,
6453    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6456class NumberToStr(Func):
6457    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6460class FromBase(Func):
6461    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6464class Struct(Func):
6465    arg_types = {"expressions": False}
6466    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6469class StructExtract(Func):
6470    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6475class Stuff(Func):
6476    _sql_names = ["STUFF", "INSERT"]
6477    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):
6480class Sum(AggFunc):
6481    pass
key = 'sum'
class Sqrt(Func):
6484class Sqrt(Func):
6485    pass
key = 'sqrt'
class Stddev(AggFunc):
6488class Stddev(AggFunc):
6489    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6492class StddevPop(AggFunc):
6493    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6496class StddevSamp(AggFunc):
6497    pass
key = 'stddevsamp'
class Time(Func):
6501class Time(Func):
6502    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6505class TimeToStr(Func):
6506    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):
6509class TimeToTimeStr(Func):
6510    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6513class TimeToUnix(Func):
6514    pass
key = 'timetounix'
class TimeStrToDate(Func):
6517class TimeStrToDate(Func):
6518    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6521class TimeStrToTime(Func):
6522    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6525class TimeStrToUnix(Func):
6526    pass
key = 'timestrtounix'
class Trim(Func):
6529class Trim(Func):
6530    arg_types = {
6531        "this": True,
6532        "expression": False,
6533        "position": False,
6534        "collation": False,
6535    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6538class TsOrDsAdd(Func, TimeUnit):
6539    # return_type is used to correctly cast the arguments of this expression when transpiling it
6540    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6541
6542    @property
6543    def return_type(self) -> DataType:
6544        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
6542    @property
6543    def return_type(self) -> DataType:
6544        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6547class TsOrDsDiff(Func, TimeUnit):
6548    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6551class TsOrDsToDateStr(Func):
6552    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6555class TsOrDsToDate(Func):
6556    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6559class TsOrDsToDatetime(Func):
6560    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6563class TsOrDsToTime(Func):
6564    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6567class TsOrDsToTimestamp(Func):
6568    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6571class TsOrDiToDi(Func):
6572    pass
key = 'tsorditodi'
class Unhex(Func):
6575class Unhex(Func):
6576    pass
key = 'unhex'
class UnixDate(Func):
6580class UnixDate(Func):
6581    pass
key = 'unixdate'
class UnixToStr(Func):
6584class UnixToStr(Func):
6585    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6590class UnixToTime(Func):
6591    arg_types = {
6592        "this": True,
6593        "scale": False,
6594        "zone": False,
6595        "hours": False,
6596        "minutes": False,
6597        "format": False,
6598    }
6599
6600    SECONDS = Literal.number(0)
6601    DECIS = Literal.number(1)
6602    CENTIS = Literal.number(2)
6603    MILLIS = Literal.number(3)
6604    DECIMILLIS = Literal.number(4)
6605    CENTIMILLIS = Literal.number(5)
6606    MICROS = Literal.number(6)
6607    DECIMICROS = Literal.number(7)
6608    CENTIMICROS = Literal.number(8)
6609    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):
6612class UnixToTimeStr(Func):
6613    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6616class UnixSeconds(Func):
6617    pass
key = 'unixseconds'
class Uuid(Func):
6620class Uuid(Func):
6621    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6622
6623    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6626class TimestampFromParts(Func):
6627    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6628    arg_types = {
6629        "year": True,
6630        "month": True,
6631        "day": True,
6632        "hour": True,
6633        "min": True,
6634        "sec": True,
6635        "nano": False,
6636        "zone": False,
6637        "milli": False,
6638    }
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):
6641class Upper(Func):
6642    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6645class Corr(Binary, AggFunc):
6646    pass
key = 'corr'
class Variance(AggFunc):
6649class Variance(AggFunc):
6650    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6653class VariancePop(AggFunc):
6654    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6657class CovarSamp(Binary, AggFunc):
6658    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6661class CovarPop(Binary, AggFunc):
6662    pass
key = 'covarpop'
class Week(Func):
6665class Week(Func):
6666    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6669class XMLTable(Func):
6670    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):
6673class Year(Func):
6674    pass
key = 'year'
class Use(Expression):
6677class Use(Expression):
6678    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6681class Merge(DML):
6682    arg_types = {
6683        "this": True,
6684        "using": True,
6685        "on": True,
6686        "whens": True,
6687        "with": False,
6688        "returning": False,
6689    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6692class When(Expression):
6693    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):
6696class Whens(Expression):
6697    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6698
6699    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6704class NextValueFor(Func):
6705    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6710class Semicolon(Expression):
6711    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 '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 '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 '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_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'>, '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'>, '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'>, '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:
6751def maybe_parse(
6752    sql_or_expression: ExpOrStr,
6753    *,
6754    into: t.Optional[IntoType] = None,
6755    dialect: DialectType = None,
6756    prefix: t.Optional[str] = None,
6757    copy: bool = False,
6758    **opts,
6759) -> Expression:
6760    """Gracefully handle a possible string or expression.
6761
6762    Example:
6763        >>> maybe_parse("1")
6764        Literal(this=1, is_string=False)
6765        >>> maybe_parse(to_identifier("x"))
6766        Identifier(this=x, quoted=False)
6767
6768    Args:
6769        sql_or_expression: the SQL code string or an expression
6770        into: the SQLGlot Expression to parse into
6771        dialect: the dialect used to parse the input expressions (in the case that an
6772            input expression is a SQL string).
6773        prefix: a string to prefix the sql with before it gets parsed
6774            (automatically includes a space)
6775        copy: whether to copy the expression.
6776        **opts: other options to use to parse the input expressions (again, in the case
6777            that an input expression is a SQL string).
6778
6779    Returns:
6780        Expression: the parsed or given expression.
6781    """
6782    if isinstance(sql_or_expression, Expression):
6783        if copy:
6784            return sql_or_expression.copy()
6785        return sql_or_expression
6786
6787    if sql_or_expression is None:
6788        raise ParseError("SQL cannot be None")
6789
6790    import sqlglot
6791
6792    sql = str(sql_or_expression)
6793    if prefix:
6794        sql = f"{prefix} {sql}"
6795
6796    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):
6807def maybe_copy(instance, copy=True):
6808    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:
7052def union(
7053    *expressions: ExpOrStr,
7054    distinct: bool = True,
7055    dialect: DialectType = None,
7056    copy: bool = True,
7057    **opts,
7058) -> Union:
7059    """
7060    Initializes a syntax tree for the `UNION` operation.
7061
7062    Example:
7063        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7064        'SELECT * FROM foo UNION SELECT * FROM bla'
7065
7066    Args:
7067        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7068            If `Expression` instances are passed, they will be used as-is.
7069        distinct: set the DISTINCT flag if and only if this is true.
7070        dialect: the dialect used to parse the input expression.
7071        copy: whether to copy the expression.
7072        opts: other options to use to parse the input expressions.
7073
7074    Returns:
7075        The new Union instance.
7076    """
7077    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7078    return _apply_set_operation(
7079        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7080    )

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:
7083def intersect(
7084    *expressions: ExpOrStr,
7085    distinct: bool = True,
7086    dialect: DialectType = None,
7087    copy: bool = True,
7088    **opts,
7089) -> Intersect:
7090    """
7091    Initializes a syntax tree for the `INTERSECT` operation.
7092
7093    Example:
7094        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7095        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7096
7097    Args:
7098        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7099            If `Expression` instances are passed, they will be used as-is.
7100        distinct: set the DISTINCT flag if and only if this is true.
7101        dialect: the dialect used to parse the input expression.
7102        copy: whether to copy the expression.
7103        opts: other options to use to parse the input expressions.
7104
7105    Returns:
7106        The new Intersect instance.
7107    """
7108    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7109    return _apply_set_operation(
7110        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7111    )

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

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

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:
7414def and_(
7415    *expressions: t.Optional[ExpOrStr],
7416    dialect: DialectType = None,
7417    copy: bool = True,
7418    wrap: bool = True,
7419    **opts,
7420) -> Condition:
7421    """
7422    Combine multiple conditions with an AND logical operator.
7423
7424    Example:
7425        >>> and_("x=1", and_("y=1", "z=1")).sql()
7426        'x = 1 AND (y = 1 AND z = 1)'
7427
7428    Args:
7429        *expressions: the SQL code strings to parse.
7430            If an Expression instance is passed, this is used as-is.
7431        dialect: the dialect used to parse the input expression.
7432        copy: whether to copy `expressions` (only applies to Expressions).
7433        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7434            precedence issues, but can be turned off when the produced AST is too deep and
7435            causes recursion-related issues.
7436        **opts: other options to use to parse the input expressions.
7437
7438    Returns:
7439        The new condition
7440    """
7441    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:
7444def or_(
7445    *expressions: t.Optional[ExpOrStr],
7446    dialect: DialectType = None,
7447    copy: bool = True,
7448    wrap: bool = True,
7449    **opts,
7450) -> Condition:
7451    """
7452    Combine multiple conditions with an OR logical operator.
7453
7454    Example:
7455        >>> or_("x=1", or_("y=1", "z=1")).sql()
7456        'x = 1 OR (y = 1 OR z = 1)'
7457
7458    Args:
7459        *expressions: the SQL code strings to parse.
7460            If an Expression instance is passed, this is used as-is.
7461        dialect: the dialect used to parse the input expression.
7462        copy: whether to copy `expressions` (only applies to Expressions).
7463        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7464            precedence issues, but can be turned off when the produced AST is too deep and
7465            causes recursion-related issues.
7466        **opts: other options to use to parse the input expressions.
7467
7468    Returns:
7469        The new condition
7470    """
7471    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:
7474def xor(
7475    *expressions: t.Optional[ExpOrStr],
7476    dialect: DialectType = None,
7477    copy: bool = True,
7478    wrap: bool = True,
7479    **opts,
7480) -> Condition:
7481    """
7482    Combine multiple conditions with an XOR logical operator.
7483
7484    Example:
7485        >>> xor("x=1", xor("y=1", "z=1")).sql()
7486        'x = 1 XOR (y = 1 XOR z = 1)'
7487
7488    Args:
7489        *expressions: the SQL code strings to parse.
7490            If an Expression instance is passed, this is used as-is.
7491        dialect: the dialect used to parse the input expression.
7492        copy: whether to copy `expressions` (only applies to Expressions).
7493        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7494            precedence issues, but can be turned off when the produced AST is too deep and
7495            causes recursion-related issues.
7496        **opts: other options to use to parse the input expressions.
7497
7498    Returns:
7499        The new condition
7500    """
7501    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:
7504def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7505    """
7506    Wrap a condition with a NOT operator.
7507
7508    Example:
7509        >>> not_("this_suit='black'").sql()
7510        "NOT this_suit = 'black'"
7511
7512    Args:
7513        expression: the SQL code string to parse.
7514            If an Expression instance is passed, this is used as-is.
7515        dialect: the dialect used to parse the input expression.
7516        copy: whether to copy the expression or not.
7517        **opts: other options to use to parse the input expressions.
7518
7519    Returns:
7520        The new condition.
7521    """
7522    this = condition(
7523        expression,
7524        dialect=dialect,
7525        copy=copy,
7526        **opts,
7527    )
7528    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:
7531def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7532    """
7533    Wrap an expression in parentheses.
7534
7535    Example:
7536        >>> paren("5 + 3").sql()
7537        '(5 + 3)'
7538
7539    Args:
7540        expression: the SQL code string to parse.
7541            If an Expression instance is passed, this is used as-is.
7542        copy: whether to copy the expression or not.
7543
7544    Returns:
7545        The wrapped expression.
7546    """
7547    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):
7563def to_identifier(name, quoted=None, copy=True):
7564    """Builds an identifier.
7565
7566    Args:
7567        name: The name to turn into an identifier.
7568        quoted: Whether to force quote the identifier.
7569        copy: Whether to copy name if it's an Identifier.
7570
7571    Returns:
7572        The identifier ast node.
7573    """
7574
7575    if name is None:
7576        return None
7577
7578    if isinstance(name, Identifier):
7579        identifier = maybe_copy(name, copy)
7580    elif isinstance(name, str):
7581        identifier = Identifier(
7582            this=name,
7583            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7584        )
7585    else:
7586        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7587    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:
7590def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7591    """
7592    Parses a given string into an identifier.
7593
7594    Args:
7595        name: The name to parse into an identifier.
7596        dialect: The dialect to parse against.
7597
7598    Returns:
7599        The identifier ast node.
7600    """
7601    try:
7602        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7603    except (ParseError, TokenError):
7604        expression = to_identifier(name)
7605
7606    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:
7612def to_interval(interval: str | Literal) -> Interval:
7613    """Builds an interval expression from a string like '1 day' or '5 months'."""
7614    if isinstance(interval, Literal):
7615        if not interval.is_string:
7616            raise ValueError("Invalid interval string.")
7617
7618        interval = interval.this
7619
7620    interval = maybe_parse(f"INTERVAL {interval}")
7621    assert isinstance(interval, Interval)
7622    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:
7625def to_table(
7626    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7627) -> Table:
7628    """
7629    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7630    If a table is passed in then that table is returned.
7631
7632    Args:
7633        sql_path: a `[catalog].[schema].[table]` string.
7634        dialect: the source dialect according to which the table name will be parsed.
7635        copy: Whether to copy a table if it is passed in.
7636        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7637
7638    Returns:
7639        A table expression.
7640    """
7641    if isinstance(sql_path, Table):
7642        return maybe_copy(sql_path, copy=copy)
7643
7644    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7645
7646    for k, v in kwargs.items():
7647        table.set(k, v)
7648
7649    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:
7652def to_column(
7653    sql_path: str | Column,
7654    quoted: t.Optional[bool] = None,
7655    dialect: DialectType = None,
7656    copy: bool = True,
7657    **kwargs,
7658) -> Column:
7659    """
7660    Create a column from a `[table].[column]` sql path. Table is optional.
7661    If a column is passed in then that column is returned.
7662
7663    Args:
7664        sql_path: a `[table].[column]` string.
7665        quoted: Whether or not to force quote identifiers.
7666        dialect: the source dialect according to which the column name will be parsed.
7667        copy: Whether to copy a column if it is passed in.
7668        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7669
7670    Returns:
7671        A column expression.
7672    """
7673    if isinstance(sql_path, Column):
7674        return maybe_copy(sql_path, copy=copy)
7675
7676    try:
7677        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7678    except ParseError:
7679        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7680
7681    for k, v in kwargs.items():
7682        col.set(k, v)
7683
7684    if quoted:
7685        for i in col.find_all(Identifier):
7686            i.set("quoted", True)
7687
7688    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):
7691def alias_(
7692    expression: ExpOrStr,
7693    alias: t.Optional[str | Identifier],
7694    table: bool | t.Sequence[str | Identifier] = False,
7695    quoted: t.Optional[bool] = None,
7696    dialect: DialectType = None,
7697    copy: bool = True,
7698    **opts,
7699):
7700    """Create an Alias expression.
7701
7702    Example:
7703        >>> alias_('foo', 'bar').sql()
7704        'foo AS bar'
7705
7706        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7707        '(SELECT 1, 2) AS bar(a, b)'
7708
7709    Args:
7710        expression: the SQL code strings to parse.
7711            If an Expression instance is passed, this is used as-is.
7712        alias: the alias name to use. If the name has
7713            special characters it is quoted.
7714        table: Whether to create a table alias, can also be a list of columns.
7715        quoted: whether to quote the alias
7716        dialect: the dialect used to parse the input expression.
7717        copy: Whether to copy the expression.
7718        **opts: other options to use to parse the input expressions.
7719
7720    Returns:
7721        Alias: the aliased expression
7722    """
7723    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7724    alias = to_identifier(alias, quoted=quoted)
7725
7726    if table:
7727        table_alias = TableAlias(this=alias)
7728        exp.set("alias", table_alias)
7729
7730        if not isinstance(table, bool):
7731            for column in table:
7732                table_alias.append("columns", to_identifier(column, quoted=quoted))
7733
7734        return exp
7735
7736    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7737    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7738    # for the complete Window expression.
7739    #
7740    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7741
7742    if "alias" in exp.arg_types and not isinstance(exp, Window):
7743        exp.set("alias", alias)
7744        return exp
7745    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:
7748def subquery(
7749    expression: ExpOrStr,
7750    alias: t.Optional[Identifier | str] = None,
7751    dialect: DialectType = None,
7752    **opts,
7753) -> Select:
7754    """
7755    Build a subquery expression that's selected from.
7756
7757    Example:
7758        >>> subquery('select x from tbl', 'bar').select('x').sql()
7759        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7760
7761    Args:
7762        expression: the SQL code strings to parse.
7763            If an Expression instance is passed, this is used as-is.
7764        alias: the alias name to use.
7765        dialect: the dialect used to parse the input expression.
7766        **opts: other options to use to parse the input expressions.
7767
7768    Returns:
7769        A new Select instance with the subquery expression included.
7770    """
7771
7772    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7773    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):
7804def column(
7805    col,
7806    table=None,
7807    db=None,
7808    catalog=None,
7809    *,
7810    fields=None,
7811    quoted=None,
7812    copy=True,
7813):
7814    """
7815    Build a Column.
7816
7817    Args:
7818        col: Column name.
7819        table: Table name.
7820        db: Database name.
7821        catalog: Catalog name.
7822        fields: Additional fields using dots.
7823        quoted: Whether to force quotes on the column's identifiers.
7824        copy: Whether to copy identifiers if passed in.
7825
7826    Returns:
7827        The new Column instance.
7828    """
7829    this = Column(
7830        this=to_identifier(col, quoted=quoted, copy=copy),
7831        table=to_identifier(table, quoted=quoted, copy=copy),
7832        db=to_identifier(db, quoted=quoted, copy=copy),
7833        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7834    )
7835
7836    if fields:
7837        this = Dot.build(
7838            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7839        )
7840    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:
7843def cast(
7844    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7845) -> Cast:
7846    """Cast an expression to a data type.
7847
7848    Example:
7849        >>> cast('x + 1', 'int').sql()
7850        'CAST(x + 1 AS INT)'
7851
7852    Args:
7853        expression: The expression to cast.
7854        to: The datatype to cast to.
7855        copy: Whether to copy the supplied expressions.
7856        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7857            - The expression to be cast is already a exp.Cast expression
7858            - The existing cast is to a type that is logically equivalent to new type
7859
7860            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7861            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7862            and instead just return the original expression `CAST(x as DATETIME)`.
7863
7864            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7865            mapping is applied in the target dialect generator.
7866
7867    Returns:
7868        The new Cast instance.
7869    """
7870    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7871    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7872
7873    # dont re-cast if the expression is already a cast to the correct type
7874    if isinstance(expr, Cast):
7875        from sqlglot.dialects.dialect import Dialect
7876
7877        target_dialect = Dialect.get_or_raise(dialect)
7878        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7879
7880        existing_cast_type: DataType.Type = expr.to.this
7881        new_cast_type: DataType.Type = data_type.this
7882        types_are_equivalent = type_mapping.get(
7883            existing_cast_type, existing_cast_type.value
7884        ) == type_mapping.get(new_cast_type, new_cast_type.value)
7885
7886        if expr.is_type(data_type) or types_are_equivalent:
7887            return expr
7888
7889    expr = Cast(this=expr, to=data_type)
7890    expr.type = data_type
7891
7892    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:
7895def table_(
7896    table: Identifier | str,
7897    db: t.Optional[Identifier | str] = None,
7898    catalog: t.Optional[Identifier | str] = None,
7899    quoted: t.Optional[bool] = None,
7900    alias: t.Optional[Identifier | str] = None,
7901) -> Table:
7902    """Build a Table.
7903
7904    Args:
7905        table: Table name.
7906        db: Database name.
7907        catalog: Catalog name.
7908        quote: Whether to force quotes on the table's identifiers.
7909        alias: Table's alias.
7910
7911    Returns:
7912        The new Table instance.
7913    """
7914    return Table(
7915        this=to_identifier(table, quoted=quoted) if table else None,
7916        db=to_identifier(db, quoted=quoted) if db else None,
7917        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7918        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7919    )

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:
7922def values(
7923    values: t.Iterable[t.Tuple[t.Any, ...]],
7924    alias: t.Optional[str] = None,
7925    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7926) -> Values:
7927    """Build VALUES statement.
7928
7929    Example:
7930        >>> values([(1, '2')]).sql()
7931        "VALUES (1, '2')"
7932
7933    Args:
7934        values: values statements that will be converted to SQL
7935        alias: optional alias
7936        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7937         If either are provided then an alias is also required.
7938
7939    Returns:
7940        Values: the Values expression object
7941    """
7942    if columns and not alias:
7943        raise ValueError("Alias is required when providing columns")
7944
7945    return Values(
7946        expressions=[convert(tup) for tup in values],
7947        alias=(
7948            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7949            if columns
7950            else (TableAlias(this=to_identifier(alias)) if alias else None)
7951        ),
7952    )

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:
7955def var(name: t.Optional[ExpOrStr]) -> Var:
7956    """Build a SQL variable.
7957
7958    Example:
7959        >>> repr(var('x'))
7960        'Var(this=x)'
7961
7962        >>> repr(var(column('x', table='y')))
7963        'Var(this=x)'
7964
7965    Args:
7966        name: The name of the var or an expression who's name will become the var.
7967
7968    Returns:
7969        The new variable node.
7970    """
7971    if not name:
7972        raise ValueError("Cannot convert empty name into var.")
7973
7974    if isinstance(name, Expression):
7975        name = name.name
7976    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:
7979def rename_table(
7980    old_name: str | Table,
7981    new_name: str | Table,
7982    dialect: DialectType = None,
7983) -> Alter:
7984    """Build ALTER TABLE... RENAME... expression
7985
7986    Args:
7987        old_name: The old name of the table
7988        new_name: The new name of the table
7989        dialect: The dialect to parse the table.
7990
7991    Returns:
7992        Alter table expression
7993    """
7994    old_table = to_table(old_name, dialect=dialect)
7995    new_table = to_table(new_name, dialect=dialect)
7996    return Alter(
7997        this=old_table,
7998        kind="TABLE",
7999        actions=[
8000            AlterRename(this=new_table),
8001        ],
8002    )

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:
8005def rename_column(
8006    table_name: str | Table,
8007    old_column_name: str | Column,
8008    new_column_name: str | Column,
8009    exists: t.Optional[bool] = None,
8010    dialect: DialectType = None,
8011) -> Alter:
8012    """Build ALTER TABLE... RENAME COLUMN... expression
8013
8014    Args:
8015        table_name: Name of the table
8016        old_column: The old name of the column
8017        new_column: The new name of the column
8018        exists: Whether to add the `IF EXISTS` clause
8019        dialect: The dialect to parse the table/column.
8020
8021    Returns:
8022        Alter table expression
8023    """
8024    table = to_table(table_name, dialect=dialect)
8025    old_column = to_column(old_column_name, dialect=dialect)
8026    new_column = to_column(new_column_name, dialect=dialect)
8027    return Alter(
8028        this=table,
8029        kind="TABLE",
8030        actions=[
8031            RenameColumn(this=old_column, to=new_column, exists=exists),
8032        ],
8033    )

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:
8036def convert(value: t.Any, copy: bool = False) -> Expression:
8037    """Convert a python value into an expression object.
8038
8039    Raises an error if a conversion is not possible.
8040
8041    Args:
8042        value: A python object.
8043        copy: Whether to copy `value` (only applies to Expressions and collections).
8044
8045    Returns:
8046        The equivalent expression object.
8047    """
8048    if isinstance(value, Expression):
8049        return maybe_copy(value, copy)
8050    if isinstance(value, str):
8051        return Literal.string(value)
8052    if isinstance(value, bool):
8053        return Boolean(this=value)
8054    if value is None or (isinstance(value, float) and math.isnan(value)):
8055        return null()
8056    if isinstance(value, numbers.Number):
8057        return Literal.number(value)
8058    if isinstance(value, bytes):
8059        return HexString(this=value.hex())
8060    if isinstance(value, datetime.datetime):
8061        datetime_literal = Literal.string(value.isoformat(sep=" "))
8062
8063        tz = None
8064        if value.tzinfo:
8065            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8066            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8067            tz = Literal.string(str(value.tzinfo))
8068
8069        return TimeStrToTime(this=datetime_literal, zone=tz)
8070    if isinstance(value, datetime.date):
8071        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8072        return DateStrToDate(this=date_literal)
8073    if isinstance(value, tuple):
8074        if hasattr(value, "_fields"):
8075            return Struct(
8076                expressions=[
8077                    PropertyEQ(
8078                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8079                    )
8080                    for k in value._fields
8081                ]
8082            )
8083        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8084    if isinstance(value, list):
8085        return Array(expressions=[convert(v, copy=copy) for v in value])
8086    if isinstance(value, dict):
8087        return Map(
8088            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8089            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8090        )
8091    if hasattr(value, "__dict__"):
8092        return Struct(
8093            expressions=[
8094                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8095                for k, v in value.__dict__.items()
8096            ]
8097        )
8098    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:
8101def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8102    """
8103    Replace children of an expression with the result of a lambda fun(child) -> exp.
8104    """
8105    for k, v in tuple(expression.args.items()):
8106        is_list_arg = type(v) is list
8107
8108        child_nodes = v if is_list_arg else [v]
8109        new_child_nodes = []
8110
8111        for cn in child_nodes:
8112            if isinstance(cn, Expression):
8113                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8114                    new_child_nodes.append(child_node)
8115            else:
8116                new_child_nodes.append(cn)
8117
8118        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:
8121def replace_tree(
8122    expression: Expression,
8123    fun: t.Callable,
8124    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8125) -> Expression:
8126    """
8127    Replace an entire tree with the result of function calls on each node.
8128
8129    This will be traversed in reverse dfs, so leaves first.
8130    If new nodes are created as a result of function calls, they will also be traversed.
8131    """
8132    stack = list(expression.dfs(prune=prune))
8133
8134    while stack:
8135        node = stack.pop()
8136        new_node = fun(node)
8137
8138        if new_node is not node:
8139            node.replace(new_node)
8140
8141            if isinstance(new_node, Expression):
8142                stack.append(new_node)
8143
8144    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]:
8147def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8148    """
8149    Return all table names referenced through columns in an expression.
8150
8151    Example:
8152        >>> import sqlglot
8153        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8154        ['a', 'c']
8155
8156    Args:
8157        expression: expression to find table names.
8158        exclude: a table name to exclude
8159
8160    Returns:
8161        A list of unique names.
8162    """
8163    return {
8164        table
8165        for table in (column.table for column in expression.find_all(Column))
8166        if table and table != exclude
8167    }

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:
8170def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8171    """Get the full name of a table as a string.
8172
8173    Args:
8174        table: Table expression node or string.
8175        dialect: The dialect to generate the table name for.
8176        identify: Determines when an identifier should be quoted. Possible values are:
8177            False (default): Never quote, except in cases where it's mandatory by the dialect.
8178            True: Always quote.
8179
8180    Examples:
8181        >>> from sqlglot import exp, parse_one
8182        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8183        'a.b.c'
8184
8185    Returns:
8186        The table name.
8187    """
8188
8189    table = maybe_parse(table, into=Table, dialect=dialect)
8190
8191    if not table:
8192        raise ValueError(f"Cannot parse {table}")
8193
8194    return ".".join(
8195        (
8196            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8197            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8198            else part.name
8199        )
8200        for part in table.parts
8201    )

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:
8204def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8205    """Returns a case normalized table name without quotes.
8206
8207    Args:
8208        table: the table to normalize
8209        dialect: the dialect to use for normalization rules
8210        copy: whether to copy the expression.
8211
8212    Examples:
8213        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8214        'A-B.c'
8215    """
8216    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8217
8218    return ".".join(
8219        p.name
8220        for p in normalize_identifiers(
8221            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8222        ).parts
8223    )

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

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:
8453def tuple_(
8454    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8455) -> Tuple:
8456    """
8457    Returns an tuple.
8458
8459    Examples:
8460        >>> tuple_(1, 'x').sql()
8461        '(1, x)'
8462
8463    Args:
8464        expressions: the expressions to add to the tuple.
8465        copy: whether to copy the argument expressions.
8466        dialect: the source dialect.
8467        kwargs: the kwargs used to instantiate the function of interest.
8468
8469    Returns:
8470        A tuple expression.
8471    """
8472    return Tuple(
8473        expressions=[
8474            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8475            for expression in expressions
8476        ]
8477    )

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:
8480def true() -> Boolean:
8481    """
8482    Returns a true Boolean expression.
8483    """
8484    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8487def false() -> Boolean:
8488    """
8489    Returns a false Boolean expression.
8490    """
8491    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8494def null() -> Null:
8495    """
8496    Returns a Null expression.
8497    """
8498    return Null()

Returns a Null expression.

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