Edit on GitHub

Expressions

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

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


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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

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

Returns a deep copy of the expression.

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

Returns the depth of this tree.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
582    def flatten(self, unnest=True):
583        """
584        Returns a generator which yields child nodes whose parents are the same class.
585
586        A AND B AND C -> [A, B, C]
587        """
588        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
589            if type(node) is not self.__class__:
590                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:
598    def to_s(self) -> str:
599        """
600        Same as __repr__, but includes additional information which can be useful
601        for debugging, like empty or missing args and the AST nodes' object IDs.
602        """
603        return _to_s(self, verbose=True)

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

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

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

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

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

AND this condition with one or multiple expressions.

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

The new And condition.

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

Wrap this condition with NOT.

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

The new Not instance.

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

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

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

The updated expression.

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

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

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

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1219    def select(
1220        self: Q,
1221        *expressions: t.Optional[ExpOrStr],
1222        append: bool = True,
1223        dialect: DialectType = None,
1224        copy: bool = True,
1225        **opts,
1226    ) -> Q:
1227        """
1228        Append to or set the SELECT expressions.
1229
1230        Example:
1231            >>> Select().select("x", "y").sql()
1232            'SELECT x, y'
1233
1234        Args:
1235            *expressions: the SQL code strings to parse.
1236                If an `Expression` instance is passed, it will be used as-is.
1237            append: if `True`, add to any existing expressions.
1238                Otherwise, this resets the expressions.
1239            dialect: the dialect used to parse the input expressions.
1240            copy: if `False`, modify this expression instance in-place.
1241            opts: other options to use to parse the input expressions.
1242
1243        Returns:
1244            The modified Query expression.
1245        """
1246        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 where( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1248    def where(
1249        self: Q,
1250        *expressions: t.Optional[ExpOrStr],
1251        append: bool = True,
1252        dialect: DialectType = None,
1253        copy: bool = True,
1254        **opts,
1255    ) -> Q:
1256        """
1257        Append to or set the WHERE expressions.
1258
1259        Examples:
1260            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1261            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1262
1263        Args:
1264            *expressions: the SQL code strings to parse.
1265                If an `Expression` instance is passed, it will be used as-is.
1266                Multiple expressions are combined with an AND operator.
1267            append: if `True`, AND the new expressions to any existing expression.
1268                Otherwise, this resets the expression.
1269            dialect: the dialect used to parse the input expressions.
1270            copy: if `False`, modify this expression instance in-place.
1271            opts: other options to use to parse the input expressions.
1272
1273        Returns:
1274            The modified expression.
1275        """
1276        return _apply_conjunction_builder(
1277            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1278            instance=self,
1279            arg="where",
1280            append=append,
1281            into=Where,
1282            dialect=dialect,
1283            copy=copy,
1284            **opts,
1285        )

Append to or set the WHERE expressions.

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

The modified expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: bool = False, **opts) -> ~Q:
1287    def with_(
1288        self: Q,
1289        alias: ExpOrStr,
1290        as_: ExpOrStr,
1291        recursive: t.Optional[bool] = None,
1292        materialized: t.Optional[bool] = None,
1293        append: bool = True,
1294        dialect: DialectType = None,
1295        copy: bool = True,
1296        scalar: bool = False,
1297        **opts,
1298    ) -> Q:
1299        """
1300        Append to or set the common table expressions.
1301
1302        Example:
1303            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1304            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1305
1306        Args:
1307            alias: the SQL code string to parse as the table name.
1308                If an `Expression` instance is passed, this is used as-is.
1309            as_: the SQL code string to parse as the table expression.
1310                If an `Expression` instance is passed, it will be used as-is.
1311            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1312            materialized: set the MATERIALIZED part of the expression.
1313            append: if `True`, add to any existing expressions.
1314                Otherwise, this resets the expressions.
1315            dialect: the dialect used to parse the input expression.
1316            copy: if `False`, modify this expression instance in-place.
1317            scalar: if `True`, this is a scalar common table expression.
1318            opts: other options to use to parse the input expressions.
1319
1320        Returns:
1321            The modified expression.
1322        """
1323        return _apply_cte_builder(
1324            self,
1325            alias,
1326            as_,
1327            recursive=recursive,
1328            materialized=materialized,
1329            append=append,
1330            dialect=dialect,
1331            copy=copy,
1332            scalar=scalar,
1333            **opts,
1334        )

Append to or set the common table expressions.

Example:
>>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • materialized: set the MATERIALIZED part of the expression.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • scalar: if True, this is a scalar common table expression.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Union:
1336    def union(
1337        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1338    ) -> Union:
1339        """
1340        Builds a UNION expression.
1341
1342        Example:
1343            >>> import sqlglot
1344            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1345            'SELECT * FROM foo UNION SELECT * FROM bla'
1346
1347        Args:
1348            expressions: the SQL code strings.
1349                If `Expression` instances are passed, they will be used as-is.
1350            distinct: set the DISTINCT flag if and only if this is true.
1351            dialect: the dialect used to parse the input expression.
1352            opts: other options to use to parse the input expressions.
1353
1354        Returns:
1355            The new Union expression.
1356        """
1357        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union expression.

def intersect( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Intersect:
1359    def intersect(
1360        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1361    ) -> Intersect:
1362        """
1363        Builds an INTERSECT expression.
1364
1365        Example:
1366            >>> import sqlglot
1367            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1368            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1369
1370        Args:
1371            expressions: the SQL code strings.
1372                If `Expression` instances are passed, they will be used as-is.
1373            distinct: set the DISTINCT flag if and only if this is true.
1374            dialect: the dialect used to parse the input expression.
1375            opts: other options to use to parse the input expressions.
1376
1377        Returns:
1378            The new Intersect expression.
1379        """
1380        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect expression.

def except_( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Except:
1382    def except_(
1383        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1384    ) -> Except:
1385        """
1386        Builds an EXCEPT expression.
1387
1388        Example:
1389            >>> import sqlglot
1390            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1391            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1392
1393        Args:
1394            expressions: the SQL code strings.
1395                If `Expression` instance are passed, they will be used as-is.
1396            distinct: set the DISTINCT flag if and only if this is true.
1397            dialect: the dialect used to parse the input expression.
1398            opts: other options to use to parse the input expressions.
1399
1400        Returns:
1401            The new Except expression.
1402        """
1403        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):
1406class UDTF(DerivedTable):
1407    @property
1408    def selects(self) -> t.List[Expression]:
1409        alias = self.args.get("alias")
1410        return alias.columns if alias else []
selects: List[Expression]
1407    @property
1408    def selects(self) -> t.List[Expression]:
1409        alias = self.args.get("alias")
1410        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1413class Cache(Expression):
1414    arg_types = {
1415        "this": True,
1416        "lazy": False,
1417        "options": False,
1418        "expression": False,
1419    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1422class Uncache(Expression):
1423    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1426class Refresh(Expression):
1427    pass
key = 'refresh'
class DDL(Expression):
1430class DDL(Expression):
1431    @property
1432    def ctes(self) -> t.List[CTE]:
1433        """Returns a list of all the CTEs attached to this statement."""
1434        with_ = self.args.get("with")
1435        return with_.expressions if with_ else []
1436
1437    @property
1438    def selects(self) -> t.List[Expression]:
1439        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1440        return self.expression.selects if isinstance(self.expression, Query) else []
1441
1442    @property
1443    def named_selects(self) -> t.List[str]:
1444        """
1445        If this statement contains a query (e.g. a CTAS), this returns the output
1446        names of the query's projections.
1447        """
1448        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1431    @property
1432    def ctes(self) -> t.List[CTE]:
1433        """Returns a list of all the CTEs attached to this statement."""
1434        with_ = self.args.get("with")
1435        return with_.expressions if with_ else []

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

selects: List[Expression]
1437    @property
1438    def selects(self) -> t.List[Expression]:
1439        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1440        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]
1442    @property
1443    def named_selects(self) -> t.List[str]:
1444        """
1445        If this statement contains a query (e.g. a CTAS), this returns the output
1446        names of the query's projections.
1447        """
1448        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):
1451class DML(Expression):
1452    def returning(
1453        self,
1454        expression: ExpOrStr,
1455        dialect: DialectType = None,
1456        copy: bool = True,
1457        **opts,
1458    ) -> "Self":
1459        """
1460        Set the RETURNING expression. Not supported by all dialects.
1461
1462        Example:
1463            >>> delete("tbl").returning("*", dialect="postgres").sql()
1464            'DELETE FROM tbl RETURNING *'
1465
1466        Args:
1467            expression: the SQL code strings to parse.
1468                If an `Expression` instance is passed, it will be used as-is.
1469            dialect: the dialect used to parse the input expressions.
1470            copy: if `False`, modify this expression instance in-place.
1471            opts: other options to use to parse the input expressions.
1472
1473        Returns:
1474            Delete: the modified expression.
1475        """
1476        return _apply_builder(
1477            expression=expression,
1478            instance=self,
1479            arg="returning",
1480            prefix="RETURNING",
1481            dialect=dialect,
1482            copy=copy,
1483            into=Returning,
1484            **opts,
1485        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1452    def returning(
1453        self,
1454        expression: ExpOrStr,
1455        dialect: DialectType = None,
1456        copy: bool = True,
1457        **opts,
1458    ) -> "Self":
1459        """
1460        Set the RETURNING expression. Not supported by all dialects.
1461
1462        Example:
1463            >>> delete("tbl").returning("*", dialect="postgres").sql()
1464            'DELETE FROM tbl RETURNING *'
1465
1466        Args:
1467            expression: the SQL code strings to parse.
1468                If an `Expression` instance is passed, it will be used as-is.
1469            dialect: the dialect used to parse the input expressions.
1470            copy: if `False`, modify this expression instance in-place.
1471            opts: other options to use to parse the input expressions.
1472
1473        Returns:
1474            Delete: the modified expression.
1475        """
1476        return _apply_builder(
1477            expression=expression,
1478            instance=self,
1479            arg="returning",
1480            prefix="RETURNING",
1481            dialect=dialect,
1482            copy=copy,
1483            into=Returning,
1484            **opts,
1485        )

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):
1488class Create(DDL):
1489    arg_types = {
1490        "with": False,
1491        "this": True,
1492        "kind": True,
1493        "expression": False,
1494        "exists": False,
1495        "properties": False,
1496        "replace": False,
1497        "refresh": False,
1498        "unique": False,
1499        "indexes": False,
1500        "no_schema_binding": False,
1501        "begin": False,
1502        "end": False,
1503        "clone": False,
1504        "concurrently": False,
1505        "clustered": False,
1506    }
1507
1508    @property
1509    def kind(self) -> t.Optional[str]:
1510        kind = self.args.get("kind")
1511        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]
1508    @property
1509    def kind(self) -> t.Optional[str]:
1510        kind = self.args.get("kind")
1511        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1514class SequenceProperties(Expression):
1515    arg_types = {
1516        "increment": False,
1517        "minvalue": False,
1518        "maxvalue": False,
1519        "cache": False,
1520        "start": False,
1521        "owned": False,
1522        "options": False,
1523    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1526class TruncateTable(Expression):
1527    arg_types = {
1528        "expressions": True,
1529        "is_database": False,
1530        "exists": False,
1531        "only": False,
1532        "cluster": False,
1533        "identity": False,
1534        "option": False,
1535        "partition": False,
1536    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1542class Clone(Expression):
1543    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1546class Describe(Expression):
1547    arg_types = {
1548        "this": True,
1549        "style": False,
1550        "kind": False,
1551        "expressions": False,
1552        "partition": False,
1553        "format": False,
1554    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1558class Attach(Expression):
1559    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1563class Detach(Expression):
1564    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1568class Summarize(Expression):
1569    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1572class Kill(Expression):
1573    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1576class Pragma(Expression):
1577    pass
key = 'pragma'
class Declare(Expression):
1580class Declare(Expression):
1581    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1584class DeclareItem(Expression):
1585    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1588class Set(Expression):
1589    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1592class Heredoc(Expression):
1593    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1596class SetItem(Expression):
1597    arg_types = {
1598        "this": False,
1599        "expressions": False,
1600        "kind": False,
1601        "collate": False,  # MySQL SET NAMES statement
1602        "global": False,
1603    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1606class Show(Expression):
1607    arg_types = {
1608        "this": True,
1609        "history": False,
1610        "terse": False,
1611        "target": False,
1612        "offset": False,
1613        "starts_with": False,
1614        "limit": False,
1615        "from": False,
1616        "like": False,
1617        "where": False,
1618        "db": False,
1619        "scope": False,
1620        "scope_kind": False,
1621        "full": False,
1622        "mutex": False,
1623        "query": False,
1624        "channel": False,
1625        "global": False,
1626        "log": False,
1627        "position": False,
1628        "types": False,
1629        "privileges": False,
1630    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False, 'privileges': False}
key = 'show'
class UserDefinedFunction(Expression):
1633class UserDefinedFunction(Expression):
1634    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1637class CharacterSet(Expression):
1638    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1641class RecursiveWithSearch(Expression):
1642    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key = 'recursivewithsearch'
class With(Expression):
1645class With(Expression):
1646    arg_types = {"expressions": True, "recursive": False, "search": False}
1647
1648    @property
1649    def recursive(self) -> bool:
1650        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1648    @property
1649    def recursive(self) -> bool:
1650        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1653class WithinGroup(Expression):
1654    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1659class CTE(DerivedTable):
1660    arg_types = {
1661        "this": True,
1662        "alias": True,
1663        "scalar": False,
1664        "materialized": False,
1665    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1668class ProjectionDef(Expression):
1669    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1672class TableAlias(Expression):
1673    arg_types = {"this": False, "columns": False}
1674
1675    @property
1676    def columns(self):
1677        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1675    @property
1676    def columns(self):
1677        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1680class BitString(Condition):
1681    pass
key = 'bitstring'
class HexString(Condition):
1684class HexString(Condition):
1685    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1688class ByteString(Condition):
1689    pass
key = 'bytestring'
class RawString(Condition):
1692class RawString(Condition):
1693    pass
key = 'rawstring'
class UnicodeString(Condition):
1696class UnicodeString(Condition):
1697    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1700class Column(Condition):
1701    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1702
1703    @property
1704    def table(self) -> str:
1705        return self.text("table")
1706
1707    @property
1708    def db(self) -> str:
1709        return self.text("db")
1710
1711    @property
1712    def catalog(self) -> str:
1713        return self.text("catalog")
1714
1715    @property
1716    def output_name(self) -> str:
1717        return self.name
1718
1719    @property
1720    def parts(self) -> t.List[Identifier]:
1721        """Return the parts of a column in order catalog, db, table, name."""
1722        return [
1723            t.cast(Identifier, self.args[part])
1724            for part in ("catalog", "db", "table", "this")
1725            if self.args.get(part)
1726        ]
1727
1728    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1729        """Converts the column into a dot expression."""
1730        parts = self.parts
1731        parent = self.parent
1732
1733        if include_dots:
1734            while isinstance(parent, Dot):
1735                parts.append(parent.expression)
1736                parent = parent.parent
1737
1738        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
1703    @property
1704    def table(self) -> str:
1705        return self.text("table")
db: str
1707    @property
1708    def db(self) -> str:
1709        return self.text("db")
catalog: str
1711    @property
1712    def catalog(self) -> str:
1713        return self.text("catalog")
output_name: str
1715    @property
1716    def output_name(self) -> str:
1717        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]
1719    @property
1720    def parts(self) -> t.List[Identifier]:
1721        """Return the parts of a column in order catalog, db, table, name."""
1722        return [
1723            t.cast(Identifier, self.args[part])
1724            for part in ("catalog", "db", "table", "this")
1725            if self.args.get(part)
1726        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1728    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1729        """Converts the column into a dot expression."""
1730        parts = self.parts
1731        parent = self.parent
1732
1733        if include_dots:
1734            while isinstance(parent, Dot):
1735                parts.append(parent.expression)
1736                parent = parent.parent
1737
1738        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1741class ColumnPosition(Expression):
1742    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1745class ColumnDef(Expression):
1746    arg_types = {
1747        "this": True,
1748        "kind": False,
1749        "constraints": False,
1750        "exists": False,
1751        "position": False,
1752        "default": False,
1753        "output": False,
1754    }
1755
1756    @property
1757    def constraints(self) -> t.List[ColumnConstraint]:
1758        return self.args.get("constraints") or []
1759
1760    @property
1761    def kind(self) -> t.Optional[DataType]:
1762        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1756    @property
1757    def constraints(self) -> t.List[ColumnConstraint]:
1758        return self.args.get("constraints") or []
kind: Optional[DataType]
1760    @property
1761    def kind(self) -> t.Optional[DataType]:
1762        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1765class AlterColumn(Expression):
1766    arg_types = {
1767        "this": True,
1768        "dtype": False,
1769        "collate": False,
1770        "using": False,
1771        "default": False,
1772        "drop": False,
1773        "comment": False,
1774        "allow_null": False,
1775        "visible": False,
1776    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False}
key = 'altercolumn'
class AlterIndex(Expression):
1780class AlterIndex(Expression):
1781    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1785class AlterDistStyle(Expression):
1786    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1789class AlterSortKey(Expression):
1790    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1793class AlterSet(Expression):
1794    arg_types = {
1795        "expressions": False,
1796        "option": False,
1797        "tablespace": False,
1798        "access_method": False,
1799        "file_format": False,
1800        "copy_options": False,
1801        "tag": False,
1802        "location": False,
1803        "serde": False,
1804    }
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):
1807class RenameColumn(Expression):
1808    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1811class AlterRename(Expression):
1812    pass
key = 'alterrename'
class SwapTable(Expression):
1815class SwapTable(Expression):
1816    pass
key = 'swaptable'
class Comment(Expression):
1819class Comment(Expression):
1820    arg_types = {
1821        "this": True,
1822        "kind": True,
1823        "expression": True,
1824        "exists": False,
1825        "materialized": False,
1826    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1829class Comprehension(Expression):
1830    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):
1834class MergeTreeTTLAction(Expression):
1835    arg_types = {
1836        "this": True,
1837        "delete": False,
1838        "recompress": False,
1839        "to_disk": False,
1840        "to_volume": False,
1841    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1845class MergeTreeTTL(Expression):
1846    arg_types = {
1847        "expressions": True,
1848        "where": False,
1849        "group": False,
1850        "aggregates": False,
1851    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1855class IndexConstraintOption(Expression):
1856    arg_types = {
1857        "key_block_size": False,
1858        "using": False,
1859        "parser": False,
1860        "comment": False,
1861        "visible": False,
1862        "engine_attr": False,
1863        "secondary_engine_attr": False,
1864    }
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):
1867class ColumnConstraint(Expression):
1868    arg_types = {"this": False, "kind": True}
1869
1870    @property
1871    def kind(self) -> ColumnConstraintKind:
1872        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1870    @property
1871    def kind(self) -> ColumnConstraintKind:
1872        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1875class ColumnConstraintKind(Expression):
1876    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1879class AutoIncrementColumnConstraint(ColumnConstraintKind):
1880    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1883class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1884    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1887class CaseSpecificColumnConstraint(ColumnConstraintKind):
1888    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1891class CharacterSetColumnConstraint(ColumnConstraintKind):
1892    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1895class CheckColumnConstraint(ColumnConstraintKind):
1896    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1899class ClusteredColumnConstraint(ColumnConstraintKind):
1900    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1903class CollateColumnConstraint(ColumnConstraintKind):
1904    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1907class CommentColumnConstraint(ColumnConstraintKind):
1908    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1911class CompressColumnConstraint(ColumnConstraintKind):
1912    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1915class DateFormatColumnConstraint(ColumnConstraintKind):
1916    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1919class DefaultColumnConstraint(ColumnConstraintKind):
1920    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1923class EncodeColumnConstraint(ColumnConstraintKind):
1924    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1928class ExcludeColumnConstraint(ColumnConstraintKind):
1929    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1932class EphemeralColumnConstraint(ColumnConstraintKind):
1933    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1936class WithOperator(Expression):
1937    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1940class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1941    # this: True -> ALWAYS, this: False -> BY DEFAULT
1942    arg_types = {
1943        "this": False,
1944        "expression": False,
1945        "on_null": False,
1946        "start": False,
1947        "increment": False,
1948        "minvalue": False,
1949        "maxvalue": False,
1950        "cycle": False,
1951        "order": False,
1952    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False, 'order': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1955class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1956    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1961class IndexColumnConstraint(ColumnConstraintKind):
1962    arg_types = {
1963        "this": False,
1964        "expressions": False,
1965        "kind": False,
1966        "index_type": False,
1967        "options": False,
1968        "expression": False,  # Clickhouse
1969        "granularity": False,
1970    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1973class InlineLengthColumnConstraint(ColumnConstraintKind):
1974    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1977class NonClusteredColumnConstraint(ColumnConstraintKind):
1978    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1981class NotForReplicationColumnConstraint(ColumnConstraintKind):
1982    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1986class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1987    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1990class NotNullColumnConstraint(ColumnConstraintKind):
1991    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1995class OnUpdateColumnConstraint(ColumnConstraintKind):
1996    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1999class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2000    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2003class TitleColumnConstraint(ColumnConstraintKind):
2004    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2007class UniqueColumnConstraint(ColumnConstraintKind):
2008    arg_types = {
2009        "this": False,
2010        "index_type": False,
2011        "on_conflict": False,
2012        "nulls": False,
2013        "options": False,
2014    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2017class UppercaseColumnConstraint(ColumnConstraintKind):
2018    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2022class WatermarkColumnConstraint(Expression):
2023    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2026class PathColumnConstraint(ColumnConstraintKind):
2027    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2031class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2032    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2037class ComputedColumnConstraint(ColumnConstraintKind):
2038    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2041class Constraint(Expression):
2042    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2045class Delete(DML):
2046    arg_types = {
2047        "with": False,
2048        "this": False,
2049        "using": False,
2050        "where": False,
2051        "returning": False,
2052        "limit": False,
2053        "tables": False,  # Multiple-Table Syntax (MySQL)
2054        "cluster": False,  # Clickhouse
2055    }
2056
2057    def delete(
2058        self,
2059        table: ExpOrStr,
2060        dialect: DialectType = None,
2061        copy: bool = True,
2062        **opts,
2063    ) -> Delete:
2064        """
2065        Create a DELETE expression or replace the table on an existing DELETE expression.
2066
2067        Example:
2068            >>> delete("tbl").sql()
2069            'DELETE FROM tbl'
2070
2071        Args:
2072            table: the table from which to delete.
2073            dialect: the dialect used to parse the input expression.
2074            copy: if `False`, modify this expression instance in-place.
2075            opts: other options to use to parse the input expressions.
2076
2077        Returns:
2078            Delete: the modified expression.
2079        """
2080        return _apply_builder(
2081            expression=table,
2082            instance=self,
2083            arg="this",
2084            dialect=dialect,
2085            into=Table,
2086            copy=copy,
2087            **opts,
2088        )
2089
2090    def where(
2091        self,
2092        *expressions: t.Optional[ExpOrStr],
2093        append: bool = True,
2094        dialect: DialectType = None,
2095        copy: bool = True,
2096        **opts,
2097    ) -> Delete:
2098        """
2099        Append to or set the WHERE expressions.
2100
2101        Example:
2102            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2103            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2104
2105        Args:
2106            *expressions: the SQL code strings to parse.
2107                If an `Expression` instance is passed, it will be used as-is.
2108                Multiple expressions are combined with an AND operator.
2109            append: if `True`, AND the new expressions to any existing expression.
2110                Otherwise, this resets the expression.
2111            dialect: the dialect used to parse the input expressions.
2112            copy: if `False`, modify this expression instance in-place.
2113            opts: other options to use to parse the input expressions.
2114
2115        Returns:
2116            Delete: the modified expression.
2117        """
2118        return _apply_conjunction_builder(
2119            *expressions,
2120            instance=self,
2121            arg="where",
2122            append=append,
2123            into=Where,
2124            dialect=dialect,
2125            copy=copy,
2126            **opts,
2127        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2057    def delete(
2058        self,
2059        table: ExpOrStr,
2060        dialect: DialectType = None,
2061        copy: bool = True,
2062        **opts,
2063    ) -> Delete:
2064        """
2065        Create a DELETE expression or replace the table on an existing DELETE expression.
2066
2067        Example:
2068            >>> delete("tbl").sql()
2069            'DELETE FROM tbl'
2070
2071        Args:
2072            table: the table from which to delete.
2073            dialect: the dialect used to parse the input expression.
2074            copy: if `False`, modify this expression instance in-place.
2075            opts: other options to use to parse the input expressions.
2076
2077        Returns:
2078            Delete: the modified expression.
2079        """
2080        return _apply_builder(
2081            expression=table,
2082            instance=self,
2083            arg="this",
2084            dialect=dialect,
2085            into=Table,
2086            copy=copy,
2087            **opts,
2088        )

Create a DELETE expression or replace the table on an existing DELETE expression.

Example:
>>> delete("tbl").sql()
'DELETE FROM tbl'
Arguments:
  • table: the table from which to delete.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2090    def where(
2091        self,
2092        *expressions: t.Optional[ExpOrStr],
2093        append: bool = True,
2094        dialect: DialectType = None,
2095        copy: bool = True,
2096        **opts,
2097    ) -> Delete:
2098        """
2099        Append to or set the WHERE expressions.
2100
2101        Example:
2102            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2103            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2104
2105        Args:
2106            *expressions: the SQL code strings to parse.
2107                If an `Expression` instance is passed, it will be used as-is.
2108                Multiple expressions are combined with an AND operator.
2109            append: if `True`, AND the new expressions to any existing expression.
2110                Otherwise, this resets the expression.
2111            dialect: the dialect used to parse the input expressions.
2112            copy: if `False`, modify this expression instance in-place.
2113            opts: other options to use to parse the input expressions.
2114
2115        Returns:
2116            Delete: the modified expression.
2117        """
2118        return _apply_conjunction_builder(
2119            *expressions,
2120            instance=self,
2121            arg="where",
2122            append=append,
2123            into=Where,
2124            dialect=dialect,
2125            copy=copy,
2126            **opts,
2127        )

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):
2130class Drop(Expression):
2131    arg_types = {
2132        "this": False,
2133        "kind": False,
2134        "expressions": False,
2135        "exists": False,
2136        "temporary": False,
2137        "materialized": False,
2138        "cascade": False,
2139        "constraints": False,
2140        "purge": False,
2141        "cluster": False,
2142        "concurrently": False,
2143    }
2144
2145    @property
2146    def kind(self) -> t.Optional[str]:
2147        kind = self.args.get("kind")
2148        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]
2145    @property
2146    def kind(self) -> t.Optional[str]:
2147        kind = self.args.get("kind")
2148        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2152class Export(Expression):
2153    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2156class Filter(Expression):
2157    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2160class Check(Expression):
2161    pass
key = 'check'
class Changes(Expression):
2164class Changes(Expression):
2165    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2169class Connect(Expression):
2170    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2173class CopyParameter(Expression):
2174    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2177class Copy(DML):
2178    arg_types = {
2179        "this": True,
2180        "kind": True,
2181        "files": True,
2182        "credentials": False,
2183        "format": False,
2184        "params": False,
2185    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2188class Credentials(Expression):
2189    arg_types = {
2190        "credentials": False,
2191        "encryption": False,
2192        "storage": False,
2193        "iam_role": False,
2194        "region": False,
2195    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2198class Prior(Expression):
2199    pass
key = 'prior'
class Directory(Expression):
2202class Directory(Expression):
2203    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2204    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2207class ForeignKey(Expression):
2208    arg_types = {
2209        "expressions": False,
2210        "reference": False,
2211        "delete": False,
2212        "update": False,
2213        "options": False,
2214    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2217class ColumnPrefix(Expression):
2218    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2221class PrimaryKey(Expression):
2222    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2227class Into(Expression):
2228    arg_types = {
2229        "this": False,
2230        "temporary": False,
2231        "unlogged": False,
2232        "bulk_collect": False,
2233        "expressions": False,
2234    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2237class From(Expression):
2238    @property
2239    def name(self) -> str:
2240        return self.this.name
2241
2242    @property
2243    def alias_or_name(self) -> str:
2244        return self.this.alias_or_name
name: str
2238    @property
2239    def name(self) -> str:
2240        return self.this.name
alias_or_name: str
2242    @property
2243    def alias_or_name(self) -> str:
2244        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2247class Having(Expression):
2248    pass
key = 'having'
class Hint(Expression):
2251class Hint(Expression):
2252    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2255class JoinHint(Expression):
2256    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2259class Identifier(Expression):
2260    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2261
2262    @property
2263    def quoted(self) -> bool:
2264        return bool(self.args.get("quoted"))
2265
2266    @property
2267    def hashable_args(self) -> t.Any:
2268        return (self.this, self.quoted)
2269
2270    @property
2271    def output_name(self) -> str:
2272        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2262    @property
2263    def quoted(self) -> bool:
2264        return bool(self.args.get("quoted"))
hashable_args: Any
2266    @property
2267    def hashable_args(self) -> t.Any:
2268        return (self.this, self.quoted)
output_name: str
2270    @property
2271    def output_name(self) -> str:
2272        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):
2276class Opclass(Expression):
2277    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2280class Index(Expression):
2281    arg_types = {
2282        "this": False,
2283        "table": False,
2284        "unique": False,
2285        "primary": False,
2286        "amp": False,  # teradata
2287        "params": False,
2288    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2291class IndexParameters(Expression):
2292    arg_types = {
2293        "using": False,
2294        "include": False,
2295        "columns": False,
2296        "with_storage": False,
2297        "partition_by": False,
2298        "tablespace": False,
2299        "where": False,
2300        "on": False,
2301    }
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):
2304class Insert(DDL, DML):
2305    arg_types = {
2306        "hint": False,
2307        "with": False,
2308        "is_function": False,
2309        "this": False,
2310        "expression": False,
2311        "conflict": False,
2312        "returning": False,
2313        "overwrite": False,
2314        "exists": False,
2315        "alternative": False,
2316        "where": False,
2317        "ignore": False,
2318        "by_name": False,
2319        "stored": False,
2320        "partition": False,
2321        "settings": False,
2322        "source": False,
2323    }
2324
2325    def with_(
2326        self,
2327        alias: ExpOrStr,
2328        as_: ExpOrStr,
2329        recursive: t.Optional[bool] = None,
2330        materialized: t.Optional[bool] = None,
2331        append: bool = True,
2332        dialect: DialectType = None,
2333        copy: bool = True,
2334        **opts,
2335    ) -> Insert:
2336        """
2337        Append to or set the common table expressions.
2338
2339        Example:
2340            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2341            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2342
2343        Args:
2344            alias: the SQL code string to parse as the table name.
2345                If an `Expression` instance is passed, this is used as-is.
2346            as_: the SQL code string to parse as the table expression.
2347                If an `Expression` instance is passed, it will be used as-is.
2348            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2349            materialized: set the MATERIALIZED part of the expression.
2350            append: if `True`, add to any existing expressions.
2351                Otherwise, this resets the expressions.
2352            dialect: the dialect used to parse the input expression.
2353            copy: if `False`, modify this expression instance in-place.
2354            opts: other options to use to parse the input expressions.
2355
2356        Returns:
2357            The modified expression.
2358        """
2359        return _apply_cte_builder(
2360            self,
2361            alias,
2362            as_,
2363            recursive=recursive,
2364            materialized=materialized,
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2325    def with_(
2326        self,
2327        alias: ExpOrStr,
2328        as_: ExpOrStr,
2329        recursive: t.Optional[bool] = None,
2330        materialized: t.Optional[bool] = None,
2331        append: bool = True,
2332        dialect: DialectType = None,
2333        copy: bool = True,
2334        **opts,
2335    ) -> Insert:
2336        """
2337        Append to or set the common table expressions.
2338
2339        Example:
2340            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2341            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2342
2343        Args:
2344            alias: the SQL code string to parse as the table name.
2345                If an `Expression` instance is passed, this is used as-is.
2346            as_: the SQL code string to parse as the table expression.
2347                If an `Expression` instance is passed, it will be used as-is.
2348            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2349            materialized: set the MATERIALIZED part of the expression.
2350            append: if `True`, add to any existing expressions.
2351                Otherwise, this resets the expressions.
2352            dialect: the dialect used to parse the input expression.
2353            copy: if `False`, modify this expression instance in-place.
2354            opts: other options to use to parse the input expressions.
2355
2356        Returns:
2357            The modified expression.
2358        """
2359        return _apply_cte_builder(
2360            self,
2361            alias,
2362            as_,
2363            recursive=recursive,
2364            materialized=materialized,
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )

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):
2372class ConditionalInsert(Expression):
2373    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2376class MultitableInserts(Expression):
2377    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2380class OnConflict(Expression):
2381    arg_types = {
2382        "duplicate": False,
2383        "expressions": False,
2384        "action": False,
2385        "conflict_keys": False,
2386        "constraint": False,
2387        "where": False,
2388    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2391class OnCondition(Expression):
2392    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2395class Returning(Expression):
2396    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2400class Introducer(Expression):
2401    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2405class National(Expression):
2406    pass
key = 'national'
class LoadData(Expression):
2409class LoadData(Expression):
2410    arg_types = {
2411        "this": True,
2412        "local": False,
2413        "overwrite": False,
2414        "inpath": True,
2415        "partition": False,
2416        "input_format": False,
2417        "serde": False,
2418    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2421class Partition(Expression):
2422    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2425class PartitionRange(Expression):
2426    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2430class PartitionId(Expression):
2431    pass
key = 'partitionid'
class Fetch(Expression):
2434class Fetch(Expression):
2435    arg_types = {
2436        "direction": False,
2437        "count": False,
2438        "limit_options": False,
2439    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2442class Grant(Expression):
2443    arg_types = {
2444        "privileges": True,
2445        "kind": False,
2446        "securable": True,
2447        "principals": True,
2448        "grant_option": False,
2449    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2452class Group(Expression):
2453    arg_types = {
2454        "expressions": False,
2455        "grouping_sets": False,
2456        "cube": False,
2457        "rollup": False,
2458        "totals": False,
2459        "all": False,
2460    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2463class Cube(Expression):
2464    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2467class Rollup(Expression):
2468    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2471class GroupingSets(Expression):
2472    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2475class Lambda(Expression):
2476    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2479class Limit(Expression):
2480    arg_types = {
2481        "this": False,
2482        "expression": True,
2483        "offset": False,
2484        "limit_options": False,
2485        "expressions": False,
2486    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2489class LimitOptions(Expression):
2490    arg_types = {
2491        "percent": False,
2492        "rows": False,
2493        "with_ties": False,
2494    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2497class Literal(Condition):
2498    arg_types = {"this": True, "is_string": True}
2499
2500    @property
2501    def hashable_args(self) -> t.Any:
2502        return (self.this, self.args.get("is_string"))
2503
2504    @classmethod
2505    def number(cls, number) -> Literal:
2506        return cls(this=str(number), is_string=False)
2507
2508    @classmethod
2509    def string(cls, string) -> Literal:
2510        return cls(this=str(string), is_string=True)
2511
2512    @property
2513    def output_name(self) -> str:
2514        return self.name
2515
2516    def to_py(self) -> int | str | Decimal:
2517        if self.is_number:
2518            try:
2519                return int(self.this)
2520            except ValueError:
2521                return Decimal(self.this)
2522        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2500    @property
2501    def hashable_args(self) -> t.Any:
2502        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2504    @classmethod
2505    def number(cls, number) -> Literal:
2506        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2508    @classmethod
2509    def string(cls, string) -> Literal:
2510        return cls(this=str(string), is_string=True)
output_name: str
2512    @property
2513    def output_name(self) -> str:
2514        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:
2516    def to_py(self) -> int | str | Decimal:
2517        if self.is_number:
2518            try:
2519                return int(self.this)
2520            except ValueError:
2521                return Decimal(self.this)
2522        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2525class Join(Expression):
2526    arg_types = {
2527        "this": True,
2528        "on": False,
2529        "side": False,
2530        "kind": False,
2531        "using": False,
2532        "method": False,
2533        "global": False,
2534        "hint": False,
2535        "match_condition": False,  # Snowflake
2536        "expressions": False,
2537        "pivots": False,
2538    }
2539
2540    @property
2541    def method(self) -> str:
2542        return self.text("method").upper()
2543
2544    @property
2545    def kind(self) -> str:
2546        return self.text("kind").upper()
2547
2548    @property
2549    def side(self) -> str:
2550        return self.text("side").upper()
2551
2552    @property
2553    def hint(self) -> str:
2554        return self.text("hint").upper()
2555
2556    @property
2557    def alias_or_name(self) -> str:
2558        return self.this.alias_or_name
2559
2560    @property
2561    def is_semi_or_anti_join(self) -> bool:
2562        return self.kind in ("SEMI", "ANTI")
2563
2564    def on(
2565        self,
2566        *expressions: t.Optional[ExpOrStr],
2567        append: bool = True,
2568        dialect: DialectType = None,
2569        copy: bool = True,
2570        **opts,
2571    ) -> Join:
2572        """
2573        Append to or set the ON expressions.
2574
2575        Example:
2576            >>> import sqlglot
2577            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2578            'JOIN x ON y = 1'
2579
2580        Args:
2581            *expressions: the SQL code strings to parse.
2582                If an `Expression` instance is passed, it will be used as-is.
2583                Multiple expressions are combined with an AND operator.
2584            append: if `True`, AND the new expressions to any existing expression.
2585                Otherwise, this resets the expression.
2586            dialect: the dialect used to parse the input expressions.
2587            copy: if `False`, modify this expression instance in-place.
2588            opts: other options to use to parse the input expressions.
2589
2590        Returns:
2591            The modified Join expression.
2592        """
2593        join = _apply_conjunction_builder(
2594            *expressions,
2595            instance=self,
2596            arg="on",
2597            append=append,
2598            dialect=dialect,
2599            copy=copy,
2600            **opts,
2601        )
2602
2603        if join.kind == "CROSS":
2604            join.set("kind", None)
2605
2606        return join
2607
2608    def using(
2609        self,
2610        *expressions: t.Optional[ExpOrStr],
2611        append: bool = True,
2612        dialect: DialectType = None,
2613        copy: bool = True,
2614        **opts,
2615    ) -> Join:
2616        """
2617        Append to or set the USING expressions.
2618
2619        Example:
2620            >>> import sqlglot
2621            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2622            'JOIN x USING (foo, bla)'
2623
2624        Args:
2625            *expressions: the SQL code strings to parse.
2626                If an `Expression` instance is passed, it will be used as-is.
2627            append: if `True`, concatenate the new expressions to the existing "using" list.
2628                Otherwise, this resets the expression.
2629            dialect: the dialect used to parse the input expressions.
2630            copy: if `False`, modify this expression instance in-place.
2631            opts: other options to use to parse the input expressions.
2632
2633        Returns:
2634            The modified Join expression.
2635        """
2636        join = _apply_list_builder(
2637            *expressions,
2638            instance=self,
2639            arg="using",
2640            append=append,
2641            dialect=dialect,
2642            copy=copy,
2643            **opts,
2644        )
2645
2646        if join.kind == "CROSS":
2647            join.set("kind", None)
2648
2649        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False, 'pivots': False}
method: str
2540    @property
2541    def method(self) -> str:
2542        return self.text("method").upper()
kind: str
2544    @property
2545    def kind(self) -> str:
2546        return self.text("kind").upper()
side: str
2548    @property
2549    def side(self) -> str:
2550        return self.text("side").upper()
hint: str
2552    @property
2553    def hint(self) -> str:
2554        return self.text("hint").upper()
alias_or_name: str
2556    @property
2557    def alias_or_name(self) -> str:
2558        return self.this.alias_or_name
is_semi_or_anti_join: bool
2560    @property
2561    def is_semi_or_anti_join(self) -> bool:
2562        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2564    def on(
2565        self,
2566        *expressions: t.Optional[ExpOrStr],
2567        append: bool = True,
2568        dialect: DialectType = None,
2569        copy: bool = True,
2570        **opts,
2571    ) -> Join:
2572        """
2573        Append to or set the ON expressions.
2574
2575        Example:
2576            >>> import sqlglot
2577            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2578            'JOIN x ON y = 1'
2579
2580        Args:
2581            *expressions: the SQL code strings to parse.
2582                If an `Expression` instance is passed, it will be used as-is.
2583                Multiple expressions are combined with an AND operator.
2584            append: if `True`, AND the new expressions to any existing expression.
2585                Otherwise, this resets the expression.
2586            dialect: the dialect used to parse the input expressions.
2587            copy: if `False`, modify this expression instance in-place.
2588            opts: other options to use to parse the input expressions.
2589
2590        Returns:
2591            The modified Join expression.
2592        """
2593        join = _apply_conjunction_builder(
2594            *expressions,
2595            instance=self,
2596            arg="on",
2597            append=append,
2598            dialect=dialect,
2599            copy=copy,
2600            **opts,
2601        )
2602
2603        if join.kind == "CROSS":
2604            join.set("kind", None)
2605
2606        return join

Append to or set the ON expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
'JOIN x ON y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2608    def using(
2609        self,
2610        *expressions: t.Optional[ExpOrStr],
2611        append: bool = True,
2612        dialect: DialectType = None,
2613        copy: bool = True,
2614        **opts,
2615    ) -> Join:
2616        """
2617        Append to or set the USING expressions.
2618
2619        Example:
2620            >>> import sqlglot
2621            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2622            'JOIN x USING (foo, bla)'
2623
2624        Args:
2625            *expressions: the SQL code strings to parse.
2626                If an `Expression` instance is passed, it will be used as-is.
2627            append: if `True`, concatenate the new expressions to the existing "using" list.
2628                Otherwise, this resets the expression.
2629            dialect: the dialect used to parse the input expressions.
2630            copy: if `False`, modify this expression instance in-place.
2631            opts: other options to use to parse the input expressions.
2632
2633        Returns:
2634            The modified Join expression.
2635        """
2636        join = _apply_list_builder(
2637            *expressions,
2638            instance=self,
2639            arg="using",
2640            append=append,
2641            dialect=dialect,
2642            copy=copy,
2643            **opts,
2644        )
2645
2646        if join.kind == "CROSS":
2647            join.set("kind", None)
2648
2649        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):
2652class Lateral(UDTF):
2653    arg_types = {
2654        "this": True,
2655        "view": False,
2656        "outer": False,
2657        "alias": False,
2658        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2659        "ordinality": False,
2660    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2665class TableFromRows(UDTF):
2666    arg_types = {
2667        "this": True,
2668        "alias": False,
2669        "joins": False,
2670        "pivots": False,
2671        "sample": False,
2672    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2675class MatchRecognizeMeasure(Expression):
2676    arg_types = {
2677        "this": True,
2678        "window_frame": False,
2679    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2682class MatchRecognize(Expression):
2683    arg_types = {
2684        "partition_by": False,
2685        "order": False,
2686        "measures": False,
2687        "rows": False,
2688        "after": False,
2689        "pattern": False,
2690        "define": False,
2691        "alias": False,
2692    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2697class Final(Expression):
2698    pass
key = 'final'
class Offset(Expression):
2701class Offset(Expression):
2702    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2705class Order(Expression):
2706    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2710class WithFill(Expression):
2711    arg_types = {
2712        "from": False,
2713        "to": False,
2714        "step": False,
2715        "interpolate": False,
2716    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2721class Cluster(Order):
2722    pass
key = 'cluster'
class Distribute(Order):
2725class Distribute(Order):
2726    pass
key = 'distribute'
class Sort(Order):
2729class Sort(Order):
2730    pass
key = 'sort'
class Ordered(Expression):
2733class Ordered(Expression):
2734    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2735
2736    @property
2737    def name(self) -> str:
2738        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2736    @property
2737    def name(self) -> str:
2738        return self.this.name
key = 'ordered'
class Property(Expression):
2741class Property(Expression):
2742    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2745class GrantPrivilege(Expression):
2746    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2749class GrantPrincipal(Expression):
2750    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2753class AllowedValuesProperty(Expression):
2754    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2757class AlgorithmProperty(Property):
2758    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2761class AutoIncrementProperty(Property):
2762    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2766class AutoRefreshProperty(Property):
2767    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2770class BackupProperty(Property):
2771    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2774class BlockCompressionProperty(Property):
2775    arg_types = {
2776        "autotemp": False,
2777        "always": False,
2778        "default": False,
2779        "manual": False,
2780        "never": False,
2781    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2784class CharacterSetProperty(Property):
2785    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2788class ChecksumProperty(Property):
2789    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2792class CollateProperty(Property):
2793    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2796class CopyGrantsProperty(Property):
2797    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2800class DataBlocksizeProperty(Property):
2801    arg_types = {
2802        "size": False,
2803        "units": False,
2804        "minimum": False,
2805        "maximum": False,
2806        "default": False,
2807    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2810class DataDeletionProperty(Property):
2811    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):
2814class DefinerProperty(Property):
2815    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2818class DistKeyProperty(Property):
2819    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2824class DistributedByProperty(Property):
2825    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):
2828class DistStyleProperty(Property):
2829    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2832class DuplicateKeyProperty(Property):
2833    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2836class EngineProperty(Property):
2837    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2840class HeapProperty(Property):
2841    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2844class ToTableProperty(Property):
2845    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2848class ExecuteAsProperty(Property):
2849    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2852class ExternalProperty(Property):
2853    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2856class FallbackProperty(Property):
2857    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2861class FileFormatProperty(Property):
2862    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2865class CredentialsProperty(Property):
2866    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2869class FreespaceProperty(Property):
2870    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2873class GlobalProperty(Property):
2874    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2877class IcebergProperty(Property):
2878    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2881class InheritsProperty(Property):
2882    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2885class InputModelProperty(Property):
2886    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2889class OutputModelProperty(Property):
2890    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2893class IsolatedLoadingProperty(Property):
2894    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2897class JournalProperty(Property):
2898    arg_types = {
2899        "no": False,
2900        "dual": False,
2901        "before": False,
2902        "local": False,
2903        "after": False,
2904    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2907class LanguageProperty(Property):
2908    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2911class EnviromentProperty(Property):
2912    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2916class ClusteredByProperty(Property):
2917    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2920class DictProperty(Property):
2921    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2924class DictSubProperty(Property):
2925    pass
key = 'dictsubproperty'
class DictRange(Property):
2928class DictRange(Property):
2929    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2932class DynamicProperty(Property):
2933    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2938class OnCluster(Property):
2939    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2943class EmptyProperty(Property):
2944    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2947class LikeProperty(Property):
2948    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2951class LocationProperty(Property):
2952    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2955class LockProperty(Property):
2956    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2959class LockingProperty(Property):
2960    arg_types = {
2961        "this": False,
2962        "kind": True,
2963        "for_or_in": False,
2964        "lock_type": True,
2965        "override": False,
2966    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2969class LogProperty(Property):
2970    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2973class MaterializedProperty(Property):
2974    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2977class MergeBlockRatioProperty(Property):
2978    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):
2981class NoPrimaryIndexProperty(Property):
2982    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2985class OnProperty(Property):
2986    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2989class OnCommitProperty(Property):
2990    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2993class PartitionedByProperty(Property):
2994    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
2997class PartitionedByBucket(Property):
2998    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3001class PartitionByTruncate(Property):
3002    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3006class PartitionByRangeProperty(Property):
3007    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3011class PartitionByRangePropertyDynamic(Expression):
3012    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class UniqueKeyProperty(Property):
3016class UniqueKeyProperty(Property):
3017    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3021class PartitionBoundSpec(Expression):
3022    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3023    arg_types = {
3024        "this": False,
3025        "expression": False,
3026        "from_expressions": False,
3027        "to_expressions": False,
3028    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3031class PartitionedOfProperty(Property):
3032    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3033    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3036class StreamingTableProperty(Property):
3037    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3040class RemoteWithConnectionModelProperty(Property):
3041    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3044class ReturnsProperty(Property):
3045    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):
3048class StrictProperty(Property):
3049    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3052class RowFormatProperty(Property):
3053    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3056class RowFormatDelimitedProperty(Property):
3057    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3058    arg_types = {
3059        "fields": False,
3060        "escaped": False,
3061        "collection_items": False,
3062        "map_keys": False,
3063        "lines": False,
3064        "null": False,
3065        "serde": False,
3066    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3069class RowFormatSerdeProperty(Property):
3070    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3074class QueryTransform(Expression):
3075    arg_types = {
3076        "expressions": True,
3077        "command_script": True,
3078        "schema": False,
3079        "row_format_before": False,
3080        "record_writer": False,
3081        "row_format_after": False,
3082        "record_reader": False,
3083    }
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):
3086class SampleProperty(Property):
3087    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3091class SecurityProperty(Property):
3092    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3095class SchemaCommentProperty(Property):
3096    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
3099class SerdeProperties(Property):
3100    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3103class SetProperty(Property):
3104    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3107class SharingProperty(Property):
3108    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3111class SetConfigProperty(Property):
3112    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3115class SettingsProperty(Property):
3116    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3119class SortKeyProperty(Property):
3120    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3123class SqlReadWriteProperty(Property):
3124    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3127class SqlSecurityProperty(Property):
3128    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3131class StabilityProperty(Property):
3132    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3135class StorageHandlerProperty(Property):
3136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3139class TemporaryProperty(Property):
3140    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3143class SecureProperty(Property):
3144    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3148class Tags(ColumnConstraintKind, Property):
3149    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3152class TransformModelProperty(Property):
3153    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3156class TransientProperty(Property):
3157    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3160class UnloggedProperty(Property):
3161    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3165class UsingTemplateProperty(Property):
3166    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3170class ViewAttributeProperty(Property):
3171    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3174class VolatileProperty(Property):
3175    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3178class WithDataProperty(Property):
3179    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3182class WithJournalTableProperty(Property):
3183    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3186class WithSchemaBindingProperty(Property):
3187    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3190class WithSystemVersioningProperty(Property):
3191    arg_types = {
3192        "on": False,
3193        "this": False,
3194        "data_consistency": False,
3195        "retention_period": False,
3196        "with": True,
3197    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3200class WithProcedureOptions(Property):
3201    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3204class EncodeProperty(Property):
3205    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3208class IncludeProperty(Property):
3209    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3212class ForceProperty(Property):
3213    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3216class Properties(Expression):
3217    arg_types = {"expressions": True}
3218
3219    NAME_TO_PROPERTY = {
3220        "ALGORITHM": AlgorithmProperty,
3221        "AUTO_INCREMENT": AutoIncrementProperty,
3222        "CHARACTER SET": CharacterSetProperty,
3223        "CLUSTERED_BY": ClusteredByProperty,
3224        "COLLATE": CollateProperty,
3225        "COMMENT": SchemaCommentProperty,
3226        "CREDENTIALS": CredentialsProperty,
3227        "DEFINER": DefinerProperty,
3228        "DISTKEY": DistKeyProperty,
3229        "DISTRIBUTED_BY": DistributedByProperty,
3230        "DISTSTYLE": DistStyleProperty,
3231        "ENGINE": EngineProperty,
3232        "EXECUTE AS": ExecuteAsProperty,
3233        "FORMAT": FileFormatProperty,
3234        "LANGUAGE": LanguageProperty,
3235        "LOCATION": LocationProperty,
3236        "LOCK": LockProperty,
3237        "PARTITIONED_BY": PartitionedByProperty,
3238        "RETURNS": ReturnsProperty,
3239        "ROW_FORMAT": RowFormatProperty,
3240        "SORTKEY": SortKeyProperty,
3241        "ENCODE": EncodeProperty,
3242        "INCLUDE": IncludeProperty,
3243    }
3244
3245    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3246
3247    # CREATE property locations
3248    # Form: schema specified
3249    #   create [POST_CREATE]
3250    #     table a [POST_NAME]
3251    #     (b int) [POST_SCHEMA]
3252    #     with ([POST_WITH])
3253    #     index (b) [POST_INDEX]
3254    #
3255    # Form: alias selection
3256    #   create [POST_CREATE]
3257    #     table a [POST_NAME]
3258    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3259    #     index (c) [POST_INDEX]
3260    class Location(AutoName):
3261        POST_CREATE = auto()
3262        POST_NAME = auto()
3263        POST_SCHEMA = auto()
3264        POST_WITH = auto()
3265        POST_ALIAS = auto()
3266        POST_EXPRESSION = auto()
3267        POST_INDEX = auto()
3268        UNSUPPORTED = auto()
3269
3270    @classmethod
3271    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3272        expressions = []
3273        for key, value in properties_dict.items():
3274            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3275            if property_cls:
3276                expressions.append(property_cls(this=convert(value)))
3277            else:
3278                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3279
3280        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'CREDENTIALS': <class 'CredentialsProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>, 'ENCODE': <class 'EncodeProperty'>, 'INCLUDE': <class 'IncludeProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'CredentialsProperty'>: 'CREDENTIALS', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistributedByProperty'>: 'DISTRIBUTED_BY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY', <class 'EncodeProperty'>: 'ENCODE', <class 'IncludeProperty'>: 'INCLUDE'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3270    @classmethod
3271    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3272        expressions = []
3273        for key, value in properties_dict.items():
3274            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3275            if property_cls:
3276                expressions.append(property_cls(this=convert(value)))
3277            else:
3278                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3279
3280        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3260    class Location(AutoName):
3261        POST_CREATE = auto()
3262        POST_NAME = auto()
3263        POST_SCHEMA = auto()
3264        POST_WITH = auto()
3265        POST_ALIAS = auto()
3266        POST_EXPRESSION = auto()
3267        POST_INDEX = auto()
3268        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):
3283class Qualify(Expression):
3284    pass
key = 'qualify'
class InputOutputFormat(Expression):
3287class InputOutputFormat(Expression):
3288    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3292class Return(Expression):
3293    pass
key = 'return'
class Reference(Expression):
3296class Reference(Expression):
3297    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3300class Tuple(Expression):
3301    arg_types = {"expressions": False}
3302
3303    def isin(
3304        self,
3305        *expressions: t.Any,
3306        query: t.Optional[ExpOrStr] = None,
3307        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3308        copy: bool = True,
3309        **opts,
3310    ) -> In:
3311        return In(
3312            this=maybe_copy(self, copy),
3313            expressions=[convert(e, copy=copy) for e in expressions],
3314            query=maybe_parse(query, copy=copy, **opts) if query else None,
3315            unnest=(
3316                Unnest(
3317                    expressions=[
3318                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3319                        for e in ensure_list(unnest)
3320                    ]
3321                )
3322                if unnest
3323                else None
3324            ),
3325        )
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:
3303    def isin(
3304        self,
3305        *expressions: t.Any,
3306        query: t.Optional[ExpOrStr] = None,
3307        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3308        copy: bool = True,
3309        **opts,
3310    ) -> In:
3311        return In(
3312            this=maybe_copy(self, copy),
3313            expressions=[convert(e, copy=copy) for e in expressions],
3314            query=maybe_parse(query, copy=copy, **opts) if query else None,
3315            unnest=(
3316                Unnest(
3317                    expressions=[
3318                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3319                        for e in ensure_list(unnest)
3320                    ]
3321                )
3322                if unnest
3323                else None
3324            ),
3325        )
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):
3356class QueryOption(Expression):
3357    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3361class WithTableHint(Expression):
3362    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3366class IndexTableHint(Expression):
3367    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3371class HistoricalData(Expression):
3372    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3376class Put(Expression):
3377    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3381class Get(Expression):
3382    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3385class Table(Expression):
3386    arg_types = {
3387        "this": False,
3388        "alias": False,
3389        "db": False,
3390        "catalog": False,
3391        "laterals": False,
3392        "joins": False,
3393        "pivots": False,
3394        "hints": False,
3395        "system_time": False,
3396        "version": False,
3397        "format": False,
3398        "pattern": False,
3399        "ordinality": False,
3400        "when": False,
3401        "only": False,
3402        "partition": False,
3403        "changes": False,
3404        "rows_from": False,
3405        "sample": False,
3406    }
3407
3408    @property
3409    def name(self) -> str:
3410        if not self.this or isinstance(self.this, Func):
3411            return ""
3412        return self.this.name
3413
3414    @property
3415    def db(self) -> str:
3416        return self.text("db")
3417
3418    @property
3419    def catalog(self) -> str:
3420        return self.text("catalog")
3421
3422    @property
3423    def selects(self) -> t.List[Expression]:
3424        return []
3425
3426    @property
3427    def named_selects(self) -> t.List[str]:
3428        return []
3429
3430    @property
3431    def parts(self) -> t.List[Expression]:
3432        """Return the parts of a table in order catalog, db, table."""
3433        parts: t.List[Expression] = []
3434
3435        for arg in ("catalog", "db", "this"):
3436            part = self.args.get(arg)
3437
3438            if isinstance(part, Dot):
3439                parts.extend(part.flatten())
3440            elif isinstance(part, Expression):
3441                parts.append(part)
3442
3443        return parts
3444
3445    def to_column(self, copy: bool = True) -> Expression:
3446        parts = self.parts
3447        last_part = parts[-1]
3448
3449        if isinstance(last_part, Identifier):
3450            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3451        else:
3452            # This branch will be reached if a function or array is wrapped in a `Table`
3453            col = last_part
3454
3455        alias = self.args.get("alias")
3456        if alias:
3457            col = alias_(col, alias.this, copy=copy)
3458
3459        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
3408    @property
3409    def name(self) -> str:
3410        if not self.this or isinstance(self.this, Func):
3411            return ""
3412        return self.this.name
db: str
3414    @property
3415    def db(self) -> str:
3416        return self.text("db")
catalog: str
3418    @property
3419    def catalog(self) -> str:
3420        return self.text("catalog")
selects: List[Expression]
3422    @property
3423    def selects(self) -> t.List[Expression]:
3424        return []
named_selects: List[str]
3426    @property
3427    def named_selects(self) -> t.List[str]:
3428        return []
parts: List[Expression]
3430    @property
3431    def parts(self) -> t.List[Expression]:
3432        """Return the parts of a table in order catalog, db, table."""
3433        parts: t.List[Expression] = []
3434
3435        for arg in ("catalog", "db", "this"):
3436            part = self.args.get(arg)
3437
3438            if isinstance(part, Dot):
3439                parts.extend(part.flatten())
3440            elif isinstance(part, Expression):
3441                parts.append(part)
3442
3443        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3445    def to_column(self, copy: bool = True) -> Expression:
3446        parts = self.parts
3447        last_part = parts[-1]
3448
3449        if isinstance(last_part, Identifier):
3450            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3451        else:
3452            # This branch will be reached if a function or array is wrapped in a `Table`
3453            col = last_part
3454
3455        alias = self.args.get("alias")
3456        if alias:
3457            col = alias_(col, alias.this, copy=copy)
3458
3459        return col
key = 'table'
class SetOperation(Query):
3462class SetOperation(Query):
3463    arg_types = {
3464        "with": False,
3465        "this": True,
3466        "expression": True,
3467        "distinct": False,
3468        "by_name": False,
3469        "side": False,
3470        "kind": False,
3471        "on": False,
3472        **QUERY_MODIFIERS,
3473    }
3474
3475    def select(
3476        self: S,
3477        *expressions: t.Optional[ExpOrStr],
3478        append: bool = True,
3479        dialect: DialectType = None,
3480        copy: bool = True,
3481        **opts,
3482    ) -> S:
3483        this = maybe_copy(self, copy)
3484        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3485        this.expression.unnest().select(
3486            *expressions, append=append, dialect=dialect, copy=False, **opts
3487        )
3488        return this
3489
3490    @property
3491    def named_selects(self) -> t.List[str]:
3492        return self.this.unnest().named_selects
3493
3494    @property
3495    def is_star(self) -> bool:
3496        return self.this.is_star or self.expression.is_star
3497
3498    @property
3499    def selects(self) -> t.List[Expression]:
3500        return self.this.unnest().selects
3501
3502    @property
3503    def left(self) -> Query:
3504        return self.this
3505
3506    @property
3507    def right(self) -> Query:
3508        return self.expression
3509
3510    @property
3511    def kind(self) -> str:
3512        return self.text("kind").upper()
3513
3514    @property
3515    def side(self) -> str:
3516        return self.text("side").upper()
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3475    def select(
3476        self: S,
3477        *expressions: t.Optional[ExpOrStr],
3478        append: bool = True,
3479        dialect: DialectType = None,
3480        copy: bool = True,
3481        **opts,
3482    ) -> S:
3483        this = maybe_copy(self, copy)
3484        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3485        this.expression.unnest().select(
3486            *expressions, append=append, dialect=dialect, copy=False, **opts
3487        )
3488        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]
3490    @property
3491    def named_selects(self) -> t.List[str]:
3492        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3494    @property
3495    def is_star(self) -> bool:
3496        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3498    @property
3499    def selects(self) -> t.List[Expression]:
3500        return self.this.unnest().selects

Returns the query's projections.

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

Set the table to update.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • expression : the SQL code strings to parse. If a Table instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Table.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3575    def set_(
3576        self,
3577        *expressions: ExpOrStr,
3578        append: bool = True,
3579        dialect: DialectType = None,
3580        copy: bool = True,
3581        **opts,
3582    ) -> Update:
3583        """
3584        Append to or set the SET expressions.
3585
3586        Example:
3587            >>> Update().table("my_table").set_("x = 1").sql()
3588            'UPDATE my_table SET x = 1'
3589
3590        Args:
3591            *expressions: the SQL code strings to parse.
3592                If `Expression` instance(s) are passed, they will be used as-is.
3593                Multiple expressions are combined with a comma.
3594            append: if `True`, add the new expressions to any existing SET expressions.
3595                Otherwise, this resets the expressions.
3596            dialect: the dialect used to parse the input expressions.
3597            copy: if `False`, modify this expression instance in-place.
3598            opts: other options to use to parse the input expressions.
3599        """
3600        return _apply_list_builder(
3601            *expressions,
3602            instance=self,
3603            arg="expressions",
3604            append=append,
3605            into=Expression,
3606            prefix=None,
3607            dialect=dialect,
3608            copy=copy,
3609            **opts,
3610        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3612    def where(
3613        self,
3614        *expressions: t.Optional[ExpOrStr],
3615        append: bool = True,
3616        dialect: DialectType = None,
3617        copy: bool = True,
3618        **opts,
3619    ) -> Select:
3620        """
3621        Append to or set the WHERE expressions.
3622
3623        Example:
3624            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3625            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3626
3627        Args:
3628            *expressions: the SQL code strings to parse.
3629                If an `Expression` instance is passed, it will be used as-is.
3630                Multiple expressions are combined with an AND operator.
3631            append: if `True`, AND the new expressions to any existing expression.
3632                Otherwise, this resets the expression.
3633            dialect: the dialect used to parse the input expressions.
3634            copy: if `False`, modify this expression instance in-place.
3635            opts: other options to use to parse the input expressions.
3636
3637        Returns:
3638            Select: the modified expression.
3639        """
3640        return _apply_conjunction_builder(
3641            *expressions,
3642            instance=self,
3643            arg="where",
3644            append=append,
3645            into=Where,
3646            dialect=dialect,
3647            copy=copy,
3648            **opts,
3649        )

Append to or set the WHERE expressions.

Example:
>>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
"UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3651    def from_(
3652        self,
3653        expression: t.Optional[ExpOrStr] = None,
3654        dialect: DialectType = None,
3655        copy: bool = True,
3656        **opts,
3657    ) -> Update:
3658        """
3659        Set the FROM expression.
3660
3661        Example:
3662            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3663            'UPDATE my_table SET x = 1 FROM baz'
3664
3665        Args:
3666            expression : the SQL code strings to parse.
3667                If a `From` instance is passed, this is used as-is.
3668                If another `Expression` instance is passed, it will be wrapped in a `From`.
3669                If nothing is passed in then a from is not applied to the expression
3670            dialect: the dialect used to parse the input expression.
3671            copy: if `False`, modify this expression instance in-place.
3672            opts: other options to use to parse the input expressions.
3673
3674        Returns:
3675            The modified Update expression.
3676        """
3677        if not expression:
3678            return maybe_copy(self, copy)
3679
3680        return _apply_builder(
3681            expression=expression,
3682            instance=self,
3683            arg="from",
3684            into=From,
3685            prefix="FROM",
3686            dialect=dialect,
3687            copy=copy,
3688            **opts,
3689        )

Set the FROM expression.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").sql()
'UPDATE my_table SET x = 1 FROM baz'
Arguments:
  • expression : the SQL code strings to parse. If a From instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a From. If nothing is passed in then a from is not applied to the expression
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3691    def with_(
3692        self,
3693        alias: ExpOrStr,
3694        as_: ExpOrStr,
3695        recursive: t.Optional[bool] = None,
3696        materialized: t.Optional[bool] = None,
3697        append: bool = True,
3698        dialect: DialectType = None,
3699        copy: bool = True,
3700        **opts,
3701    ) -> Update:
3702        """
3703        Append to or set the common table expressions.
3704
3705        Example:
3706            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3707            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3708
3709        Args:
3710            alias: the SQL code string to parse as the table name.
3711                If an `Expression` instance is passed, this is used as-is.
3712            as_: the SQL code string to parse as the table expression.
3713                If an `Expression` instance is passed, it will be used as-is.
3714            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3715            materialized: set the MATERIALIZED part of the expression.
3716            append: if `True`, add to any existing expressions.
3717                Otherwise, this resets the expressions.
3718            dialect: the dialect used to parse the input expression.
3719            copy: if `False`, modify this expression instance in-place.
3720            opts: other options to use to parse the input expressions.
3721
3722        Returns:
3723            The modified expression.
3724        """
3725        return _apply_cte_builder(
3726            self,
3727            alias,
3728            as_,
3729            recursive=recursive,
3730            materialized=materialized,
3731            append=append,
3732            dialect=dialect,
3733            copy=copy,
3734            **opts,
3735        )

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

Set the FROM expression.

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

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3815    def group_by(
3816        self,
3817        *expressions: t.Optional[ExpOrStr],
3818        append: bool = True,
3819        dialect: DialectType = None,
3820        copy: bool = True,
3821        **opts,
3822    ) -> Select:
3823        """
3824        Set the GROUP BY expression.
3825
3826        Example:
3827            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3828            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3829
3830        Args:
3831            *expressions: the SQL code strings to parse.
3832                If a `Group` instance is passed, this is used as-is.
3833                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3834                If nothing is passed in then a group by is not applied to the expression
3835            append: if `True`, add to any existing expressions.
3836                Otherwise, this flattens all the `Group` expression into a single expression.
3837            dialect: the dialect used to parse the input expression.
3838            copy: if `False`, modify this expression instance in-place.
3839            opts: other options to use to parse the input expressions.
3840
3841        Returns:
3842            The modified Select expression.
3843        """
3844        if not expressions:
3845            return self if not copy else self.copy()
3846
3847        return _apply_child_list_builder(
3848            *expressions,
3849            instance=self,
3850            arg="group",
3851            append=append,
3852            copy=copy,
3853            prefix="GROUP BY",
3854            into=Group,
3855            dialect=dialect,
3856            **opts,
3857        )

Set the GROUP BY expression.

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

The modified Select expression.

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

Set the SORT BY expression.

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

The modified Select expression.

def cluster_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3899    def cluster_by(
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        Set the CLUSTER BY expression.
3909
3910        Example:
3911            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3912            'SELECT x FROM tbl CLUSTER BY x DESC'
3913
3914        Args:
3915            *expressions: the SQL code strings to parse.
3916                If a `Group` instance is passed, this is used as-is.
3917                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3918            append: if `True`, add to any existing expressions.
3919                Otherwise, this flattens all the `Order` expression into a single expression.
3920            dialect: the dialect used to parse the input expression.
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            The modified Select expression.
3926        """
3927        return _apply_child_list_builder(
3928            *expressions,
3929            instance=self,
3930            arg="cluster",
3931            append=append,
3932            copy=copy,
3933            prefix="CLUSTER BY",
3934            into=Cluster,
3935            dialect=dialect,
3936            **opts,
3937        )

Set the CLUSTER BY expression.

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

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3939    def select(
3940        self,
3941        *expressions: t.Optional[ExpOrStr],
3942        append: bool = True,
3943        dialect: DialectType = None,
3944        copy: bool = True,
3945        **opts,
3946    ) -> Select:
3947        return _apply_list_builder(
3948            *expressions,
3949            instance=self,
3950            arg="expressions",
3951            append=append,
3952            dialect=dialect,
3953            into=Expression,
3954            copy=copy,
3955            **opts,
3956        )

Append to or set the SELECT expressions.

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

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3958    def lateral(
3959        self,
3960        *expressions: t.Optional[ExpOrStr],
3961        append: bool = True,
3962        dialect: DialectType = None,
3963        copy: bool = True,
3964        **opts,
3965    ) -> Select:
3966        """
3967        Append to or set the LATERAL expressions.
3968
3969        Example:
3970            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3971            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3972
3973        Args:
3974            *expressions: the SQL code strings to parse.
3975                If an `Expression` instance is passed, it will be used as-is.
3976            append: if `True`, add to any existing expressions.
3977                Otherwise, this resets the expressions.
3978            dialect: the dialect used to parse the input expressions.
3979            copy: if `False`, modify this expression instance in-place.
3980            opts: other options to use to parse the input expressions.
3981
3982        Returns:
3983            The modified Select expression.
3984        """
3985        return _apply_list_builder(
3986            *expressions,
3987            instance=self,
3988            arg="laterals",
3989            append=append,
3990            into=Lateral,
3991            prefix="LATERAL VIEW",
3992            dialect=dialect,
3993            copy=copy,
3994            **opts,
3995        )

Append to or set the LATERAL expressions.

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

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3997    def join(
3998        self,
3999        expression: ExpOrStr,
4000        on: t.Optional[ExpOrStr] = None,
4001        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4002        append: bool = True,
4003        join_type: t.Optional[str] = None,
4004        join_alias: t.Optional[Identifier | str] = None,
4005        dialect: DialectType = None,
4006        copy: bool = True,
4007        **opts,
4008    ) -> Select:
4009        """
4010        Append to or set the JOIN expressions.
4011
4012        Example:
4013            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4014            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4015
4016            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4017            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4018
4019            Use `join_type` to change the type of join:
4020
4021            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4022            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4023
4024        Args:
4025            expression: the SQL code string to parse.
4026                If an `Expression` instance is passed, it will be used as-is.
4027            on: optionally specify the join "on" criteria as a SQL string.
4028                If an `Expression` instance is passed, it will be used as-is.
4029            using: optionally specify the join "using" criteria as a SQL string.
4030                If an `Expression` instance is passed, it will be used as-is.
4031            append: if `True`, add to any existing expressions.
4032                Otherwise, this resets the expressions.
4033            join_type: if set, alter the parsed join type.
4034            join_alias: an optional alias for the joined source.
4035            dialect: the dialect used to parse the input expressions.
4036            copy: if `False`, modify this expression instance in-place.
4037            opts: other options to use to parse the input expressions.
4038
4039        Returns:
4040            Select: the modified expression.
4041        """
4042        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4043
4044        try:
4045            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4046        except ParseError:
4047            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4048
4049        join = expression if isinstance(expression, Join) else Join(this=expression)
4050
4051        if isinstance(join.this, Select):
4052            join.this.replace(join.this.subquery())
4053
4054        if join_type:
4055            method: t.Optional[Token]
4056            side: t.Optional[Token]
4057            kind: t.Optional[Token]
4058
4059            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4060
4061            if method:
4062                join.set("method", method.text)
4063            if side:
4064                join.set("side", side.text)
4065            if kind:
4066                join.set("kind", kind.text)
4067
4068        if on:
4069            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4070            join.set("on", on)
4071
4072        if using:
4073            join = _apply_list_builder(
4074                *ensure_list(using),
4075                instance=join,
4076                arg="using",
4077                append=append,
4078                copy=copy,
4079                into=Identifier,
4080                **opts,
4081            )
4082
4083        if join_alias:
4084            join.set("this", alias_(join.this, join_alias, table=True))
4085
4086        return _apply_list_builder(
4087            join,
4088            instance=self,
4089            arg="joins",
4090            append=append,
4091            copy=copy,
4092            **opts,
4093        )

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

Append to or set the HAVING expressions.

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

The modified Select expression.

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

Set the OFFSET expression.

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

Select: the modified expression.

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

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

Set the locking read mode for this expression.

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

The modified expression.

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

Checks whether an expression is a star.

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

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

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

Returns a Python object equivalent of the SQL node.

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

Returns a Python object equivalent of the SQL node.

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

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BLOB = <Type.BLOB: 'BLOB'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME2 = <Type.DATETIME2: 'DATETIME2'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
DYNAMIC = <Type.DYNAMIC: 'DYNAMIC'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NOTHING = <Type.NOTHING: 'NOTHING'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
class PseudoType(DataType):
4804class PseudoType(DataType):
4805    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4809class ObjectIdentifier(DataType):
4810    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4814class SubqueryPredicate(Predicate):
4815    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4818class All(SubqueryPredicate):
4819    pass
key = 'all'
class Any(SubqueryPredicate):
4822class Any(SubqueryPredicate):
4823    pass
key = 'any'
class Command(Expression):
4828class Command(Expression):
4829    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4832class Transaction(Expression):
4833    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4836class Commit(Expression):
4837    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4840class Rollback(Expression):
4841    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4844class Alter(Expression):
4845    arg_types = {
4846        "this": True,
4847        "kind": True,
4848        "actions": True,
4849        "exists": False,
4850        "only": False,
4851        "options": False,
4852        "cluster": False,
4853        "not_valid": False,
4854    }
4855
4856    @property
4857    def kind(self) -> t.Optional[str]:
4858        kind = self.args.get("kind")
4859        return kind and kind.upper()
4860
4861    @property
4862    def actions(self) -> t.List[Expression]:
4863        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]
4856    @property
4857    def kind(self) -> t.Optional[str]:
4858        kind = self.args.get("kind")
4859        return kind and kind.upper()
actions: List[Expression]
4861    @property
4862    def actions(self) -> t.List[Expression]:
4863        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4866class Analyze(Expression):
4867    arg_types = {
4868        "kind": False,
4869        "this": False,
4870        "options": False,
4871        "mode": False,
4872        "partition": False,
4873        "expression": False,
4874        "properties": False,
4875    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4878class AnalyzeStatistics(Expression):
4879    arg_types = {
4880        "kind": True,
4881        "option": False,
4882        "this": False,
4883        "expressions": False,
4884    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4887class AnalyzeHistogram(Expression):
4888    arg_types = {
4889        "this": True,
4890        "expressions": True,
4891        "expression": False,
4892        "update_options": False,
4893    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4896class AnalyzeSample(Expression):
4897    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4900class AnalyzeListChainedRows(Expression):
4901    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4904class AnalyzeDelete(Expression):
4905    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4908class AnalyzeWith(Expression):
4909    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4912class AnalyzeValidate(Expression):
4913    arg_types = {
4914        "kind": True,
4915        "this": False,
4916        "expression": False,
4917    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4920class AnalyzeColumns(Expression):
4921    pass
key = 'analyzecolumns'
class UsingData(Expression):
4924class UsingData(Expression):
4925    pass
key = 'usingdata'
class AddConstraint(Expression):
4928class AddConstraint(Expression):
4929    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AddPartition(Expression):
4932class AddPartition(Expression):
4933    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'addpartition'
class AttachOption(Expression):
4936class AttachOption(Expression):
4937    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4940class DropPartition(Expression):
4941    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4945class ReplacePartition(Expression):
4946    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4950class Binary(Condition):
4951    arg_types = {"this": True, "expression": True}
4952
4953    @property
4954    def left(self) -> Expression:
4955        return self.this
4956
4957    @property
4958    def right(self) -> Expression:
4959        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4953    @property
4954    def left(self) -> Expression:
4955        return self.this
right: Expression
4957    @property
4958    def right(self) -> Expression:
4959        return self.expression
key = 'binary'
class Add(Binary):
4962class Add(Binary):
4963    pass
key = 'add'
class Connector(Binary):
4966class Connector(Binary):
4967    pass
key = 'connector'
class BitwiseAnd(Binary):
4970class BitwiseAnd(Binary):
4971    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4974class BitwiseLeftShift(Binary):
4975    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4978class BitwiseOr(Binary):
4979    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4982class BitwiseRightShift(Binary):
4983    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4986class BitwiseXor(Binary):
4987    pass
key = 'bitwisexor'
class Div(Binary):
4990class Div(Binary):
4991    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):
4994class Overlaps(Binary):
4995    pass
key = 'overlaps'
class Dot(Binary):
4998class Dot(Binary):
4999    @property
5000    def is_star(self) -> bool:
5001        return self.expression.is_star
5002
5003    @property
5004    def name(self) -> str:
5005        return self.expression.name
5006
5007    @property
5008    def output_name(self) -> str:
5009        return self.name
5010
5011    @classmethod
5012    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5013        """Build a Dot object with a sequence of expressions."""
5014        if len(expressions) < 2:
5015            raise ValueError("Dot requires >= 2 expressions.")
5016
5017        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5018
5019    @property
5020    def parts(self) -> t.List[Expression]:
5021        """Return the parts of a table / column in order catalog, db, table."""
5022        this, *parts = self.flatten()
5023
5024        parts.reverse()
5025
5026        for arg in COLUMN_PARTS:
5027            part = this.args.get(arg)
5028
5029            if isinstance(part, Expression):
5030                parts.append(part)
5031
5032        parts.reverse()
5033        return parts
is_star: bool
4999    @property
5000    def is_star(self) -> bool:
5001        return self.expression.is_star

Checks whether an expression is a star.

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

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

key = 'dot'
DATA_TYPE = typing.Union[str, Identifier, Dot, DataType, DataType.Type]
class DPipe(Binary):
5039class DPipe(Binary):
5040    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5043class EQ(Binary, Predicate):
5044    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5047class NullSafeEQ(Binary, Predicate):
5048    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5051class NullSafeNEQ(Binary, Predicate):
5052    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5056class PropertyEQ(Binary):
5057    pass
key = 'propertyeq'
class Distance(Binary):
5060class Distance(Binary):
5061    pass
key = 'distance'
class Escape(Binary):
5064class Escape(Binary):
5065    pass
key = 'escape'
class Glob(Binary, Predicate):
5068class Glob(Binary, Predicate):
5069    pass
key = 'glob'
class GT(Binary, Predicate):
5072class GT(Binary, Predicate):
5073    pass
key = 'gt'
class GTE(Binary, Predicate):
5076class GTE(Binary, Predicate):
5077    pass
key = 'gte'
class ILike(Binary, Predicate):
5080class ILike(Binary, Predicate):
5081    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5084class ILikeAny(Binary, Predicate):
5085    pass
key = 'ilikeany'
class IntDiv(Binary):
5088class IntDiv(Binary):
5089    pass
key = 'intdiv'
class Is(Binary, Predicate):
5092class Is(Binary, Predicate):
5093    pass
key = 'is'
class Kwarg(Binary):
5096class Kwarg(Binary):
5097    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5100class Like(Binary, Predicate):
5101    pass
key = 'like'
class LikeAny(Binary, Predicate):
5104class LikeAny(Binary, Predicate):
5105    pass
key = 'likeany'
class LT(Binary, Predicate):
5108class LT(Binary, Predicate):
5109    pass
key = 'lt'
class LTE(Binary, Predicate):
5112class LTE(Binary, Predicate):
5113    pass
key = 'lte'
class Mod(Binary):
5116class Mod(Binary):
5117    pass
key = 'mod'
class Mul(Binary):
5120class Mul(Binary):
5121    pass
key = 'mul'
class NEQ(Binary, Predicate):
5124class NEQ(Binary, Predicate):
5125    pass
key = 'neq'
class Operator(Binary):
5129class Operator(Binary):
5130    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5133class SimilarTo(Binary, Predicate):
5134    pass
key = 'similarto'
class Slice(Binary):
5137class Slice(Binary):
5138    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5141class Sub(Binary):
5142    pass
key = 'sub'
class Unary(Condition):
5147class Unary(Condition):
5148    pass
key = 'unary'
class BitwiseNot(Unary):
5151class BitwiseNot(Unary):
5152    pass
key = 'bitwisenot'
class Not(Unary):
5155class Not(Unary):
5156    pass
key = 'not'
class Paren(Unary):
5159class Paren(Unary):
5160    @property
5161    def output_name(self) -> str:
5162        return self.this.name
output_name: str
5160    @property
5161    def output_name(self) -> str:
5162        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):
5165class Neg(Unary):
5166    def to_py(self) -> int | Decimal:
5167        if self.is_number:
5168            return self.this.to_py() * -1
5169        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5166    def to_py(self) -> int | Decimal:
5167        if self.is_number:
5168            return self.this.to_py() * -1
5169        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5172class Alias(Expression):
5173    arg_types = {"this": True, "alias": False}
5174
5175    @property
5176    def output_name(self) -> str:
5177        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5175    @property
5176    def output_name(self) -> str:
5177        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):
5182class PivotAlias(Alias):
5183    pass
key = 'pivotalias'
class PivotAny(Expression):
5188class PivotAny(Expression):
5189    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5192class Aliases(Expression):
5193    arg_types = {"this": True, "expressions": True}
5194
5195    @property
5196    def aliases(self):
5197        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5195    @property
5196    def aliases(self):
5197        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5201class AtIndex(Expression):
5202    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5205class AtTimeZone(Expression):
5206    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5209class FromTimeZone(Expression):
5210    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class FormatPhrase(Expression):
5213class FormatPhrase(Expression):
5214    """Format override for a column in Teradata.
5215    Can be expanded to additional dialects as needed
5216
5217    https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT
5218    """
5219
5220    arg_types = {"this": True, "format": True}

Format override for a column in Teradata. Can be expanded to additional dialects as needed

https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT

arg_types = {'this': True, 'format': True}
key = 'formatphrase'
class Between(Predicate):
5223class Between(Predicate):
5224    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5227class Bracket(Condition):
5228    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5229    arg_types = {
5230        "this": True,
5231        "expressions": True,
5232        "offset": False,
5233        "safe": False,
5234        "returns_list_for_maps": False,
5235    }
5236
5237    @property
5238    def output_name(self) -> str:
5239        if len(self.expressions) == 1:
5240            return self.expressions[0].output_name
5241
5242        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5237    @property
5238    def output_name(self) -> str:
5239        if len(self.expressions) == 1:
5240            return self.expressions[0].output_name
5241
5242        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):
5245class Distinct(Expression):
5246    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5249class In(Predicate):
5250    arg_types = {
5251        "this": True,
5252        "expressions": False,
5253        "query": False,
5254        "unnest": False,
5255        "field": False,
5256        "is_global": False,
5257    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5261class ForIn(Expression):
5262    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5265class TimeUnit(Expression):
5266    """Automatically converts unit arg into a var."""
5267
5268    arg_types = {"unit": False}
5269
5270    UNABBREVIATED_UNIT_NAME = {
5271        "D": "DAY",
5272        "H": "HOUR",
5273        "M": "MINUTE",
5274        "MS": "MILLISECOND",
5275        "NS": "NANOSECOND",
5276        "Q": "QUARTER",
5277        "S": "SECOND",
5278        "US": "MICROSECOND",
5279        "W": "WEEK",
5280        "Y": "YEAR",
5281    }
5282
5283    VAR_LIKE = (Column, Literal, Var)
5284
5285    def __init__(self, **args):
5286        unit = args.get("unit")
5287        if isinstance(unit, self.VAR_LIKE):
5288            args["unit"] = Var(
5289                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5290            )
5291        elif isinstance(unit, Week):
5292            unit.set("this", Var(this=unit.this.name.upper()))
5293
5294        super().__init__(**args)
5295
5296    @property
5297    def unit(self) -> t.Optional[Var | IntervalSpan]:
5298        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5285    def __init__(self, **args):
5286        unit = args.get("unit")
5287        if isinstance(unit, self.VAR_LIKE):
5288            args["unit"] = Var(
5289                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5290            )
5291        elif isinstance(unit, Week):
5292            unit.set("this", Var(this=unit.this.name.upper()))
5293
5294        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]
5296    @property
5297    def unit(self) -> t.Optional[Var | IntervalSpan]:
5298        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5301class IntervalOp(TimeUnit):
5302    arg_types = {"unit": False, "expression": True}
5303
5304    def interval(self):
5305        return Interval(
5306            this=self.expression.copy(),
5307            unit=self.unit.copy() if self.unit else None,
5308        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5304    def interval(self):
5305        return Interval(
5306            this=self.expression.copy(),
5307            unit=self.unit.copy() if self.unit else None,
5308        )
key = 'intervalop'
class IntervalSpan(DataType):
5314class IntervalSpan(DataType):
5315    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5318class Interval(TimeUnit):
5319    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5322class IgnoreNulls(Expression):
5323    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5326class RespectNulls(Expression):
5327    pass
key = 'respectnulls'
class HavingMax(Expression):
5331class HavingMax(Expression):
5332    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5336class Func(Condition):
5337    """
5338    The base class for all function expressions.
5339
5340    Attributes:
5341        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5342            treated as a variable length argument and the argument's value will be stored as a list.
5343        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5344            function expression. These values are used to map this node to a name during parsing as
5345            well as to provide the function's name during SQL string generation. By default the SQL
5346            name is set to the expression's class name transformed to snake case.
5347    """
5348
5349    is_var_len_args = False
5350
5351    @classmethod
5352    def from_arg_list(cls, args):
5353        if cls.is_var_len_args:
5354            all_arg_keys = list(cls.arg_types)
5355            # If this function supports variable length argument treat the last argument as such.
5356            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5357            num_non_var = len(non_var_len_arg_keys)
5358
5359            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5360            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5361        else:
5362            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5363
5364        return cls(**args_dict)
5365
5366    @classmethod
5367    def sql_names(cls):
5368        if cls is Func:
5369            raise NotImplementedError(
5370                "SQL name is only supported by concrete function implementations"
5371            )
5372        if "_sql_names" not in cls.__dict__:
5373            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5374        return cls._sql_names
5375
5376    @classmethod
5377    def sql_name(cls):
5378        return cls.sql_names()[0]
5379
5380    @classmethod
5381    def default_parser_mappings(cls):
5382        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):
5351    @classmethod
5352    def from_arg_list(cls, args):
5353        if cls.is_var_len_args:
5354            all_arg_keys = list(cls.arg_types)
5355            # If this function supports variable length argument treat the last argument as such.
5356            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5357            num_non_var = len(non_var_len_arg_keys)
5358
5359            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5360            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5361        else:
5362            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5363
5364        return cls(**args_dict)
@classmethod
def sql_names(cls):
5366    @classmethod
5367    def sql_names(cls):
5368        if cls is Func:
5369            raise NotImplementedError(
5370                "SQL name is only supported by concrete function implementations"
5371            )
5372        if "_sql_names" not in cls.__dict__:
5373            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5374        return cls._sql_names
@classmethod
def sql_name(cls):
5376    @classmethod
5377    def sql_name(cls):
5378        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5380    @classmethod
5381    def default_parser_mappings(cls):
5382        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5385class Typeof(Func):
5386    pass
key = 'typeof'
class AggFunc(Func):
5389class AggFunc(Func):
5390    pass
key = 'aggfunc'
class ArrayRemove(Func):
5393class ArrayRemove(Func):
5394    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5397class ParameterizedAgg(AggFunc):
5398    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5401class Abs(Func):
5402    pass
key = 'abs'
class ArgMax(AggFunc):
5405class ArgMax(AggFunc):
5406    arg_types = {"this": True, "expression": True, "count": False}
5407    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5410class ArgMin(AggFunc):
5411    arg_types = {"this": True, "expression": True, "count": False}
5412    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5415class ApproxTopK(AggFunc):
5416    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5419class Flatten(Func):
5420    pass
key = 'flatten'
class Transform(Func):
5424class Transform(Func):
5425    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5428class Anonymous(Func):
5429    arg_types = {"this": True, "expressions": False}
5430    is_var_len_args = True
5431
5432    @property
5433    def name(self) -> str:
5434        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
5432    @property
5433    def name(self) -> str:
5434        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5437class AnonymousAggFunc(AggFunc):
5438    arg_types = {"this": True, "expressions": False}
5439    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5443class CombinedAggFunc(AnonymousAggFunc):
5444    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5447class CombinedParameterizedAgg(ParameterizedAgg):
5448    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5453class Hll(AggFunc):
5454    arg_types = {"this": True, "expressions": False}
5455    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5458class ApproxDistinct(AggFunc):
5459    arg_types = {"this": True, "accuracy": False}
5460    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5463class Apply(Func):
5464    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5467class Array(Func):
5468    arg_types = {"expressions": False, "bracket_notation": False}
5469    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5473class ToArray(Func):
5474    pass
key = 'toarray'
class List(Func):
5478class List(Func):
5479    arg_types = {"expressions": False}
5480    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5484class Pad(Func):
5485    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):
5490class ToChar(Func):
5491    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5496class ToNumber(Func):
5497    arg_types = {
5498        "this": True,
5499        "format": False,
5500        "nlsparam": False,
5501        "precision": False,
5502        "scale": False,
5503    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5507class ToDouble(Func):
5508    arg_types = {
5509        "this": True,
5510        "format": False,
5511    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5514class Columns(Func):
5515    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5519class Convert(Func):
5520    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5524class ConvertToCharset(Func):
5525    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5528class ConvertTimezone(Func):
5529    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):
5532class GenerateSeries(Func):
5533    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):
5539class ExplodingGenerateSeries(GenerateSeries):
5540    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5543class ArrayAgg(AggFunc):
5544    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5547class ArrayUniqueAgg(AggFunc):
5548    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5551class ArrayAll(Func):
5552    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5556class ArrayAny(Func):
5557    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5560class ArrayConcat(Func):
5561    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5562    arg_types = {"this": True, "expressions": False}
5563    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5566class ArrayConcatAgg(AggFunc):
5567    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5570class ArrayConstructCompact(Func):
5571    arg_types = {"expressions": True}
5572    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5575class ArrayContains(Binary, Func):
5576    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5579class ArrayContainsAll(Binary, Func):
5580    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5583class ArrayFilter(Func):
5584    arg_types = {"this": True, "expression": True}
5585    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5588class ArrayFirst(Func):
5589    pass
key = 'arrayfirst'
class ArrayLast(Func):
5592class ArrayLast(Func):
5593    pass
key = 'arraylast'
class ArrayReverse(Func):
5596class ArrayReverse(Func):
5597    pass
key = 'arrayreverse'
class ArraySlice(Func):
5600class ArraySlice(Func):
5601    arg_types = {"this": True, "start": True, "end": False, "step": False}
arg_types = {'this': True, 'start': True, 'end': False, 'step': False}
key = 'arrayslice'
class ArrayToString(Func):
5604class ArrayToString(Func):
5605    arg_types = {"this": True, "expression": True, "null": False}
5606    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5609class ArrayIntersect(Func):
5610    arg_types = {"expressions": True}
5611    is_var_len_args = True
5612    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5615class StPoint(Func):
5616    arg_types = {"this": True, "expression": True, "null": False}
5617    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5620class StDistance(Func):
5621    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5625class String(Func):
5626    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5629class StringToArray(Func):
5630    arg_types = {"this": True, "expression": False, "null": False}
5631    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
arg_types = {'this': True, 'expression': False, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5634class ArrayOverlaps(Binary, Func):
5635    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5638class ArraySize(Func):
5639    arg_types = {"this": True, "expression": False}
5640    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5643class ArraySort(Func):
5644    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5647class ArraySum(Func):
5648    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5651class ArrayUnionAgg(AggFunc):
5652    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5655class Avg(AggFunc):
5656    pass
key = 'avg'
class AnyValue(AggFunc):
5659class AnyValue(AggFunc):
5660    pass
key = 'anyvalue'
class Lag(AggFunc):
5663class Lag(AggFunc):
5664    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5667class Lead(AggFunc):
5668    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5673class First(AggFunc):
5674    pass
key = 'first'
class Last(AggFunc):
5677class Last(AggFunc):
5678    pass
key = 'last'
class FirstValue(AggFunc):
5681class FirstValue(AggFunc):
5682    pass
key = 'firstvalue'
class LastValue(AggFunc):
5685class LastValue(AggFunc):
5686    pass
key = 'lastvalue'
class NthValue(AggFunc):
5689class NthValue(AggFunc):
5690    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5693class Case(Func):
5694    arg_types = {"this": False, "ifs": True, "default": False}
5695
5696    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5697        instance = maybe_copy(self, copy)
5698        instance.append(
5699            "ifs",
5700            If(
5701                this=maybe_parse(condition, copy=copy, **opts),
5702                true=maybe_parse(then, copy=copy, **opts),
5703            ),
5704        )
5705        return instance
5706
5707    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5708        instance = maybe_copy(self, copy)
5709        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5710        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:
5696    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5697        instance = maybe_copy(self, copy)
5698        instance.append(
5699            "ifs",
5700            If(
5701                this=maybe_parse(condition, copy=copy, **opts),
5702                true=maybe_parse(then, copy=copy, **opts),
5703            ),
5704        )
5705        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5707    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5708        instance = maybe_copy(self, copy)
5709        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5710        return instance
key = 'case'
class Cast(Func):
5713class Cast(Func):
5714    arg_types = {
5715        "this": True,
5716        "to": True,
5717        "format": False,
5718        "safe": False,
5719        "action": False,
5720        "default": False,
5721    }
5722
5723    @property
5724    def name(self) -> str:
5725        return self.this.name
5726
5727    @property
5728    def to(self) -> DataType:
5729        return self.args["to"]
5730
5731    @property
5732    def output_name(self) -> str:
5733        return self.name
5734
5735    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5736        """
5737        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5738        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5739        array<int> != array<float>.
5740
5741        Args:
5742            dtypes: the data types to compare this Cast's DataType to.
5743
5744        Returns:
5745            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5746        """
5747        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5723    @property
5724    def name(self) -> str:
5725        return self.this.name
to: DataType
5727    @property
5728    def to(self) -> DataType:
5729        return self.args["to"]
output_name: str
5731    @property
5732    def output_name(self) -> str:
5733        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, Identifier, Dot, DataType, DataType.Type]) -> bool:
5735    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5736        """
5737        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5738        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5739        array<int> != array<float>.
5740
5741        Args:
5742            dtypes: the data types to compare this Cast's DataType to.
5743
5744        Returns:
5745            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5746        """
5747        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):
5750class TryCast(Cast):
5751    pass
key = 'trycast'
class JSONCast(Cast):
5755class JSONCast(Cast):
5756    pass
key = 'jsoncast'
class Try(Func):
5759class Try(Func):
5760    pass
key = 'try'
class CastToStrType(Func):
5763class CastToStrType(Func):
5764    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5768class TranslateCharacters(Expression):
5769    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5772class Collate(Binary, Func):
5773    pass
key = 'collate'
class Ceil(Func):
5776class Ceil(Func):
5777    arg_types = {"this": True, "decimals": False, "to": False}
5778    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5781class Coalesce(Func):
5782    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5783    is_var_len_args = True
5784    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False, 'is_null': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5787class Chr(Func):
5788    arg_types = {"expressions": True, "charset": False}
5789    is_var_len_args = True
5790    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5793class Concat(Func):
5794    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5795    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5798class ConcatWs(Concat):
5799    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5802class Contains(Func):
5803    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5807class ConnectByRoot(Func):
5808    pass
key = 'connectbyroot'
class Count(AggFunc):
5811class Count(AggFunc):
5812    arg_types = {"this": False, "expressions": False, "big_int": False}
5813    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5816class CountIf(AggFunc):
5817    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5821class Cbrt(Func):
5822    pass
key = 'cbrt'
class CurrentDate(Func):
5825class CurrentDate(Func):
5826    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5829class CurrentDatetime(Func):
5830    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5833class CurrentTime(Func):
5834    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5837class CurrentTimestamp(Func):
5838    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
5841class CurrentTimestampLTZ(Func):
5842    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
5845class CurrentSchema(Func):
5846    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5849class CurrentUser(Func):
5850    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5853class DateAdd(Func, IntervalOp):
5854    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5857class DateBin(Func, IntervalOp):
5858    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
5861class DateSub(Func, IntervalOp):
5862    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5865class DateDiff(Func, TimeUnit):
5866    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5867    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datediff'
class DateTrunc(Func):
5870class DateTrunc(Func):
5871    arg_types = {"unit": True, "this": True, "zone": False}
5872
5873    def __init__(self, **args):
5874        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5875        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5876        unabbreviate = args.pop("unabbreviate", True)
5877
5878        unit = args.get("unit")
5879        if isinstance(unit, TimeUnit.VAR_LIKE):
5880            unit_name = unit.name.upper()
5881            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5882                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5883
5884            args["unit"] = Literal.string(unit_name)
5885
5886        super().__init__(**args)
5887
5888    @property
5889    def unit(self) -> Expression:
5890        return self.args["unit"]
DateTrunc(**args)
5873    def __init__(self, **args):
5874        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5875        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5876        unabbreviate = args.pop("unabbreviate", True)
5877
5878        unit = args.get("unit")
5879        if isinstance(unit, TimeUnit.VAR_LIKE):
5880            unit_name = unit.name.upper()
5881            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5882                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5883
5884            args["unit"] = Literal.string(unit_name)
5885
5886        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5888    @property
5889    def unit(self) -> Expression:
5890        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5895class Datetime(Func):
5896    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5899class DatetimeAdd(Func, IntervalOp):
5900    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5903class DatetimeSub(Func, IntervalOp):
5904    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5907class DatetimeDiff(Func, TimeUnit):
5908    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5911class DatetimeTrunc(Func, TimeUnit):
5912    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5915class DayOfWeek(Func):
5916    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5921class DayOfWeekIso(Func):
5922    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5925class DayOfMonth(Func):
5926    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5929class DayOfYear(Func):
5930    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5933class ToDays(Func):
5934    pass
key = 'todays'
class WeekOfYear(Func):
5937class WeekOfYear(Func):
5938    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5941class MonthsBetween(Func):
5942    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5945class MakeInterval(Func):
5946    arg_types = {
5947        "year": False,
5948        "month": False,
5949        "day": False,
5950        "hour": False,
5951        "minute": False,
5952        "second": False,
5953    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5956class LastDay(Func, TimeUnit):
5957    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5958    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5961class Extract(Func):
5962    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5965class Exists(Func, SubqueryPredicate):
5966    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5969class Timestamp(Func):
5970    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5973class TimestampAdd(Func, TimeUnit):
5974    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5977class TimestampSub(Func, TimeUnit):
5978    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5981class TimestampDiff(Func, TimeUnit):
5982    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5983    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5986class TimestampTrunc(Func, TimeUnit):
5987    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5990class TimeAdd(Func, TimeUnit):
5991    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5994class TimeSub(Func, TimeUnit):
5995    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5998class TimeDiff(Func, TimeUnit):
5999    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6002class TimeTrunc(Func, TimeUnit):
6003    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6006class DateFromParts(Func):
6007    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6008    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6011class TimeFromParts(Func):
6012    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6013    arg_types = {
6014        "hour": True,
6015        "min": True,
6016        "sec": True,
6017        "nano": False,
6018        "fractions": False,
6019        "precision": False,
6020    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6023class DateStrToDate(Func):
6024    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6027class DateToDateStr(Func):
6028    pass
key = 'datetodatestr'
class DateToDi(Func):
6031class DateToDi(Func):
6032    pass
key = 'datetodi'
class Date(Func):
6036class Date(Func):
6037    arg_types = {"this": False, "zone": False, "expressions": False}
6038    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6041class Day(Func):
6042    pass
key = 'day'
class Decode(Func):
6045class Decode(Func):
6046    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6049class DecodeCase(Func):
6050    _sql_names: t.List[str] = []
6051    arg_types = {"expressions": True}
6052    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DiToDate(Func):
6055class DiToDate(Func):
6056    pass
key = 'ditodate'
class Encode(Func):
6059class Encode(Func):
6060    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6063class Exp(Func):
6064    pass
key = 'exp'
class Explode(Func, UDTF):
6068class Explode(Func, UDTF):
6069    arg_types = {"this": True, "expressions": False}
6070    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6074class Inline(Func):
6075    pass
key = 'inline'
class ExplodeOuter(Explode):
6078class ExplodeOuter(Explode):
6079    pass
key = 'explodeouter'
class Posexplode(Explode):
6082class Posexplode(Explode):
6083    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6086class PosexplodeOuter(Posexplode, ExplodeOuter):
6087    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
6090class Unnest(Func, UDTF):
6091    arg_types = {
6092        "expressions": True,
6093        "alias": False,
6094        "offset": False,
6095        "explode_array": False,
6096    }
6097
6098    @property
6099    def selects(self) -> t.List[Expression]:
6100        columns = super().selects
6101        offset = self.args.get("offset")
6102        if offset:
6103            columns = columns + [to_identifier("offset") if offset is True else offset]
6104        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6098    @property
6099    def selects(self) -> t.List[Expression]:
6100        columns = super().selects
6101        offset = self.args.get("offset")
6102        if offset:
6103            columns = columns + [to_identifier("offset") if offset is True else offset]
6104        return columns
key = 'unnest'
class Floor(Func):
6107class Floor(Func):
6108    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6111class FromBase64(Func):
6112    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6115class FeaturesAtTime(Func):
6116    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):
6119class ToBase64(Func):
6120    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6124class FromISO8601Timestamp(Func):
6125    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6128class GapFill(Func):
6129    arg_types = {
6130        "this": True,
6131        "ts_column": True,
6132        "bucket_width": True,
6133        "partitioning_columns": False,
6134        "value_columns": False,
6135        "origin": False,
6136        "ignore_nulls": False,
6137    }
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):
6141class GenerateDateArray(Func):
6142    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6146class GenerateTimestampArray(Func):
6147    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6150class Greatest(Func):
6151    arg_types = {"this": True, "expressions": False}
6152    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6157class OverflowTruncateBehavior(Expression):
6158    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6161class GroupConcat(AggFunc):
6162    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6165class Hex(Func):
6166    pass
key = 'hex'
class LowerHex(Hex):
6169class LowerHex(Hex):
6170    pass
key = 'lowerhex'
class And(Connector, Func):
6173class And(Connector, Func):
6174    pass
key = 'and'
class Or(Connector, Func):
6177class Or(Connector, Func):
6178    pass
key = 'or'
class Xor(Connector, Func):
6181class Xor(Connector, Func):
6182    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6185class If(Func):
6186    arg_types = {"this": True, "true": True, "false": False}
6187    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6190class Nullif(Func):
6191    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6194class Initcap(Func):
6195    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6198class IsAscii(Func):
6199    pass
key = 'isascii'
class IsNan(Func):
6202class IsNan(Func):
6203    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6207class Int64(Func):
6208    pass
key = 'int64'
class IsInf(Func):
6211class IsInf(Func):
6212    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6216class JSON(Expression):
6217    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6220class JSONPath(Expression):
6221    arg_types = {"expressions": True, "escape": False}
6222
6223    @property
6224    def output_name(self) -> str:
6225        last_segment = self.expressions[-1].this
6226        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6223    @property
6224    def output_name(self) -> str:
6225        last_segment = self.expressions[-1].this
6226        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):
6229class JSONPathPart(Expression):
6230    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6233class JSONPathFilter(JSONPathPart):
6234    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6237class JSONPathKey(JSONPathPart):
6238    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6241class JSONPathRecursive(JSONPathPart):
6242    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6245class JSONPathRoot(JSONPathPart):
6246    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6249class JSONPathScript(JSONPathPart):
6250    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6253class JSONPathSlice(JSONPathPart):
6254    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6257class JSONPathSelector(JSONPathPart):
6258    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6261class JSONPathSubscript(JSONPathPart):
6262    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6265class JSONPathUnion(JSONPathPart):
6266    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6269class JSONPathWildcard(JSONPathPart):
6270    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6273class FormatJson(Expression):
6274    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6277class JSONKeyValue(Expression):
6278    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6281class JSONObject(Func):
6282    arg_types = {
6283        "expressions": False,
6284        "null_handling": False,
6285        "unique_keys": False,
6286        "return_type": False,
6287        "encoding": False,
6288    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6291class JSONObjectAgg(AggFunc):
6292    arg_types = {
6293        "expressions": False,
6294        "null_handling": False,
6295        "unique_keys": False,
6296        "return_type": False,
6297        "encoding": False,
6298    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6302class JSONBObjectAgg(AggFunc):
6303    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6307class JSONArray(Func):
6308    arg_types = {
6309        "expressions": True,
6310        "null_handling": False,
6311        "return_type": False,
6312        "strict": False,
6313    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6317class JSONArrayAgg(Func):
6318    arg_types = {
6319        "this": True,
6320        "order": False,
6321        "null_handling": False,
6322        "return_type": False,
6323        "strict": False,
6324    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6327class JSONExists(Func):
6328    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):
6333class JSONColumnDef(Expression):
6334    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):
6337class JSONSchema(Expression):
6338    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6342class JSONValue(Expression):
6343    arg_types = {
6344        "this": True,
6345        "path": True,
6346        "returning": False,
6347        "on_condition": False,
6348    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6351class JSONValueArray(Func):
6352    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6356class JSONTable(Func):
6357    arg_types = {
6358        "this": True,
6359        "schema": True,
6360        "path": False,
6361        "error_handling": False,
6362        "empty_handling": False,
6363    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6367class ObjectInsert(Func):
6368    arg_types = {
6369        "this": True,
6370        "key": True,
6371        "value": True,
6372        "update_flag": False,
6373    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6376class OpenJSONColumnDef(Expression):
6377    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):
6380class OpenJSON(Func):
6381    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6384class JSONBContains(Binary, Func):
6385    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6388class JSONBExists(Func):
6389    arg_types = {"this": True, "path": True}
6390    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6393class JSONExtract(Binary, Func):
6394    arg_types = {
6395        "this": True,
6396        "expression": True,
6397        "only_json_types": False,
6398        "expressions": False,
6399        "variant_extract": False,
6400        "json_query": False,
6401        "option": False,
6402        "quote": False,
6403        "on_condition": False,
6404    }
6405    _sql_names = ["JSON_EXTRACT"]
6406    is_var_len_args = True
6407
6408    @property
6409    def output_name(self) -> str:
6410        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False, 'json_query': False, 'option': False, 'quote': False, 'on_condition': False}
is_var_len_args = True
output_name: str
6408    @property
6409    def output_name(self) -> str:
6410        return self.expression.output_name if not self.expressions else ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextract'
class JSONExtractQuote(Expression):
6414class JSONExtractQuote(Expression):
6415    arg_types = {
6416        "option": True,
6417        "scalar": False,
6418    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6421class JSONExtractArray(Func):
6422    arg_types = {"this": True, "expression": False}
6423    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6426class JSONExtractScalar(Binary, Func):
6427    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6428    _sql_names = ["JSON_EXTRACT_SCALAR"]
6429    is_var_len_args = True
6430
6431    @property
6432    def output_name(self) -> str:
6433        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
6431    @property
6432    def output_name(self) -> str:
6433        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):
6436class JSONBExtract(Binary, Func):
6437    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6440class JSONBExtractScalar(Binary, Func):
6441    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6444class JSONFormat(Func):
6445    arg_types = {"this": False, "options": False, "is_json": False}
6446    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6450class JSONArrayContains(Binary, Predicate, Func):
6451    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6454class ParseJSON(Func):
6455    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6456    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6457    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6458    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6461class Least(Func):
6462    arg_types = {"this": True, "expressions": False}
6463    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6466class Left(Func):
6467    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6474class Length(Func):
6475    arg_types = {"this": True, "binary": False, "encoding": False}
6476    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6479class Levenshtein(Func):
6480    arg_types = {
6481        "this": True,
6482        "expression": False,
6483        "ins_cost": False,
6484        "del_cost": False,
6485        "sub_cost": False,
6486        "max_dist": False,
6487    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6490class Ln(Func):
6491    pass
key = 'ln'
class Log(Func):
6494class Log(Func):
6495    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6498class LogicalOr(AggFunc):
6499    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6502class LogicalAnd(AggFunc):
6503    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6506class Lower(Func):
6507    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6510class Map(Func):
6511    arg_types = {"keys": False, "values": False}
6512
6513    @property
6514    def keys(self) -> t.List[Expression]:
6515        keys = self.args.get("keys")
6516        return keys.expressions if keys else []
6517
6518    @property
6519    def values(self) -> t.List[Expression]:
6520        values = self.args.get("values")
6521        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6513    @property
6514    def keys(self) -> t.List[Expression]:
6515        keys = self.args.get("keys")
6516        return keys.expressions if keys else []
values: List[Expression]
6518    @property
6519    def values(self) -> t.List[Expression]:
6520        values = self.args.get("values")
6521        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6525class ToMap(Func):
6526    pass
key = 'tomap'
class MapFromEntries(Func):
6529class MapFromEntries(Func):
6530    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6534class ScopeResolution(Expression):
6535    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6538class Stream(Expression):
6539    pass
key = 'stream'
class StarMap(Func):
6542class StarMap(Func):
6543    pass
key = 'starmap'
class VarMap(Func):
6546class VarMap(Func):
6547    arg_types = {"keys": True, "values": True}
6548    is_var_len_args = True
6549
6550    @property
6551    def keys(self) -> t.List[Expression]:
6552        return self.args["keys"].expressions
6553
6554    @property
6555    def values(self) -> t.List[Expression]:
6556        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6550    @property
6551    def keys(self) -> t.List[Expression]:
6552        return self.args["keys"].expressions
values: List[Expression]
6554    @property
6555    def values(self) -> t.List[Expression]:
6556        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6560class MatchAgainst(Func):
6561    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6564class Max(AggFunc):
6565    arg_types = {"this": True, "expressions": False}
6566    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6569class MD5(Func):
6570    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6574class MD5Digest(Func):
6575    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6578class Median(AggFunc):
6579    pass
key = 'median'
class Min(AggFunc):
6582class Min(AggFunc):
6583    arg_types = {"this": True, "expressions": False}
6584    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6587class Month(Func):
6588    pass
key = 'month'
class AddMonths(Func):
6591class AddMonths(Func):
6592    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6595class Nvl2(Func):
6596    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6599class Normalize(Func):
6600    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6603class Overlay(Func):
6604    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):
6608class Predict(Func):
6609    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6612class Pow(Binary, Func):
6613    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6616class PercentileCont(AggFunc):
6617    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6620class PercentileDisc(AggFunc):
6621    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6624class Quantile(AggFunc):
6625    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6628class ApproxQuantile(Quantile):
6629    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):
6632class Quarter(Func):
6633    pass
key = 'quarter'
class Rand(Func):
6638class Rand(Func):
6639    _sql_names = ["RAND", "RANDOM"]
6640    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6643class Randn(Func):
6644    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6647class RangeN(Func):
6648    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6651class ReadCSV(Func):
6652    _sql_names = ["READ_CSV"]
6653    is_var_len_args = True
6654    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6657class Reduce(Func):
6658    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):
6661class RegexpExtract(Func):
6662    arg_types = {
6663        "this": True,
6664        "expression": True,
6665        "position": False,
6666        "occurrence": False,
6667        "parameters": False,
6668        "group": False,
6669    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6672class RegexpExtractAll(Func):
6673    arg_types = {
6674        "this": True,
6675        "expression": True,
6676        "position": False,
6677        "occurrence": False,
6678        "parameters": False,
6679        "group": False,
6680    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6683class RegexpReplace(Func):
6684    arg_types = {
6685        "this": True,
6686        "expression": True,
6687        "replacement": False,
6688        "position": False,
6689        "occurrence": False,
6690        "modifiers": False,
6691    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6694class RegexpLike(Binary, Func):
6695    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6698class RegexpILike(Binary, Func):
6699    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6704class RegexpSplit(Func):
6705    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6708class Repeat(Func):
6709    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
6713class Replace(Func):
6714    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
6719class Round(Func):
6720    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6723class RowNumber(Func):
6724    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6727class SafeDivide(Func):
6728    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6731class SHA(Func):
6732    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6735class SHA2(Func):
6736    _sql_names = ["SHA2"]
6737    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6740class Sign(Func):
6741    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6744class SortArray(Func):
6745    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6748class Split(Func):
6749    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6753class SplitPart(Func):
6754    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6759class Substring(Func):
6760    _sql_names = ["SUBSTRING", "SUBSTR"]
6761    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
6764class SubstringIndex(Func):
6765    """
6766    SUBSTRING_INDEX(str, delim, count)
6767
6768    *count* > 0  → left slice before the *count*-th delimiter
6769    *count* < 0  → right slice after the |count|-th delimiter
6770    """
6771
6772    arg_types = {"this": True, "delimiter": True, "count": True}

SUBSTRING_INDEX(str, delim, count)

count > 0 → left slice before the count-th delimiter count < 0 → right slice after the |count|-th delimiter

arg_types = {'this': True, 'delimiter': True, 'count': True}
key = 'substringindex'
class StandardHash(Func):
6775class StandardHash(Func):
6776    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6779class StartsWith(Func):
6780    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6781    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
6784class EndsWith(Func):
6785    _sql_names = ["ENDS_WITH", "ENDSWITH"]
6786    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
6789class StrPosition(Func):
6790    arg_types = {
6791        "this": True,
6792        "substr": True,
6793        "position": False,
6794        "occurrence": False,
6795    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6798class StrToDate(Func):
6799    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6802class StrToTime(Func):
6803    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):
6808class StrToUnix(Func):
6809    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6814class StrToMap(Func):
6815    arg_types = {
6816        "this": True,
6817        "pair_delim": False,
6818        "key_value_delim": False,
6819        "duplicate_resolution_callback": False,
6820    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6823class NumberToStr(Func):
6824    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6827class FromBase(Func):
6828    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
6831class Space(Func):
6832    """
6833    SPACE(n) → string consisting of n blank characters
6834    """
6835
6836    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
6839class Struct(Func):
6840    arg_types = {"expressions": False}
6841    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6844class StructExtract(Func):
6845    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6850class Stuff(Func):
6851    _sql_names = ["STUFF", "INSERT"]
6852    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):
6855class Sum(AggFunc):
6856    pass
key = 'sum'
class Sqrt(Func):
6859class Sqrt(Func):
6860    pass
key = 'sqrt'
class Stddev(AggFunc):
6863class Stddev(AggFunc):
6864    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6867class StddevPop(AggFunc):
6868    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6871class StddevSamp(AggFunc):
6872    pass
key = 'stddevsamp'
class Time(Func):
6876class Time(Func):
6877    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6880class TimeToStr(Func):
6881    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):
6884class TimeToTimeStr(Func):
6885    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6888class TimeToUnix(Func):
6889    pass
key = 'timetounix'
class TimeStrToDate(Func):
6892class TimeStrToDate(Func):
6893    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6896class TimeStrToTime(Func):
6897    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6900class TimeStrToUnix(Func):
6901    pass
key = 'timestrtounix'
class Trim(Func):
6904class Trim(Func):
6905    arg_types = {
6906        "this": True,
6907        "expression": False,
6908        "position": False,
6909        "collation": False,
6910    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6913class TsOrDsAdd(Func, TimeUnit):
6914    # return_type is used to correctly cast the arguments of this expression when transpiling it
6915    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6916
6917    @property
6918    def return_type(self) -> DataType:
6919        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
6917    @property
6918    def return_type(self) -> DataType:
6919        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6922class TsOrDsDiff(Func, TimeUnit):
6923    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6926class TsOrDsToDateStr(Func):
6927    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6930class TsOrDsToDate(Func):
6931    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6934class TsOrDsToDatetime(Func):
6935    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6938class TsOrDsToTime(Func):
6939    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6942class TsOrDsToTimestamp(Func):
6943    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6946class TsOrDiToDi(Func):
6947    pass
key = 'tsorditodi'
class Unhex(Func):
6950class Unhex(Func):
6951    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6954class Unicode(Func):
6955    pass
key = 'unicode'
class UnixDate(Func):
6959class UnixDate(Func):
6960    pass
key = 'unixdate'
class UnixToStr(Func):
6963class UnixToStr(Func):
6964    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6969class UnixToTime(Func):
6970    arg_types = {
6971        "this": True,
6972        "scale": False,
6973        "zone": False,
6974        "hours": False,
6975        "minutes": False,
6976        "format": False,
6977    }
6978
6979    SECONDS = Literal.number(0)
6980    DECIS = Literal.number(1)
6981    CENTIS = Literal.number(2)
6982    MILLIS = Literal.number(3)
6983    DECIMILLIS = Literal.number(4)
6984    CENTIMILLIS = Literal.number(5)
6985    MICROS = Literal.number(6)
6986    DECIMICROS = Literal.number(7)
6987    CENTIMICROS = Literal.number(8)
6988    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):
6991class UnixToTimeStr(Func):
6992    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6995class UnixSeconds(Func):
6996    pass
key = 'unixseconds'
class Uuid(Func):
6999class Uuid(Func):
7000    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7001
7002    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7005class TimestampFromParts(Func):
7006    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7007    arg_types = {
7008        "year": True,
7009        "month": True,
7010        "day": True,
7011        "hour": True,
7012        "min": True,
7013        "sec": True,
7014        "nano": False,
7015        "zone": False,
7016        "milli": False,
7017    }
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):
7020class Upper(Func):
7021    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7024class Corr(Binary, AggFunc):
7025    pass
key = 'corr'
class Variance(AggFunc):
7028class Variance(AggFunc):
7029    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7032class VariancePop(AggFunc):
7033    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7036class CovarSamp(Binary, AggFunc):
7037    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7040class CovarPop(Binary, AggFunc):
7041    pass
key = 'covarpop'
class Week(Func):
7044class Week(Func):
7045    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
7048class XMLElement(Func):
7049    _sql_names = ["XMLELEMENT"]
7050    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7053class XMLTable(Func):
7054    arg_types = {
7055        "this": True,
7056        "namespaces": False,
7057        "passing": False,
7058        "columns": False,
7059        "by_ref": False,
7060    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7063class XMLNamespace(Expression):
7064    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7068class XMLKeyValueOption(Expression):
7069    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7072class Year(Func):
7073    pass
key = 'year'
class Use(Expression):
7076class Use(Expression):
7077    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7080class Merge(DML):
7081    arg_types = {
7082        "this": True,
7083        "using": True,
7084        "on": True,
7085        "whens": True,
7086        "with": False,
7087        "returning": False,
7088    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7091class When(Expression):
7092    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):
7095class Whens(Expression):
7096    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7097
7098    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7103class NextValueFor(Func):
7104    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7109class Semicolon(Expression):
7110    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7115class TableColumn(Expression):
7116    pass
key = 'tablecolumn'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConcatAgg'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayFirst'>, <class 'ArrayIntersect'>, <class 'ArrayLast'>, <class 'ArrayOverlaps'>, <class 'ArrayRemove'>, <class 'ArrayReverse'>, <class 'ArraySize'>, <class 'ArraySlice'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentTimestampLTZ'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DecodeCase'>, <class 'DiToDate'>, <class 'Encode'>, <class 'EndsWith'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Replace'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Space'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StDistance'>, <class 'StPoint'>, <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 'SubstringIndex'>, <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 'Typeof'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONCAT_AGG': <class 'ArrayConcatAgg'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_FIRST': <class 'ArrayFirst'>, 'ARRAY_INTERSECT': <class 'ArrayIntersect'>, 'ARRAY_INTERSECTION': <class 'ArrayIntersect'>, 'ARRAY_LAST': <class 'ArrayLast'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_REMOVE': <class 'ArrayRemove'>, 'ARRAY_REVERSE': <class 'ArrayReverse'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SLICE': <class 'ArraySlice'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CONVERT_TO_CHARSET': <class 'ConvertToCharset'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_TIMESTAMP_L_T_Z': <class 'CurrentTimestampLTZ'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'ENDS_WITH': <class 'EndsWith'>, 'ENDSWITH': <class 'EndsWith'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_ASCII': <class 'IsAscii'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'CHAR_LENGTH': <class 'Length'>, 'CHARACTER_LENGTH': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OR': <class 'Or'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'REPLACE': <class 'Replace'>, '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'>, 'SPACE': <class 'Space'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'ST_DISTANCE': <class 'StDistance'>, 'ST_POINT': <class 'StPoint'>, 'ST_MAKEPOINT': <class 'StPoint'>, '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'>, 'STRTOK_TO_ARRAY': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUBSTRING_INDEX': <class 'SubstringIndex'>, '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'>, 'TYPEOF': <class 'Typeof'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_SECONDS': <class 'UnixSeconds'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'UUID': <class 'Uuid'>, 'GEN_RANDOM_UUID': <class 'Uuid'>, 'GENERATE_UUID': <class 'Uuid'>, 'UUID_STRING': <class 'Uuid'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'XMLELEMENT': <class 'XMLElement'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
7156def maybe_parse(
7157    sql_or_expression: ExpOrStr,
7158    *,
7159    into: t.Optional[IntoType] = None,
7160    dialect: DialectType = None,
7161    prefix: t.Optional[str] = None,
7162    copy: bool = False,
7163    **opts,
7164) -> Expression:
7165    """Gracefully handle a possible string or expression.
7166
7167    Example:
7168        >>> maybe_parse("1")
7169        Literal(this=1, is_string=False)
7170        >>> maybe_parse(to_identifier("x"))
7171        Identifier(this=x, quoted=False)
7172
7173    Args:
7174        sql_or_expression: the SQL code string or an expression
7175        into: the SQLGlot Expression to parse into
7176        dialect: the dialect used to parse the input expressions (in the case that an
7177            input expression is a SQL string).
7178        prefix: a string to prefix the sql with before it gets parsed
7179            (automatically includes a space)
7180        copy: whether to copy the expression.
7181        **opts: other options to use to parse the input expressions (again, in the case
7182            that an input expression is a SQL string).
7183
7184    Returns:
7185        Expression: the parsed or given expression.
7186    """
7187    if isinstance(sql_or_expression, Expression):
7188        if copy:
7189            return sql_or_expression.copy()
7190        return sql_or_expression
7191
7192    if sql_or_expression is None:
7193        raise ParseError("SQL cannot be None")
7194
7195    import sqlglot
7196
7197    sql = str(sql_or_expression)
7198    if prefix:
7199        sql = f"{prefix} {sql}"
7200
7201    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):
7212def maybe_copy(instance, copy=True):
7213    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7468def union(
7469    *expressions: ExpOrStr,
7470    distinct: bool = True,
7471    dialect: DialectType = None,
7472    copy: bool = True,
7473    **opts,
7474) -> Union:
7475    """
7476    Initializes a syntax tree for the `UNION` operation.
7477
7478    Example:
7479        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7480        'SELECT * FROM foo UNION SELECT * FROM bla'
7481
7482    Args:
7483        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7484            If `Expression` instances are passed, they will be used as-is.
7485        distinct: set the DISTINCT flag if and only if this is true.
7486        dialect: the dialect used to parse the input expression.
7487        copy: whether to copy the expression.
7488        opts: other options to use to parse the input expressions.
7489
7490    Returns:
7491        The new Union instance.
7492    """
7493    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7494    return _apply_set_operation(
7495        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7496    )

Initializes a syntax tree for the UNION operation.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the UNION's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7499def intersect(
7500    *expressions: ExpOrStr,
7501    distinct: bool = True,
7502    dialect: DialectType = None,
7503    copy: bool = True,
7504    **opts,
7505) -> Intersect:
7506    """
7507    Initializes a syntax tree for the `INTERSECT` operation.
7508
7509    Example:
7510        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7511        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7512
7513    Args:
7514        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7515            If `Expression` instances are passed, they will be used as-is.
7516        distinct: set the DISTINCT flag if and only if this is true.
7517        dialect: the dialect used to parse the input expression.
7518        copy: whether to copy the expression.
7519        opts: other options to use to parse the input expressions.
7520
7521    Returns:
7522        The new Intersect instance.
7523    """
7524    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7525    return _apply_set_operation(
7526        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7527    )

Initializes a syntax tree for the INTERSECT operation.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the INTERSECT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7530def except_(
7531    *expressions: ExpOrStr,
7532    distinct: bool = True,
7533    dialect: DialectType = None,
7534    copy: bool = True,
7535    **opts,
7536) -> Except:
7537    """
7538    Initializes a syntax tree for the `EXCEPT` operation.
7539
7540    Example:
7541        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7542        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7543
7544    Args:
7545        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7546            If `Expression` instances are passed, they will be used as-is.
7547        distinct: set the DISTINCT flag if and only if this is true.
7548        dialect: the dialect used to parse the input expression.
7549        copy: whether to copy the expression.
7550        opts: other options to use to parse the input expressions.
7551
7552    Returns:
7553        The new Except instance.
7554    """
7555    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7556    return _apply_set_operation(
7557        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7558    )

Initializes a syntax tree for the EXCEPT operation.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the EXCEPT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7561def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7562    """
7563    Initializes a syntax tree from one or multiple SELECT expressions.
7564
7565    Example:
7566        >>> select("col1", "col2").from_("tbl").sql()
7567        'SELECT col1, col2 FROM tbl'
7568
7569    Args:
7570        *expressions: the SQL code string to parse as the expressions of a
7571            SELECT statement. If an Expression instance is passed, this is used as-is.
7572        dialect: the dialect used to parse the input expressions (in the case that an
7573            input expression is a SQL string).
7574        **opts: other options to use to parse the input expressions (again, in the case
7575            that an input expression is a SQL string).
7576
7577    Returns:
7578        Select: the syntax tree for the SELECT statement.
7579    """
7580    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

Example:
>>> select("col1", "col2").from_("tbl").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expressions: the SQL code string to parse as the expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7583def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7584    """
7585    Initializes a syntax tree from a FROM expression.
7586
7587    Example:
7588        >>> from_("tbl").select("col1", "col2").sql()
7589        'SELECT col1, col2 FROM tbl'
7590
7591    Args:
7592        *expression: the SQL code string to parse as the FROM expressions of a
7593            SELECT statement. If an Expression instance is passed, this is used as-is.
7594        dialect: the dialect used to parse the input expression (in the case that the
7595            input expression is a SQL string).
7596        **opts: other options to use to parse the input expressions (again, in the case
7597            that the input expression is a SQL string).
7598
7599    Returns:
7600        Select: the syntax tree for the SELECT statement.
7601    """
7602    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

Example:
>>> from_("tbl").select("col1", "col2").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expression: the SQL code string to parse as the FROM expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Update:
7605def update(
7606    table: str | Table,
7607    properties: t.Optional[dict] = None,
7608    where: t.Optional[ExpOrStr] = None,
7609    from_: t.Optional[ExpOrStr] = None,
7610    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7611    dialect: DialectType = None,
7612    **opts,
7613) -> Update:
7614    """
7615    Creates an update statement.
7616
7617    Example:
7618        >>> 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()
7619        "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"
7620
7621    Args:
7622        properties: dictionary of properties to SET which are
7623            auto converted to sql objects eg None -> NULL
7624        where: sql conditional parsed into a WHERE statement
7625        from_: sql statement parsed into a FROM statement
7626        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7627        dialect: the dialect used to parse the input expressions.
7628        **opts: other options to use to parse the input expressions.
7629
7630    Returns:
7631        Update: the syntax tree for the UPDATE statement.
7632    """
7633    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7634    if properties:
7635        update_expr.set(
7636            "expressions",
7637            [
7638                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7639                for k, v in properties.items()
7640            ],
7641        )
7642    if from_:
7643        update_expr.set(
7644            "from",
7645            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7646        )
7647    if isinstance(where, Condition):
7648        where = Where(this=where)
7649    if where:
7650        update_expr.set(
7651            "where",
7652            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7653        )
7654    if with_:
7655        cte_list = [
7656            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7657            for alias, qry in with_.items()
7658        ]
7659        update_expr.set(
7660            "with",
7661            With(expressions=cte_list),
7662        )
7663    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
"WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
Arguments:
  • properties: dictionary of properties to SET which are auto converted to sql objects eg None -> NULL
  • where: sql conditional parsed into a WHERE statement
  • from_: sql statement parsed into a FROM statement
  • with_: dictionary of CTE aliases / select statements to include in a WITH clause.
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Delete:
7666def delete(
7667    table: ExpOrStr,
7668    where: t.Optional[ExpOrStr] = None,
7669    returning: t.Optional[ExpOrStr] = None,
7670    dialect: DialectType = None,
7671    **opts,
7672) -> Delete:
7673    """
7674    Builds a delete statement.
7675
7676    Example:
7677        >>> delete("my_table", where="id > 1").sql()
7678        'DELETE FROM my_table WHERE id > 1'
7679
7680    Args:
7681        where: sql conditional parsed into a WHERE statement
7682        returning: sql conditional parsed into a RETURNING statement
7683        dialect: the dialect used to parse the input expressions.
7684        **opts: other options to use to parse the input expressions.
7685
7686    Returns:
7687        Delete: the syntax tree for the DELETE statement.
7688    """
7689    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7690    if where:
7691        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7692    if returning:
7693        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7694    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7697def insert(
7698    expression: ExpOrStr,
7699    into: ExpOrStr,
7700    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7701    overwrite: t.Optional[bool] = None,
7702    returning: t.Optional[ExpOrStr] = None,
7703    dialect: DialectType = None,
7704    copy: bool = True,
7705    **opts,
7706) -> Insert:
7707    """
7708    Builds an INSERT statement.
7709
7710    Example:
7711        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7712        'INSERT INTO tbl VALUES (1, 2, 3)'
7713
7714    Args:
7715        expression: the sql string or expression of the INSERT statement
7716        into: the tbl to insert data to.
7717        columns: optionally the table's column names.
7718        overwrite: whether to INSERT OVERWRITE or not.
7719        returning: sql conditional parsed into a RETURNING statement
7720        dialect: the dialect used to parse the input expressions.
7721        copy: whether to copy the expression.
7722        **opts: other options to use to parse the input expressions.
7723
7724    Returns:
7725        Insert: the syntax tree for the INSERT statement.
7726    """
7727    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7728    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7729
7730    if columns:
7731        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7732
7733    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7734
7735    if returning:
7736        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7737
7738    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7741def merge(
7742    *when_exprs: ExpOrStr,
7743    into: ExpOrStr,
7744    using: ExpOrStr,
7745    on: ExpOrStr,
7746    returning: t.Optional[ExpOrStr] = None,
7747    dialect: DialectType = None,
7748    copy: bool = True,
7749    **opts,
7750) -> Merge:
7751    """
7752    Builds a MERGE statement.
7753
7754    Example:
7755        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7756        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7757        ...       into="my_table",
7758        ...       using="source_table",
7759        ...       on="my_table.id = source_table.id").sql()
7760        '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)'
7761
7762    Args:
7763        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7764        into: The target table to merge data into.
7765        using: The source table to merge data from.
7766        on: The join condition for the merge.
7767        returning: The columns to return from the merge.
7768        dialect: The dialect used to parse the input expressions.
7769        copy: Whether to copy the expression.
7770        **opts: Other options to use to parse the input expressions.
7771
7772    Returns:
7773        Merge: The syntax tree for the MERGE statement.
7774    """
7775    expressions: t.List[Expression] = []
7776    for when_expr in when_exprs:
7777        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7778        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7779
7780    merge = Merge(
7781        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7782        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7783        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7784        whens=Whens(expressions=expressions),
7785    )
7786    if returning:
7787        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7788
7789    return merge

Builds a MERGE statement.

Example:
>>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
...       into="my_table",
...       using="source_table",
...       on="my_table.id = source_table.id").sql()
'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
Arguments:
  • *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
  • into: The target table to merge data into.
  • using: The source table to merge data from.
  • on: The join condition for the merge.
  • returning: The columns to return from the merge.
  • dialect: The dialect used to parse the input expressions.
  • copy: Whether to copy the expression.
  • **opts: Other options to use to parse the input expressions.
Returns:

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7792def condition(
7793    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7794) -> Condition:
7795    """
7796    Initialize a logical condition expression.
7797
7798    Example:
7799        >>> condition("x=1").sql()
7800        'x = 1'
7801
7802        This is helpful for composing larger logical syntax trees:
7803        >>> where = condition("x=1")
7804        >>> where = where.and_("y=1")
7805        >>> Select().from_("tbl").select("*").where(where).sql()
7806        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7807
7808    Args:
7809        *expression: the SQL code string to parse.
7810            If an Expression instance is passed, this is used as-is.
7811        dialect: the dialect used to parse the input expression (in the case that the
7812            input expression is a SQL string).
7813        copy: Whether to copy `expression` (only applies to expressions).
7814        **opts: other options to use to parse the input expressions (again, in the case
7815            that the input expression is a SQL string).
7816
7817    Returns:
7818        The new Condition instance
7819    """
7820    return maybe_parse(
7821        expression,
7822        into=Condition,
7823        dialect=dialect,
7824        copy=copy,
7825        **opts,
7826    )

Initialize a logical condition expression.

Example:
>>> condition("x=1").sql()
'x = 1'

This is helpful for composing larger logical syntax trees:

>>> where = condition("x=1")
>>> where = where.and_("y=1")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • copy: Whether to copy expression (only applies to expressions).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7829def and_(
7830    *expressions: t.Optional[ExpOrStr],
7831    dialect: DialectType = None,
7832    copy: bool = True,
7833    wrap: bool = True,
7834    **opts,
7835) -> Condition:
7836    """
7837    Combine multiple conditions with an AND logical operator.
7838
7839    Example:
7840        >>> and_("x=1", and_("y=1", "z=1")).sql()
7841        'x = 1 AND (y = 1 AND z = 1)'
7842
7843    Args:
7844        *expressions: the SQL code strings to parse.
7845            If an Expression instance is passed, this is used as-is.
7846        dialect: the dialect used to parse the input expression.
7847        copy: whether to copy `expressions` (only applies to Expressions).
7848        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7849            precedence issues, but can be turned off when the produced AST is too deep and
7850            causes recursion-related issues.
7851        **opts: other options to use to parse the input expressions.
7852
7853    Returns:
7854        The new condition
7855    """
7856    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an AND logical operator.

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

The new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7859def or_(
7860    *expressions: t.Optional[ExpOrStr],
7861    dialect: DialectType = None,
7862    copy: bool = True,
7863    wrap: bool = True,
7864    **opts,
7865) -> Condition:
7866    """
7867    Combine multiple conditions with an OR logical operator.
7868
7869    Example:
7870        >>> or_("x=1", or_("y=1", "z=1")).sql()
7871        'x = 1 OR (y = 1 OR z = 1)'
7872
7873    Args:
7874        *expressions: the SQL code strings to parse.
7875            If an Expression instance is passed, this is used as-is.
7876        dialect: the dialect used to parse the input expression.
7877        copy: whether to copy `expressions` (only applies to Expressions).
7878        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7879            precedence issues, but can be turned off when the produced AST is too deep and
7880            causes recursion-related issues.
7881        **opts: other options to use to parse the input expressions.
7882
7883    Returns:
7884        The new condition
7885    """
7886    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an OR logical operator.

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

The new condition

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7889def xor(
7890    *expressions: t.Optional[ExpOrStr],
7891    dialect: DialectType = None,
7892    copy: bool = True,
7893    wrap: bool = True,
7894    **opts,
7895) -> Condition:
7896    """
7897    Combine multiple conditions with an XOR logical operator.
7898
7899    Example:
7900        >>> xor("x=1", xor("y=1", "z=1")).sql()
7901        'x = 1 XOR (y = 1 XOR z = 1)'
7902
7903    Args:
7904        *expressions: the SQL code strings to parse.
7905            If an Expression instance is passed, this is used as-is.
7906        dialect: the dialect used to parse the input expression.
7907        copy: whether to copy `expressions` (only applies to Expressions).
7908        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7909            precedence issues, but can be turned off when the produced AST is too deep and
7910            causes recursion-related issues.
7911        **opts: other options to use to parse the input expressions.
7912
7913    Returns:
7914        The new condition
7915    """
7916    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an XOR logical operator.

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

The new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7919def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7920    """
7921    Wrap a condition with a NOT operator.
7922
7923    Example:
7924        >>> not_("this_suit='black'").sql()
7925        "NOT this_suit = 'black'"
7926
7927    Args:
7928        expression: the SQL code string to parse.
7929            If an Expression instance is passed, this is used as-is.
7930        dialect: the dialect used to parse the input expression.
7931        copy: whether to copy the expression or not.
7932        **opts: other options to use to parse the input expressions.
7933
7934    Returns:
7935        The new condition.
7936    """
7937    this = condition(
7938        expression,
7939        dialect=dialect,
7940        copy=copy,
7941        **opts,
7942    )
7943    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:
7946def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7947    """
7948    Wrap an expression in parentheses.
7949
7950    Example:
7951        >>> paren("5 + 3").sql()
7952        '(5 + 3)'
7953
7954    Args:
7955        expression: the SQL code string to parse.
7956            If an Expression instance is passed, this is used as-is.
7957        copy: whether to copy the expression or not.
7958
7959    Returns:
7960        The wrapped expression.
7961    """
7962    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):
7978def to_identifier(name, quoted=None, copy=True):
7979    """Builds an identifier.
7980
7981    Args:
7982        name: The name to turn into an identifier.
7983        quoted: Whether to force quote the identifier.
7984        copy: Whether to copy name if it's an Identifier.
7985
7986    Returns:
7987        The identifier ast node.
7988    """
7989
7990    if name is None:
7991        return None
7992
7993    if isinstance(name, Identifier):
7994        identifier = maybe_copy(name, copy)
7995    elif isinstance(name, str):
7996        identifier = Identifier(
7997            this=name,
7998            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7999        )
8000    else:
8001        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8002    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Identifier:
8005def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8006    """
8007    Parses a given string into an identifier.
8008
8009    Args:
8010        name: The name to parse into an identifier.
8011        dialect: The dialect to parse against.
8012
8013    Returns:
8014        The identifier ast node.
8015    """
8016    try:
8017        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8018    except (ParseError, TokenError):
8019        expression = to_identifier(name)
8020
8021    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]+(?:\\.[0-9]+)?)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
8027def to_interval(interval: str | Literal) -> Interval:
8028    """Builds an interval expression from a string like '1 day' or '5 months'."""
8029    if isinstance(interval, Literal):
8030        if not interval.is_string:
8031            raise ValueError("Invalid interval string.")
8032
8033        interval = interval.this
8034
8035    interval = maybe_parse(f"INTERVAL {interval}")
8036    assert isinstance(interval, Interval)
8037    return interval

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
8040def to_table(
8041    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8042) -> Table:
8043    """
8044    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8045    If a table is passed in then that table is returned.
8046
8047    Args:
8048        sql_path: a `[catalog].[schema].[table]` string.
8049        dialect: the source dialect according to which the table name will be parsed.
8050        copy: Whether to copy a table if it is passed in.
8051        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8052
8053    Returns:
8054        A table expression.
8055    """
8056    if isinstance(sql_path, Table):
8057        return maybe_copy(sql_path, copy=copy)
8058
8059    try:
8060        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8061    except ParseError:
8062        catalog, db, this = split_num_words(sql_path, ".", 3)
8063
8064        if not this:
8065            raise
8066
8067        table = table_(this, db=db, catalog=catalog)
8068
8069    for k, v in kwargs.items():
8070        table.set(k, v)
8071
8072    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
8075def to_column(
8076    sql_path: str | Column,
8077    quoted: t.Optional[bool] = None,
8078    dialect: DialectType = None,
8079    copy: bool = True,
8080    **kwargs,
8081) -> Column:
8082    """
8083    Create a column from a `[table].[column]` sql path. Table is optional.
8084    If a column is passed in then that column is returned.
8085
8086    Args:
8087        sql_path: a `[table].[column]` string.
8088        quoted: Whether or not to force quote identifiers.
8089        dialect: the source dialect according to which the column name will be parsed.
8090        copy: Whether to copy a column if it is passed in.
8091        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8092
8093    Returns:
8094        A column expression.
8095    """
8096    if isinstance(sql_path, Column):
8097        return maybe_copy(sql_path, copy=copy)
8098
8099    try:
8100        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8101    except ParseError:
8102        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8103
8104    for k, v in kwargs.items():
8105        col.set(k, v)
8106
8107    if quoted:
8108        for i in col.find_all(Identifier):
8109            i.set("quoted", True)
8110
8111    return col

Create a column from a [table].[column] sql path. Table is optional. If a column is passed in then that column is returned.

Arguments:
  • sql_path: a [table].[column] string.
  • quoted: Whether or not to force quote identifiers.
  • dialect: the source dialect according to which the column name will be parsed.
  • copy: Whether to copy a column if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Column expression with.
Returns:

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts):
8114def alias_(
8115    expression: ExpOrStr,
8116    alias: t.Optional[str | Identifier],
8117    table: bool | t.Sequence[str | Identifier] = False,
8118    quoted: t.Optional[bool] = None,
8119    dialect: DialectType = None,
8120    copy: bool = True,
8121    **opts,
8122):
8123    """Create an Alias expression.
8124
8125    Example:
8126        >>> alias_('foo', 'bar').sql()
8127        'foo AS bar'
8128
8129        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8130        '(SELECT 1, 2) AS bar(a, b)'
8131
8132    Args:
8133        expression: the SQL code strings to parse.
8134            If an Expression instance is passed, this is used as-is.
8135        alias: the alias name to use. If the name has
8136            special characters it is quoted.
8137        table: Whether to create a table alias, can also be a list of columns.
8138        quoted: whether to quote the alias
8139        dialect: the dialect used to parse the input expression.
8140        copy: Whether to copy the expression.
8141        **opts: other options to use to parse the input expressions.
8142
8143    Returns:
8144        Alias: the aliased expression
8145    """
8146    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8147    alias = to_identifier(alias, quoted=quoted)
8148
8149    if table:
8150        table_alias = TableAlias(this=alias)
8151        exp.set("alias", table_alias)
8152
8153        if not isinstance(table, bool):
8154            for column in table:
8155                table_alias.append("columns", to_identifier(column, quoted=quoted))
8156
8157        return exp
8158
8159    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8160    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8161    # for the complete Window expression.
8162    #
8163    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8164
8165    if "alias" in exp.arg_types and not isinstance(exp, Window):
8166        exp.set("alias", alias)
8167        return exp
8168    return Alias(this=exp, alias=alias)

Create an Alias expression.

Example:
>>> alias_('foo', 'bar').sql()
'foo AS bar'
>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
'(SELECT 1, 2) AS bar(a, b)'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use. If the name has special characters it is quoted.
  • table: Whether to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8171def subquery(
8172    expression: ExpOrStr,
8173    alias: t.Optional[Identifier | str] = None,
8174    dialect: DialectType = None,
8175    **opts,
8176) -> Select:
8177    """
8178    Build a subquery expression that's selected from.
8179
8180    Example:
8181        >>> subquery('select x from tbl', 'bar').select('x').sql()
8182        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8183
8184    Args:
8185        expression: the SQL code strings to parse.
8186            If an Expression instance is passed, this is used as-is.
8187        alias: the alias name to use.
8188        dialect: the dialect used to parse the input expression.
8189        **opts: other options to use to parse the input expressions.
8190
8191    Returns:
8192        A new Select instance with the subquery expression included.
8193    """
8194
8195    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8196    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):
8227def column(
8228    col,
8229    table=None,
8230    db=None,
8231    catalog=None,
8232    *,
8233    fields=None,
8234    quoted=None,
8235    copy=True,
8236):
8237    """
8238    Build a Column.
8239
8240    Args:
8241        col: Column name.
8242        table: Table name.
8243        db: Database name.
8244        catalog: Catalog name.
8245        fields: Additional fields using dots.
8246        quoted: Whether to force quotes on the column's identifiers.
8247        copy: Whether to copy identifiers if passed in.
8248
8249    Returns:
8250        The new Column instance.
8251    """
8252    if not isinstance(col, Star):
8253        col = to_identifier(col, quoted=quoted, copy=copy)
8254
8255    this = Column(
8256        this=col,
8257        table=to_identifier(table, quoted=quoted, copy=copy),
8258        db=to_identifier(db, quoted=quoted, copy=copy),
8259        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8260    )
8261
8262    if fields:
8263        this = Dot.build(
8264            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8265        )
8266    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, Identifier, Dot, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8269def cast(
8270    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8271) -> Cast:
8272    """Cast an expression to a data type.
8273
8274    Example:
8275        >>> cast('x + 1', 'int').sql()
8276        'CAST(x + 1 AS INT)'
8277
8278    Args:
8279        expression: The expression to cast.
8280        to: The datatype to cast to.
8281        copy: Whether to copy the supplied expressions.
8282        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8283            - The expression to be cast is already a exp.Cast expression
8284            - The existing cast is to a type that is logically equivalent to new type
8285
8286            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8287            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8288            and instead just return the original expression `CAST(x as DATETIME)`.
8289
8290            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8291            mapping is applied in the target dialect generator.
8292
8293    Returns:
8294        The new Cast instance.
8295    """
8296    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8297    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8298
8299    # dont re-cast if the expression is already a cast to the correct type
8300    if isinstance(expr, Cast):
8301        from sqlglot.dialects.dialect import Dialect
8302
8303        target_dialect = Dialect.get_or_raise(dialect)
8304        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8305
8306        existing_cast_type: DataType.Type = expr.to.this
8307        new_cast_type: DataType.Type = data_type.this
8308        types_are_equivalent = type_mapping.get(
8309            existing_cast_type, existing_cast_type.value
8310        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8311
8312        if expr.is_type(data_type) or types_are_equivalent:
8313            return expr
8314
8315    expr = Cast(this=expr, to=data_type)
8316    expr.type = data_type
8317
8318    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:
8321def table_(
8322    table: Identifier | str,
8323    db: t.Optional[Identifier | str] = None,
8324    catalog: t.Optional[Identifier | str] = None,
8325    quoted: t.Optional[bool] = None,
8326    alias: t.Optional[Identifier | str] = None,
8327) -> Table:
8328    """Build a Table.
8329
8330    Args:
8331        table: Table name.
8332        db: Database name.
8333        catalog: Catalog name.
8334        quote: Whether to force quotes on the table's identifiers.
8335        alias: Table's alias.
8336
8337    Returns:
8338        The new Table instance.
8339    """
8340    return Table(
8341        this=to_identifier(table, quoted=quoted) if table else None,
8342        db=to_identifier(db, quoted=quoted) if db else None,
8343        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8344        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8345    )

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:
8348def values(
8349    values: t.Iterable[t.Tuple[t.Any, ...]],
8350    alias: t.Optional[str] = None,
8351    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8352) -> Values:
8353    """Build VALUES statement.
8354
8355    Example:
8356        >>> values([(1, '2')]).sql()
8357        "VALUES (1, '2')"
8358
8359    Args:
8360        values: values statements that will be converted to SQL
8361        alias: optional alias
8362        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8363         If either are provided then an alias is also required.
8364
8365    Returns:
8366        Values: the Values expression object
8367    """
8368    if columns and not alias:
8369        raise ValueError("Alias is required when providing columns")
8370
8371    return Values(
8372        expressions=[convert(tup) for tup in values],
8373        alias=(
8374            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8375            if columns
8376            else (TableAlias(this=to_identifier(alias)) if alias else None)
8377        ),
8378    )

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:
8381def var(name: t.Optional[ExpOrStr]) -> Var:
8382    """Build a SQL variable.
8383
8384    Example:
8385        >>> repr(var('x'))
8386        'Var(this=x)'
8387
8388        >>> repr(var(column('x', table='y')))
8389        'Var(this=x)'
8390
8391    Args:
8392        name: The name of the var or an expression who's name will become the var.
8393
8394    Returns:
8395        The new variable node.
8396    """
8397    if not name:
8398        raise ValueError("Cannot convert empty name into var.")
8399
8400    if isinstance(name, Expression):
8401        name = name.name
8402    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8405def rename_table(
8406    old_name: str | Table,
8407    new_name: str | Table,
8408    dialect: DialectType = None,
8409) -> Alter:
8410    """Build ALTER TABLE... RENAME... expression
8411
8412    Args:
8413        old_name: The old name of the table
8414        new_name: The new name of the table
8415        dialect: The dialect to parse the table.
8416
8417    Returns:
8418        Alter table expression
8419    """
8420    old_table = to_table(old_name, dialect=dialect)
8421    new_table = to_table(new_name, dialect=dialect)
8422    return Alter(
8423        this=old_table,
8424        kind="TABLE",
8425        actions=[
8426            AlterRename(this=new_table),
8427        ],
8428    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse the table.
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8431def rename_column(
8432    table_name: str | Table,
8433    old_column_name: str | Column,
8434    new_column_name: str | Column,
8435    exists: t.Optional[bool] = None,
8436    dialect: DialectType = None,
8437) -> Alter:
8438    """Build ALTER TABLE... RENAME COLUMN... expression
8439
8440    Args:
8441        table_name: Name of the table
8442        old_column: The old name of the column
8443        new_column: The new name of the column
8444        exists: Whether to add the `IF EXISTS` clause
8445        dialect: The dialect to parse the table/column.
8446
8447    Returns:
8448        Alter table expression
8449    """
8450    table = to_table(table_name, dialect=dialect)
8451    old_column = to_column(old_column_name, dialect=dialect)
8452    new_column = to_column(new_column_name, dialect=dialect)
8453    return Alter(
8454        this=table,
8455        kind="TABLE",
8456        actions=[
8457            RenameColumn(this=old_column, to=new_column, exists=exists),
8458        ],
8459    )

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:
8462def convert(value: t.Any, copy: bool = False) -> Expression:
8463    """Convert a python value into an expression object.
8464
8465    Raises an error if a conversion is not possible.
8466
8467    Args:
8468        value: A python object.
8469        copy: Whether to copy `value` (only applies to Expressions and collections).
8470
8471    Returns:
8472        The equivalent expression object.
8473    """
8474    if isinstance(value, Expression):
8475        return maybe_copy(value, copy)
8476    if isinstance(value, str):
8477        return Literal.string(value)
8478    if isinstance(value, bool):
8479        return Boolean(this=value)
8480    if value is None or (isinstance(value, float) and math.isnan(value)):
8481        return null()
8482    if isinstance(value, numbers.Number):
8483        return Literal.number(value)
8484    if isinstance(value, bytes):
8485        return HexString(this=value.hex())
8486    if isinstance(value, datetime.datetime):
8487        datetime_literal = Literal.string(value.isoformat(sep=" "))
8488
8489        tz = None
8490        if value.tzinfo:
8491            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8492            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8493            tz = Literal.string(str(value.tzinfo))
8494
8495        return TimeStrToTime(this=datetime_literal, zone=tz)
8496    if isinstance(value, datetime.date):
8497        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8498        return DateStrToDate(this=date_literal)
8499    if isinstance(value, tuple):
8500        if hasattr(value, "_fields"):
8501            return Struct(
8502                expressions=[
8503                    PropertyEQ(
8504                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8505                    )
8506                    for k in value._fields
8507                ]
8508            )
8509        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8510    if isinstance(value, list):
8511        return Array(expressions=[convert(v, copy=copy) for v in value])
8512    if isinstance(value, dict):
8513        return Map(
8514            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8515            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8516        )
8517    if hasattr(value, "__dict__"):
8518        return Struct(
8519            expressions=[
8520                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8521                for k, v in value.__dict__.items()
8522            ]
8523        )
8524    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:
8527def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8528    """
8529    Replace children of an expression with the result of a lambda fun(child) -> exp.
8530    """
8531    for k, v in tuple(expression.args.items()):
8532        is_list_arg = type(v) is list
8533
8534        child_nodes = v if is_list_arg else [v]
8535        new_child_nodes = []
8536
8537        for cn in child_nodes:
8538            if isinstance(cn, Expression):
8539                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8540                    new_child_nodes.append(child_node)
8541            else:
8542                new_child_nodes.append(cn)
8543
8544        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:
8547def replace_tree(
8548    expression: Expression,
8549    fun: t.Callable,
8550    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8551) -> Expression:
8552    """
8553    Replace an entire tree with the result of function calls on each node.
8554
8555    This will be traversed in reverse dfs, so leaves first.
8556    If new nodes are created as a result of function calls, they will also be traversed.
8557    """
8558    stack = list(expression.dfs(prune=prune))
8559
8560    while stack:
8561        node = stack.pop()
8562        new_node = fun(node)
8563
8564        if new_node is not node:
8565            node.replace(new_node)
8566
8567            if isinstance(new_node, Expression):
8568                stack.append(new_node)
8569
8570    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]:
8573def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8574    """
8575    Return all table names referenced through columns in an expression.
8576
8577    Example:
8578        >>> import sqlglot
8579        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8580        ['a', 'c']
8581
8582    Args:
8583        expression: expression to find table names.
8584        exclude: a table name to exclude
8585
8586    Returns:
8587        A list of unique names.
8588    """
8589    return {
8590        table
8591        for table in (column.table for column in expression.find_all(Column))
8592        if table and table != exclude
8593    }

Return all table names referenced through columns in an expression.

Example:
>>> import sqlglot
>>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
['a', 'c']
Arguments:
  • expression: expression to find table names.
  • exclude: a table name to exclude
Returns:

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, identify: bool = False) -> str:
8596def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8597    """Get the full name of a table as a string.
8598
8599    Args:
8600        table: Table expression node or string.
8601        dialect: The dialect to generate the table name for.
8602        identify: Determines when an identifier should be quoted. Possible values are:
8603            False (default): Never quote, except in cases where it's mandatory by the dialect.
8604            True: Always quote.
8605
8606    Examples:
8607        >>> from sqlglot import exp, parse_one
8608        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8609        'a.b.c'
8610
8611    Returns:
8612        The table name.
8613    """
8614
8615    table = maybe_parse(table, into=Table, dialect=dialect)
8616
8617    if not table:
8618        raise ValueError(f"Cannot parse {table}")
8619
8620    return ".".join(
8621        (
8622            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8623            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8624            else part.name
8625        )
8626        for part in table.parts
8627    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> str:
8630def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8631    """Returns a case normalized table name without quotes.
8632
8633    Args:
8634        table: the table to normalize
8635        dialect: the dialect to use for normalization rules
8636        copy: whether to copy the expression.
8637
8638    Examples:
8639        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8640        'A-B.c'
8641    """
8642    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8643
8644    return ".".join(
8645        p.name
8646        for p in normalize_identifiers(
8647            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8648        ).parts
8649    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8652def replace_tables(
8653    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8654) -> E:
8655    """Replace all tables in expression according to the mapping.
8656
8657    Args:
8658        expression: expression node to be transformed and replaced.
8659        mapping: mapping of table names.
8660        dialect: the dialect of the mapping table
8661        copy: whether to copy the expression.
8662
8663    Examples:
8664        >>> from sqlglot import exp, parse_one
8665        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8666        'SELECT * FROM c /* a.b */'
8667
8668    Returns:
8669        The mapped expression.
8670    """
8671
8672    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8673
8674    def _replace_tables(node: Expression) -> Expression:
8675        if isinstance(node, Table) and node.meta.get("replace") is not False:
8676            original = normalize_table_name(node, dialect=dialect)
8677            new_name = mapping.get(original)
8678
8679            if new_name:
8680                table = to_table(
8681                    new_name,
8682                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8683                    dialect=dialect,
8684                )
8685                table.add_comments([original])
8686                return table
8687        return node
8688
8689    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:
8692def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8693    """Replace placeholders in an expression.
8694
8695    Args:
8696        expression: expression node to be transformed and replaced.
8697        args: positional names that will substitute unnamed placeholders in the given order.
8698        kwargs: keyword arguments that will substitute named placeholders.
8699
8700    Examples:
8701        >>> from sqlglot import exp, parse_one
8702        >>> replace_placeholders(
8703        ...     parse_one("select * from :tbl where ? = ?"),
8704        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8705        ... ).sql()
8706        "SELECT * FROM foo WHERE str_col = 'b'"
8707
8708    Returns:
8709        The mapped expression.
8710    """
8711
8712    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8713        if isinstance(node, Placeholder):
8714            if node.this:
8715                new_name = kwargs.get(node.this)
8716                if new_name is not None:
8717                    return convert(new_name)
8718            else:
8719                try:
8720                    return convert(next(args))
8721                except StopIteration:
8722                    pass
8723        return node
8724
8725    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Union[Query, Callable[[], Query]]], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8728def expand(
8729    expression: Expression,
8730    sources: t.Dict[str, Query | t.Callable[[], Query]],
8731    dialect: DialectType = None,
8732    copy: bool = True,
8733) -> Expression:
8734    """Transforms an expression by expanding all referenced sources into subqueries.
8735
8736    Examples:
8737        >>> from sqlglot import parse_one
8738        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8739        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8740
8741        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8742        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8743
8744    Args:
8745        expression: The expression to expand.
8746        sources: A dict of name to query or a callable that provides a query on demand.
8747        dialect: The dialect of the sources dict or the callable.
8748        copy: Whether to copy the expression during transformation. Defaults to True.
8749
8750    Returns:
8751        The transformed expression.
8752    """
8753    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8754
8755    def _expand(node: Expression):
8756        if isinstance(node, Table):
8757            name = normalize_table_name(node, dialect=dialect)
8758            source = normalized_sources.get(name)
8759
8760            if source:
8761                # Create a subquery with the same alias (or table name if no alias)
8762                parsed_source = source() if callable(source) else source
8763                subquery = parsed_source.subquery(node.alias or name)
8764                subquery.comments = [f"source: {name}"]
8765
8766                # Continue expanding within the subquery
8767                return subquery.transform(_expand, copy=False)
8768
8769        return node
8770
8771    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dict of name to query or a callable that provides a query on demand.
  • dialect: The dialect of the sources dict or the callable.
  • copy: Whether to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Func:
8774def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8775    """
8776    Returns a Func expression.
8777
8778    Examples:
8779        >>> func("abs", 5).sql()
8780        'ABS(5)'
8781
8782        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8783        'CAST(5 AS DOUBLE)'
8784
8785    Args:
8786        name: the name of the function to build.
8787        args: the args used to instantiate the function of interest.
8788        copy: whether to copy the argument expressions.
8789        dialect: the source dialect.
8790        kwargs: the kwargs used to instantiate the function of interest.
8791
8792    Note:
8793        The arguments `args` and `kwargs` are mutually exclusive.
8794
8795    Returns:
8796        An instance of the function of interest, or an anonymous function, if `name` doesn't
8797        correspond to an existing `sqlglot.expressions.Func` class.
8798    """
8799    if args and kwargs:
8800        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8801
8802    from sqlglot.dialects.dialect import Dialect
8803
8804    dialect = Dialect.get_or_raise(dialect)
8805
8806    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8807    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8808
8809    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8810    if constructor:
8811        if converted:
8812            if "dialect" in constructor.__code__.co_varnames:
8813                function = constructor(converted, dialect=dialect)
8814            else:
8815                function = constructor(converted)
8816        elif constructor.__name__ == "from_arg_list":
8817            function = constructor.__self__(**kwargs)  # type: ignore
8818        else:
8819            constructor = FUNCTION_BY_NAME.get(name.upper())
8820            if constructor:
8821                function = constructor(**kwargs)
8822            else:
8823                raise ValueError(
8824                    f"Unable to convert '{name}' into a Func. Either manually construct "
8825                    "the Func expression of interest or parse the function call."
8826                )
8827    else:
8828        kwargs = kwargs or {"expressions": converted}
8829        function = Anonymous(this=name, **kwargs)
8830
8831    for error_message in function.error_messages(converted):
8832        raise ValueError(error_message)
8833
8834    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:
8837def case(
8838    expression: t.Optional[ExpOrStr] = None,
8839    **opts,
8840) -> Case:
8841    """
8842    Initialize a CASE statement.
8843
8844    Example:
8845        case().when("a = 1", "foo").else_("bar")
8846
8847    Args:
8848        expression: Optionally, the input expression (not all dialects support this)
8849        **opts: Extra keyword arguments for parsing `expression`
8850    """
8851    if expression is not None:
8852        this = maybe_parse(expression, **opts)
8853    else:
8854        this = None
8855    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Array:
8858def array(
8859    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8860) -> Array:
8861    """
8862    Returns an array.
8863
8864    Examples:
8865        >>> array(1, 'x').sql()
8866        'ARRAY(1, x)'
8867
8868    Args:
8869        expressions: the expressions to add to the array.
8870        copy: whether to copy the argument expressions.
8871        dialect: the source dialect.
8872        kwargs: the kwargs used to instantiate the function of interest.
8873
8874    Returns:
8875        An array expression.
8876    """
8877    return Array(
8878        expressions=[
8879            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8880            for expression in expressions
8881        ]
8882    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Tuple:
8885def tuple_(
8886    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8887) -> Tuple:
8888    """
8889    Returns an tuple.
8890
8891    Examples:
8892        >>> tuple_(1, 'x').sql()
8893        '(1, x)'
8894
8895    Args:
8896        expressions: the expressions to add to the tuple.
8897        copy: whether to copy the argument expressions.
8898        dialect: the source dialect.
8899        kwargs: the kwargs used to instantiate the function of interest.
8900
8901    Returns:
8902        A tuple expression.
8903    """
8904    return Tuple(
8905        expressions=[
8906            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8907            for expression in expressions
8908        ]
8909    )

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:
8912def true() -> Boolean:
8913    """
8914    Returns a true Boolean expression.
8915    """
8916    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8919def false() -> Boolean:
8920    """
8921    Returns a false Boolean expression.
8922    """
8923    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8926def null() -> Null:
8927    """
8928    Returns a Null expression.
8929    """
8930    return Null()

Returns a Null expression.

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