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

Logical conditions like x AND y, or simply x

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

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

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

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:
1137    def offset(
1138        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1139    ) -> Q:
1140        """
1141        Set the OFFSET expression.
1142
1143        Example:
1144            >>> Select().from_("tbl").select("x").offset(10).sql()
1145            'SELECT x FROM tbl OFFSET 10'
1146
1147        Args:
1148            expression: the SQL code string to parse.
1149                This can also be an integer.
1150                If a `Offset` instance is passed, this is used as-is.
1151                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1152            dialect: the dialect used to parse the input expression.
1153            copy: if `False`, modify this expression instance in-place.
1154            opts: other options to use to parse the input expressions.
1155
1156        Returns:
1157            The modified Select expression.
1158        """
1159        return _apply_builder(
1160            expression=expression,
1161            instance=self,
1162            arg="offset",
1163            into=Offset,
1164            prefix="OFFSET",
1165            dialect=dialect,
1166            copy=copy,
1167            into_arg="expression",
1168            **opts,
1169        )

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

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

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

selects: List[Expression]
1217    @property
1218    def selects(self) -> t.List[Expression]:
1219        """Returns the query's projections."""
1220        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

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

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

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:
1344    def union(
1345        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1346    ) -> Union:
1347        """
1348        Builds a UNION expression.
1349
1350        Example:
1351            >>> import sqlglot
1352            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1353            'SELECT * FROM foo UNION SELECT * FROM bla'
1354
1355        Args:
1356            expressions: the SQL code strings.
1357                If `Expression` instances are passed, they will be used as-is.
1358            distinct: set the DISTINCT flag if and only if this is true.
1359            dialect: the dialect used to parse the input expression.
1360            opts: other options to use to parse the input expressions.
1361
1362        Returns:
1363            The new Union expression.
1364        """
1365        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:
1367    def intersect(
1368        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1369    ) -> Intersect:
1370        """
1371        Builds an INTERSECT expression.
1372
1373        Example:
1374            >>> import sqlglot
1375            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1376            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1377
1378        Args:
1379            expressions: the SQL code strings.
1380                If `Expression` instances are passed, they will be used as-is.
1381            distinct: set the DISTINCT flag if and only if this is true.
1382            dialect: the dialect used to parse the input expression.
1383            opts: other options to use to parse the input expressions.
1384
1385        Returns:
1386            The new Intersect expression.
1387        """
1388        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:
1390    def except_(
1391        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1392    ) -> Except:
1393        """
1394        Builds an EXCEPT expression.
1395
1396        Example:
1397            >>> import sqlglot
1398            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1399            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1400
1401        Args:
1402            expressions: the SQL code strings.
1403                If `Expression` instance are passed, they will be used as-is.
1404            distinct: set the DISTINCT flag if and only if this is true.
1405            dialect: the dialect used to parse the input expression.
1406            opts: other options to use to parse the input expressions.
1407
1408        Returns:
1409            The new Except expression.
1410        """
1411        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):
1414class UDTF(DerivedTable):
1415    @property
1416    def selects(self) -> t.List[Expression]:
1417        alias = self.args.get("alias")
1418        return alias.columns if alias else []
selects: List[Expression]
1415    @property
1416    def selects(self) -> t.List[Expression]:
1417        alias = self.args.get("alias")
1418        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1421class Cache(Expression):
1422    arg_types = {
1423        "this": True,
1424        "lazy": False,
1425        "options": False,
1426        "expression": False,
1427    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1430class Uncache(Expression):
1431    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1434class Refresh(Expression):
1435    pass
key = 'refresh'
class DDL(Expression):
1438class DDL(Expression):
1439    @property
1440    def ctes(self) -> t.List[CTE]:
1441        """Returns a list of all the CTEs attached to this statement."""
1442        with_ = self.args.get("with")
1443        return with_.expressions if with_ else []
1444
1445    @property
1446    def selects(self) -> t.List[Expression]:
1447        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1448        return self.expression.selects if isinstance(self.expression, Query) else []
1449
1450    @property
1451    def named_selects(self) -> t.List[str]:
1452        """
1453        If this statement contains a query (e.g. a CTAS), this returns the output
1454        names of the query's projections.
1455        """
1456        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1439    @property
1440    def ctes(self) -> t.List[CTE]:
1441        """Returns a list of all the CTEs attached to this statement."""
1442        with_ = self.args.get("with")
1443        return with_.expressions if with_ else []

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

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

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):
1496class Create(DDL):
1497    arg_types = {
1498        "with": False,
1499        "this": True,
1500        "kind": True,
1501        "expression": False,
1502        "exists": False,
1503        "properties": False,
1504        "replace": False,
1505        "refresh": False,
1506        "unique": False,
1507        "indexes": False,
1508        "no_schema_binding": False,
1509        "begin": False,
1510        "end": False,
1511        "clone": False,
1512        "concurrently": False,
1513        "clustered": False,
1514    }
1515
1516    @property
1517    def kind(self) -> t.Optional[str]:
1518        kind = self.args.get("kind")
1519        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]
1516    @property
1517    def kind(self) -> t.Optional[str]:
1518        kind = self.args.get("kind")
1519        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1522class SequenceProperties(Expression):
1523    arg_types = {
1524        "increment": False,
1525        "minvalue": False,
1526        "maxvalue": False,
1527        "cache": False,
1528        "start": False,
1529        "owned": False,
1530        "options": False,
1531    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1534class TruncateTable(Expression):
1535    arg_types = {
1536        "expressions": True,
1537        "is_database": False,
1538        "exists": False,
1539        "only": False,
1540        "cluster": False,
1541        "identity": False,
1542        "option": False,
1543        "partition": False,
1544    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1550class Clone(Expression):
1551    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1554class Describe(Expression):
1555    arg_types = {
1556        "this": True,
1557        "style": False,
1558        "kind": False,
1559        "expressions": False,
1560        "partition": False,
1561        "format": False,
1562    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1566class Attach(Expression):
1567    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1571class Detach(Expression):
1572    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1576class Summarize(Expression):
1577    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1580class Kill(Expression):
1581    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1584class Pragma(Expression):
1585    pass
key = 'pragma'
class Declare(Expression):
1588class Declare(Expression):
1589    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1592class DeclareItem(Expression):
1593    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
class Set(Expression):
1596class Set(Expression):
1597    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1600class Heredoc(Expression):
1601    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1604class SetItem(Expression):
1605    arg_types = {
1606        "this": False,
1607        "expressions": False,
1608        "kind": False,
1609        "collate": False,  # MySQL SET NAMES statement
1610        "global": False,
1611    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1614class Show(Expression):
1615    arg_types = {
1616        "this": True,
1617        "history": False,
1618        "terse": False,
1619        "target": False,
1620        "offset": False,
1621        "starts_with": False,
1622        "limit": False,
1623        "from": False,
1624        "like": False,
1625        "where": False,
1626        "db": False,
1627        "scope": False,
1628        "scope_kind": False,
1629        "full": False,
1630        "mutex": False,
1631        "query": False,
1632        "channel": False,
1633        "global": False,
1634        "log": False,
1635        "position": False,
1636        "types": False,
1637        "privileges": False,
1638    }
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):
1641class UserDefinedFunction(Expression):
1642    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1645class CharacterSet(Expression):
1646    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1649class RecursiveWithSearch(Expression):
1650    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):
1653class With(Expression):
1654    arg_types = {"expressions": True, "recursive": False, "search": False}
1655
1656    @property
1657    def recursive(self) -> bool:
1658        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1656    @property
1657    def recursive(self) -> bool:
1658        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1661class WithinGroup(Expression):
1662    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1667class CTE(DerivedTable):
1668    arg_types = {
1669        "this": True,
1670        "alias": True,
1671        "scalar": False,
1672        "materialized": False,
1673    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1676class ProjectionDef(Expression):
1677    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1680class TableAlias(Expression):
1681    arg_types = {"this": False, "columns": False, "column_only": False}
1682
1683    @property
1684    def columns(self):
1685        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False, 'column_only': False}
columns
1683    @property
1684    def columns(self):
1685        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1688class BitString(Condition):
1689    pass
key = 'bitstring'
class HexString(Condition):
1692class HexString(Condition):
1693    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1696class ByteString(Condition):
1697    pass
key = 'bytestring'
class RawString(Condition):
1700class RawString(Condition):
1701    pass
key = 'rawstring'
class UnicodeString(Condition):
1704class UnicodeString(Condition):
1705    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1708class Column(Condition):
1709    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1710
1711    @property
1712    def table(self) -> str:
1713        return self.text("table")
1714
1715    @property
1716    def db(self) -> str:
1717        return self.text("db")
1718
1719    @property
1720    def catalog(self) -> str:
1721        return self.text("catalog")
1722
1723    @property
1724    def output_name(self) -> str:
1725        return self.name
1726
1727    @property
1728    def parts(self) -> t.List[Identifier]:
1729        """Return the parts of a column in order catalog, db, table, name."""
1730        return [
1731            t.cast(Identifier, self.args[part])
1732            for part in ("catalog", "db", "table", "this")
1733            if self.args.get(part)
1734        ]
1735
1736    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1737        """Converts the column into a dot expression."""
1738        parts = self.parts
1739        parent = self.parent
1740
1741        if include_dots:
1742            while isinstance(parent, Dot):
1743                parts.append(parent.expression)
1744                parent = parent.parent
1745
1746        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
1711    @property
1712    def table(self) -> str:
1713        return self.text("table")
db: str
1715    @property
1716    def db(self) -> str:
1717        return self.text("db")
catalog: str
1719    @property
1720    def catalog(self) -> str:
1721        return self.text("catalog")
output_name: str
1723    @property
1724    def output_name(self) -> str:
1725        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]
1727    @property
1728    def parts(self) -> t.List[Identifier]:
1729        """Return the parts of a column in order catalog, db, table, name."""
1730        return [
1731            t.cast(Identifier, self.args[part])
1732            for part in ("catalog", "db", "table", "this")
1733            if self.args.get(part)
1734        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1736    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1737        """Converts the column into a dot expression."""
1738        parts = self.parts
1739        parent = self.parent
1740
1741        if include_dots:
1742            while isinstance(parent, Dot):
1743                parts.append(parent.expression)
1744                parent = parent.parent
1745
1746        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1749class ColumnPosition(Expression):
1750    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1753class ColumnDef(Expression):
1754    arg_types = {
1755        "this": True,
1756        "kind": False,
1757        "constraints": False,
1758        "exists": False,
1759        "position": False,
1760        "default": False,
1761        "output": False,
1762    }
1763
1764    @property
1765    def constraints(self) -> t.List[ColumnConstraint]:
1766        return self.args.get("constraints") or []
1767
1768    @property
1769    def kind(self) -> t.Optional[DataType]:
1770        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1764    @property
1765    def constraints(self) -> t.List[ColumnConstraint]:
1766        return self.args.get("constraints") or []
kind: Optional[DataType]
1768    @property
1769    def kind(self) -> t.Optional[DataType]:
1770        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1773class AlterColumn(Expression):
1774    arg_types = {
1775        "this": True,
1776        "dtype": False,
1777        "collate": False,
1778        "using": False,
1779        "default": False,
1780        "drop": False,
1781        "comment": False,
1782        "allow_null": False,
1783        "visible": False,
1784    }
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):
1788class AlterIndex(Expression):
1789    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1793class AlterDistStyle(Expression):
1794    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1797class AlterSortKey(Expression):
1798    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1801class AlterSet(Expression):
1802    arg_types = {
1803        "expressions": False,
1804        "option": False,
1805        "tablespace": False,
1806        "access_method": False,
1807        "file_format": False,
1808        "copy_options": False,
1809        "tag": False,
1810        "location": False,
1811        "serde": False,
1812    }
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):
1815class RenameColumn(Expression):
1816    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1819class AlterRename(Expression):
1820    pass
key = 'alterrename'
class SwapTable(Expression):
1823class SwapTable(Expression):
1824    pass
key = 'swaptable'
class Comment(Expression):
1827class Comment(Expression):
1828    arg_types = {
1829        "this": True,
1830        "kind": True,
1831        "expression": True,
1832        "exists": False,
1833        "materialized": False,
1834    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1837class Comprehension(Expression):
1838    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):
1842class MergeTreeTTLAction(Expression):
1843    arg_types = {
1844        "this": True,
1845        "delete": False,
1846        "recompress": False,
1847        "to_disk": False,
1848        "to_volume": False,
1849    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1853class MergeTreeTTL(Expression):
1854    arg_types = {
1855        "expressions": True,
1856        "where": False,
1857        "group": False,
1858        "aggregates": False,
1859    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1863class IndexConstraintOption(Expression):
1864    arg_types = {
1865        "key_block_size": False,
1866        "using": False,
1867        "parser": False,
1868        "comment": False,
1869        "visible": False,
1870        "engine_attr": False,
1871        "secondary_engine_attr": False,
1872    }
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):
1875class ColumnConstraint(Expression):
1876    arg_types = {"this": False, "kind": True}
1877
1878    @property
1879    def kind(self) -> ColumnConstraintKind:
1880        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1878    @property
1879    def kind(self) -> ColumnConstraintKind:
1880        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1883class ColumnConstraintKind(Expression):
1884    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1887class AutoIncrementColumnConstraint(ColumnConstraintKind):
1888    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1891class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1892    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1895class CaseSpecificColumnConstraint(ColumnConstraintKind):
1896    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1899class CharacterSetColumnConstraint(ColumnConstraintKind):
1900    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1903class CheckColumnConstraint(ColumnConstraintKind):
1904    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1907class ClusteredColumnConstraint(ColumnConstraintKind):
1908    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1911class CollateColumnConstraint(ColumnConstraintKind):
1912    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1915class CommentColumnConstraint(ColumnConstraintKind):
1916    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1919class CompressColumnConstraint(ColumnConstraintKind):
1920    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1923class DateFormatColumnConstraint(ColumnConstraintKind):
1924    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1927class DefaultColumnConstraint(ColumnConstraintKind):
1928    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1931class EncodeColumnConstraint(ColumnConstraintKind):
1932    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1936class ExcludeColumnConstraint(ColumnConstraintKind):
1937    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1940class EphemeralColumnConstraint(ColumnConstraintKind):
1941    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1944class WithOperator(Expression):
1945    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1948class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1949    # this: True -> ALWAYS, this: False -> BY DEFAULT
1950    arg_types = {
1951        "this": False,
1952        "expression": False,
1953        "on_null": False,
1954        "start": False,
1955        "increment": False,
1956        "minvalue": False,
1957        "maxvalue": False,
1958        "cycle": False,
1959        "order": False,
1960    }
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):
1963class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1964    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1969class IndexColumnConstraint(ColumnConstraintKind):
1970    arg_types = {
1971        "this": False,
1972        "expressions": False,
1973        "kind": False,
1974        "index_type": False,
1975        "options": False,
1976        "expression": False,  # Clickhouse
1977        "granularity": False,
1978    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1981class InlineLengthColumnConstraint(ColumnConstraintKind):
1982    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1985class NonClusteredColumnConstraint(ColumnConstraintKind):
1986    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1989class NotForReplicationColumnConstraint(ColumnConstraintKind):
1990    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1994class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1995    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1998class NotNullColumnConstraint(ColumnConstraintKind):
1999    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
2003class OnUpdateColumnConstraint(ColumnConstraintKind):
2004    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2007class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2008    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2011class TitleColumnConstraint(ColumnConstraintKind):
2012    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2015class UniqueColumnConstraint(ColumnConstraintKind):
2016    arg_types = {
2017        "this": False,
2018        "index_type": False,
2019        "on_conflict": False,
2020        "nulls": False,
2021        "options": False,
2022    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2025class UppercaseColumnConstraint(ColumnConstraintKind):
2026    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2030class WatermarkColumnConstraint(Expression):
2031    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2034class PathColumnConstraint(ColumnConstraintKind):
2035    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2039class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2040    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2045class ComputedColumnConstraint(ColumnConstraintKind):
2046    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2049class Constraint(Expression):
2050    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2053class Delete(DML):
2054    arg_types = {
2055        "with": False,
2056        "this": False,
2057        "using": False,
2058        "where": False,
2059        "returning": False,
2060        "limit": False,
2061        "tables": False,  # Multiple-Table Syntax (MySQL)
2062        "cluster": False,  # Clickhouse
2063    }
2064
2065    def delete(
2066        self,
2067        table: ExpOrStr,
2068        dialect: DialectType = None,
2069        copy: bool = True,
2070        **opts,
2071    ) -> Delete:
2072        """
2073        Create a DELETE expression or replace the table on an existing DELETE expression.
2074
2075        Example:
2076            >>> delete("tbl").sql()
2077            'DELETE FROM tbl'
2078
2079        Args:
2080            table: the table from which to delete.
2081            dialect: the dialect used to parse the input expression.
2082            copy: if `False`, modify this expression instance in-place.
2083            opts: other options to use to parse the input expressions.
2084
2085        Returns:
2086            Delete: the modified expression.
2087        """
2088        return _apply_builder(
2089            expression=table,
2090            instance=self,
2091            arg="this",
2092            dialect=dialect,
2093            into=Table,
2094            copy=copy,
2095            **opts,
2096        )
2097
2098    def where(
2099        self,
2100        *expressions: t.Optional[ExpOrStr],
2101        append: bool = True,
2102        dialect: DialectType = None,
2103        copy: bool = True,
2104        **opts,
2105    ) -> Delete:
2106        """
2107        Append to or set the WHERE expressions.
2108
2109        Example:
2110            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2111            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2112
2113        Args:
2114            *expressions: the SQL code strings to parse.
2115                If an `Expression` instance is passed, it will be used as-is.
2116                Multiple expressions are combined with an AND operator.
2117            append: if `True`, AND the new expressions to any existing expression.
2118                Otherwise, this resets the expression.
2119            dialect: the dialect used to parse the input expressions.
2120            copy: if `False`, modify this expression instance in-place.
2121            opts: other options to use to parse the input expressions.
2122
2123        Returns:
2124            Delete: the modified expression.
2125        """
2126        return _apply_conjunction_builder(
2127            *expressions,
2128            instance=self,
2129            arg="where",
2130            append=append,
2131            into=Where,
2132            dialect=dialect,
2133            copy=copy,
2134            **opts,
2135        )
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:
2065    def delete(
2066        self,
2067        table: ExpOrStr,
2068        dialect: DialectType = None,
2069        copy: bool = True,
2070        **opts,
2071    ) -> Delete:
2072        """
2073        Create a DELETE expression or replace the table on an existing DELETE expression.
2074
2075        Example:
2076            >>> delete("tbl").sql()
2077            'DELETE FROM tbl'
2078
2079        Args:
2080            table: the table from which to delete.
2081            dialect: the dialect used to parse the input expression.
2082            copy: if `False`, modify this expression instance in-place.
2083            opts: other options to use to parse the input expressions.
2084
2085        Returns:
2086            Delete: the modified expression.
2087        """
2088        return _apply_builder(
2089            expression=table,
2090            instance=self,
2091            arg="this",
2092            dialect=dialect,
2093            into=Table,
2094            copy=copy,
2095            **opts,
2096        )

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

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

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):
2380class ConditionalInsert(Expression):
2381    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2384class MultitableInserts(Expression):
2385    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2388class OnConflict(Expression):
2389    arg_types = {
2390        "duplicate": False,
2391        "expressions": False,
2392        "action": False,
2393        "conflict_keys": False,
2394        "constraint": False,
2395        "where": False,
2396    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2399class OnCondition(Expression):
2400    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2403class Returning(Expression):
2404    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2408class Introducer(Expression):
2409    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2413class National(Expression):
2414    pass
key = 'national'
class LoadData(Expression):
2417class LoadData(Expression):
2418    arg_types = {
2419        "this": True,
2420        "local": False,
2421        "overwrite": False,
2422        "inpath": True,
2423        "partition": False,
2424        "input_format": False,
2425        "serde": False,
2426    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2429class Partition(Expression):
2430    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2433class PartitionRange(Expression):
2434    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
class PartitionId(Expression):
2438class PartitionId(Expression):
2439    pass
key = 'partitionid'
class Fetch(Expression):
2442class Fetch(Expression):
2443    arg_types = {
2444        "direction": False,
2445        "count": False,
2446        "limit_options": False,
2447    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2450class Grant(Expression):
2451    arg_types = {
2452        "privileges": True,
2453        "kind": False,
2454        "securable": True,
2455        "principals": True,
2456        "grant_option": False,
2457    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2460class Group(Expression):
2461    arg_types = {
2462        "expressions": False,
2463        "grouping_sets": False,
2464        "cube": False,
2465        "rollup": False,
2466        "totals": False,
2467        "all": False,
2468    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2471class Cube(Expression):
2472    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2475class Rollup(Expression):
2476    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2479class GroupingSets(Expression):
2480    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2483class Lambda(Expression):
2484    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2487class Limit(Expression):
2488    arg_types = {
2489        "this": False,
2490        "expression": True,
2491        "offset": False,
2492        "limit_options": False,
2493        "expressions": False,
2494    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2497class LimitOptions(Expression):
2498    arg_types = {
2499        "percent": False,
2500        "rows": False,
2501        "with_ties": False,
2502    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2505class Literal(Condition):
2506    arg_types = {"this": True, "is_string": True}
2507
2508    @property
2509    def hashable_args(self) -> t.Any:
2510        return (self.this, self.args.get("is_string"))
2511
2512    @classmethod
2513    def number(cls, number) -> Literal:
2514        return cls(this=str(number), is_string=False)
2515
2516    @classmethod
2517    def string(cls, string) -> Literal:
2518        return cls(this=str(string), is_string=True)
2519
2520    @property
2521    def output_name(self) -> str:
2522        return self.name
2523
2524    def to_py(self) -> int | str | Decimal:
2525        if self.is_number:
2526            try:
2527                return int(self.this)
2528            except ValueError:
2529                return Decimal(self.this)
2530        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2508    @property
2509    def hashable_args(self) -> t.Any:
2510        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2512    @classmethod
2513    def number(cls, number) -> Literal:
2514        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2516    @classmethod
2517    def string(cls, string) -> Literal:
2518        return cls(this=str(string), is_string=True)
output_name: str
2520    @property
2521    def output_name(self) -> str:
2522        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:
2524    def to_py(self) -> int | str | Decimal:
2525        if self.is_number:
2526            try:
2527                return int(self.this)
2528            except ValueError:
2529                return Decimal(self.this)
2530        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2533class Join(Expression):
2534    arg_types = {
2535        "this": True,
2536        "on": False,
2537        "side": False,
2538        "kind": False,
2539        "using": False,
2540        "method": False,
2541        "global": False,
2542        "hint": False,
2543        "match_condition": False,  # Snowflake
2544        "expressions": False,
2545        "pivots": False,
2546    }
2547
2548    @property
2549    def method(self) -> str:
2550        return self.text("method").upper()
2551
2552    @property
2553    def kind(self) -> str:
2554        return self.text("kind").upper()
2555
2556    @property
2557    def side(self) -> str:
2558        return self.text("side").upper()
2559
2560    @property
2561    def hint(self) -> str:
2562        return self.text("hint").upper()
2563
2564    @property
2565    def alias_or_name(self) -> str:
2566        return self.this.alias_or_name
2567
2568    @property
2569    def is_semi_or_anti_join(self) -> bool:
2570        return self.kind in ("SEMI", "ANTI")
2571
2572    def on(
2573        self,
2574        *expressions: t.Optional[ExpOrStr],
2575        append: bool = True,
2576        dialect: DialectType = None,
2577        copy: bool = True,
2578        **opts,
2579    ) -> Join:
2580        """
2581        Append to or set the ON expressions.
2582
2583        Example:
2584            >>> import sqlglot
2585            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2586            'JOIN x ON y = 1'
2587
2588        Args:
2589            *expressions: the SQL code strings to parse.
2590                If an `Expression` instance is passed, it will be used as-is.
2591                Multiple expressions are combined with an AND operator.
2592            append: if `True`, AND the new expressions to any existing expression.
2593                Otherwise, this resets the expression.
2594            dialect: the dialect used to parse the input expressions.
2595            copy: if `False`, modify this expression instance in-place.
2596            opts: other options to use to parse the input expressions.
2597
2598        Returns:
2599            The modified Join expression.
2600        """
2601        join = _apply_conjunction_builder(
2602            *expressions,
2603            instance=self,
2604            arg="on",
2605            append=append,
2606            dialect=dialect,
2607            copy=copy,
2608            **opts,
2609        )
2610
2611        if join.kind == "CROSS":
2612            join.set("kind", None)
2613
2614        return join
2615
2616    def using(
2617        self,
2618        *expressions: t.Optional[ExpOrStr],
2619        append: bool = True,
2620        dialect: DialectType = None,
2621        copy: bool = True,
2622        **opts,
2623    ) -> Join:
2624        """
2625        Append to or set the USING expressions.
2626
2627        Example:
2628            >>> import sqlglot
2629            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2630            'JOIN x USING (foo, bla)'
2631
2632        Args:
2633            *expressions: the SQL code strings to parse.
2634                If an `Expression` instance is passed, it will be used as-is.
2635            append: if `True`, concatenate the new expressions to the existing "using" list.
2636                Otherwise, this resets the expression.
2637            dialect: the dialect used to parse the input expressions.
2638            copy: if `False`, modify this expression instance in-place.
2639            opts: other options to use to parse the input expressions.
2640
2641        Returns:
2642            The modified Join expression.
2643        """
2644        join = _apply_list_builder(
2645            *expressions,
2646            instance=self,
2647            arg="using",
2648            append=append,
2649            dialect=dialect,
2650            copy=copy,
2651            **opts,
2652        )
2653
2654        if join.kind == "CROSS":
2655            join.set("kind", None)
2656
2657        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
2548    @property
2549    def method(self) -> str:
2550        return self.text("method").upper()
kind: str
2552    @property
2553    def kind(self) -> str:
2554        return self.text("kind").upper()
side: str
2556    @property
2557    def side(self) -> str:
2558        return self.text("side").upper()
hint: str
2560    @property
2561    def hint(self) -> str:
2562        return self.text("hint").upper()
alias_or_name: str
2564    @property
2565    def alias_or_name(self) -> str:
2566        return self.this.alias_or_name
is_semi_or_anti_join: bool
2568    @property
2569    def is_semi_or_anti_join(self) -> bool:
2570        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:
2572    def on(
2573        self,
2574        *expressions: t.Optional[ExpOrStr],
2575        append: bool = True,
2576        dialect: DialectType = None,
2577        copy: bool = True,
2578        **opts,
2579    ) -> Join:
2580        """
2581        Append to or set the ON expressions.
2582
2583        Example:
2584            >>> import sqlglot
2585            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2586            'JOIN x ON y = 1'
2587
2588        Args:
2589            *expressions: the SQL code strings to parse.
2590                If an `Expression` instance is passed, it will be used as-is.
2591                Multiple expressions are combined with an AND operator.
2592            append: if `True`, AND the new expressions to any existing expression.
2593                Otherwise, this resets the expression.
2594            dialect: the dialect used to parse the input expressions.
2595            copy: if `False`, modify this expression instance in-place.
2596            opts: other options to use to parse the input expressions.
2597
2598        Returns:
2599            The modified Join expression.
2600        """
2601        join = _apply_conjunction_builder(
2602            *expressions,
2603            instance=self,
2604            arg="on",
2605            append=append,
2606            dialect=dialect,
2607            copy=copy,
2608            **opts,
2609        )
2610
2611        if join.kind == "CROSS":
2612            join.set("kind", None)
2613
2614        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:
2616    def using(
2617        self,
2618        *expressions: t.Optional[ExpOrStr],
2619        append: bool = True,
2620        dialect: DialectType = None,
2621        copy: bool = True,
2622        **opts,
2623    ) -> Join:
2624        """
2625        Append to or set the USING expressions.
2626
2627        Example:
2628            >>> import sqlglot
2629            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2630            'JOIN x USING (foo, bla)'
2631
2632        Args:
2633            *expressions: the SQL code strings to parse.
2634                If an `Expression` instance is passed, it will be used as-is.
2635            append: if `True`, concatenate the new expressions to the existing "using" list.
2636                Otherwise, this resets the expression.
2637            dialect: the dialect used to parse the input expressions.
2638            copy: if `False`, modify this expression instance in-place.
2639            opts: other options to use to parse the input expressions.
2640
2641        Returns:
2642            The modified Join expression.
2643        """
2644        join = _apply_list_builder(
2645            *expressions,
2646            instance=self,
2647            arg="using",
2648            append=append,
2649            dialect=dialect,
2650            copy=copy,
2651            **opts,
2652        )
2653
2654        if join.kind == "CROSS":
2655            join.set("kind", None)
2656
2657        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):
2660class Lateral(UDTF):
2661    arg_types = {
2662        "this": True,
2663        "view": False,
2664        "outer": False,
2665        "alias": False,
2666        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2667        "ordinality": False,
2668    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2673class TableFromRows(UDTF):
2674    arg_types = {
2675        "this": True,
2676        "alias": False,
2677        "joins": False,
2678        "pivots": False,
2679        "sample": False,
2680    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2683class MatchRecognizeMeasure(Expression):
2684    arg_types = {
2685        "this": True,
2686        "window_frame": False,
2687    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2690class MatchRecognize(Expression):
2691    arg_types = {
2692        "partition_by": False,
2693        "order": False,
2694        "measures": False,
2695        "rows": False,
2696        "after": False,
2697        "pattern": False,
2698        "define": False,
2699        "alias": False,
2700    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2705class Final(Expression):
2706    pass
key = 'final'
class Offset(Expression):
2709class Offset(Expression):
2710    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2713class Order(Expression):
2714    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2718class WithFill(Expression):
2719    arg_types = {
2720        "from": False,
2721        "to": False,
2722        "step": False,
2723        "interpolate": False,
2724    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2729class Cluster(Order):
2730    pass
key = 'cluster'
class Distribute(Order):
2733class Distribute(Order):
2734    pass
key = 'distribute'
class Sort(Order):
2737class Sort(Order):
2738    pass
key = 'sort'
class Ordered(Expression):
2741class Ordered(Expression):
2742    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2743
2744    @property
2745    def name(self) -> str:
2746        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2744    @property
2745    def name(self) -> str:
2746        return self.this.name
key = 'ordered'
class Property(Expression):
2749class Property(Expression):
2750    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2753class GrantPrivilege(Expression):
2754    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2757class GrantPrincipal(Expression):
2758    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2761class AllowedValuesProperty(Expression):
2762    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2765class AlgorithmProperty(Property):
2766    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2769class AutoIncrementProperty(Property):
2770    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2774class AutoRefreshProperty(Property):
2775    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2778class BackupProperty(Property):
2779    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2782class BlockCompressionProperty(Property):
2783    arg_types = {
2784        "autotemp": False,
2785        "always": False,
2786        "default": False,
2787        "manual": False,
2788        "never": False,
2789    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2792class CharacterSetProperty(Property):
2793    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2796class ChecksumProperty(Property):
2797    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2800class CollateProperty(Property):
2801    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2804class CopyGrantsProperty(Property):
2805    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2808class DataBlocksizeProperty(Property):
2809    arg_types = {
2810        "size": False,
2811        "units": False,
2812        "minimum": False,
2813        "maximum": False,
2814        "default": False,
2815    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2818class DataDeletionProperty(Property):
2819    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):
2822class DefinerProperty(Property):
2823    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2826class DistKeyProperty(Property):
2827    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2832class DistributedByProperty(Property):
2833    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):
2836class DistStyleProperty(Property):
2837    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2840class DuplicateKeyProperty(Property):
2841    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2844class EngineProperty(Property):
2845    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2848class HeapProperty(Property):
2849    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2852class ToTableProperty(Property):
2853    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2856class ExecuteAsProperty(Property):
2857    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2860class ExternalProperty(Property):
2861    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2864class FallbackProperty(Property):
2865    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2869class FileFormatProperty(Property):
2870    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2873class CredentialsProperty(Property):
2874    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2877class FreespaceProperty(Property):
2878    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2881class GlobalProperty(Property):
2882    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2885class IcebergProperty(Property):
2886    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2889class InheritsProperty(Property):
2890    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2893class InputModelProperty(Property):
2894    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2897class OutputModelProperty(Property):
2898    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2901class IsolatedLoadingProperty(Property):
2902    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2905class JournalProperty(Property):
2906    arg_types = {
2907        "no": False,
2908        "dual": False,
2909        "before": False,
2910        "local": False,
2911        "after": False,
2912    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2915class LanguageProperty(Property):
2916    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2919class EnviromentProperty(Property):
2920    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2924class ClusteredByProperty(Property):
2925    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2928class DictProperty(Property):
2929    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2932class DictSubProperty(Property):
2933    pass
key = 'dictsubproperty'
class DictRange(Property):
2936class DictRange(Property):
2937    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2940class DynamicProperty(Property):
2941    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2946class OnCluster(Property):
2947    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2951class EmptyProperty(Property):
2952    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2955class LikeProperty(Property):
2956    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2959class LocationProperty(Property):
2960    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2963class LockProperty(Property):
2964    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2967class LockingProperty(Property):
2968    arg_types = {
2969        "this": False,
2970        "kind": True,
2971        "for_or_in": False,
2972        "lock_type": True,
2973        "override": False,
2974    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2977class LogProperty(Property):
2978    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2981class MaterializedProperty(Property):
2982    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2985class MergeBlockRatioProperty(Property):
2986    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):
2989class NoPrimaryIndexProperty(Property):
2990    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2993class OnProperty(Property):
2994    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2997class OnCommitProperty(Property):
2998    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3001class PartitionedByProperty(Property):
3002    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3005class PartitionedByBucket(Property):
3006    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3009class PartitionByTruncate(Property):
3010    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3014class PartitionByRangeProperty(Property):
3015    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3019class PartitionByRangePropertyDynamic(Expression):
3020    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):
3024class UniqueKeyProperty(Property):
3025    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3029class PartitionBoundSpec(Expression):
3030    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3031    arg_types = {
3032        "this": False,
3033        "expression": False,
3034        "from_expressions": False,
3035        "to_expressions": False,
3036    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3039class PartitionedOfProperty(Property):
3040    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3041    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3044class StreamingTableProperty(Property):
3045    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3048class RemoteWithConnectionModelProperty(Property):
3049    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3052class ReturnsProperty(Property):
3053    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):
3056class StrictProperty(Property):
3057    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3060class RowFormatProperty(Property):
3061    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3064class RowFormatDelimitedProperty(Property):
3065    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3066    arg_types = {
3067        "fields": False,
3068        "escaped": False,
3069        "collection_items": False,
3070        "map_keys": False,
3071        "lines": False,
3072        "null": False,
3073        "serde": False,
3074    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3077class RowFormatSerdeProperty(Property):
3078    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3082class QueryTransform(Expression):
3083    arg_types = {
3084        "expressions": True,
3085        "command_script": True,
3086        "schema": False,
3087        "row_format_before": False,
3088        "record_writer": False,
3089        "row_format_after": False,
3090        "record_reader": False,
3091    }
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):
3094class SampleProperty(Property):
3095    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3099class SecurityProperty(Property):
3100    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3103class SchemaCommentProperty(Property):
3104    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3107class SemanticView(Expression):
3108    arg_types = {"this": True, "metrics": False, "dimensions": False, "where": False}
arg_types = {'this': True, 'metrics': False, 'dimensions': False, 'where': False}
key = 'semanticview'
class SerdeProperties(Property):
3111class SerdeProperties(Property):
3112    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3115class SetProperty(Property):
3116    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3119class SharingProperty(Property):
3120    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3123class SetConfigProperty(Property):
3124    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3127class SettingsProperty(Property):
3128    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3131class SortKeyProperty(Property):
3132    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3135class SqlReadWriteProperty(Property):
3136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3139class SqlSecurityProperty(Property):
3140    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3143class StabilityProperty(Property):
3144    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3147class StorageHandlerProperty(Property):
3148    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3151class TemporaryProperty(Property):
3152    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3155class SecureProperty(Property):
3156    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3160class Tags(ColumnConstraintKind, Property):
3161    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3164class TransformModelProperty(Property):
3165    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3168class TransientProperty(Property):
3169    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3172class UnloggedProperty(Property):
3173    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3177class UsingTemplateProperty(Property):
3178    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3182class ViewAttributeProperty(Property):
3183    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3186class VolatileProperty(Property):
3187    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3190class WithDataProperty(Property):
3191    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3194class WithJournalTableProperty(Property):
3195    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3198class WithSchemaBindingProperty(Property):
3199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3202class WithSystemVersioningProperty(Property):
3203    arg_types = {
3204        "on": False,
3205        "this": False,
3206        "data_consistency": False,
3207        "retention_period": False,
3208        "with": True,
3209    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3212class WithProcedureOptions(Property):
3213    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3216class EncodeProperty(Property):
3217    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3220class IncludeProperty(Property):
3221    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3224class ForceProperty(Property):
3225    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3228class Properties(Expression):
3229    arg_types = {"expressions": True}
3230
3231    NAME_TO_PROPERTY = {
3232        "ALGORITHM": AlgorithmProperty,
3233        "AUTO_INCREMENT": AutoIncrementProperty,
3234        "CHARACTER SET": CharacterSetProperty,
3235        "CLUSTERED_BY": ClusteredByProperty,
3236        "COLLATE": CollateProperty,
3237        "COMMENT": SchemaCommentProperty,
3238        "CREDENTIALS": CredentialsProperty,
3239        "DEFINER": DefinerProperty,
3240        "DISTKEY": DistKeyProperty,
3241        "DISTRIBUTED_BY": DistributedByProperty,
3242        "DISTSTYLE": DistStyleProperty,
3243        "ENGINE": EngineProperty,
3244        "EXECUTE AS": ExecuteAsProperty,
3245        "FORMAT": FileFormatProperty,
3246        "LANGUAGE": LanguageProperty,
3247        "LOCATION": LocationProperty,
3248        "LOCK": LockProperty,
3249        "PARTITIONED_BY": PartitionedByProperty,
3250        "RETURNS": ReturnsProperty,
3251        "ROW_FORMAT": RowFormatProperty,
3252        "SORTKEY": SortKeyProperty,
3253        "ENCODE": EncodeProperty,
3254        "INCLUDE": IncludeProperty,
3255    }
3256
3257    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3258
3259    # CREATE property locations
3260    # Form: schema specified
3261    #   create [POST_CREATE]
3262    #     table a [POST_NAME]
3263    #     (b int) [POST_SCHEMA]
3264    #     with ([POST_WITH])
3265    #     index (b) [POST_INDEX]
3266    #
3267    # Form: alias selection
3268    #   create [POST_CREATE]
3269    #     table a [POST_NAME]
3270    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3271    #     index (c) [POST_INDEX]
3272    class Location(AutoName):
3273        POST_CREATE = auto()
3274        POST_NAME = auto()
3275        POST_SCHEMA = auto()
3276        POST_WITH = auto()
3277        POST_ALIAS = auto()
3278        POST_EXPRESSION = auto()
3279        POST_INDEX = auto()
3280        UNSUPPORTED = auto()
3281
3282    @classmethod
3283    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3284        expressions = []
3285        for key, value in properties_dict.items():
3286            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3287            if property_cls:
3288                expressions.append(property_cls(this=convert(value)))
3289            else:
3290                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3291
3292        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:
3282    @classmethod
3283    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3284        expressions = []
3285        for key, value in properties_dict.items():
3286            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3287            if property_cls:
3288                expressions.append(property_cls(this=convert(value)))
3289            else:
3290                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3291
3292        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3272    class Location(AutoName):
3273        POST_CREATE = auto()
3274        POST_NAME = auto()
3275        POST_SCHEMA = auto()
3276        POST_WITH = auto()
3277        POST_ALIAS = auto()
3278        POST_EXPRESSION = auto()
3279        POST_INDEX = auto()
3280        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):
3295class Qualify(Expression):
3296    pass
key = 'qualify'
class InputOutputFormat(Expression):
3299class InputOutputFormat(Expression):
3300    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3304class Return(Expression):
3305    pass
key = 'return'
class Reference(Expression):
3308class Reference(Expression):
3309    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3312class Tuple(Expression):
3313    arg_types = {"expressions": False}
3314
3315    def isin(
3316        self,
3317        *expressions: t.Any,
3318        query: t.Optional[ExpOrStr] = None,
3319        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3320        copy: bool = True,
3321        **opts,
3322    ) -> In:
3323        return In(
3324            this=maybe_copy(self, copy),
3325            expressions=[convert(e, copy=copy) for e in expressions],
3326            query=maybe_parse(query, copy=copy, **opts) if query else None,
3327            unnest=(
3328                Unnest(
3329                    expressions=[
3330                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3331                        for e in ensure_list(unnest)
3332                    ]
3333                )
3334                if unnest
3335                else None
3336            ),
3337        )
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:
3315    def isin(
3316        self,
3317        *expressions: t.Any,
3318        query: t.Optional[ExpOrStr] = None,
3319        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3320        copy: bool = True,
3321        **opts,
3322    ) -> In:
3323        return In(
3324            this=maybe_copy(self, copy),
3325            expressions=[convert(e, copy=copy) for e in expressions],
3326            query=maybe_parse(query, copy=copy, **opts) if query else None,
3327            unnest=(
3328                Unnest(
3329                    expressions=[
3330                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3331                        for e in ensure_list(unnest)
3332                    ]
3333                )
3334                if unnest
3335                else None
3336            ),
3337        )
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):
3368class QueryOption(Expression):
3369    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3373class WithTableHint(Expression):
3374    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3378class IndexTableHint(Expression):
3379    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3383class HistoricalData(Expression):
3384    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3388class Put(Expression):
3389    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3393class Get(Expression):
3394    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3397class Table(Expression):
3398    arg_types = {
3399        "this": False,
3400        "alias": False,
3401        "db": False,
3402        "catalog": False,
3403        "laterals": False,
3404        "joins": False,
3405        "pivots": False,
3406        "hints": False,
3407        "system_time": False,
3408        "version": False,
3409        "format": False,
3410        "pattern": False,
3411        "ordinality": False,
3412        "when": False,
3413        "only": False,
3414        "partition": False,
3415        "changes": False,
3416        "rows_from": False,
3417        "sample": False,
3418    }
3419
3420    @property
3421    def name(self) -> str:
3422        if not self.this or isinstance(self.this, Func):
3423            return ""
3424        return self.this.name
3425
3426    @property
3427    def db(self) -> str:
3428        return self.text("db")
3429
3430    @property
3431    def catalog(self) -> str:
3432        return self.text("catalog")
3433
3434    @property
3435    def selects(self) -> t.List[Expression]:
3436        return []
3437
3438    @property
3439    def named_selects(self) -> t.List[str]:
3440        return []
3441
3442    @property
3443    def parts(self) -> t.List[Expression]:
3444        """Return the parts of a table in order catalog, db, table."""
3445        parts: t.List[Expression] = []
3446
3447        for arg in ("catalog", "db", "this"):
3448            part = self.args.get(arg)
3449
3450            if isinstance(part, Dot):
3451                parts.extend(part.flatten())
3452            elif isinstance(part, Expression):
3453                parts.append(part)
3454
3455        return parts
3456
3457    def to_column(self, copy: bool = True) -> Expression:
3458        parts = self.parts
3459        last_part = parts[-1]
3460
3461        if isinstance(last_part, Identifier):
3462            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3463        else:
3464            # This branch will be reached if a function or array is wrapped in a `Table`
3465            col = last_part
3466
3467        alias = self.args.get("alias")
3468        if alias:
3469            col = alias_(col, alias.this, copy=copy)
3470
3471        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
3420    @property
3421    def name(self) -> str:
3422        if not self.this or isinstance(self.this, Func):
3423            return ""
3424        return self.this.name
db: str
3426    @property
3427    def db(self) -> str:
3428        return self.text("db")
catalog: str
3430    @property
3431    def catalog(self) -> str:
3432        return self.text("catalog")
selects: List[Expression]
3434    @property
3435    def selects(self) -> t.List[Expression]:
3436        return []
named_selects: List[str]
3438    @property
3439    def named_selects(self) -> t.List[str]:
3440        return []
parts: List[Expression]
3442    @property
3443    def parts(self) -> t.List[Expression]:
3444        """Return the parts of a table in order catalog, db, table."""
3445        parts: t.List[Expression] = []
3446
3447        for arg in ("catalog", "db", "this"):
3448            part = self.args.get(arg)
3449
3450            if isinstance(part, Dot):
3451                parts.extend(part.flatten())
3452            elif isinstance(part, Expression):
3453                parts.append(part)
3454
3455        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3457    def to_column(self, copy: bool = True) -> Expression:
3458        parts = self.parts
3459        last_part = parts[-1]
3460
3461        if isinstance(last_part, Identifier):
3462            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3463        else:
3464            # This branch will be reached if a function or array is wrapped in a `Table`
3465            col = last_part
3466
3467        alias = self.args.get("alias")
3468        if alias:
3469            col = alias_(col, alias.this, copy=copy)
3470
3471        return col
key = 'table'
class SetOperation(Query):
3474class SetOperation(Query):
3475    arg_types = {
3476        "with": False,
3477        "this": True,
3478        "expression": True,
3479        "distinct": False,
3480        "by_name": False,
3481        "side": False,
3482        "kind": False,
3483        "on": False,
3484        **QUERY_MODIFIERS,
3485    }
3486
3487    def select(
3488        self: S,
3489        *expressions: t.Optional[ExpOrStr],
3490        append: bool = True,
3491        dialect: DialectType = None,
3492        copy: bool = True,
3493        **opts,
3494    ) -> S:
3495        this = maybe_copy(self, copy)
3496        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3497        this.expression.unnest().select(
3498            *expressions, append=append, dialect=dialect, copy=False, **opts
3499        )
3500        return this
3501
3502    @property
3503    def named_selects(self) -> t.List[str]:
3504        return self.this.unnest().named_selects
3505
3506    @property
3507    def is_star(self) -> bool:
3508        return self.this.is_star or self.expression.is_star
3509
3510    @property
3511    def selects(self) -> t.List[Expression]:
3512        return self.this.unnest().selects
3513
3514    @property
3515    def left(self) -> Query:
3516        return self.this
3517
3518    @property
3519    def right(self) -> Query:
3520        return self.expression
3521
3522    @property
3523    def kind(self) -> str:
3524        return self.text("kind").upper()
3525
3526    @property
3527    def side(self) -> str:
3528        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:
3487    def select(
3488        self: S,
3489        *expressions: t.Optional[ExpOrStr],
3490        append: bool = True,
3491        dialect: DialectType = None,
3492        copy: bool = True,
3493        **opts,
3494    ) -> S:
3495        this = maybe_copy(self, copy)
3496        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3497        this.expression.unnest().select(
3498            *expressions, append=append, dialect=dialect, copy=False, **opts
3499        )
3500        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]
3502    @property
3503    def named_selects(self) -> t.List[str]:
3504        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3506    @property
3507    def is_star(self) -> bool:
3508        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3510    @property
3511    def selects(self) -> t.List[Expression]:
3512        return self.this.unnest().selects

Returns the query's projections.

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

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:
3587    def set_(
3588        self,
3589        *expressions: ExpOrStr,
3590        append: bool = True,
3591        dialect: DialectType = None,
3592        copy: bool = True,
3593        **opts,
3594    ) -> Update:
3595        """
3596        Append to or set the SET expressions.
3597
3598        Example:
3599            >>> Update().table("my_table").set_("x = 1").sql()
3600            'UPDATE my_table SET x = 1'
3601
3602        Args:
3603            *expressions: the SQL code strings to parse.
3604                If `Expression` instance(s) are passed, they will be used as-is.
3605                Multiple expressions are combined with a comma.
3606            append: if `True`, add the new expressions to any existing SET expressions.
3607                Otherwise, this resets the expressions.
3608            dialect: the dialect used to parse the input expressions.
3609            copy: if `False`, modify this expression instance in-place.
3610            opts: other options to use to parse the input expressions.
3611        """
3612        return _apply_list_builder(
3613            *expressions,
3614            instance=self,
3615            arg="expressions",
3616            append=append,
3617            into=Expression,
3618            prefix=None,
3619            dialect=dialect,
3620            copy=copy,
3621            **opts,
3622        )

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:
3624    def where(
3625        self,
3626        *expressions: t.Optional[ExpOrStr],
3627        append: bool = True,
3628        dialect: DialectType = None,
3629        copy: bool = True,
3630        **opts,
3631    ) -> Select:
3632        """
3633        Append to or set the WHERE expressions.
3634
3635        Example:
3636            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3637            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3638
3639        Args:
3640            *expressions: the SQL code strings to parse.
3641                If an `Expression` instance is passed, it will be used as-is.
3642                Multiple expressions are combined with an AND operator.
3643            append: if `True`, AND the new expressions to any existing expression.
3644                Otherwise, this resets the expression.
3645            dialect: the dialect used to parse the input expressions.
3646            copy: if `False`, modify this expression instance in-place.
3647            opts: other options to use to parse the input expressions.
3648
3649        Returns:
3650            Select: the modified expression.
3651        """
3652        return _apply_conjunction_builder(
3653            *expressions,
3654            instance=self,
3655            arg="where",
3656            append=append,
3657            into=Where,
3658            dialect=dialect,
3659            copy=copy,
3660            **opts,
3661        )

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:
3663    def from_(
3664        self,
3665        expression: t.Optional[ExpOrStr] = None,
3666        dialect: DialectType = None,
3667        copy: bool = True,
3668        **opts,
3669    ) -> Update:
3670        """
3671        Set the FROM expression.
3672
3673        Example:
3674            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3675            'UPDATE my_table SET x = 1 FROM baz'
3676
3677        Args:
3678            expression : the SQL code strings to parse.
3679                If a `From` instance is passed, this is used as-is.
3680                If another `Expression` instance is passed, it will be wrapped in a `From`.
3681                If nothing is passed in then a from is not applied to the expression
3682            dialect: the dialect used to parse the input expression.
3683            copy: if `False`, modify this expression instance in-place.
3684            opts: other options to use to parse the input expressions.
3685
3686        Returns:
3687            The modified Update expression.
3688        """
3689        if not expression:
3690            return maybe_copy(self, copy)
3691
3692        return _apply_builder(
3693            expression=expression,
3694            instance=self,
3695            arg="from",
3696            into=From,
3697            prefix="FROM",
3698            dialect=dialect,
3699            copy=copy,
3700            **opts,
3701        )

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:
3703    def with_(
3704        self,
3705        alias: ExpOrStr,
3706        as_: ExpOrStr,
3707        recursive: t.Optional[bool] = None,
3708        materialized: t.Optional[bool] = None,
3709        append: bool = True,
3710        dialect: DialectType = None,
3711        copy: bool = True,
3712        **opts,
3713    ) -> Update:
3714        """
3715        Append to or set the common table expressions.
3716
3717        Example:
3718            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3719            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3720
3721        Args:
3722            alias: the SQL code string to parse as the table name.
3723                If an `Expression` instance is passed, this is used as-is.
3724            as_: the SQL code string to parse as the table expression.
3725                If an `Expression` instance is passed, it will be used as-is.
3726            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3727            materialized: set the MATERIALIZED part of the expression.
3728            append: if `True`, add to any existing expressions.
3729                Otherwise, this resets the expressions.
3730            dialect: the dialect used to parse the input expression.
3731            copy: if `False`, modify this expression instance in-place.
3732            opts: other options to use to parse the input expressions.
3733
3734        Returns:
3735            The modified expression.
3736        """
3737        return _apply_cte_builder(
3738            self,
3739            alias,
3740            as_,
3741            recursive=recursive,
3742            materialized=materialized,
3743            append=append,
3744            dialect=dialect,
3745            copy=copy,
3746            **opts,
3747        )

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

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:
3827    def group_by(
3828        self,
3829        *expressions: t.Optional[ExpOrStr],
3830        append: bool = True,
3831        dialect: DialectType = None,
3832        copy: bool = True,
3833        **opts,
3834    ) -> Select:
3835        """
3836        Set the GROUP BY expression.
3837
3838        Example:
3839            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3840            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3841
3842        Args:
3843            *expressions: the SQL code strings to parse.
3844                If a `Group` instance is passed, this is used as-is.
3845                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3846                If nothing is passed in then a group by is not applied to the expression
3847            append: if `True`, add to any existing expressions.
3848                Otherwise, this flattens all the `Group` expression into a single expression.
3849            dialect: the dialect used to parse the input expression.
3850            copy: if `False`, modify this expression instance in-place.
3851            opts: other options to use to parse the input expressions.
3852
3853        Returns:
3854            The modified Select expression.
3855        """
3856        if not expressions:
3857            return self if not copy else self.copy()
3858
3859        return _apply_child_list_builder(
3860            *expressions,
3861            instance=self,
3862            arg="group",
3863            append=append,
3864            copy=copy,
3865            prefix="GROUP BY",
3866            into=Group,
3867            dialect=dialect,
3868            **opts,
3869        )

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:
3871    def sort_by(
3872        self,
3873        *expressions: t.Optional[ExpOrStr],
3874        append: bool = True,
3875        dialect: DialectType = None,
3876        copy: bool = True,
3877        **opts,
3878    ) -> Select:
3879        """
3880        Set the SORT BY expression.
3881
3882        Example:
3883            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3884            'SELECT x FROM tbl SORT BY x DESC'
3885
3886        Args:
3887            *expressions: the SQL code strings to parse.
3888                If a `Group` instance is passed, this is used as-is.
3889                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3890            append: if `True`, add to any existing expressions.
3891                Otherwise, this flattens all the `Order` expression into a single expression.
3892            dialect: the dialect used to parse the input expression.
3893            copy: if `False`, modify this expression instance in-place.
3894            opts: other options to use to parse the input expressions.
3895
3896        Returns:
3897            The modified Select expression.
3898        """
3899        return _apply_child_list_builder(
3900            *expressions,
3901            instance=self,
3902            arg="sort",
3903            append=append,
3904            copy=copy,
3905            prefix="SORT BY",
3906            into=Sort,
3907            dialect=dialect,
3908            **opts,
3909        )

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:
3911    def cluster_by(
3912        self,
3913        *expressions: t.Optional[ExpOrStr],
3914        append: bool = True,
3915        dialect: DialectType = None,
3916        copy: bool = True,
3917        **opts,
3918    ) -> Select:
3919        """
3920        Set the CLUSTER BY expression.
3921
3922        Example:
3923            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3924            'SELECT x FROM tbl CLUSTER BY x DESC'
3925
3926        Args:
3927            *expressions: the SQL code strings to parse.
3928                If a `Group` instance is passed, this is used as-is.
3929                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3930            append: if `True`, add to any existing expressions.
3931                Otherwise, this flattens all the `Order` expression into a single expression.
3932            dialect: the dialect used to parse the input expression.
3933            copy: if `False`, modify this expression instance in-place.
3934            opts: other options to use to parse the input expressions.
3935
3936        Returns:
3937            The modified Select expression.
3938        """
3939        return _apply_child_list_builder(
3940            *expressions,
3941            instance=self,
3942            arg="cluster",
3943            append=append,
3944            copy=copy,
3945            prefix="CLUSTER BY",
3946            into=Cluster,
3947            dialect=dialect,
3948            **opts,
3949        )

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:
3951    def select(
3952        self,
3953        *expressions: t.Optional[ExpOrStr],
3954        append: bool = True,
3955        dialect: DialectType = None,
3956        copy: bool = True,
3957        **opts,
3958    ) -> Select:
3959        return _apply_list_builder(
3960            *expressions,
3961            instance=self,
3962            arg="expressions",
3963            append=append,
3964            dialect=dialect,
3965            into=Expression,
3966            copy=copy,
3967            **opts,
3968        )

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:
3970    def lateral(
3971        self,
3972        *expressions: t.Optional[ExpOrStr],
3973        append: bool = True,
3974        dialect: DialectType = None,
3975        copy: bool = True,
3976        **opts,
3977    ) -> Select:
3978        """
3979        Append to or set the LATERAL expressions.
3980
3981        Example:
3982            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3983            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3984
3985        Args:
3986            *expressions: the SQL code strings to parse.
3987                If an `Expression` instance is passed, it will be used as-is.
3988            append: if `True`, add to any existing expressions.
3989                Otherwise, this resets the expressions.
3990            dialect: the dialect used to parse the input expressions.
3991            copy: if `False`, modify this expression instance in-place.
3992            opts: other options to use to parse the input expressions.
3993
3994        Returns:
3995            The modified Select expression.
3996        """
3997        return _apply_list_builder(
3998            *expressions,
3999            instance=self,
4000            arg="laterals",
4001            append=append,
4002            into=Lateral,
4003            prefix="LATERAL VIEW",
4004            dialect=dialect,
4005            copy=copy,
4006            **opts,
4007        )

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
4302    @property
4303    def selects(self) -> t.List[Expression]:
4304        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
4325    def unwrap(self) -> Subquery:
4326        expression = self
4327        while expression.same_parent and expression.is_wrapper:
4328            expression = t.cast(Subquery, expression.parent)
4329        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:
4331    def select(
4332        self,
4333        *expressions: t.Optional[ExpOrStr],
4334        append: bool = True,
4335        dialect: DialectType = None,
4336        copy: bool = True,
4337        **opts,
4338    ) -> Subquery:
4339        this = maybe_copy(self, copy)
4340        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4341        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
4343    @property
4344    def is_wrapper(self) -> bool:
4345        """
4346        Whether this Subquery acts as a simple wrapper around another expression.
4347
4348        SELECT * FROM (((SELECT * FROM t)))
4349                      ^
4350                      This corresponds to a "wrapper" Subquery node
4351        """
4352        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
4354    @property
4355    def is_star(self) -> bool:
4356        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4358    @property
4359    def output_name(self) -> str:
4360        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):
4363class TableSample(Expression):
4364    arg_types = {
4365        "expressions": False,
4366        "method": False,
4367        "bucket_numerator": False,
4368        "bucket_denominator": False,
4369        "bucket_field": False,
4370        "percent": False,
4371        "rows": False,
4372        "size": False,
4373        "seed": False,
4374    }
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):
4377class Tag(Expression):
4378    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4379
4380    arg_types = {
4381        "this": False,
4382        "prefix": False,
4383        "postfix": False,
4384    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4389class Pivot(Expression):
4390    arg_types = {
4391        "this": False,
4392        "alias": False,
4393        "expressions": False,
4394        "fields": False,
4395        "unpivot": False,
4396        "using": False,
4397        "group": False,
4398        "columns": False,
4399        "include_nulls": False,
4400        "default_on_null": False,
4401        "into": False,
4402    }
4403
4404    @property
4405    def unpivot(self) -> bool:
4406        return bool(self.args.get("unpivot"))
4407
4408    @property
4409    def fields(self) -> t.List[Expression]:
4410        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
4404    @property
4405    def unpivot(self) -> bool:
4406        return bool(self.args.get("unpivot"))
fields: List[Expression]
4408    @property
4409    def fields(self) -> t.List[Expression]:
4410        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4415class UnpivotColumns(Expression):
4416    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4419class Window(Condition):
4420    arg_types = {
4421        "this": True,
4422        "partition_by": False,
4423        "order": False,
4424        "spec": False,
4425        "alias": False,
4426        "over": False,
4427        "first": False,
4428    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4431class WindowSpec(Expression):
4432    arg_types = {
4433        "kind": False,
4434        "start": False,
4435        "start_side": False,
4436        "end": False,
4437        "end_side": False,
4438        "exclude": False,
4439    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4442class PreWhere(Expression):
4443    pass
key = 'prewhere'
class Where(Expression):
4446class Where(Expression):
4447    pass
key = 'where'
class Star(Expression):
4450class Star(Expression):
4451    arg_types = {"except": False, "replace": False, "rename": False}
4452
4453    @property
4454    def name(self) -> str:
4455        return "*"
4456
4457    @property
4458    def output_name(self) -> str:
4459        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4453    @property
4454    def name(self) -> str:
4455        return "*"
output_name: str
4457    @property
4458    def output_name(self) -> str:
4459        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):
4462class Parameter(Condition):
4463    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4466class SessionParameter(Condition):
4467    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4471class Placeholder(Condition):
4472    arg_types = {"this": False, "kind": False, "widget": False}
4473
4474    @property
4475    def name(self) -> str:
4476        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False}
name: str
4474    @property
4475    def name(self) -> str:
4476        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4479class Null(Condition):
4480    arg_types: t.Dict[str, t.Any] = {}
4481
4482    @property
4483    def name(self) -> str:
4484        return "NULL"
4485
4486    def to_py(self) -> Lit[None]:
4487        return None
arg_types: Dict[str, Any] = {}
name: str
4482    @property
4483    def name(self) -> str:
4484        return "NULL"
def to_py(self) -> Literal[None]:
4486    def to_py(self) -> Lit[None]:
4487        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4490class Boolean(Condition):
4491    def to_py(self) -> bool:
4492        return self.this
def to_py(self) -> bool:
4491    def to_py(self) -> bool:
4492        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
5015    @property
5016    def name(self) -> str:
5017        return self.expression.name
output_name: str
5019    @property
5020    def output_name(self) -> str:
5021        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:
5023    @classmethod
5024    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5025        """Build a Dot object with a sequence of expressions."""
5026        if len(expressions) < 2:
5027            raise ValueError("Dot requires >= 2 expressions.")
5028
5029        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]
5031    @property
5032    def parts(self) -> t.List[Expression]:
5033        """Return the parts of a table / column in order catalog, db, table."""
5034        this, *parts = self.flatten()
5035
5036        parts.reverse()
5037
5038        for arg in COLUMN_PARTS:
5039            part = this.args.get(arg)
5040
5041            if isinstance(part, Expression):
5042                parts.append(part)
5043
5044        parts.reverse()
5045        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):
5051class DPipe(Binary):
5052    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5055class EQ(Binary, Predicate):
5056    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5059class NullSafeEQ(Binary, Predicate):
5060    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5063class NullSafeNEQ(Binary, Predicate):
5064    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5068class PropertyEQ(Binary):
5069    pass
key = 'propertyeq'
class Distance(Binary):
5072class Distance(Binary):
5073    pass
key = 'distance'
class Escape(Binary):
5076class Escape(Binary):
5077    pass
key = 'escape'
class Glob(Binary, Predicate):
5080class Glob(Binary, Predicate):
5081    pass
key = 'glob'
class GT(Binary, Predicate):
5084class GT(Binary, Predicate):
5085    pass
key = 'gt'
class GTE(Binary, Predicate):
5088class GTE(Binary, Predicate):
5089    pass
key = 'gte'
class ILike(Binary, Predicate):
5092class ILike(Binary, Predicate):
5093    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5096class ILikeAny(Binary, Predicate):
5097    pass
key = 'ilikeany'
class IntDiv(Binary):
5100class IntDiv(Binary):
5101    pass
key = 'intdiv'
class Is(Binary, Predicate):
5104class Is(Binary, Predicate):
5105    pass
key = 'is'
class Kwarg(Binary):
5108class Kwarg(Binary):
5109    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5112class Like(Binary, Predicate):
5113    pass
key = 'like'
class LikeAny(Binary, Predicate):
5116class LikeAny(Binary, Predicate):
5117    pass
key = 'likeany'
class LT(Binary, Predicate):
5120class LT(Binary, Predicate):
5121    pass
key = 'lt'
class LTE(Binary, Predicate):
5124class LTE(Binary, Predicate):
5125    pass
key = 'lte'
class Mod(Binary):
5128class Mod(Binary):
5129    pass
key = 'mod'
class Mul(Binary):
5132class Mul(Binary):
5133    pass
key = 'mul'
class NEQ(Binary, Predicate):
5136class NEQ(Binary, Predicate):
5137    pass
key = 'neq'
class Operator(Binary):
5141class Operator(Binary):
5142    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5145class SimilarTo(Binary, Predicate):
5146    pass
key = 'similarto'
class Slice(Binary):
5149class Slice(Binary):
5150    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5153class Sub(Binary):
5154    pass
key = 'sub'
class Unary(Condition):
5159class Unary(Condition):
5160    pass
key = 'unary'
class BitwiseNot(Unary):
5163class BitwiseNot(Unary):
5164    pass
key = 'bitwisenot'
class Not(Unary):
5167class Not(Unary):
5168    pass
key = 'not'
class Paren(Unary):
5171class Paren(Unary):
5172    @property
5173    def output_name(self) -> str:
5174        return self.this.name
output_name: str
5172    @property
5173    def output_name(self) -> str:
5174        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):
5177class Neg(Unary):
5178    def to_py(self) -> int | Decimal:
5179        if self.is_number:
5180            return self.this.to_py() * -1
5181        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5178    def to_py(self) -> int | Decimal:
5179        if self.is_number:
5180            return self.this.to_py() * -1
5181        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5184class Alias(Expression):
5185    arg_types = {"this": True, "alias": False}
5186
5187    @property
5188    def output_name(self) -> str:
5189        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5187    @property
5188    def output_name(self) -> str:
5189        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):
5194class PivotAlias(Alias):
5195    pass
key = 'pivotalias'
class PivotAny(Expression):
5200class PivotAny(Expression):
5201    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5204class Aliases(Expression):
5205    arg_types = {"this": True, "expressions": True}
5206
5207    @property
5208    def aliases(self):
5209        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5207    @property
5208    def aliases(self):
5209        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5213class AtIndex(Expression):
5214    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5217class AtTimeZone(Expression):
5218    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5221class FromTimeZone(Expression):
5222    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class FormatPhrase(Expression):
5225class FormatPhrase(Expression):
5226    """Format override for a column in Teradata.
5227    Can be expanded to additional dialects as needed
5228
5229    https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT
5230    """
5231
5232    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):
5235class Between(Predicate):
5236    arg_types = {"this": True, "low": True, "high": True, "symmetric": False}
arg_types = {'this': True, 'low': True, 'high': True, 'symmetric': False}
key = 'between'
class Bracket(Condition):
5239class Bracket(Condition):
5240    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5241    arg_types = {
5242        "this": True,
5243        "expressions": True,
5244        "offset": False,
5245        "safe": False,
5246        "returns_list_for_maps": False,
5247    }
5248
5249    @property
5250    def output_name(self) -> str:
5251        if len(self.expressions) == 1:
5252            return self.expressions[0].output_name
5253
5254        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5249    @property
5250    def output_name(self) -> str:
5251        if len(self.expressions) == 1:
5252            return self.expressions[0].output_name
5253
5254        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):
5257class Distinct(Expression):
5258    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5261class In(Predicate):
5262    arg_types = {
5263        "this": True,
5264        "expressions": False,
5265        "query": False,
5266        "unnest": False,
5267        "field": False,
5268        "is_global": False,
5269    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5273class ForIn(Expression):
5274    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5277class TimeUnit(Expression):
5278    """Automatically converts unit arg into a var."""
5279
5280    arg_types = {"unit": False}
5281
5282    UNABBREVIATED_UNIT_NAME = {
5283        "D": "DAY",
5284        "H": "HOUR",
5285        "M": "MINUTE",
5286        "MS": "MILLISECOND",
5287        "NS": "NANOSECOND",
5288        "Q": "QUARTER",
5289        "S": "SECOND",
5290        "US": "MICROSECOND",
5291        "W": "WEEK",
5292        "Y": "YEAR",
5293    }
5294
5295    VAR_LIKE = (Column, Literal, Var)
5296
5297    def __init__(self, **args):
5298        unit = args.get("unit")
5299        if isinstance(unit, self.VAR_LIKE):
5300            args["unit"] = Var(
5301                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5302            )
5303        elif isinstance(unit, Week):
5304            unit.set("this", Var(this=unit.this.name.upper()))
5305
5306        super().__init__(**args)
5307
5308    @property
5309    def unit(self) -> t.Optional[Var | IntervalSpan]:
5310        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5297    def __init__(self, **args):
5298        unit = args.get("unit")
5299        if isinstance(unit, self.VAR_LIKE):
5300            args["unit"] = Var(
5301                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5302            )
5303        elif isinstance(unit, Week):
5304            unit.set("this", Var(this=unit.this.name.upper()))
5305
5306        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]
5308    @property
5309    def unit(self) -> t.Optional[Var | IntervalSpan]:
5310        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5313class IntervalOp(TimeUnit):
5314    arg_types = {"unit": False, "expression": True}
5315
5316    def interval(self):
5317        return Interval(
5318            this=self.expression.copy(),
5319            unit=self.unit.copy() if self.unit else None,
5320        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5316    def interval(self):
5317        return Interval(
5318            this=self.expression.copy(),
5319            unit=self.unit.copy() if self.unit else None,
5320        )
key = 'intervalop'
class IntervalSpan(DataType):
5326class IntervalSpan(DataType):
5327    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5330class Interval(TimeUnit):
5331    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5334class IgnoreNulls(Expression):
5335    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5338class RespectNulls(Expression):
5339    pass
key = 'respectnulls'
class HavingMax(Expression):
5343class HavingMax(Expression):
5344    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5348class Func(Condition):
5349    """
5350    The base class for all function expressions.
5351
5352    Attributes:
5353        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5354            treated as a variable length argument and the argument's value will be stored as a list.
5355        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5356            function expression. These values are used to map this node to a name during parsing as
5357            well as to provide the function's name during SQL string generation. By default the SQL
5358            name is set to the expression's class name transformed to snake case.
5359    """
5360
5361    is_var_len_args = False
5362
5363    @classmethod
5364    def from_arg_list(cls, args):
5365        if cls.is_var_len_args:
5366            all_arg_keys = list(cls.arg_types)
5367            # If this function supports variable length argument treat the last argument as such.
5368            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5369            num_non_var = len(non_var_len_arg_keys)
5370
5371            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5372            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5373        else:
5374            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5375
5376        return cls(**args_dict)
5377
5378    @classmethod
5379    def sql_names(cls):
5380        if cls is Func:
5381            raise NotImplementedError(
5382                "SQL name is only supported by concrete function implementations"
5383            )
5384        if "_sql_names" not in cls.__dict__:
5385            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5386        return cls._sql_names
5387
5388    @classmethod
5389    def sql_name(cls):
5390        return cls.sql_names()[0]
5391
5392    @classmethod
5393    def default_parser_mappings(cls):
5394        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):
5363    @classmethod
5364    def from_arg_list(cls, args):
5365        if cls.is_var_len_args:
5366            all_arg_keys = list(cls.arg_types)
5367            # If this function supports variable length argument treat the last argument as such.
5368            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5369            num_non_var = len(non_var_len_arg_keys)
5370
5371            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5372            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5373        else:
5374            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5375
5376        return cls(**args_dict)
@classmethod
def sql_names(cls):
5378    @classmethod
5379    def sql_names(cls):
5380        if cls is Func:
5381            raise NotImplementedError(
5382                "SQL name is only supported by concrete function implementations"
5383            )
5384        if "_sql_names" not in cls.__dict__:
5385            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5386        return cls._sql_names
@classmethod
def sql_name(cls):
5388    @classmethod
5389    def sql_name(cls):
5390        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5392    @classmethod
5393    def default_parser_mappings(cls):
5394        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5397class Typeof(Func):
5398    pass
key = 'typeof'
class AggFunc(Func):
5401class AggFunc(Func):
5402    pass
key = 'aggfunc'
class BitwiseAndAgg(AggFunc):
5405class BitwiseAndAgg(AggFunc):
5406    _sql_names = ["BIT_AND"]
key = 'bitwiseandagg'
class BitwiseOrAgg(AggFunc):
5409class BitwiseOrAgg(AggFunc):
5410    _sql_names = ["BIT_OR"]
key = 'bitwiseoragg'
class BitwiseXorAgg(AggFunc):
5413class BitwiseXorAgg(AggFunc):
5414    _sql_names = ["BIT_XOR"]
key = 'bitwisexoragg'
class BitwiseCountAgg(AggFunc):
5417class BitwiseCountAgg(AggFunc):
5418    _sql_names = ["BIT_COUNT"]
key = 'bitwisecountagg'
class ArrayRemove(Func):
5421class ArrayRemove(Func):
5422    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5425class ParameterizedAgg(AggFunc):
5426    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5429class Abs(Func):
5430    pass
key = 'abs'
class ArgMax(AggFunc):
5433class ArgMax(AggFunc):
5434    arg_types = {"this": True, "expression": True, "count": False}
5435    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5438class ArgMin(AggFunc):
5439    arg_types = {"this": True, "expression": True, "count": False}
5440    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5443class ApproxTopK(AggFunc):
5444    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5447class Flatten(Func):
5448    pass
key = 'flatten'
class Transform(Func):
5452class Transform(Func):
5453    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5456class Anonymous(Func):
5457    arg_types = {"this": True, "expressions": False}
5458    is_var_len_args = True
5459
5460    @property
5461    def name(self) -> str:
5462        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
5460    @property
5461    def name(self) -> str:
5462        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5465class AnonymousAggFunc(AggFunc):
5466    arg_types = {"this": True, "expressions": False}
5467    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5471class CombinedAggFunc(AnonymousAggFunc):
5472    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5475class CombinedParameterizedAgg(ParameterizedAgg):
5476    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5481class Hll(AggFunc):
5482    arg_types = {"this": True, "expressions": False}
5483    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5486class ApproxDistinct(AggFunc):
5487    arg_types = {"this": True, "accuracy": False}
5488    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5491class Apply(Func):
5492    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5495class Array(Func):
5496    arg_types = {"expressions": False, "bracket_notation": False}
5497    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5500class Ascii(Func):
5501    pass
key = 'ascii'
class ToArray(Func):
5505class ToArray(Func):
5506    pass
key = 'toarray'
class List(Func):
5510class List(Func):
5511    arg_types = {"expressions": False}
5512    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5516class Pad(Func):
5517    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):
5522class ToChar(Func):
5523    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5528class ToNumber(Func):
5529    arg_types = {
5530        "this": True,
5531        "format": False,
5532        "nlsparam": False,
5533        "precision": False,
5534        "scale": False,
5535    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5539class ToDouble(Func):
5540    arg_types = {
5541        "this": True,
5542        "format": False,
5543    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5546class Columns(Func):
5547    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5551class Convert(Func):
5552    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5556class ConvertToCharset(Func):
5557    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5560class ConvertTimezone(Func):
5561    arg_types = {
5562        "source_tz": False,
5563        "target_tz": True,
5564        "timestamp": True,
5565        "options": False,
5566    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class GenerateSeries(Func):
5569class GenerateSeries(Func):
5570    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):
5576class ExplodingGenerateSeries(GenerateSeries):
5577    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5580class ArrayAgg(AggFunc):
5581    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5584class ArrayUniqueAgg(AggFunc):
5585    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5588class ArrayAll(Func):
5589    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5593class ArrayAny(Func):
5594    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5597class ArrayConcat(Func):
5598    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5599    arg_types = {"this": True, "expressions": False}
5600    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5603class ArrayConcatAgg(AggFunc):
5604    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5607class ArrayConstructCompact(Func):
5608    arg_types = {"expressions": True}
5609    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5612class ArrayContains(Binary, Func):
5613    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5616class ArrayContainsAll(Binary, Func):
5617    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5620class ArrayFilter(Func):
5621    arg_types = {"this": True, "expression": True}
5622    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5625class ArrayFirst(Func):
5626    pass
key = 'arrayfirst'
class ArrayLast(Func):
5629class ArrayLast(Func):
5630    pass
key = 'arraylast'
class ArrayReverse(Func):
5633class ArrayReverse(Func):
5634    pass
key = 'arrayreverse'
class ArraySlice(Func):
5637class ArraySlice(Func):
5638    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):
5641class ArrayToString(Func):
5642    arg_types = {"this": True, "expression": True, "null": False}
5643    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5646class ArrayIntersect(Func):
5647    arg_types = {"expressions": True}
5648    is_var_len_args = True
5649    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5652class StPoint(Func):
5653    arg_types = {"this": True, "expression": True, "null": False}
5654    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5657class StDistance(Func):
5658    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5662class String(Func):
5663    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5666class StringToArray(Func):
5667    arg_types = {"this": True, "expression": False, "null": False}
5668    _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):
5671class ArrayOverlaps(Binary, Func):
5672    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5675class ArraySize(Func):
5676    arg_types = {"this": True, "expression": False}
5677    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5680class ArraySort(Func):
5681    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5684class ArraySum(Func):
5685    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5688class ArrayUnionAgg(AggFunc):
5689    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5692class Avg(AggFunc):
5693    pass
key = 'avg'
class AnyValue(AggFunc):
5696class AnyValue(AggFunc):
5697    pass
key = 'anyvalue'
class Lag(AggFunc):
5700class Lag(AggFunc):
5701    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5704class Lead(AggFunc):
5705    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5710class First(AggFunc):
5711    pass
key = 'first'
class Last(AggFunc):
5714class Last(AggFunc):
5715    pass
key = 'last'
class FirstValue(AggFunc):
5718class FirstValue(AggFunc):
5719    pass
key = 'firstvalue'
class LastValue(AggFunc):
5722class LastValue(AggFunc):
5723    pass
key = 'lastvalue'
class NthValue(AggFunc):
5726class NthValue(AggFunc):
5727    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5730class Case(Func):
5731    arg_types = {"this": False, "ifs": True, "default": False}
5732
5733    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5734        instance = maybe_copy(self, copy)
5735        instance.append(
5736            "ifs",
5737            If(
5738                this=maybe_parse(condition, copy=copy, **opts),
5739                true=maybe_parse(then, copy=copy, **opts),
5740            ),
5741        )
5742        return instance
5743
5744    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5745        instance = maybe_copy(self, copy)
5746        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5747        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:
5733    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5734        instance = maybe_copy(self, copy)
5735        instance.append(
5736            "ifs",
5737            If(
5738                this=maybe_parse(condition, copy=copy, **opts),
5739                true=maybe_parse(then, copy=copy, **opts),
5740            ),
5741        )
5742        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5744    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5745        instance = maybe_copy(self, copy)
5746        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5747        return instance
key = 'case'
class Cast(Func):
5750class Cast(Func):
5751    arg_types = {
5752        "this": True,
5753        "to": True,
5754        "format": False,
5755        "safe": False,
5756        "action": False,
5757        "default": False,
5758    }
5759
5760    @property
5761    def name(self) -> str:
5762        return self.this.name
5763
5764    @property
5765    def to(self) -> DataType:
5766        return self.args["to"]
5767
5768    @property
5769    def output_name(self) -> str:
5770        return self.name
5771
5772    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5773        """
5774        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5775        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5776        array<int> != array<float>.
5777
5778        Args:
5779            dtypes: the data types to compare this Cast's DataType to.
5780
5781        Returns:
5782            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5783        """
5784        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5760    @property
5761    def name(self) -> str:
5762        return self.this.name
to: DataType
5764    @property
5765    def to(self) -> DataType:
5766        return self.args["to"]
output_name: str
5768    @property
5769    def output_name(self) -> str:
5770        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:
5772    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5773        """
5774        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5775        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5776        array<int> != array<float>.
5777
5778        Args:
5779            dtypes: the data types to compare this Cast's DataType to.
5780
5781        Returns:
5782            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5783        """
5784        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):
5787class TryCast(Cast):
5788    pass
key = 'trycast'
class JSONCast(Cast):
5792class JSONCast(Cast):
5793    pass
key = 'jsoncast'
class Try(Func):
5796class Try(Func):
5797    pass
key = 'try'
class CastToStrType(Func):
5800class CastToStrType(Func):
5801    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5805class TranslateCharacters(Expression):
5806    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5809class Collate(Binary, Func):
5810    pass
key = 'collate'
class Ceil(Func):
5813class Ceil(Func):
5814    arg_types = {"this": True, "decimals": False, "to": False}
5815    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5818class Coalesce(Func):
5819    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5820    is_var_len_args = True
5821    _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):
5824class Chr(Func):
5825    arg_types = {"expressions": True, "charset": False}
5826    is_var_len_args = True
5827    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5830class Concat(Func):
5831    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5832    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5835class ConcatWs(Concat):
5836    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5839class Contains(Func):
5840    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5844class ConnectByRoot(Func):
5845    pass
key = 'connectbyroot'
class Count(AggFunc):
5848class Count(AggFunc):
5849    arg_types = {"this": False, "expressions": False, "big_int": False}
5850    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5853class CountIf(AggFunc):
5854    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5858class Cbrt(Func):
5859    pass
key = 'cbrt'
class CurrentDate(Func):
5862class CurrentDate(Func):
5863    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5866class CurrentDatetime(Func):
5867    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5870class CurrentTime(Func):
5871    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5874class CurrentTimestamp(Func):
5875    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
5878class CurrentTimestampLTZ(Func):
5879    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
5882class CurrentSchema(Func):
5883    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5886class CurrentUser(Func):
5887    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5890class DateAdd(Func, IntervalOp):
5891    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5894class DateBin(Func, IntervalOp):
5895    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):
5898class DateSub(Func, IntervalOp):
5899    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5902class DateDiff(Func, TimeUnit):
5903    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5904    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):
5907class DateTrunc(Func):
5908    arg_types = {"unit": True, "this": True, "zone": False}
5909
5910    def __init__(self, **args):
5911        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5912        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5913        unabbreviate = args.pop("unabbreviate", True)
5914
5915        unit = args.get("unit")
5916        if isinstance(unit, TimeUnit.VAR_LIKE):
5917            unit_name = unit.name.upper()
5918            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5919                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5920
5921            args["unit"] = Literal.string(unit_name)
5922
5923        super().__init__(**args)
5924
5925    @property
5926    def unit(self) -> Expression:
5927        return self.args["unit"]
DateTrunc(**args)
5910    def __init__(self, **args):
5911        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5912        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5913        unabbreviate = args.pop("unabbreviate", True)
5914
5915        unit = args.get("unit")
5916        if isinstance(unit, TimeUnit.VAR_LIKE):
5917            unit_name = unit.name.upper()
5918            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5919                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5920
5921            args["unit"] = Literal.string(unit_name)
5922
5923        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5925    @property
5926    def unit(self) -> Expression:
5927        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5932class Datetime(Func):
5933    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5936class DatetimeAdd(Func, IntervalOp):
5937    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5940class DatetimeSub(Func, IntervalOp):
5941    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5944class DatetimeDiff(Func, TimeUnit):
5945    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5948class DatetimeTrunc(Func, TimeUnit):
5949    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5952class DayOfWeek(Func):
5953    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5958class DayOfWeekIso(Func):
5959    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5962class DayOfMonth(Func):
5963    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5966class DayOfYear(Func):
5967    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5970class ToDays(Func):
5971    pass
key = 'todays'
class WeekOfYear(Func):
5974class WeekOfYear(Func):
5975    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5978class MonthsBetween(Func):
5979    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5982class MakeInterval(Func):
5983    arg_types = {
5984        "year": False,
5985        "month": False,
5986        "day": False,
5987        "hour": False,
5988        "minute": False,
5989        "second": False,
5990    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5993class LastDay(Func, TimeUnit):
5994    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5995    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5998class Extract(Func):
5999    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6002class Exists(Func, SubqueryPredicate):
6003    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6006class Timestamp(Func):
6007    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6010class TimestampAdd(Func, TimeUnit):
6011    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6014class TimestampSub(Func, TimeUnit):
6015    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6018class TimestampDiff(Func, TimeUnit):
6019    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6020    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6023class TimestampTrunc(Func, TimeUnit):
6024    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6027class TimeAdd(Func, TimeUnit):
6028    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6031class TimeSub(Func, TimeUnit):
6032    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6035class TimeDiff(Func, TimeUnit):
6036    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6039class TimeTrunc(Func, TimeUnit):
6040    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6043class DateFromParts(Func):
6044    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6045    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6048class TimeFromParts(Func):
6049    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6050    arg_types = {
6051        "hour": True,
6052        "min": True,
6053        "sec": True,
6054        "nano": False,
6055        "fractions": False,
6056        "precision": False,
6057    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6060class DateStrToDate(Func):
6061    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6064class DateToDateStr(Func):
6065    pass
key = 'datetodatestr'
class DateToDi(Func):
6068class DateToDi(Func):
6069    pass
key = 'datetodi'
class Date(Func):
6073class Date(Func):
6074    arg_types = {"this": False, "zone": False, "expressions": False}
6075    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6078class Day(Func):
6079    pass
key = 'day'
class Decode(Func):
6082class Decode(Func):
6083    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6086class DecodeCase(Func):
6087    _sql_names: t.List[str] = []
6088    arg_types = {"expressions": True}
6089    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DiToDate(Func):
6092class DiToDate(Func):
6093    pass
key = 'ditodate'
class Encode(Func):
6096class Encode(Func):
6097    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6100class Exp(Func):
6101    pass
key = 'exp'
class Explode(Func, UDTF):
6105class Explode(Func, UDTF):
6106    arg_types = {"this": True, "expressions": False}
6107    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6111class Inline(Func):
6112    pass
key = 'inline'
class ExplodeOuter(Explode):
6115class ExplodeOuter(Explode):
6116    pass
key = 'explodeouter'
class Posexplode(Explode):
6119class Posexplode(Explode):
6120    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6123class PosexplodeOuter(Posexplode, ExplodeOuter):
6124    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6127class PositionalColumn(Expression):
6128    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6131class Unnest(Func, UDTF):
6132    arg_types = {
6133        "expressions": True,
6134        "alias": False,
6135        "offset": False,
6136        "explode_array": False,
6137    }
6138
6139    @property
6140    def selects(self) -> t.List[Expression]:
6141        columns = super().selects
6142        offset = self.args.get("offset")
6143        if offset:
6144            columns = columns + [to_identifier("offset") if offset is True else offset]
6145        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6139    @property
6140    def selects(self) -> t.List[Expression]:
6141        columns = super().selects
6142        offset = self.args.get("offset")
6143        if offset:
6144            columns = columns + [to_identifier("offset") if offset is True else offset]
6145        return columns
key = 'unnest'
class Floor(Func):
6148class Floor(Func):
6149    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6152class FromBase64(Func):
6153    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6156class FeaturesAtTime(Func):
6157    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):
6160class ToBase64(Func):
6161    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6165class FromISO8601Timestamp(Func):
6166    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6169class GapFill(Func):
6170    arg_types = {
6171        "this": True,
6172        "ts_column": True,
6173        "bucket_width": True,
6174        "partitioning_columns": False,
6175        "value_columns": False,
6176        "origin": False,
6177        "ignore_nulls": False,
6178    }
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):
6182class GenerateDateArray(Func):
6183    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6187class GenerateTimestampArray(Func):
6188    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6191class Greatest(Func):
6192    arg_types = {"this": True, "expressions": False}
6193    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6198class OverflowTruncateBehavior(Expression):
6199    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6202class GroupConcat(AggFunc):
6203    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6206class Hex(Func):
6207    pass
key = 'hex'
class LowerHex(Hex):
6210class LowerHex(Hex):
6211    pass
key = 'lowerhex'
class And(Connector, Func):
6214class And(Connector, Func):
6215    pass
key = 'and'
class Or(Connector, Func):
6218class Or(Connector, Func):
6219    pass
key = 'or'
class Xor(Connector, Func):
6222class Xor(Connector, Func):
6223    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6226class If(Func):
6227    arg_types = {"this": True, "true": True, "false": False}
6228    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6231class Nullif(Func):
6232    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6235class Initcap(Func):
6236    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6239class IsAscii(Func):
6240    pass
key = 'isascii'
class IsNan(Func):
6243class IsNan(Func):
6244    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6248class Int64(Func):
6249    pass
key = 'int64'
class IsInf(Func):
6252class IsInf(Func):
6253    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6257class JSON(Expression):
6258    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6261class JSONPath(Expression):
6262    arg_types = {"expressions": True, "escape": False}
6263
6264    @property
6265    def output_name(self) -> str:
6266        last_segment = self.expressions[-1].this
6267        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6264    @property
6265    def output_name(self) -> str:
6266        last_segment = self.expressions[-1].this
6267        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):
6270class JSONPathPart(Expression):
6271    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6274class JSONPathFilter(JSONPathPart):
6275    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6278class JSONPathKey(JSONPathPart):
6279    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6282class JSONPathRecursive(JSONPathPart):
6283    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6286class JSONPathRoot(JSONPathPart):
6287    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6290class JSONPathScript(JSONPathPart):
6291    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6294class JSONPathSlice(JSONPathPart):
6295    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6298class JSONPathSelector(JSONPathPart):
6299    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6302class JSONPathSubscript(JSONPathPart):
6303    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6306class JSONPathUnion(JSONPathPart):
6307    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6310class JSONPathWildcard(JSONPathPart):
6311    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6314class FormatJson(Expression):
6315    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6318class JSONKeyValue(Expression):
6319    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6322class JSONObject(Func):
6323    arg_types = {
6324        "expressions": False,
6325        "null_handling": False,
6326        "unique_keys": False,
6327        "return_type": False,
6328        "encoding": False,
6329    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6332class JSONObjectAgg(AggFunc):
6333    arg_types = {
6334        "expressions": False,
6335        "null_handling": False,
6336        "unique_keys": False,
6337        "return_type": False,
6338        "encoding": False,
6339    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6343class JSONBObjectAgg(AggFunc):
6344    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6348class JSONArray(Func):
6349    arg_types = {
6350        "expressions": False,
6351        "null_handling": False,
6352        "return_type": False,
6353        "strict": False,
6354    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6358class JSONArrayAgg(Func):
6359    arg_types = {
6360        "this": True,
6361        "order": False,
6362        "null_handling": False,
6363        "return_type": False,
6364        "strict": False,
6365    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6368class JSONExists(Func):
6369    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):
6374class JSONColumnDef(Expression):
6375    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):
6378class JSONSchema(Expression):
6379    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6383class JSONValue(Expression):
6384    arg_types = {
6385        "this": True,
6386        "path": True,
6387        "returning": False,
6388        "on_condition": False,
6389    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6392class JSONValueArray(Func):
6393    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6397class JSONTable(Func):
6398    arg_types = {
6399        "this": True,
6400        "schema": True,
6401        "path": False,
6402        "error_handling": False,
6403        "empty_handling": False,
6404    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6409class JSONType(Func):
6410    arg_types = {"this": True, "expression": False}
6411    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6415class ObjectInsert(Func):
6416    arg_types = {
6417        "this": True,
6418        "key": True,
6419        "value": True,
6420        "update_flag": False,
6421    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6424class OpenJSONColumnDef(Expression):
6425    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):
6428class OpenJSON(Func):
6429    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6432class JSONBContains(Binary, Func):
6433    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6436class JSONBExists(Func):
6437    arg_types = {"this": True, "path": True}
6438    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6441class JSONExtract(Binary, Func):
6442    arg_types = {
6443        "this": True,
6444        "expression": True,
6445        "only_json_types": False,
6446        "expressions": False,
6447        "variant_extract": False,
6448        "json_query": False,
6449        "option": False,
6450        "quote": False,
6451        "on_condition": False,
6452    }
6453    _sql_names = ["JSON_EXTRACT"]
6454    is_var_len_args = True
6455
6456    @property
6457    def output_name(self) -> str:
6458        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
6456    @property
6457    def output_name(self) -> str:
6458        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):
6462class JSONExtractQuote(Expression):
6463    arg_types = {
6464        "option": True,
6465        "scalar": False,
6466    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6469class JSONExtractArray(Func):
6470    arg_types = {"this": True, "expression": False}
6471    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6474class JSONExtractScalar(Binary, Func):
6475    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6476    _sql_names = ["JSON_EXTRACT_SCALAR"]
6477    is_var_len_args = True
6478
6479    @property
6480    def output_name(self) -> str:
6481        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
6479    @property
6480    def output_name(self) -> str:
6481        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):
6484class JSONBExtract(Binary, Func):
6485    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6488class JSONBExtractScalar(Binary, Func):
6489    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6492class JSONFormat(Func):
6493    arg_types = {"this": False, "options": False, "is_json": False}
6494    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6498class JSONArrayContains(Binary, Predicate, Func):
6499    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6502class ParseJSON(Func):
6503    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6504    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6505    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6506    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6509class Least(Func):
6510    arg_types = {"this": True, "expressions": False}
6511    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6514class Left(Func):
6515    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6522class Length(Func):
6523    arg_types = {"this": True, "binary": False, "encoding": False}
6524    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6527class Levenshtein(Func):
6528    arg_types = {
6529        "this": True,
6530        "expression": False,
6531        "ins_cost": False,
6532        "del_cost": False,
6533        "sub_cost": False,
6534        "max_dist": False,
6535    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6538class Ln(Func):
6539    pass
key = 'ln'
class Log(Func):
6542class Log(Func):
6543    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6546class LogicalOr(AggFunc):
6547    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6550class LogicalAnd(AggFunc):
6551    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6554class Lower(Func):
6555    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6558class Map(Func):
6559    arg_types = {"keys": False, "values": False}
6560
6561    @property
6562    def keys(self) -> t.List[Expression]:
6563        keys = self.args.get("keys")
6564        return keys.expressions if keys else []
6565
6566    @property
6567    def values(self) -> t.List[Expression]:
6568        values = self.args.get("values")
6569        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6561    @property
6562    def keys(self) -> t.List[Expression]:
6563        keys = self.args.get("keys")
6564        return keys.expressions if keys else []
values: List[Expression]
6566    @property
6567    def values(self) -> t.List[Expression]:
6568        values = self.args.get("values")
6569        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6573class ToMap(Func):
6574    pass
key = 'tomap'
class MapFromEntries(Func):
6577class MapFromEntries(Func):
6578    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6582class ScopeResolution(Expression):
6583    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6586class Stream(Expression):
6587    pass
key = 'stream'
class StarMap(Func):
6590class StarMap(Func):
6591    pass
key = 'starmap'
class VarMap(Func):
6594class VarMap(Func):
6595    arg_types = {"keys": True, "values": True}
6596    is_var_len_args = True
6597
6598    @property
6599    def keys(self) -> t.List[Expression]:
6600        return self.args["keys"].expressions
6601
6602    @property
6603    def values(self) -> t.List[Expression]:
6604        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6598    @property
6599    def keys(self) -> t.List[Expression]:
6600        return self.args["keys"].expressions
values: List[Expression]
6602    @property
6603    def values(self) -> t.List[Expression]:
6604        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6608class MatchAgainst(Func):
6609    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6612class Max(AggFunc):
6613    arg_types = {"this": True, "expressions": False}
6614    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6617class MD5(Func):
6618    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6622class MD5Digest(Func):
6623    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6626class Median(AggFunc):
6627    pass
key = 'median'
class Min(AggFunc):
6630class Min(AggFunc):
6631    arg_types = {"this": True, "expressions": False}
6632    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6635class Month(Func):
6636    pass
key = 'month'
class AddMonths(Func):
6639class AddMonths(Func):
6640    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6643class Nvl2(Func):
6644    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6647class Normalize(Func):
6648    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6651class Overlay(Func):
6652    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):
6656class Predict(Func):
6657    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6660class Pow(Binary, Func):
6661    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6664class PercentileCont(AggFunc):
6665    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6668class PercentileDisc(AggFunc):
6669    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6672class Quantile(AggFunc):
6673    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6676class ApproxQuantile(Quantile):
6677    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):
6680class Quarter(Func):
6681    pass
key = 'quarter'
class Rand(Func):
6686class Rand(Func):
6687    _sql_names = ["RAND", "RANDOM"]
6688    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6691class Randn(Func):
6692    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6695class RangeN(Func):
6696    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6699class ReadCSV(Func):
6700    _sql_names = ["READ_CSV"]
6701    is_var_len_args = True
6702    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6705class Reduce(Func):
6706    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):
6709class RegexpExtract(Func):
6710    arg_types = {
6711        "this": True,
6712        "expression": True,
6713        "position": False,
6714        "occurrence": False,
6715        "parameters": False,
6716        "group": False,
6717    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6720class RegexpExtractAll(Func):
6721    arg_types = {
6722        "this": True,
6723        "expression": True,
6724        "position": False,
6725        "occurrence": False,
6726        "parameters": False,
6727        "group": False,
6728    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6731class RegexpReplace(Func):
6732    arg_types = {
6733        "this": True,
6734        "expression": True,
6735        "replacement": False,
6736        "position": False,
6737        "occurrence": False,
6738        "modifiers": False,
6739    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6742class RegexpLike(Binary, Func):
6743    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6746class RegexpILike(Binary, Func):
6747    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6752class RegexpSplit(Func):
6753    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6756class Repeat(Func):
6757    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
6761class Replace(Func):
6762    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
6767class Round(Func):
6768    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6771class RowNumber(Func):
6772    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6775class SafeDivide(Func):
6776    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6779class SHA(Func):
6780    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6783class SHA2(Func):
6784    _sql_names = ["SHA2"]
6785    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6788class Sign(Func):
6789    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6792class SortArray(Func):
6793    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6796class Split(Func):
6797    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6801class SplitPart(Func):
6802    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6807class Substring(Func):
6808    _sql_names = ["SUBSTRING", "SUBSTR"]
6809    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
6812class SubstringIndex(Func):
6813    """
6814    SUBSTRING_INDEX(str, delim, count)
6815
6816    *count* > 0  → left slice before the *count*-th delimiter
6817    *count* < 0  → right slice after the |count|-th delimiter
6818    """
6819
6820    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):
6823class StandardHash(Func):
6824    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6827class StartsWith(Func):
6828    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6829    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
6832class EndsWith(Func):
6833    _sql_names = ["ENDS_WITH", "ENDSWITH"]
6834    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
6837class StrPosition(Func):
6838    arg_types = {
6839        "this": True,
6840        "substr": True,
6841        "position": False,
6842        "occurrence": False,
6843    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6846class StrToDate(Func):
6847    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6850class StrToTime(Func):
6851    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):
6856class StrToUnix(Func):
6857    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6862class StrToMap(Func):
6863    arg_types = {
6864        "this": True,
6865        "pair_delim": False,
6866        "key_value_delim": False,
6867        "duplicate_resolution_callback": False,
6868    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6871class NumberToStr(Func):
6872    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6875class FromBase(Func):
6876    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
6879class Space(Func):
6880    """
6881    SPACE(n) → string consisting of n blank characters
6882    """
6883
6884    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
6887class Struct(Func):
6888    arg_types = {"expressions": False}
6889    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6892class StructExtract(Func):
6893    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6898class Stuff(Func):
6899    _sql_names = ["STUFF", "INSERT"]
6900    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):
6903class Sum(AggFunc):
6904    pass
key = 'sum'
class Sqrt(Func):
6907class Sqrt(Func):
6908    pass
key = 'sqrt'
class Stddev(AggFunc):
6911class Stddev(AggFunc):
6912    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6915class StddevPop(AggFunc):
6916    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6919class StddevSamp(AggFunc):
6920    pass
key = 'stddevsamp'
class Time(Func):
6924class Time(Func):
6925    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6928class TimeToStr(Func):
6929    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):
6932class TimeToTimeStr(Func):
6933    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6936class TimeToUnix(Func):
6937    pass
key = 'timetounix'
class TimeStrToDate(Func):
6940class TimeStrToDate(Func):
6941    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6944class TimeStrToTime(Func):
6945    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6948class TimeStrToUnix(Func):
6949    pass
key = 'timestrtounix'
class Trim(Func):
6952class Trim(Func):
6953    arg_types = {
6954        "this": True,
6955        "expression": False,
6956        "position": False,
6957        "collation": False,
6958    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6961class TsOrDsAdd(Func, TimeUnit):
6962    # return_type is used to correctly cast the arguments of this expression when transpiling it
6963    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6964
6965    @property
6966    def return_type(self) -> DataType:
6967        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
6965    @property
6966    def return_type(self) -> DataType:
6967        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6970class TsOrDsDiff(Func, TimeUnit):
6971    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6974class TsOrDsToDateStr(Func):
6975    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6978class TsOrDsToDate(Func):
6979    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6982class TsOrDsToDatetime(Func):
6983    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6986class TsOrDsToTime(Func):
6987    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6990class TsOrDsToTimestamp(Func):
6991    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6994class TsOrDiToDi(Func):
6995    pass
key = 'tsorditodi'
class Unhex(Func):
6998class Unhex(Func):
6999    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7002class Unicode(Func):
7003    pass
key = 'unicode'
class UnixDate(Func):
7007class UnixDate(Func):
7008    pass
key = 'unixdate'
class UnixToStr(Func):
7011class UnixToStr(Func):
7012    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7017class UnixToTime(Func):
7018    arg_types = {
7019        "this": True,
7020        "scale": False,
7021        "zone": False,
7022        "hours": False,
7023        "minutes": False,
7024        "format": False,
7025    }
7026
7027    SECONDS = Literal.number(0)
7028    DECIS = Literal.number(1)
7029    CENTIS = Literal.number(2)
7030    MILLIS = Literal.number(3)
7031    DECIMILLIS = Literal.number(4)
7032    CENTIMILLIS = Literal.number(5)
7033    MICROS = Literal.number(6)
7034    DECIMICROS = Literal.number(7)
7035    CENTIMICROS = Literal.number(8)
7036    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):
7039class UnixToTimeStr(Func):
7040    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7043class UnixSeconds(Func):
7044    pass
key = 'unixseconds'
class Uuid(Func):
7047class Uuid(Func):
7048    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7049
7050    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7053class TimestampFromParts(Func):
7054    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7055    arg_types = {
7056        "year": True,
7057        "month": True,
7058        "day": True,
7059        "hour": True,
7060        "min": True,
7061        "sec": True,
7062        "nano": False,
7063        "zone": False,
7064        "milli": False,
7065    }
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):
7068class Upper(Func):
7069    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7072class Corr(Binary, AggFunc):
7073    pass
key = 'corr'
class Variance(AggFunc):
7076class Variance(AggFunc):
7077    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7080class VariancePop(AggFunc):
7081    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7084class CovarSamp(Binary, AggFunc):
7085    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7088class CovarPop(Binary, AggFunc):
7089    pass
key = 'covarpop'
class Week(Func):
7092class Week(Func):
7093    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
7096class XMLElement(Func):
7097    _sql_names = ["XMLELEMENT"]
7098    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7101class XMLTable(Func):
7102    arg_types = {
7103        "this": True,
7104        "namespaces": False,
7105        "passing": False,
7106        "columns": False,
7107        "by_ref": False,
7108    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7111class XMLNamespace(Expression):
7112    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7116class XMLKeyValueOption(Expression):
7117    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7120class Year(Func):
7121    pass
key = 'year'
class Use(Expression):
7124class Use(Expression):
7125    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7128class Merge(DML):
7129    arg_types = {
7130        "this": True,
7131        "using": True,
7132        "on": True,
7133        "whens": True,
7134        "with": False,
7135        "returning": False,
7136    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7139class When(Expression):
7140    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):
7143class Whens(Expression):
7144    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7145
7146    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7151class NextValueFor(Func):
7152    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7157class Semicolon(Expression):
7158    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7163class TableColumn(Expression):
7164    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 'Ascii'>, <class 'Avg'>, <class 'BitwiseAndAgg'>, <class 'BitwiseCountAgg'>, <class 'BitwiseOrAgg'>, <class 'BitwiseXorAgg'>, <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 'JSONType'>, <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'>, 'ASCII': <class 'Ascii'>, 'AVG': <class 'Avg'>, 'BIT_AND': <class 'BitwiseAndAgg'>, 'BIT_COUNT': <class 'BitwiseCountAgg'>, 'BIT_OR': <class 'BitwiseOrAgg'>, 'BIT_XOR': <class 'BitwiseXorAgg'>, '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'>, 'JSON_TYPE': <class 'JSONType'>, '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:
7204def maybe_parse(
7205    sql_or_expression: ExpOrStr,
7206    *,
7207    into: t.Optional[IntoType] = None,
7208    dialect: DialectType = None,
7209    prefix: t.Optional[str] = None,
7210    copy: bool = False,
7211    **opts,
7212) -> Expression:
7213    """Gracefully handle a possible string or expression.
7214
7215    Example:
7216        >>> maybe_parse("1")
7217        Literal(this=1, is_string=False)
7218        >>> maybe_parse(to_identifier("x"))
7219        Identifier(this=x, quoted=False)
7220
7221    Args:
7222        sql_or_expression: the SQL code string or an expression
7223        into: the SQLGlot Expression to parse into
7224        dialect: the dialect used to parse the input expressions (in the case that an
7225            input expression is a SQL string).
7226        prefix: a string to prefix the sql with before it gets parsed
7227            (automatically includes a space)
7228        copy: whether to copy the expression.
7229        **opts: other options to use to parse the input expressions (again, in the case
7230            that an input expression is a SQL string).
7231
7232    Returns:
7233        Expression: the parsed or given expression.
7234    """
7235    if isinstance(sql_or_expression, Expression):
7236        if copy:
7237            return sql_or_expression.copy()
7238        return sql_or_expression
7239
7240    if sql_or_expression is None:
7241        raise ParseError("SQL cannot be None")
7242
7243    import sqlglot
7244
7245    sql = str(sql_or_expression)
7246    if prefix:
7247        sql = f"{prefix} {sql}"
7248
7249    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):
7260def maybe_copy(instance, copy=True):
7261    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:
7516def union(
7517    *expressions: ExpOrStr,
7518    distinct: bool = True,
7519    dialect: DialectType = None,
7520    copy: bool = True,
7521    **opts,
7522) -> Union:
7523    """
7524    Initializes a syntax tree for the `UNION` operation.
7525
7526    Example:
7527        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7528        'SELECT * FROM foo UNION SELECT * FROM bla'
7529
7530    Args:
7531        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7532            If `Expression` instances are passed, they will be used as-is.
7533        distinct: set the DISTINCT flag if and only if this is true.
7534        dialect: the dialect used to parse the input expression.
7535        copy: whether to copy the expression.
7536        opts: other options to use to parse the input expressions.
7537
7538    Returns:
7539        The new Union instance.
7540    """
7541    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7542    return _apply_set_operation(
7543        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7544    )

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:
7547def intersect(
7548    *expressions: ExpOrStr,
7549    distinct: bool = True,
7550    dialect: DialectType = None,
7551    copy: bool = True,
7552    **opts,
7553) -> Intersect:
7554    """
7555    Initializes a syntax tree for the `INTERSECT` operation.
7556
7557    Example:
7558        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7559        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7560
7561    Args:
7562        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7563            If `Expression` instances are passed, they will be used as-is.
7564        distinct: set the DISTINCT flag if and only if this is true.
7565        dialect: the dialect used to parse the input expression.
7566        copy: whether to copy the expression.
7567        opts: other options to use to parse the input expressions.
7568
7569    Returns:
7570        The new Intersect instance.
7571    """
7572    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7573    return _apply_set_operation(
7574        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7575    )

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:
7578def except_(
7579    *expressions: ExpOrStr,
7580    distinct: bool = True,
7581    dialect: DialectType = None,
7582    copy: bool = True,
7583    **opts,
7584) -> Except:
7585    """
7586    Initializes a syntax tree for the `EXCEPT` operation.
7587
7588    Example:
7589        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7590        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7591
7592    Args:
7593        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7594            If `Expression` instances are passed, they will be used as-is.
7595        distinct: set the DISTINCT flag if and only if this is true.
7596        dialect: the dialect used to parse the input expression.
7597        copy: whether to copy the expression.
7598        opts: other options to use to parse the input expressions.
7599
7600    Returns:
7601        The new Except instance.
7602    """
7603    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7604    return _apply_set_operation(
7605        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7606    )

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:
7609def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7610    """
7611    Initializes a syntax tree from one or multiple SELECT expressions.
7612
7613    Example:
7614        >>> select("col1", "col2").from_("tbl").sql()
7615        'SELECT col1, col2 FROM tbl'
7616
7617    Args:
7618        *expressions: the SQL code string to parse as the expressions of a
7619            SELECT statement. If an Expression instance is passed, this is used as-is.
7620        dialect: the dialect used to parse the input expressions (in the case that an
7621            input expression is a SQL string).
7622        **opts: other options to use to parse the input expressions (again, in the case
7623            that an input expression is a SQL string).
7624
7625    Returns:
7626        Select: the syntax tree for the SELECT statement.
7627    """
7628    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:
7631def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7632    """
7633    Initializes a syntax tree from a FROM expression.
7634
7635    Example:
7636        >>> from_("tbl").select("col1", "col2").sql()
7637        'SELECT col1, col2 FROM tbl'
7638
7639    Args:
7640        *expression: the SQL code string to parse as the FROM expressions of a
7641            SELECT statement. If an Expression instance is passed, this is used as-is.
7642        dialect: the dialect used to parse the input expression (in the case that the
7643            input expression is a SQL string).
7644        **opts: other options to use to parse the input expressions (again, in the case
7645            that the input expression is a SQL string).
7646
7647    Returns:
7648        Select: the syntax tree for the SELECT statement.
7649    """
7650    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:
7653def update(
7654    table: str | Table,
7655    properties: t.Optional[dict] = None,
7656    where: t.Optional[ExpOrStr] = None,
7657    from_: t.Optional[ExpOrStr] = None,
7658    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7659    dialect: DialectType = None,
7660    **opts,
7661) -> Update:
7662    """
7663    Creates an update statement.
7664
7665    Example:
7666        >>> 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()
7667        "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"
7668
7669    Args:
7670        properties: dictionary of properties to SET which are
7671            auto converted to sql objects eg None -> NULL
7672        where: sql conditional parsed into a WHERE statement
7673        from_: sql statement parsed into a FROM statement
7674        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7675        dialect: the dialect used to parse the input expressions.
7676        **opts: other options to use to parse the input expressions.
7677
7678    Returns:
7679        Update: the syntax tree for the UPDATE statement.
7680    """
7681    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7682    if properties:
7683        update_expr.set(
7684            "expressions",
7685            [
7686                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7687                for k, v in properties.items()
7688            ],
7689        )
7690    if from_:
7691        update_expr.set(
7692            "from",
7693            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7694        )
7695    if isinstance(where, Condition):
7696        where = Where(this=where)
7697    if where:
7698        update_expr.set(
7699            "where",
7700            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7701        )
7702    if with_:
7703        cte_list = [
7704            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7705            for alias, qry in with_.items()
7706        ]
7707        update_expr.set(
7708            "with",
7709            With(expressions=cte_list),
7710        )
7711    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:
7714def delete(
7715    table: ExpOrStr,
7716    where: t.Optional[ExpOrStr] = None,
7717    returning: t.Optional[ExpOrStr] = None,
7718    dialect: DialectType = None,
7719    **opts,
7720) -> Delete:
7721    """
7722    Builds a delete statement.
7723
7724    Example:
7725        >>> delete("my_table", where="id > 1").sql()
7726        'DELETE FROM my_table WHERE id > 1'
7727
7728    Args:
7729        where: sql conditional parsed into a WHERE statement
7730        returning: sql conditional parsed into a RETURNING statement
7731        dialect: the dialect used to parse the input expressions.
7732        **opts: other options to use to parse the input expressions.
7733
7734    Returns:
7735        Delete: the syntax tree for the DELETE statement.
7736    """
7737    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7738    if where:
7739        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7740    if returning:
7741        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7742    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:
7745def insert(
7746    expression: ExpOrStr,
7747    into: ExpOrStr,
7748    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7749    overwrite: t.Optional[bool] = None,
7750    returning: t.Optional[ExpOrStr] = None,
7751    dialect: DialectType = None,
7752    copy: bool = True,
7753    **opts,
7754) -> Insert:
7755    """
7756    Builds an INSERT statement.
7757
7758    Example:
7759        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7760        'INSERT INTO tbl VALUES (1, 2, 3)'
7761
7762    Args:
7763        expression: the sql string or expression of the INSERT statement
7764        into: the tbl to insert data to.
7765        columns: optionally the table's column names.
7766        overwrite: whether to INSERT OVERWRITE or not.
7767        returning: sql conditional parsed into a RETURNING statement
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        Insert: the syntax tree for the INSERT statement.
7774    """
7775    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7776    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7777
7778    if columns:
7779        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7780
7781    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7782
7783    if returning:
7784        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7785
7786    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:
7789def merge(
7790    *when_exprs: ExpOrStr,
7791    into: ExpOrStr,
7792    using: ExpOrStr,
7793    on: ExpOrStr,
7794    returning: t.Optional[ExpOrStr] = None,
7795    dialect: DialectType = None,
7796    copy: bool = True,
7797    **opts,
7798) -> Merge:
7799    """
7800    Builds a MERGE statement.
7801
7802    Example:
7803        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7804        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7805        ...       into="my_table",
7806        ...       using="source_table",
7807        ...       on="my_table.id = source_table.id").sql()
7808        '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)'
7809
7810    Args:
7811        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7812        into: The target table to merge data into.
7813        using: The source table to merge data from.
7814        on: The join condition for the merge.
7815        returning: The columns to return from the merge.
7816        dialect: The dialect used to parse the input expressions.
7817        copy: Whether to copy the expression.
7818        **opts: Other options to use to parse the input expressions.
7819
7820    Returns:
7821        Merge: The syntax tree for the MERGE statement.
7822    """
7823    expressions: t.List[Expression] = []
7824    for when_expr in when_exprs:
7825        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7826        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7827
7828    merge = Merge(
7829        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7830        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7831        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7832        whens=Whens(expressions=expressions),
7833    )
7834    if returning:
7835        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7836
7837    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:
7840def condition(
7841    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7842) -> Condition:
7843    """
7844    Initialize a logical condition expression.
7845
7846    Example:
7847        >>> condition("x=1").sql()
7848        'x = 1'
7849
7850        This is helpful for composing larger logical syntax trees:
7851        >>> where = condition("x=1")
7852        >>> where = where.and_("y=1")
7853        >>> Select().from_("tbl").select("*").where(where).sql()
7854        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7855
7856    Args:
7857        *expression: the SQL code string to parse.
7858            If an Expression instance is passed, this is used as-is.
7859        dialect: the dialect used to parse the input expression (in the case that the
7860            input expression is a SQL string).
7861        copy: Whether to copy `expression` (only applies to expressions).
7862        **opts: other options to use to parse the input expressions (again, in the case
7863            that the input expression is a SQL string).
7864
7865    Returns:
7866        The new Condition instance
7867    """
7868    return maybe_parse(
7869        expression,
7870        into=Condition,
7871        dialect=dialect,
7872        copy=copy,
7873        **opts,
7874    )

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:
7877def and_(
7878    *expressions: t.Optional[ExpOrStr],
7879    dialect: DialectType = None,
7880    copy: bool = True,
7881    wrap: bool = True,
7882    **opts,
7883) -> Condition:
7884    """
7885    Combine multiple conditions with an AND logical operator.
7886
7887    Example:
7888        >>> and_("x=1", and_("y=1", "z=1")).sql()
7889        'x = 1 AND (y = 1 AND z = 1)'
7890
7891    Args:
7892        *expressions: the SQL code strings to parse.
7893            If an Expression instance is passed, this is used as-is.
7894        dialect: the dialect used to parse the input expression.
7895        copy: whether to copy `expressions` (only applies to Expressions).
7896        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7897            precedence issues, but can be turned off when the produced AST is too deep and
7898            causes recursion-related issues.
7899        **opts: other options to use to parse the input expressions.
7900
7901    Returns:
7902        The new condition
7903    """
7904    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:
7907def or_(
7908    *expressions: t.Optional[ExpOrStr],
7909    dialect: DialectType = None,
7910    copy: bool = True,
7911    wrap: bool = True,
7912    **opts,
7913) -> Condition:
7914    """
7915    Combine multiple conditions with an OR logical operator.
7916
7917    Example:
7918        >>> or_("x=1", or_("y=1", "z=1")).sql()
7919        'x = 1 OR (y = 1 OR z = 1)'
7920
7921    Args:
7922        *expressions: the SQL code strings to parse.
7923            If an Expression instance is passed, this is used as-is.
7924        dialect: the dialect used to parse the input expression.
7925        copy: whether to copy `expressions` (only applies to Expressions).
7926        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7927            precedence issues, but can be turned off when the produced AST is too deep and
7928            causes recursion-related issues.
7929        **opts: other options to use to parse the input expressions.
7930
7931    Returns:
7932        The new condition
7933    """
7934    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:
7937def xor(
7938    *expressions: t.Optional[ExpOrStr],
7939    dialect: DialectType = None,
7940    copy: bool = True,
7941    wrap: bool = True,
7942    **opts,
7943) -> Condition:
7944    """
7945    Combine multiple conditions with an XOR logical operator.
7946
7947    Example:
7948        >>> xor("x=1", xor("y=1", "z=1")).sql()
7949        'x = 1 XOR (y = 1 XOR z = 1)'
7950
7951    Args:
7952        *expressions: the SQL code strings to parse.
7953            If an Expression instance is passed, this is used as-is.
7954        dialect: the dialect used to parse the input expression.
7955        copy: whether to copy `expressions` (only applies to Expressions).
7956        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7957            precedence issues, but can be turned off when the produced AST is too deep and
7958            causes recursion-related issues.
7959        **opts: other options to use to parse the input expressions.
7960
7961    Returns:
7962        The new condition
7963    """
7964    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:
7967def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7968    """
7969    Wrap a condition with a NOT operator.
7970
7971    Example:
7972        >>> not_("this_suit='black'").sql()
7973        "NOT this_suit = 'black'"
7974
7975    Args:
7976        expression: the SQL code string to parse.
7977            If an Expression instance is passed, this is used as-is.
7978        dialect: the dialect used to parse the input expression.
7979        copy: whether to copy the expression or not.
7980        **opts: other options to use to parse the input expressions.
7981
7982    Returns:
7983        The new condition.
7984    """
7985    this = condition(
7986        expression,
7987        dialect=dialect,
7988        copy=copy,
7989        **opts,
7990    )
7991    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:
7994def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7995    """
7996    Wrap an expression in parentheses.
7997
7998    Example:
7999        >>> paren("5 + 3").sql()
8000        '(5 + 3)'
8001
8002    Args:
8003        expression: the SQL code string to parse.
8004            If an Expression instance is passed, this is used as-is.
8005        copy: whether to copy the expression or not.
8006
8007    Returns:
8008        The wrapped expression.
8009    """
8010    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):
8026def to_identifier(name, quoted=None, copy=True):
8027    """Builds an identifier.
8028
8029    Args:
8030        name: The name to turn into an identifier.
8031        quoted: Whether to force quote the identifier.
8032        copy: Whether to copy name if it's an Identifier.
8033
8034    Returns:
8035        The identifier ast node.
8036    """
8037
8038    if name is None:
8039        return None
8040
8041    if isinstance(name, Identifier):
8042        identifier = maybe_copy(name, copy)
8043    elif isinstance(name, str):
8044        identifier = Identifier(
8045            this=name,
8046            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8047        )
8048    else:
8049        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8050    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:
8053def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8054    """
8055    Parses a given string into an identifier.
8056
8057    Args:
8058        name: The name to parse into an identifier.
8059        dialect: The dialect to parse against.
8060
8061    Returns:
8062        The identifier ast node.
8063    """
8064    try:
8065        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8066    except (ParseError, TokenError):
8067        expression = to_identifier(name)
8068
8069    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:
8075def to_interval(interval: str | Literal) -> Interval:
8076    """Builds an interval expression from a string like '1 day' or '5 months'."""
8077    if isinstance(interval, Literal):
8078        if not interval.is_string:
8079            raise ValueError("Invalid interval string.")
8080
8081        interval = interval.this
8082
8083    interval = maybe_parse(f"INTERVAL {interval}")
8084    assert isinstance(interval, Interval)
8085    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:
8088def to_table(
8089    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8090) -> Table:
8091    """
8092    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8093    If a table is passed in then that table is returned.
8094
8095    Args:
8096        sql_path: a `[catalog].[schema].[table]` string.
8097        dialect: the source dialect according to which the table name will be parsed.
8098        copy: Whether to copy a table if it is passed in.
8099        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8100
8101    Returns:
8102        A table expression.
8103    """
8104    if isinstance(sql_path, Table):
8105        return maybe_copy(sql_path, copy=copy)
8106
8107    try:
8108        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8109    except ParseError:
8110        catalog, db, this = split_num_words(sql_path, ".", 3)
8111
8112        if not this:
8113            raise
8114
8115        table = table_(this, db=db, catalog=catalog)
8116
8117    for k, v in kwargs.items():
8118        table.set(k, v)
8119
8120    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:
8123def to_column(
8124    sql_path: str | Column,
8125    quoted: t.Optional[bool] = None,
8126    dialect: DialectType = None,
8127    copy: bool = True,
8128    **kwargs,
8129) -> Column:
8130    """
8131    Create a column from a `[table].[column]` sql path. Table is optional.
8132    If a column is passed in then that column is returned.
8133
8134    Args:
8135        sql_path: a `[table].[column]` string.
8136        quoted: Whether or not to force quote identifiers.
8137        dialect: the source dialect according to which the column name will be parsed.
8138        copy: Whether to copy a column if it is passed in.
8139        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8140
8141    Returns:
8142        A column expression.
8143    """
8144    if isinstance(sql_path, Column):
8145        return maybe_copy(sql_path, copy=copy)
8146
8147    try:
8148        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8149    except ParseError:
8150        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8151
8152    for k, v in kwargs.items():
8153        col.set(k, v)
8154
8155    if quoted:
8156        for i in col.find_all(Identifier):
8157            i.set("quoted", True)
8158
8159    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):
8162def alias_(
8163    expression: ExpOrStr,
8164    alias: t.Optional[str | Identifier],
8165    table: bool | t.Sequence[str | Identifier] = False,
8166    quoted: t.Optional[bool] = None,
8167    dialect: DialectType = None,
8168    copy: bool = True,
8169    **opts,
8170):
8171    """Create an Alias expression.
8172
8173    Example:
8174        >>> alias_('foo', 'bar').sql()
8175        'foo AS bar'
8176
8177        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8178        '(SELECT 1, 2) AS bar(a, b)'
8179
8180    Args:
8181        expression: the SQL code strings to parse.
8182            If an Expression instance is passed, this is used as-is.
8183        alias: the alias name to use. If the name has
8184            special characters it is quoted.
8185        table: Whether to create a table alias, can also be a list of columns.
8186        quoted: whether to quote the alias
8187        dialect: the dialect used to parse the input expression.
8188        copy: Whether to copy the expression.
8189        **opts: other options to use to parse the input expressions.
8190
8191    Returns:
8192        Alias: the aliased expression
8193    """
8194    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8195    alias = to_identifier(alias, quoted=quoted)
8196
8197    if table:
8198        table_alias = TableAlias(this=alias)
8199        exp.set("alias", table_alias)
8200
8201        if not isinstance(table, bool):
8202            for column in table:
8203                table_alias.append("columns", to_identifier(column, quoted=quoted))
8204
8205        return exp
8206
8207    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8208    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8209    # for the complete Window expression.
8210    #
8211    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8212
8213    if "alias" in exp.arg_types and not isinstance(exp, Window):
8214        exp.set("alias", alias)
8215        return exp
8216    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:
8219def subquery(
8220    expression: ExpOrStr,
8221    alias: t.Optional[Identifier | str] = None,
8222    dialect: DialectType = None,
8223    **opts,
8224) -> Select:
8225    """
8226    Build a subquery expression that's selected from.
8227
8228    Example:
8229        >>> subquery('select x from tbl', 'bar').select('x').sql()
8230        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8231
8232    Args:
8233        expression: the SQL code strings to parse.
8234            If an Expression instance is passed, this is used as-is.
8235        alias: the alias name to use.
8236        dialect: the dialect used to parse the input expression.
8237        **opts: other options to use to parse the input expressions.
8238
8239    Returns:
8240        A new Select instance with the subquery expression included.
8241    """
8242
8243    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8244    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):
8275def column(
8276    col,
8277    table=None,
8278    db=None,
8279    catalog=None,
8280    *,
8281    fields=None,
8282    quoted=None,
8283    copy=True,
8284):
8285    """
8286    Build a Column.
8287
8288    Args:
8289        col: Column name.
8290        table: Table name.
8291        db: Database name.
8292        catalog: Catalog name.
8293        fields: Additional fields using dots.
8294        quoted: Whether to force quotes on the column's identifiers.
8295        copy: Whether to copy identifiers if passed in.
8296
8297    Returns:
8298        The new Column instance.
8299    """
8300    if not isinstance(col, Star):
8301        col = to_identifier(col, quoted=quoted, copy=copy)
8302
8303    this = Column(
8304        this=col,
8305        table=to_identifier(table, quoted=quoted, copy=copy),
8306        db=to_identifier(db, quoted=quoted, copy=copy),
8307        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8308    )
8309
8310    if fields:
8311        this = Dot.build(
8312            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8313        )
8314    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:
8317def cast(
8318    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8319) -> Cast:
8320    """Cast an expression to a data type.
8321
8322    Example:
8323        >>> cast('x + 1', 'int').sql()
8324        'CAST(x + 1 AS INT)'
8325
8326    Args:
8327        expression: The expression to cast.
8328        to: The datatype to cast to.
8329        copy: Whether to copy the supplied expressions.
8330        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8331            - The expression to be cast is already a exp.Cast expression
8332            - The existing cast is to a type that is logically equivalent to new type
8333
8334            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8335            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8336            and instead just return the original expression `CAST(x as DATETIME)`.
8337
8338            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8339            mapping is applied in the target dialect generator.
8340
8341    Returns:
8342        The new Cast instance.
8343    """
8344    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8345    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8346
8347    # dont re-cast if the expression is already a cast to the correct type
8348    if isinstance(expr, Cast):
8349        from sqlglot.dialects.dialect import Dialect
8350
8351        target_dialect = Dialect.get_or_raise(dialect)
8352        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8353
8354        existing_cast_type: DataType.Type = expr.to.this
8355        new_cast_type: DataType.Type = data_type.this
8356        types_are_equivalent = type_mapping.get(
8357            existing_cast_type, existing_cast_type.value
8358        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8359
8360        if expr.is_type(data_type) or types_are_equivalent:
8361            return expr
8362
8363    expr = Cast(this=expr, to=data_type)
8364    expr.type = data_type
8365
8366    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:
8369def table_(
8370    table: Identifier | str,
8371    db: t.Optional[Identifier | str] = None,
8372    catalog: t.Optional[Identifier | str] = None,
8373    quoted: t.Optional[bool] = None,
8374    alias: t.Optional[Identifier | str] = None,
8375) -> Table:
8376    """Build a Table.
8377
8378    Args:
8379        table: Table name.
8380        db: Database name.
8381        catalog: Catalog name.
8382        quote: Whether to force quotes on the table's identifiers.
8383        alias: Table's alias.
8384
8385    Returns:
8386        The new Table instance.
8387    """
8388    return Table(
8389        this=to_identifier(table, quoted=quoted) if table else None,
8390        db=to_identifier(db, quoted=quoted) if db else None,
8391        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8392        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8393    )

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:
8396def values(
8397    values: t.Iterable[t.Tuple[t.Any, ...]],
8398    alias: t.Optional[str] = None,
8399    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8400) -> Values:
8401    """Build VALUES statement.
8402
8403    Example:
8404        >>> values([(1, '2')]).sql()
8405        "VALUES (1, '2')"
8406
8407    Args:
8408        values: values statements that will be converted to SQL
8409        alias: optional alias
8410        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8411         If either are provided then an alias is also required.
8412
8413    Returns:
8414        Values: the Values expression object
8415    """
8416    if columns and not alias:
8417        raise ValueError("Alias is required when providing columns")
8418
8419    return Values(
8420        expressions=[convert(tup) for tup in values],
8421        alias=(
8422            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8423            if columns
8424            else (TableAlias(this=to_identifier(alias)) if alias else None)
8425        ),
8426    )

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:
8429def var(name: t.Optional[ExpOrStr]) -> Var:
8430    """Build a SQL variable.
8431
8432    Example:
8433        >>> repr(var('x'))
8434        'Var(this=x)'
8435
8436        >>> repr(var(column('x', table='y')))
8437        'Var(this=x)'
8438
8439    Args:
8440        name: The name of the var or an expression who's name will become the var.
8441
8442    Returns:
8443        The new variable node.
8444    """
8445    if not name:
8446        raise ValueError("Cannot convert empty name into var.")
8447
8448    if isinstance(name, Expression):
8449        name = name.name
8450    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:
8453def rename_table(
8454    old_name: str | Table,
8455    new_name: str | Table,
8456    dialect: DialectType = None,
8457) -> Alter:
8458    """Build ALTER TABLE... RENAME... expression
8459
8460    Args:
8461        old_name: The old name of the table
8462        new_name: The new name of the table
8463        dialect: The dialect to parse the table.
8464
8465    Returns:
8466        Alter table expression
8467    """
8468    old_table = to_table(old_name, dialect=dialect)
8469    new_table = to_table(new_name, dialect=dialect)
8470    return Alter(
8471        this=old_table,
8472        kind="TABLE",
8473        actions=[
8474            AlterRename(this=new_table),
8475        ],
8476    )

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:
8479def rename_column(
8480    table_name: str | Table,
8481    old_column_name: str | Column,
8482    new_column_name: str | Column,
8483    exists: t.Optional[bool] = None,
8484    dialect: DialectType = None,
8485) -> Alter:
8486    """Build ALTER TABLE... RENAME COLUMN... expression
8487
8488    Args:
8489        table_name: Name of the table
8490        old_column: The old name of the column
8491        new_column: The new name of the column
8492        exists: Whether to add the `IF EXISTS` clause
8493        dialect: The dialect to parse the table/column.
8494
8495    Returns:
8496        Alter table expression
8497    """
8498    table = to_table(table_name, dialect=dialect)
8499    old_column = to_column(old_column_name, dialect=dialect)
8500    new_column = to_column(new_column_name, dialect=dialect)
8501    return Alter(
8502        this=table,
8503        kind="TABLE",
8504        actions=[
8505            RenameColumn(this=old_column, to=new_column, exists=exists),
8506        ],
8507    )

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:
8510def convert(value: t.Any, copy: bool = False) -> Expression:
8511    """Convert a python value into an expression object.
8512
8513    Raises an error if a conversion is not possible.
8514
8515    Args:
8516        value: A python object.
8517        copy: Whether to copy `value` (only applies to Expressions and collections).
8518
8519    Returns:
8520        The equivalent expression object.
8521    """
8522    if isinstance(value, Expression):
8523        return maybe_copy(value, copy)
8524    if isinstance(value, str):
8525        return Literal.string(value)
8526    if isinstance(value, bool):
8527        return Boolean(this=value)
8528    if value is None or (isinstance(value, float) and math.isnan(value)):
8529        return null()
8530    if isinstance(value, numbers.Number):
8531        return Literal.number(value)
8532    if isinstance(value, bytes):
8533        return HexString(this=value.hex())
8534    if isinstance(value, datetime.datetime):
8535        datetime_literal = Literal.string(value.isoformat(sep=" "))
8536
8537        tz = None
8538        if value.tzinfo:
8539            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8540            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8541            tz = Literal.string(str(value.tzinfo))
8542
8543        return TimeStrToTime(this=datetime_literal, zone=tz)
8544    if isinstance(value, datetime.date):
8545        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8546        return DateStrToDate(this=date_literal)
8547    if isinstance(value, datetime.time):
8548        time_literal = Literal.string(value.isoformat())
8549        return TsOrDsToTime(this=time_literal)
8550    if isinstance(value, tuple):
8551        if hasattr(value, "_fields"):
8552            return Struct(
8553                expressions=[
8554                    PropertyEQ(
8555                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8556                    )
8557                    for k in value._fields
8558                ]
8559            )
8560        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8561    if isinstance(value, list):
8562        return Array(expressions=[convert(v, copy=copy) for v in value])
8563    if isinstance(value, dict):
8564        return Map(
8565            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8566            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8567        )
8568    if hasattr(value, "__dict__"):
8569        return Struct(
8570            expressions=[
8571                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8572                for k, v in value.__dict__.items()
8573            ]
8574        )
8575    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:
8578def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8579    """
8580    Replace children of an expression with the result of a lambda fun(child) -> exp.
8581    """
8582    for k, v in tuple(expression.args.items()):
8583        is_list_arg = type(v) is list
8584
8585        child_nodes = v if is_list_arg else [v]
8586        new_child_nodes = []
8587
8588        for cn in child_nodes:
8589            if isinstance(cn, Expression):
8590                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8591                    new_child_nodes.append(child_node)
8592            else:
8593                new_child_nodes.append(cn)
8594
8595        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:
8598def replace_tree(
8599    expression: Expression,
8600    fun: t.Callable,
8601    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8602) -> Expression:
8603    """
8604    Replace an entire tree with the result of function calls on each node.
8605
8606    This will be traversed in reverse dfs, so leaves first.
8607    If new nodes are created as a result of function calls, they will also be traversed.
8608    """
8609    stack = list(expression.dfs(prune=prune))
8610
8611    while stack:
8612        node = stack.pop()
8613        new_node = fun(node)
8614
8615        if new_node is not node:
8616            node.replace(new_node)
8617
8618            if isinstance(new_node, Expression):
8619                stack.append(new_node)
8620
8621    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]:
8624def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8625    """
8626    Return all table names referenced through columns in an expression.
8627
8628    Example:
8629        >>> import sqlglot
8630        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8631        ['a', 'c']
8632
8633    Args:
8634        expression: expression to find table names.
8635        exclude: a table name to exclude
8636
8637    Returns:
8638        A list of unique names.
8639    """
8640    return {
8641        table
8642        for table in (column.table for column in expression.find_all(Column))
8643        if table and table != exclude
8644    }

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:
8647def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8648    """Get the full name of a table as a string.
8649
8650    Args:
8651        table: Table expression node or string.
8652        dialect: The dialect to generate the table name for.
8653        identify: Determines when an identifier should be quoted. Possible values are:
8654            False (default): Never quote, except in cases where it's mandatory by the dialect.
8655            True: Always quote.
8656
8657    Examples:
8658        >>> from sqlglot import exp, parse_one
8659        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8660        'a.b.c'
8661
8662    Returns:
8663        The table name.
8664    """
8665
8666    table = maybe_parse(table, into=Table, dialect=dialect)
8667
8668    if not table:
8669        raise ValueError(f"Cannot parse {table}")
8670
8671    return ".".join(
8672        (
8673            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8674            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8675            else part.name
8676        )
8677        for part in table.parts
8678    )

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:
8681def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8682    """Returns a case normalized table name without quotes.
8683
8684    Args:
8685        table: the table to normalize
8686        dialect: the dialect to use for normalization rules
8687        copy: whether to copy the expression.
8688
8689    Examples:
8690        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8691        'A-B.c'
8692    """
8693    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8694
8695    return ".".join(
8696        p.name
8697        for p in normalize_identifiers(
8698            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8699        ).parts
8700    )

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:
8703def replace_tables(
8704    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8705) -> E:
8706    """Replace all tables in expression according to the mapping.
8707
8708    Args:
8709        expression: expression node to be transformed and replaced.
8710        mapping: mapping of table names.
8711        dialect: the dialect of the mapping table
8712        copy: whether to copy the expression.
8713
8714    Examples:
8715        >>> from sqlglot import exp, parse_one
8716        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8717        'SELECT * FROM c /* a.b */'
8718
8719    Returns:
8720        The mapped expression.
8721    """
8722
8723    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8724
8725    def _replace_tables(node: Expression) -> Expression:
8726        if isinstance(node, Table) and node.meta.get("replace") is not False:
8727            original = normalize_table_name(node, dialect=dialect)
8728            new_name = mapping.get(original)
8729
8730            if new_name:
8731                table = to_table(
8732                    new_name,
8733                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8734                    dialect=dialect,
8735                )
8736                table.add_comments([original])
8737                return table
8738        return node
8739
8740    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:
8743def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8744    """Replace placeholders in an expression.
8745
8746    Args:
8747        expression: expression node to be transformed and replaced.
8748        args: positional names that will substitute unnamed placeholders in the given order.
8749        kwargs: keyword arguments that will substitute named placeholders.
8750
8751    Examples:
8752        >>> from sqlglot import exp, parse_one
8753        >>> replace_placeholders(
8754        ...     parse_one("select * from :tbl where ? = ?"),
8755        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8756        ... ).sql()
8757        "SELECT * FROM foo WHERE str_col = 'b'"
8758
8759    Returns:
8760        The mapped expression.
8761    """
8762
8763    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8764        if isinstance(node, Placeholder):
8765            if node.this:
8766                new_name = kwargs.get(node.this)
8767                if new_name is not None:
8768                    return convert(new_name)
8769            else:
8770                try:
8771                    return convert(next(args))
8772                except StopIteration:
8773                    pass
8774        return node
8775
8776    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:
8779def expand(
8780    expression: Expression,
8781    sources: t.Dict[str, Query | t.Callable[[], Query]],
8782    dialect: DialectType = None,
8783    copy: bool = True,
8784) -> Expression:
8785    """Transforms an expression by expanding all referenced sources into subqueries.
8786
8787    Examples:
8788        >>> from sqlglot import parse_one
8789        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8790        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8791
8792        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8793        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8794
8795    Args:
8796        expression: The expression to expand.
8797        sources: A dict of name to query or a callable that provides a query on demand.
8798        dialect: The dialect of the sources dict or the callable.
8799        copy: Whether to copy the expression during transformation. Defaults to True.
8800
8801    Returns:
8802        The transformed expression.
8803    """
8804    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8805
8806    def _expand(node: Expression):
8807        if isinstance(node, Table):
8808            name = normalize_table_name(node, dialect=dialect)
8809            source = normalized_sources.get(name)
8810
8811            if source:
8812                # Create a subquery with the same alias (or table name if no alias)
8813                parsed_source = source() if callable(source) else source
8814                subquery = parsed_source.subquery(node.alias or name)
8815                subquery.comments = [f"source: {name}"]
8816
8817                # Continue expanding within the subquery
8818                return subquery.transform(_expand, copy=False)
8819
8820        return node
8821
8822    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:
8825def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8826    """
8827    Returns a Func expression.
8828
8829    Examples:
8830        >>> func("abs", 5).sql()
8831        'ABS(5)'
8832
8833        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8834        'CAST(5 AS DOUBLE)'
8835
8836    Args:
8837        name: the name of the function to build.
8838        args: the args used to instantiate the function of interest.
8839        copy: whether to copy the argument expressions.
8840        dialect: the source dialect.
8841        kwargs: the kwargs used to instantiate the function of interest.
8842
8843    Note:
8844        The arguments `args` and `kwargs` are mutually exclusive.
8845
8846    Returns:
8847        An instance of the function of interest, or an anonymous function, if `name` doesn't
8848        correspond to an existing `sqlglot.expressions.Func` class.
8849    """
8850    if args and kwargs:
8851        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8852
8853    from sqlglot.dialects.dialect import Dialect
8854
8855    dialect = Dialect.get_or_raise(dialect)
8856
8857    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8858    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8859
8860    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8861    if constructor:
8862        if converted:
8863            if "dialect" in constructor.__code__.co_varnames:
8864                function = constructor(converted, dialect=dialect)
8865            else:
8866                function = constructor(converted)
8867        elif constructor.__name__ == "from_arg_list":
8868            function = constructor.__self__(**kwargs)  # type: ignore
8869        else:
8870            constructor = FUNCTION_BY_NAME.get(name.upper())
8871            if constructor:
8872                function = constructor(**kwargs)
8873            else:
8874                raise ValueError(
8875                    f"Unable to convert '{name}' into a Func. Either manually construct "
8876                    "the Func expression of interest or parse the function call."
8877                )
8878    else:
8879        kwargs = kwargs or {"expressions": converted}
8880        function = Anonymous(this=name, **kwargs)
8881
8882    for error_message in function.error_messages(converted):
8883        raise ValueError(error_message)
8884
8885    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:
8888def case(
8889    expression: t.Optional[ExpOrStr] = None,
8890    **opts,
8891) -> Case:
8892    """
8893    Initialize a CASE statement.
8894
8895    Example:
8896        case().when("a = 1", "foo").else_("bar")
8897
8898    Args:
8899        expression: Optionally, the input expression (not all dialects support this)
8900        **opts: Extra keyword arguments for parsing `expression`
8901    """
8902    if expression is not None:
8903        this = maybe_parse(expression, **opts)
8904    else:
8905        this = None
8906    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:
8909def array(
8910    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8911) -> Array:
8912    """
8913    Returns an array.
8914
8915    Examples:
8916        >>> array(1, 'x').sql()
8917        'ARRAY(1, x)'
8918
8919    Args:
8920        expressions: the expressions to add to the array.
8921        copy: whether to copy the argument expressions.
8922        dialect: the source dialect.
8923        kwargs: the kwargs used to instantiate the function of interest.
8924
8925    Returns:
8926        An array expression.
8927    """
8928    return Array(
8929        expressions=[
8930            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8931            for expression in expressions
8932        ]
8933    )

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:
8936def tuple_(
8937    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8938) -> Tuple:
8939    """
8940    Returns an tuple.
8941
8942    Examples:
8943        >>> tuple_(1, 'x').sql()
8944        '(1, x)'
8945
8946    Args:
8947        expressions: the expressions to add to the tuple.
8948        copy: whether to copy the argument expressions.
8949        dialect: the source dialect.
8950        kwargs: the kwargs used to instantiate the function of interest.
8951
8952    Returns:
8953        A tuple expression.
8954    """
8955    return Tuple(
8956        expressions=[
8957            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8958            for expression in expressions
8959        ]
8960    )

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:
8963def true() -> Boolean:
8964    """
8965    Returns a true Boolean expression.
8966    """
8967    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8970def false() -> Boolean:
8971    """
8972    Returns a false Boolean expression.
8973    """
8974    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8977def null() -> Null:
8978    """
8979    Returns a Null expression.
8980    """
8981    return Null()

Returns a Null expression.

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