Edit on GitHub

Expressions

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

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


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

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)
102    def __init__(self, **args: t.Any):
103        self.args: t.Dict[str, t.Any] = args
104        self.parent: t.Optional[Expression] = None
105        self.arg_key: t.Optional[str] = None
106        self.index: t.Optional[int] = None
107        self.comments: t.Optional[t.List[str]] = None
108        self._type: t.Optional[DataType] = None
109        self._meta: t.Optional[t.Dict[str, t.Any]] = None
110        self._hash: t.Optional[int] = None
111
112        for arg_key, value in self.args.items():
113            self._set_parent(arg_key, value)
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
118    @property
119    def hashable_args(self) -> t.Any:
120        return frozenset(
121            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
122            for k, v in self.args.items()
123            if not (v is None or v is False or (type(v) is list and not v))
124        )
this: Any
132    @property
133    def this(self) -> t.Any:
134        """
135        Retrieves the argument with key "this".
136        """
137        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
153    def text(self, key) -> str:
154        """
155        Returns a textual representation of the argument corresponding to "key". This can only be used
156        for args that are strings or leaf Expression instances, such as identifiers and literals.
157        """
158        field = self.args.get(key)
159        if isinstance(field, str):
160            return field
161        if isinstance(field, (Identifier, Literal, Var)):
162            return field.this
163        if isinstance(field, (Star, Null)):
164            return field.name
165        return ""

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
167    @property
168    def is_string(self) -> bool:
169        """
170        Checks whether a Literal expression is a string.
171        """
172        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
210    @property
211    def alias_column_names(self) -> t.List[str]:
212        table_alias = self.args.get("alias")
213        if not table_alias:
214            return []
215        return [c.name for c in table_alias.args.get("columns") or []]
name: str
217    @property
218    def name(self) -> str:
219        return self.text("this")
alias_or_name: str
221    @property
222    def alias_or_name(self) -> str:
223        return self.alias or self.name
output_name: str
225    @property
226    def output_name(self) -> str:
227        """
228        Name of the output column if this expression is a selection.
229
230        If the Expression has no output name, an empty string is returned.
231
232        Example:
233            >>> from sqlglot import parse_one
234            >>> parse_one("SELECT a").expressions[0].output_name
235            'a'
236            >>> parse_one("SELECT b AS c").expressions[0].output_name
237            'c'
238            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
239            ''
240        """
241        return ""

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

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
305    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
306        if self.comments is None:
307            self.comments = []
308
309        if comments:
310            for comment in comments:
311                _, *meta = comment.split(SQLGLOT_META)
312                if meta:
313                    for kv in "".join(meta).split(","):
314                        k, *v = kv.split("=")
315                        value = v[0].strip() if v else True
316                        self.meta[k.strip()] = value
317
318                if not prepend:
319                    self.comments.append(comment)
320
321            if prepend:
322                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
324    def pop_comments(self) -> t.List[str]:
325        comments = self.comments or []
326        self.comments = None
327        return comments
def append(self, arg_key: str, value: Any) -> None:
329    def append(self, arg_key: str, value: t.Any) -> None:
330        """
331        Appends value to arg_key if it's a list or sets it as a new list.
332
333        Args:
334            arg_key (str): name of the list expression arg
335            value (Any): value to append to the list
336        """
337        if type(self.args.get(arg_key)) is not list:
338            self.args[arg_key] = []
339        self._set_parent(arg_key, value)
340        values = self.args[arg_key]
341        if hasattr(value, "parent"):
342            value.index = len(values)
343        values.append(value)

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:
345    def set(
346        self,
347        arg_key: str,
348        value: t.Any,
349        index: t.Optional[int] = None,
350        overwrite: bool = True,
351    ) -> None:
352        """
353        Sets arg_key to value.
354
355        Args:
356            arg_key: name of the expression arg.
357            value: value to set the arg to.
358            index: if the arg is a list, this specifies what position to add the value in it.
359            overwrite: assuming an index is given, this determines whether to overwrite the
360                list entry instead of only inserting a new value (i.e., like list.insert).
361        """
362        if index is not None:
363            expressions = self.args.get(arg_key) or []
364
365            if seq_get(expressions, index) is None:
366                return
367            if value is None:
368                expressions.pop(index)
369                for v in expressions[index:]:
370                    v.index = v.index - 1
371                return
372
373            if isinstance(value, list):
374                expressions.pop(index)
375                expressions[index:index] = value
376            elif overwrite:
377                expressions[index] = value
378            else:
379                expressions.insert(index, value)
380
381            value = expressions
382        elif value is None:
383            self.args.pop(arg_key, None)
384            return
385
386        self.args[arg_key] = value
387        self._set_parent(arg_key, value, index)

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
401    @property
402    def depth(self) -> int:
403        """
404        Returns the depth of this tree.
405        """
406        if self.parent:
407            return self.parent.depth + 1
408        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
410    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
411        """Yields the key and expression for all arguments, exploding list args."""
412        # remove tuple when python 3.7 is deprecated
413        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():  # type: ignore
414            if type(vs) is list:
415                for v in reversed(vs) if reverse else vs:  # type: ignore
416                    if hasattr(v, "parent"):
417                        yield v
418            else:
419                if hasattr(vs, "parent"):
420                    yield vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
422    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
423        """
424        Returns the first node in this tree which matches at least one of
425        the specified types.
426
427        Args:
428            expression_types: the expression type(s) to match.
429            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
430
431        Returns:
432            The node which matches the criteria or None if no such node was found.
433        """
434        return next(self.find_all(*expression_types, bfs=bfs), None)

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]:
436    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
437        """
438        Returns a generator object which visits all nodes in this tree and only
439        yields those that match at least one of the specified expression types.
440
441        Args:
442            expression_types: the expression type(s) to match.
443            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
444
445        Returns:
446            The generator object.
447        """
448        for expression in self.walk(bfs=bfs):
449            if isinstance(expression, expression_types):
450                yield expression

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]:
452    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
453        """
454        Returns a nearest parent matching expression_types.
455
456        Args:
457            expression_types: the expression type(s) to match.
458
459        Returns:
460            The parent node.
461        """
462        ancestor = self.parent
463        while ancestor and not isinstance(ancestor, expression_types):
464            ancestor = ancestor.parent
465        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
488    def walk(
489        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
490    ) -> t.Iterator[Expression]:
491        """
492        Returns a generator object which visits all nodes in this tree.
493
494        Args:
495            bfs: if set to True the BFS traversal order will be applied,
496                otherwise the DFS traversal will be used instead.
497            prune: callable that returns True if the generator should stop traversing
498                this branch of the tree.
499
500        Returns:
501            the generator object.
502        """
503        if bfs:
504            yield from self.bfs(prune=prune)
505        else:
506            yield from self.dfs(prune=prune)

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]:
508    def dfs(
509        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
510    ) -> t.Iterator[Expression]:
511        """
512        Returns a generator object which visits all nodes in this tree in
513        the DFS (Depth-first) order.
514
515        Returns:
516            The generator object.
517        """
518        stack = [self]
519
520        while stack:
521            node = stack.pop()
522
523            yield node
524
525            if prune and prune(node):
526                continue
527
528            for v in node.iter_expressions(reverse=True):
529                stack.append(v)

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]:
531    def bfs(
532        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
533    ) -> t.Iterator[Expression]:
534        """
535        Returns a generator object which visits all nodes in this tree in
536        the BFS (Breadth-first) order.
537
538        Returns:
539            The generator object.
540        """
541        queue = deque([self])
542
543        while queue:
544            node = queue.popleft()
545
546            yield node
547
548            if prune and prune(node):
549                continue
550
551            for v in node.iter_expressions():
552                queue.append(v)

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

Returns:

The generator object.

def unnest(self):
554    def unnest(self):
555        """
556        Returns the first non parenthesis child or self.
557        """
558        expression = self
559        while type(expression) is Paren:
560            expression = expression.this
561        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
577    def flatten(self, unnest=True):
578        """
579        Returns a generator which yields child nodes whose parents are the same class.
580
581        A AND B AND C -> [A, B, C]
582        """
583        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
584            if type(node) is not self.__class__:
585                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

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:
593    def to_s(self) -> str:
594        """
595        Same as __repr__, but includes additional information which can be useful
596        for debugging, like empty or missing args and the AST nodes' object IDs.
597        """
598        return _to_s(self, verbose=True)

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

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
600    def sql(self, dialect: DialectType = None, **opts) -> str:
601        """
602        Returns SQL string representation of this tree.
603
604        Args:
605            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
606            opts: other `sqlglot.generator.Generator` options.
607
608        Returns:
609            The SQL string.
610        """
611        from sqlglot.dialects import Dialect
612
613        return Dialect.get_or_raise(dialect).generate(self, **opts)

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:
615    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
616        """
617        Visits all tree nodes (excluding already transformed ones)
618        and applies the given transformation function to each node.
619
620        Args:
621            fun: a function which takes a node as an argument and returns a
622                new transformed node or the same node without modifications. If the function
623                returns None, then the corresponding node will be removed from the syntax tree.
624            copy: if set to True a new tree instance is constructed, otherwise the tree is
625                modified in place.
626
627        Returns:
628            The transformed tree.
629        """
630        root = None
631        new_node = None
632
633        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
634            parent, arg_key, index = node.parent, node.arg_key, node.index
635            new_node = fun(node, *args, **kwargs)
636
637            if not root:
638                root = new_node
639            elif new_node is not node:
640                parent.set(arg_key, new_node, index)
641
642        assert root
643        return root.assert_is(Expression)

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):
651    def replace(self, expression):
652        """
653        Swap out this expression with a new expression.
654
655        For example::
656
657            >>> tree = Select().select("x").from_("tbl")
658            >>> tree.find(Column).replace(column("y"))
659            Column(
660              this=Identifier(this=y, quoted=False))
661            >>> tree.sql()
662            'SELECT y FROM tbl'
663
664        Args:
665            expression: new node
666
667        Returns:
668            The new expression or expressions.
669        """
670        parent = self.parent
671
672        if not parent or parent is expression:
673            return expression
674
675        key = self.arg_key
676        value = parent.args.get(key)
677
678        if type(expression) is list and isinstance(value, Expression):
679            # We are trying to replace an Expression with a list, so it's assumed that
680            # the intention was to really replace the parent of this expression.
681            value.parent.replace(expression)
682        else:
683            parent.set(key, expression, self.index)
684
685        if expression is not self:
686            self.parent = None
687            self.arg_key = None
688            self.index = None
689
690        return expression

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:
692    def pop(self: E) -> E:
693        """
694        Remove this expression from its AST.
695
696        Returns:
697            The popped expression.
698        """
699        self.replace(None)
700        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
702    def assert_is(self, type_: t.Type[E]) -> E:
703        """
704        Assert that this `Expression` is an instance of `type_`.
705
706        If it is NOT an instance of `type_`, this raises an assertion error.
707        Otherwise, this returns this expression.
708
709        Examples:
710            This is useful for type security in chained expressions:
711
712            >>> import sqlglot
713            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
714            'SELECT x, z FROM y'
715        """
716        if not isinstance(self, type_):
717            raise AssertionError(f"{self} is not {type_}.")
718        return self

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]:
720    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
721        """
722        Checks if this expression is valid (e.g. all mandatory args are set).
723
724        Args:
725            args: a sequence of values that were used to instantiate a Func expression. This is used
726                to check that the provided arguments don't exceed the function argument limit.
727
728        Returns:
729            A list of error messages for all possible errors that were found.
730        """
731        errors: t.List[str] = []
732
733        for k in self.args:
734            if k not in self.arg_types:
735                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
736        for k, mandatory in self.arg_types.items():
737            v = self.args.get(k)
738            if mandatory and (v is None or (isinstance(v, list) and not v)):
739                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
740
741        if (
742            args
743            and isinstance(self, Func)
744            and len(args) > len(self.arg_types)
745            and not self.is_var_len_args
746        ):
747            errors.append(
748                f"The number of provided arguments ({len(args)}) is greater than "
749                f"the maximum number of supported arguments ({len(self.arg_types)})"
750            )
751
752        return errors

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):
754    def dump(self):
755        """
756        Dump this Expression to a JSON-serializable dict.
757        """
758        from sqlglot.serde import dump
759
760        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
762    @classmethod
763    def load(cls, obj):
764        """
765        Load a dict (as returned by `Expression.dump`) into an Expression instance.
766        """
767        from sqlglot.serde import load
768
769        return load(obj)

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

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

AND this condition with one or multiple expressions.

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

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
801    def or_(
802        self,
803        *expressions: t.Optional[ExpOrStr],
804        dialect: DialectType = None,
805        copy: bool = True,
806        wrap: bool = True,
807        **opts,
808    ) -> Condition:
809        """
810        OR this condition with one or multiple expressions.
811
812        Example:
813            >>> condition("x=1").or_("y=1").sql()
814            'x = 1 OR y = 1'
815
816        Args:
817            *expressions: the SQL code strings to parse.
818                If an `Expression` instance is passed, it will be used as-is.
819            dialect: the dialect used to parse the input expression.
820            copy: whether to copy the involved expressions (only applies to Expressions).
821            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
822                precedence issues, but can be turned off when the produced AST is too deep and
823                causes recursion-related issues.
824            opts: other options to use to parse the input expressions.
825
826        Returns:
827            The new Or condition.
828        """
829        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)

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):
831    def not_(self, copy: bool = True):
832        """
833        Wrap this condition with NOT.
834
835        Example:
836            >>> condition("x=1").not_().sql()
837            'NOT x = 1'
838
839        Args:
840            copy: whether to copy this object.
841
842        Returns:
843            The new Not instance.
844        """
845        return not_(self, copy=copy)

Wrap this condition with NOT.

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

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
847    def as_(
848        self,
849        alias: str | Identifier,
850        quoted: t.Optional[bool] = None,
851        dialect: DialectType = None,
852        copy: bool = True,
853        **opts,
854    ) -> Alias:
855        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
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:
880    def isin(
881        self,
882        *expressions: t.Any,
883        query: t.Optional[ExpOrStr] = None,
884        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
885        copy: bool = True,
886        **opts,
887    ) -> In:
888        subquery = maybe_parse(query, copy=copy, **opts) if query else None
889        if subquery and not isinstance(subquery, Subquery):
890            subquery = subquery.subquery(copy=False)
891
892        return In(
893            this=maybe_copy(self, copy),
894            expressions=[convert(e, copy=copy) for e in expressions],
895            query=subquery,
896            unnest=(
897                Unnest(
898                    expressions=[
899                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
900                        for e in ensure_list(unnest)
901                    ]
902                )
903                if unnest
904                else None
905            ),
906        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
908    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
909        return Between(
910            this=maybe_copy(self, copy),
911            low=convert(low, copy=copy, **opts),
912            high=convert(high, copy=copy, **opts),
913        )
def is_( self, other: Union[str, Expression]) -> Is:
915    def is_(self, other: ExpOrStr) -> Is:
916        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
918    def like(self, other: ExpOrStr) -> Like:
919        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
921    def ilike(self, other: ExpOrStr) -> ILike:
922        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
924    def eq(self, other: t.Any) -> EQ:
925        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
927    def neq(self, other: t.Any) -> NEQ:
928        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
930    def rlike(self, other: ExpOrStr) -> RegexpLike:
931        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
933    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
934        div = self._binop(Div, other)
935        div.args["typed"] = typed
936        div.args["safe"] = safe
937        return div
def asc(self, nulls_first: bool = True) -> Ordered:
939    def asc(self, nulls_first: bool = True) -> Ordered:
940        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
942    def desc(self, nulls_first: bool = False) -> Ordered:
943        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):
1026class Condition(Expression):
1027    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1064    def limit(
1065        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1066    ) -> Q:
1067        """
1068        Adds a LIMIT clause to this query.
1069
1070        Example:
1071            >>> select("1").union(select("1")).limit(1).sql()
1072            'SELECT 1 UNION SELECT 1 LIMIT 1'
1073
1074        Args:
1075            expression: the SQL code string to parse.
1076                This can also be an integer.
1077                If a `Limit` instance is passed, it will be used as-is.
1078                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1079            dialect: the dialect used to parse the input expression.
1080            copy: if `False`, modify this expression instance in-place.
1081            opts: other options to use to parse the input expressions.
1082
1083        Returns:
1084            A limited Select expression.
1085        """
1086        return _apply_builder(
1087            expression=expression,
1088            instance=self,
1089            arg="limit",
1090            into=Limit,
1091            prefix="LIMIT",
1092            dialect=dialect,
1093            copy=copy,
1094            into_arg="expression",
1095            **opts,
1096        )

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1188    def select(
1189        self: Q,
1190        *expressions: t.Optional[ExpOrStr],
1191        append: bool = True,
1192        dialect: DialectType = None,
1193        copy: bool = True,
1194        **opts,
1195    ) -> Q:
1196        """
1197        Append to or set the SELECT expressions.
1198
1199        Example:
1200            >>> Select().select("x", "y").sql()
1201            'SELECT x, y'
1202
1203        Args:
1204            *expressions: the SQL code strings to parse.
1205                If an `Expression` instance is passed, it will be used as-is.
1206            append: if `True`, add to any existing expressions.
1207                Otherwise, this resets the expressions.
1208            dialect: the dialect used to parse the input expressions.
1209            copy: if `False`, modify this expression instance in-place.
1210            opts: other options to use to parse the input expressions.
1211
1212        Returns:
1213            The modified Query expression.
1214        """
1215        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

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

The modified Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1217    def with_(
1218        self: Q,
1219        alias: ExpOrStr,
1220        as_: ExpOrStr,
1221        recursive: t.Optional[bool] = None,
1222        materialized: t.Optional[bool] = None,
1223        append: bool = True,
1224        dialect: DialectType = None,
1225        copy: bool = True,
1226        **opts,
1227    ) -> Q:
1228        """
1229        Append to or set the common table expressions.
1230
1231        Example:
1232            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1233            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1234
1235        Args:
1236            alias: the SQL code string to parse as the table name.
1237                If an `Expression` instance is passed, this is used as-is.
1238            as_: the SQL code string to parse as the table expression.
1239                If an `Expression` instance is passed, it will be used as-is.
1240            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1241            materialized: set the MATERIALIZED part of the expression.
1242            append: if `True`, add to any existing expressions.
1243                Otherwise, this resets the expressions.
1244            dialect: the dialect used to parse the input expression.
1245            copy: if `False`, modify this expression instance in-place.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The modified expression.
1250        """
1251        return _apply_cte_builder(
1252            self,
1253            alias,
1254            as_,
1255            recursive=recursive,
1256            materialized=materialized,
1257            append=append,
1258            dialect=dialect,
1259            copy=copy,
1260            **opts,
1261        )

Append to or set the common table expressions.

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

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1263    def union(
1264        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1265    ) -> Union:
1266        """
1267        Builds a UNION expression.
1268
1269        Example:
1270            >>> import sqlglot
1271            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1272            'SELECT * FROM foo UNION SELECT * FROM bla'
1273
1274        Args:
1275            expressions: the SQL code strings.
1276                If `Expression` instances are passed, they will be used as-is.
1277            distinct: set the DISTINCT flag if and only if this is true.
1278            dialect: the dialect used to parse the input expression.
1279            opts: other options to use to parse the input expressions.
1280
1281        Returns:
1282            The new Union expression.
1283        """
1284        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

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

The new Union expression.

def intersect( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1286    def intersect(
1287        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1288    ) -> Intersect:
1289        """
1290        Builds an INTERSECT expression.
1291
1292        Example:
1293            >>> import sqlglot
1294            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1295            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1296
1297        Args:
1298            expressions: the SQL code strings.
1299                If `Expression` instances are passed, they will be used as-is.
1300            distinct: set the DISTINCT flag if and only if this is true.
1301            dialect: the dialect used to parse the input expression.
1302            opts: other options to use to parse the input expressions.
1303
1304        Returns:
1305            The new Intersect expression.
1306        """
1307        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

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

The new Intersect expression.

def except_( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1309    def except_(
1310        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1311    ) -> Except:
1312        """
1313        Builds an EXCEPT expression.
1314
1315        Example:
1316            >>> import sqlglot
1317            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1318            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1319
1320        Args:
1321            expressions: the SQL code strings.
1322                If `Expression` instance are passed, they will be used as-is.
1323            distinct: set the DISTINCT flag if and only if this is true.
1324            dialect: the dialect used to parse the input expression.
1325            opts: other options to use to parse the input expressions.
1326
1327        Returns:
1328            The new Except expression.
1329        """
1330        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)

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):
1333class UDTF(DerivedTable):
1334    @property
1335    def selects(self) -> t.List[Expression]:
1336        alias = self.args.get("alias")
1337        return alias.columns if alias else []
selects: List[Expression]
1334    @property
1335    def selects(self) -> t.List[Expression]:
1336        alias = self.args.get("alias")
1337        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1340class Cache(Expression):
1341    arg_types = {
1342        "this": True,
1343        "lazy": False,
1344        "options": False,
1345        "expression": False,
1346    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1349class Uncache(Expression):
1350    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1353class Refresh(Expression):
1354    pass
key = 'refresh'
class DDL(Expression):
1357class DDL(Expression):
1358    @property
1359    def ctes(self) -> t.List[CTE]:
1360        """Returns a list of all the CTEs attached to this statement."""
1361        with_ = self.args.get("with")
1362        return with_.expressions if with_ else []
1363
1364    @property
1365    def selects(self) -> t.List[Expression]:
1366        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1367        return self.expression.selects if isinstance(self.expression, Query) else []
1368
1369    @property
1370    def named_selects(self) -> t.List[str]:
1371        """
1372        If this statement contains a query (e.g. a CTAS), this returns the output
1373        names of the query's projections.
1374        """
1375        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1358    @property
1359    def ctes(self) -> t.List[CTE]:
1360        """Returns a list of all the CTEs attached to this statement."""
1361        with_ = self.args.get("with")
1362        return with_.expressions if with_ else []

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

selects: List[Expression]
1364    @property
1365    def selects(self) -> t.List[Expression]:
1366        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1367        return self.expression.selects if isinstance(self.expression, Query) else []

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

named_selects: List[str]
1369    @property
1370    def named_selects(self) -> t.List[str]:
1371        """
1372        If this statement contains a query (e.g. a CTAS), this returns the output
1373        names of the query's projections.
1374        """
1375        return self.expression.named_selects if isinstance(self.expression, Query) else []

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):
1378class DML(Expression):
1379    def returning(
1380        self,
1381        expression: ExpOrStr,
1382        dialect: DialectType = None,
1383        copy: bool = True,
1384        **opts,
1385    ) -> "Self":
1386        """
1387        Set the RETURNING expression. Not supported by all dialects.
1388
1389        Example:
1390            >>> delete("tbl").returning("*", dialect="postgres").sql()
1391            'DELETE FROM tbl RETURNING *'
1392
1393        Args:
1394            expression: the SQL code strings to parse.
1395                If an `Expression` instance is passed, it will be used as-is.
1396            dialect: the dialect used to parse the input expressions.
1397            copy: if `False`, modify this expression instance in-place.
1398            opts: other options to use to parse the input expressions.
1399
1400        Returns:
1401            Delete: the modified expression.
1402        """
1403        return _apply_builder(
1404            expression=expression,
1405            instance=self,
1406            arg="returning",
1407            prefix="RETURNING",
1408            dialect=dialect,
1409            copy=copy,
1410            into=Returning,
1411            **opts,
1412        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1379    def returning(
1380        self,
1381        expression: ExpOrStr,
1382        dialect: DialectType = None,
1383        copy: bool = True,
1384        **opts,
1385    ) -> "Self":
1386        """
1387        Set the RETURNING expression. Not supported by all dialects.
1388
1389        Example:
1390            >>> delete("tbl").returning("*", dialect="postgres").sql()
1391            'DELETE FROM tbl RETURNING *'
1392
1393        Args:
1394            expression: the SQL code strings to parse.
1395                If an `Expression` instance is passed, it will be used as-is.
1396            dialect: the dialect used to parse the input expressions.
1397            copy: if `False`, modify this expression instance in-place.
1398            opts: other options to use to parse the input expressions.
1399
1400        Returns:
1401            Delete: the modified expression.
1402        """
1403        return _apply_builder(
1404            expression=expression,
1405            instance=self,
1406            arg="returning",
1407            prefix="RETURNING",
1408            dialect=dialect,
1409            copy=copy,
1410            into=Returning,
1411            **opts,
1412        )

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):
1415class Create(DDL):
1416    arg_types = {
1417        "with": False,
1418        "this": True,
1419        "kind": True,
1420        "expression": False,
1421        "exists": False,
1422        "properties": False,
1423        "replace": False,
1424        "refresh": False,
1425        "unique": False,
1426        "indexes": False,
1427        "no_schema_binding": False,
1428        "begin": False,
1429        "end": False,
1430        "clone": False,
1431        "concurrently": False,
1432        "clustered": False,
1433    }
1434
1435    @property
1436    def kind(self) -> t.Optional[str]:
1437        kind = self.args.get("kind")
1438        return kind and kind.upper()
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]
1435    @property
1436    def kind(self) -> t.Optional[str]:
1437        kind = self.args.get("kind")
1438        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1441class SequenceProperties(Expression):
1442    arg_types = {
1443        "increment": False,
1444        "minvalue": False,
1445        "maxvalue": False,
1446        "cache": False,
1447        "start": False,
1448        "owned": False,
1449        "options": False,
1450    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1453class TruncateTable(Expression):
1454    arg_types = {
1455        "expressions": True,
1456        "is_database": False,
1457        "exists": False,
1458        "only": False,
1459        "cluster": False,
1460        "identity": False,
1461        "option": False,
1462        "partition": False,
1463    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1469class Clone(Expression):
1470    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1473class Describe(Expression):
1474    arg_types = {
1475        "this": True,
1476        "style": False,
1477        "kind": False,
1478        "expressions": False,
1479        "partition": False,
1480    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False}
key = 'describe'
class Summarize(Expression):
1484class Summarize(Expression):
1485    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1488class Kill(Expression):
1489    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1492class Pragma(Expression):
1493    pass
key = 'pragma'
class Declare(Expression):
1496class Declare(Expression):
1497    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1500class DeclareItem(Expression):
1501    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1504class Set(Expression):
1505    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1508class Heredoc(Expression):
1509    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1512class SetItem(Expression):
1513    arg_types = {
1514        "this": False,
1515        "expressions": False,
1516        "kind": False,
1517        "collate": False,  # MySQL SET NAMES statement
1518        "global": False,
1519    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1522class Show(Expression):
1523    arg_types = {
1524        "this": True,
1525        "history": False,
1526        "terse": False,
1527        "target": False,
1528        "offset": False,
1529        "starts_with": False,
1530        "limit": False,
1531        "from": False,
1532        "like": False,
1533        "where": False,
1534        "db": False,
1535        "scope": False,
1536        "scope_kind": False,
1537        "full": False,
1538        "mutex": False,
1539        "query": False,
1540        "channel": False,
1541        "global": False,
1542        "log": False,
1543        "position": False,
1544        "types": False,
1545    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False}
key = 'show'
class UserDefinedFunction(Expression):
1548class UserDefinedFunction(Expression):
1549    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1552class CharacterSet(Expression):
1553    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1556class With(Expression):
1557    arg_types = {"expressions": True, "recursive": False}
1558
1559    @property
1560    def recursive(self) -> bool:
1561        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1559    @property
1560    def recursive(self) -> bool:
1561        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1564class WithinGroup(Expression):
1565    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1570class CTE(DerivedTable):
1571    arg_types = {
1572        "this": True,
1573        "alias": True,
1574        "scalar": False,
1575        "materialized": False,
1576    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1579class ProjectionDef(Expression):
1580    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1583class TableAlias(Expression):
1584    arg_types = {"this": False, "columns": False}
1585
1586    @property
1587    def columns(self):
1588        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1586    @property
1587    def columns(self):
1588        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1591class BitString(Condition):
1592    pass
key = 'bitstring'
class HexString(Condition):
1595class HexString(Condition):
1596    pass
key = 'hexstring'
class ByteString(Condition):
1599class ByteString(Condition):
1600    pass
key = 'bytestring'
class RawString(Condition):
1603class RawString(Condition):
1604    pass
key = 'rawstring'
class UnicodeString(Condition):
1607class UnicodeString(Condition):
1608    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1611class Column(Condition):
1612    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1613
1614    @property
1615    def table(self) -> str:
1616        return self.text("table")
1617
1618    @property
1619    def db(self) -> str:
1620        return self.text("db")
1621
1622    @property
1623    def catalog(self) -> str:
1624        return self.text("catalog")
1625
1626    @property
1627    def output_name(self) -> str:
1628        return self.name
1629
1630    @property
1631    def parts(self) -> t.List[Identifier]:
1632        """Return the parts of a column in order catalog, db, table, name."""
1633        return [
1634            t.cast(Identifier, self.args[part])
1635            for part in ("catalog", "db", "table", "this")
1636            if self.args.get(part)
1637        ]
1638
1639    def to_dot(self) -> Dot | Identifier:
1640        """Converts the column into a dot expression."""
1641        parts = self.parts
1642        parent = self.parent
1643
1644        while parent:
1645            if isinstance(parent, Dot):
1646                parts.append(parent.expression)
1647            parent = parent.parent
1648
1649        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
1614    @property
1615    def table(self) -> str:
1616        return self.text("table")
db: str
1618    @property
1619    def db(self) -> str:
1620        return self.text("db")
catalog: str
1622    @property
1623    def catalog(self) -> str:
1624        return self.text("catalog")
output_name: str
1626    @property
1627    def output_name(self) -> str:
1628        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]
1630    @property
1631    def parts(self) -> t.List[Identifier]:
1632        """Return the parts of a column in order catalog, db, table, name."""
1633        return [
1634            t.cast(Identifier, self.args[part])
1635            for part in ("catalog", "db", "table", "this")
1636            if self.args.get(part)
1637        ]

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

def to_dot(self) -> Dot | Identifier:
1639    def to_dot(self) -> Dot | Identifier:
1640        """Converts the column into a dot expression."""
1641        parts = self.parts
1642        parent = self.parent
1643
1644        while parent:
1645            if isinstance(parent, Dot):
1646                parts.append(parent.expression)
1647            parent = parent.parent
1648
1649        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1652class ColumnPosition(Expression):
1653    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1656class ColumnDef(Expression):
1657    arg_types = {
1658        "this": True,
1659        "kind": False,
1660        "constraints": False,
1661        "exists": False,
1662        "position": False,
1663    }
1664
1665    @property
1666    def constraints(self) -> t.List[ColumnConstraint]:
1667        return self.args.get("constraints") or []
1668
1669    @property
1670    def kind(self) -> t.Optional[DataType]:
1671        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1665    @property
1666    def constraints(self) -> t.List[ColumnConstraint]:
1667        return self.args.get("constraints") or []
kind: Optional[DataType]
1669    @property
1670    def kind(self) -> t.Optional[DataType]:
1671        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1674class AlterColumn(Expression):
1675    arg_types = {
1676        "this": True,
1677        "dtype": False,
1678        "collate": False,
1679        "using": False,
1680        "default": False,
1681        "drop": False,
1682        "comment": False,
1683        "allow_null": False,
1684    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1688class AlterDistStyle(Expression):
1689    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1692class AlterSortKey(Expression):
1693    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1696class AlterSet(Expression):
1697    arg_types = {
1698        "expressions": False,
1699        "option": False,
1700        "tablespace": False,
1701        "access_method": False,
1702        "file_format": False,
1703        "copy_options": False,
1704        "tag": False,
1705        "location": False,
1706        "serde": False,
1707    }
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):
1710class RenameColumn(Expression):
1711    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1714class AlterRename(Expression):
1715    pass
key = 'alterrename'
class SwapTable(Expression):
1718class SwapTable(Expression):
1719    pass
key = 'swaptable'
class Comment(Expression):
1722class Comment(Expression):
1723    arg_types = {
1724        "this": True,
1725        "kind": True,
1726        "expression": True,
1727        "exists": False,
1728        "materialized": False,
1729    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1732class Comprehension(Expression):
1733    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):
1737class MergeTreeTTLAction(Expression):
1738    arg_types = {
1739        "this": True,
1740        "delete": False,
1741        "recompress": False,
1742        "to_disk": False,
1743        "to_volume": False,
1744    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1748class MergeTreeTTL(Expression):
1749    arg_types = {
1750        "expressions": True,
1751        "where": False,
1752        "group": False,
1753        "aggregates": False,
1754    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1758class IndexConstraintOption(Expression):
1759    arg_types = {
1760        "key_block_size": False,
1761        "using": False,
1762        "parser": False,
1763        "comment": False,
1764        "visible": False,
1765        "engine_attr": False,
1766        "secondary_engine_attr": False,
1767    }
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):
1770class ColumnConstraint(Expression):
1771    arg_types = {"this": False, "kind": True}
1772
1773    @property
1774    def kind(self) -> ColumnConstraintKind:
1775        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1773    @property
1774    def kind(self) -> ColumnConstraintKind:
1775        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1778class ColumnConstraintKind(Expression):
1779    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1782class AutoIncrementColumnConstraint(ColumnConstraintKind):
1783    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1786class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1787    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1790class CaseSpecificColumnConstraint(ColumnConstraintKind):
1791    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1794class CharacterSetColumnConstraint(ColumnConstraintKind):
1795    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1798class CheckColumnConstraint(ColumnConstraintKind):
1799    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1802class ClusteredColumnConstraint(ColumnConstraintKind):
1803    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1806class CollateColumnConstraint(ColumnConstraintKind):
1807    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1810class CommentColumnConstraint(ColumnConstraintKind):
1811    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1814class CompressColumnConstraint(ColumnConstraintKind):
1815    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1818class DateFormatColumnConstraint(ColumnConstraintKind):
1819    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1822class DefaultColumnConstraint(ColumnConstraintKind):
1823    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1826class EncodeColumnConstraint(ColumnConstraintKind):
1827    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1831class ExcludeColumnConstraint(ColumnConstraintKind):
1832    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1835class EphemeralColumnConstraint(ColumnConstraintKind):
1836    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1839class WithOperator(Expression):
1840    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1843class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1844    # this: True -> ALWAYS, this: False -> BY DEFAULT
1845    arg_types = {
1846        "this": False,
1847        "expression": False,
1848        "on_null": False,
1849        "start": False,
1850        "increment": False,
1851        "minvalue": False,
1852        "maxvalue": False,
1853        "cycle": False,
1854    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1857class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1858    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1863class IndexColumnConstraint(ColumnConstraintKind):
1864    arg_types = {
1865        "this": False,
1866        "expressions": False,
1867        "kind": False,
1868        "index_type": False,
1869        "options": False,
1870        "expression": False,  # Clickhouse
1871        "granularity": False,
1872    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1875class InlineLengthColumnConstraint(ColumnConstraintKind):
1876    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1879class NonClusteredColumnConstraint(ColumnConstraintKind):
1880    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1883class NotForReplicationColumnConstraint(ColumnConstraintKind):
1884    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1888class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1889    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1892class NotNullColumnConstraint(ColumnConstraintKind):
1893    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1897class OnUpdateColumnConstraint(ColumnConstraintKind):
1898    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1902class TagColumnConstraint(ColumnConstraintKind):
1903    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1907class TransformColumnConstraint(ColumnConstraintKind):
1908    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1911class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1912    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1915class TitleColumnConstraint(ColumnConstraintKind):
1916    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1919class UniqueColumnConstraint(ColumnConstraintKind):
1920    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1923class UppercaseColumnConstraint(ColumnConstraintKind):
1924    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1927class PathColumnConstraint(ColumnConstraintKind):
1928    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1932class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1933    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1938class ComputedColumnConstraint(ColumnConstraintKind):
1939    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1942class Constraint(Expression):
1943    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1946class Delete(DML):
1947    arg_types = {
1948        "with": False,
1949        "this": False,
1950        "using": False,
1951        "where": False,
1952        "returning": False,
1953        "limit": False,
1954        "tables": False,  # Multiple-Table Syntax (MySQL)
1955        "cluster": False,  # Clickhouse
1956    }
1957
1958    def delete(
1959        self,
1960        table: ExpOrStr,
1961        dialect: DialectType = None,
1962        copy: bool = True,
1963        **opts,
1964    ) -> Delete:
1965        """
1966        Create a DELETE expression or replace the table on an existing DELETE expression.
1967
1968        Example:
1969            >>> delete("tbl").sql()
1970            'DELETE FROM tbl'
1971
1972        Args:
1973            table: the table from which to delete.
1974            dialect: the dialect used to parse the input expression.
1975            copy: if `False`, modify this expression instance in-place.
1976            opts: other options to use to parse the input expressions.
1977
1978        Returns:
1979            Delete: the modified expression.
1980        """
1981        return _apply_builder(
1982            expression=table,
1983            instance=self,
1984            arg="this",
1985            dialect=dialect,
1986            into=Table,
1987            copy=copy,
1988            **opts,
1989        )
1990
1991    def where(
1992        self,
1993        *expressions: t.Optional[ExpOrStr],
1994        append: bool = True,
1995        dialect: DialectType = None,
1996        copy: bool = True,
1997        **opts,
1998    ) -> Delete:
1999        """
2000        Append to or set the WHERE expressions.
2001
2002        Example:
2003            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2004            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2005
2006        Args:
2007            *expressions: the SQL code strings to parse.
2008                If an `Expression` instance is passed, it will be used as-is.
2009                Multiple expressions are combined with an AND operator.
2010            append: if `True`, AND the new expressions to any existing expression.
2011                Otherwise, this resets the expression.
2012            dialect: the dialect used to parse the input expressions.
2013            copy: if `False`, modify this expression instance in-place.
2014            opts: other options to use to parse the input expressions.
2015
2016        Returns:
2017            Delete: the modified expression.
2018        """
2019        return _apply_conjunction_builder(
2020            *expressions,
2021            instance=self,
2022            arg="where",
2023            append=append,
2024            into=Where,
2025            dialect=dialect,
2026            copy=copy,
2027            **opts,
2028        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1958    def delete(
1959        self,
1960        table: ExpOrStr,
1961        dialect: DialectType = None,
1962        copy: bool = True,
1963        **opts,
1964    ) -> Delete:
1965        """
1966        Create a DELETE expression or replace the table on an existing DELETE expression.
1967
1968        Example:
1969            >>> delete("tbl").sql()
1970            'DELETE FROM tbl'
1971
1972        Args:
1973            table: the table from which to delete.
1974            dialect: the dialect used to parse the input expression.
1975            copy: if `False`, modify this expression instance in-place.
1976            opts: other options to use to parse the input expressions.
1977
1978        Returns:
1979            Delete: the modified expression.
1980        """
1981        return _apply_builder(
1982            expression=table,
1983            instance=self,
1984            arg="this",
1985            dialect=dialect,
1986            into=Table,
1987            copy=copy,
1988            **opts,
1989        )

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

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

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1991    def where(
1992        self,
1993        *expressions: t.Optional[ExpOrStr],
1994        append: bool = True,
1995        dialect: DialectType = None,
1996        copy: bool = True,
1997        **opts,
1998    ) -> Delete:
1999        """
2000        Append to or set the WHERE expressions.
2001
2002        Example:
2003            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2004            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2005
2006        Args:
2007            *expressions: the SQL code strings to parse.
2008                If an `Expression` instance is passed, it will be used as-is.
2009                Multiple expressions are combined with an AND operator.
2010            append: if `True`, AND the new expressions to any existing expression.
2011                Otherwise, this resets the expression.
2012            dialect: the dialect used to parse the input expressions.
2013            copy: if `False`, modify this expression instance in-place.
2014            opts: other options to use to parse the input expressions.
2015
2016        Returns:
2017            Delete: the modified expression.
2018        """
2019        return _apply_conjunction_builder(
2020            *expressions,
2021            instance=self,
2022            arg="where",
2023            append=append,
2024            into=Where,
2025            dialect=dialect,
2026            copy=copy,
2027            **opts,
2028        )

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

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):
2267class ConditionalInsert(Expression):
2268    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2271class MultitableInserts(Expression):
2272    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2275class OnConflict(Expression):
2276    arg_types = {
2277        "duplicate": False,
2278        "expressions": False,
2279        "action": False,
2280        "conflict_keys": False,
2281        "constraint": False,
2282    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2285class OnCondition(Expression):
2286    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2289class Returning(Expression):
2290    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2294class Introducer(Expression):
2295    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2299class National(Expression):
2300    pass
key = 'national'
class LoadData(Expression):
2303class LoadData(Expression):
2304    arg_types = {
2305        "this": True,
2306        "local": False,
2307        "overwrite": False,
2308        "inpath": True,
2309        "partition": False,
2310        "input_format": False,
2311        "serde": False,
2312    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2315class Partition(Expression):
2316    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2319class PartitionRange(Expression):
2320    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2324class PartitionId(Expression):
2325    pass
key = 'partitionid'
class Fetch(Expression):
2328class Fetch(Expression):
2329    arg_types = {
2330        "direction": False,
2331        "count": False,
2332        "percent": False,
2333        "with_ties": False,
2334    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2337class Grant(Expression):
2338    arg_types = {
2339        "privileges": True,
2340        "kind": False,
2341        "securable": True,
2342        "principals": True,
2343        "grant_option": False,
2344    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2347class Group(Expression):
2348    arg_types = {
2349        "expressions": False,
2350        "grouping_sets": False,
2351        "cube": False,
2352        "rollup": False,
2353        "totals": False,
2354        "all": False,
2355    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2358class Cube(Expression):
2359    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2362class Rollup(Expression):
2363    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2366class GroupingSets(Expression):
2367    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2370class Lambda(Expression):
2371    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2374class Limit(Expression):
2375    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2378class Literal(Condition):
2379    arg_types = {"this": True, "is_string": True}
2380
2381    @property
2382    def hashable_args(self) -> t.Any:
2383        return (self.this, self.args.get("is_string"))
2384
2385    @classmethod
2386    def number(cls, number) -> Literal:
2387        return cls(this=str(number), is_string=False)
2388
2389    @classmethod
2390    def string(cls, string) -> Literal:
2391        return cls(this=str(string), is_string=True)
2392
2393    @property
2394    def output_name(self) -> str:
2395        return self.name
2396
2397    def to_py(self) -> int | str | Decimal:
2398        if self.is_number:
2399            try:
2400                return int(self.this)
2401            except ValueError:
2402                return Decimal(self.this)
2403        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2381    @property
2382    def hashable_args(self) -> t.Any:
2383        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2385    @classmethod
2386    def number(cls, number) -> Literal:
2387        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2389    @classmethod
2390    def string(cls, string) -> Literal:
2391        return cls(this=str(string), is_string=True)
output_name: str
2393    @property
2394    def output_name(self) -> str:
2395        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:
2397    def to_py(self) -> int | str | Decimal:
2398        if self.is_number:
2399            try:
2400                return int(self.this)
2401            except ValueError:
2402                return Decimal(self.this)
2403        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2406class Join(Expression):
2407    arg_types = {
2408        "this": True,
2409        "on": False,
2410        "side": False,
2411        "kind": False,
2412        "using": False,
2413        "method": False,
2414        "global": False,
2415        "hint": False,
2416        "match_condition": False,  # Snowflake
2417        "expressions": False,
2418    }
2419
2420    @property
2421    def method(self) -> str:
2422        return self.text("method").upper()
2423
2424    @property
2425    def kind(self) -> str:
2426        return self.text("kind").upper()
2427
2428    @property
2429    def side(self) -> str:
2430        return self.text("side").upper()
2431
2432    @property
2433    def hint(self) -> str:
2434        return self.text("hint").upper()
2435
2436    @property
2437    def alias_or_name(self) -> str:
2438        return self.this.alias_or_name
2439
2440    def on(
2441        self,
2442        *expressions: t.Optional[ExpOrStr],
2443        append: bool = True,
2444        dialect: DialectType = None,
2445        copy: bool = True,
2446        **opts,
2447    ) -> Join:
2448        """
2449        Append to or set the ON expressions.
2450
2451        Example:
2452            >>> import sqlglot
2453            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2454            'JOIN x ON y = 1'
2455
2456        Args:
2457            *expressions: the SQL code strings to parse.
2458                If an `Expression` instance is passed, it will be used as-is.
2459                Multiple expressions are combined with an AND operator.
2460            append: if `True`, AND the new expressions to any existing expression.
2461                Otherwise, this resets the expression.
2462            dialect: the dialect used to parse the input expressions.
2463            copy: if `False`, modify this expression instance in-place.
2464            opts: other options to use to parse the input expressions.
2465
2466        Returns:
2467            The modified Join expression.
2468        """
2469        join = _apply_conjunction_builder(
2470            *expressions,
2471            instance=self,
2472            arg="on",
2473            append=append,
2474            dialect=dialect,
2475            copy=copy,
2476            **opts,
2477        )
2478
2479        if join.kind == "CROSS":
2480            join.set("kind", None)
2481
2482        return join
2483
2484    def using(
2485        self,
2486        *expressions: t.Optional[ExpOrStr],
2487        append: bool = True,
2488        dialect: DialectType = None,
2489        copy: bool = True,
2490        **opts,
2491    ) -> Join:
2492        """
2493        Append to or set the USING expressions.
2494
2495        Example:
2496            >>> import sqlglot
2497            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2498            'JOIN x USING (foo, bla)'
2499
2500        Args:
2501            *expressions: the SQL code strings to parse.
2502                If an `Expression` instance is passed, it will be used as-is.
2503            append: if `True`, concatenate the new expressions to the existing "using" list.
2504                Otherwise, this resets the expression.
2505            dialect: the dialect used to parse the input expressions.
2506            copy: if `False`, modify this expression instance in-place.
2507            opts: other options to use to parse the input expressions.
2508
2509        Returns:
2510            The modified Join expression.
2511        """
2512        join = _apply_list_builder(
2513            *expressions,
2514            instance=self,
2515            arg="using",
2516            append=append,
2517            dialect=dialect,
2518            copy=copy,
2519            **opts,
2520        )
2521
2522        if join.kind == "CROSS":
2523            join.set("kind", None)
2524
2525        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False}
method: str
2420    @property
2421    def method(self) -> str:
2422        return self.text("method").upper()
kind: str
2424    @property
2425    def kind(self) -> str:
2426        return self.text("kind").upper()
side: str
2428    @property
2429    def side(self) -> str:
2430        return self.text("side").upper()
hint: str
2432    @property
2433    def hint(self) -> str:
2434        return self.text("hint").upper()
alias_or_name: str
2436    @property
2437    def alias_or_name(self) -> str:
2438        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2440    def on(
2441        self,
2442        *expressions: t.Optional[ExpOrStr],
2443        append: bool = True,
2444        dialect: DialectType = None,
2445        copy: bool = True,
2446        **opts,
2447    ) -> Join:
2448        """
2449        Append to or set the ON expressions.
2450
2451        Example:
2452            >>> import sqlglot
2453            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2454            'JOIN x ON y = 1'
2455
2456        Args:
2457            *expressions: the SQL code strings to parse.
2458                If an `Expression` instance is passed, it will be used as-is.
2459                Multiple expressions are combined with an AND operator.
2460            append: if `True`, AND the new expressions to any existing expression.
2461                Otherwise, this resets the expression.
2462            dialect: the dialect used to parse the input expressions.
2463            copy: if `False`, modify this expression instance in-place.
2464            opts: other options to use to parse the input expressions.
2465
2466        Returns:
2467            The modified Join expression.
2468        """
2469        join = _apply_conjunction_builder(
2470            *expressions,
2471            instance=self,
2472            arg="on",
2473            append=append,
2474            dialect=dialect,
2475            copy=copy,
2476            **opts,
2477        )
2478
2479        if join.kind == "CROSS":
2480            join.set("kind", None)
2481
2482        return join

Append to or set the ON expressions.

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

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2484    def using(
2485        self,
2486        *expressions: t.Optional[ExpOrStr],
2487        append: bool = True,
2488        dialect: DialectType = None,
2489        copy: bool = True,
2490        **opts,
2491    ) -> Join:
2492        """
2493        Append to or set the USING expressions.
2494
2495        Example:
2496            >>> import sqlglot
2497            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2498            'JOIN x USING (foo, bla)'
2499
2500        Args:
2501            *expressions: the SQL code strings to parse.
2502                If an `Expression` instance is passed, it will be used as-is.
2503            append: if `True`, concatenate the new expressions to the existing "using" list.
2504                Otherwise, this resets the expression.
2505            dialect: the dialect used to parse the input expressions.
2506            copy: if `False`, modify this expression instance in-place.
2507            opts: other options to use to parse the input expressions.
2508
2509        Returns:
2510            The modified Join expression.
2511        """
2512        join = _apply_list_builder(
2513            *expressions,
2514            instance=self,
2515            arg="using",
2516            append=append,
2517            dialect=dialect,
2518            copy=copy,
2519            **opts,
2520        )
2521
2522        if join.kind == "CROSS":
2523            join.set("kind", None)
2524
2525        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):
2528class Lateral(UDTF):
2529    arg_types = {
2530        "this": True,
2531        "view": False,
2532        "outer": False,
2533        "alias": False,
2534        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2535    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2538class MatchRecognizeMeasure(Expression):
2539    arg_types = {
2540        "this": True,
2541        "window_frame": False,
2542    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2545class MatchRecognize(Expression):
2546    arg_types = {
2547        "partition_by": False,
2548        "order": False,
2549        "measures": False,
2550        "rows": False,
2551        "after": False,
2552        "pattern": False,
2553        "define": False,
2554        "alias": False,
2555    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2560class Final(Expression):
2561    pass
key = 'final'
class Offset(Expression):
2564class Offset(Expression):
2565    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2568class Order(Expression):
2569    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2573class WithFill(Expression):
2574    arg_types = {
2575        "from": False,
2576        "to": False,
2577        "step": False,
2578        "interpolate": False,
2579    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2584class Cluster(Order):
2585    pass
key = 'cluster'
class Distribute(Order):
2588class Distribute(Order):
2589    pass
key = 'distribute'
class Sort(Order):
2592class Sort(Order):
2593    pass
key = 'sort'
class Ordered(Expression):
2596class Ordered(Expression):
2597    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2600class Property(Expression):
2601    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2604class GrantPrivilege(Expression):
2605    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2608class GrantPrincipal(Expression):
2609    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2612class AllowedValuesProperty(Expression):
2613    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2616class AlgorithmProperty(Property):
2617    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2620class AutoIncrementProperty(Property):
2621    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2625class AutoRefreshProperty(Property):
2626    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2629class BackupProperty(Property):
2630    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2633class BlockCompressionProperty(Property):
2634    arg_types = {
2635        "autotemp": False,
2636        "always": False,
2637        "default": False,
2638        "manual": False,
2639        "never": False,
2640    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2643class CharacterSetProperty(Property):
2644    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2647class ChecksumProperty(Property):
2648    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2651class CollateProperty(Property):
2652    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2655class CopyGrantsProperty(Property):
2656    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2659class DataBlocksizeProperty(Property):
2660    arg_types = {
2661        "size": False,
2662        "units": False,
2663        "minimum": False,
2664        "maximum": False,
2665        "default": False,
2666    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2669class DataDeletionProperty(Property):
2670    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):
2673class DefinerProperty(Property):
2674    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2677class DistKeyProperty(Property):
2678    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2683class DistributedByProperty(Property):
2684    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):
2687class DistStyleProperty(Property):
2688    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2691class DuplicateKeyProperty(Property):
2692    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2695class EngineProperty(Property):
2696    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2699class HeapProperty(Property):
2700    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2703class ToTableProperty(Property):
2704    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2707class ExecuteAsProperty(Property):
2708    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2711class ExternalProperty(Property):
2712    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2715class FallbackProperty(Property):
2716    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2719class FileFormatProperty(Property):
2720    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2723class FreespaceProperty(Property):
2724    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2727class GlobalProperty(Property):
2728    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2731class IcebergProperty(Property):
2732    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2735class InheritsProperty(Property):
2736    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2739class InputModelProperty(Property):
2740    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2743class OutputModelProperty(Property):
2744    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2747class IsolatedLoadingProperty(Property):
2748    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2751class JournalProperty(Property):
2752    arg_types = {
2753        "no": False,
2754        "dual": False,
2755        "before": False,
2756        "local": False,
2757        "after": False,
2758    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2761class LanguageProperty(Property):
2762    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2766class ClusteredByProperty(Property):
2767    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2770class DictProperty(Property):
2771    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2774class DictSubProperty(Property):
2775    pass
key = 'dictsubproperty'
class DictRange(Property):
2778class DictRange(Property):
2779    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2782class DynamicProperty(Property):
2783    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2788class OnCluster(Property):
2789    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2793class EmptyProperty(Property):
2794    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2797class LikeProperty(Property):
2798    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2801class LocationProperty(Property):
2802    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2805class LockProperty(Property):
2806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2809class LockingProperty(Property):
2810    arg_types = {
2811        "this": False,
2812        "kind": True,
2813        "for_or_in": False,
2814        "lock_type": True,
2815        "override": False,
2816    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2819class LogProperty(Property):
2820    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2823class MaterializedProperty(Property):
2824    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2827class MergeBlockRatioProperty(Property):
2828    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):
2831class NoPrimaryIndexProperty(Property):
2832    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2835class OnProperty(Property):
2836    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2839class OnCommitProperty(Property):
2840    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2843class PartitionedByProperty(Property):
2844    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2848class PartitionBoundSpec(Expression):
2849    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2850    arg_types = {
2851        "this": False,
2852        "expression": False,
2853        "from_expressions": False,
2854        "to_expressions": False,
2855    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2858class PartitionedOfProperty(Property):
2859    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2860    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2863class StreamingTableProperty(Property):
2864    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2867class RemoteWithConnectionModelProperty(Property):
2868    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2871class ReturnsProperty(Property):
2872    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):
2875class StrictProperty(Property):
2876    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2879class RowFormatProperty(Property):
2880    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2883class RowFormatDelimitedProperty(Property):
2884    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2885    arg_types = {
2886        "fields": False,
2887        "escaped": False,
2888        "collection_items": False,
2889        "map_keys": False,
2890        "lines": False,
2891        "null": False,
2892        "serde": False,
2893    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2896class RowFormatSerdeProperty(Property):
2897    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2901class QueryTransform(Expression):
2902    arg_types = {
2903        "expressions": True,
2904        "command_script": True,
2905        "schema": False,
2906        "row_format_before": False,
2907        "record_writer": False,
2908        "row_format_after": False,
2909        "record_reader": False,
2910    }
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):
2913class SampleProperty(Property):
2914    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2918class SecurityProperty(Property):
2919    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2922class SchemaCommentProperty(Property):
2923    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2926class SerdeProperties(Property):
2927    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2930class SetProperty(Property):
2931    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2934class SharingProperty(Property):
2935    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2938class SetConfigProperty(Property):
2939    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2942class SettingsProperty(Property):
2943    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2946class SortKeyProperty(Property):
2947    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2950class SqlReadWriteProperty(Property):
2951    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2954class SqlSecurityProperty(Property):
2955    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2958class StabilityProperty(Property):
2959    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2962class TemporaryProperty(Property):
2963    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2966class SecureProperty(Property):
2967    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2970class TransformModelProperty(Property):
2971    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2974class TransientProperty(Property):
2975    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2978class UnloggedProperty(Property):
2979    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2983class ViewAttributeProperty(Property):
2984    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2987class VolatileProperty(Property):
2988    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2991class WithDataProperty(Property):
2992    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2995class WithJournalTableProperty(Property):
2996    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2999class WithSchemaBindingProperty(Property):
3000    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3003class WithSystemVersioningProperty(Property):
3004    arg_types = {
3005        "on": False,
3006        "this": False,
3007        "data_consistency": False,
3008        "retention_period": False,
3009        "with": True,
3010    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3013class WithProcedureOptions(Property):
3014    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class Properties(Expression):
3017class Properties(Expression):
3018    arg_types = {"expressions": True}
3019
3020    NAME_TO_PROPERTY = {
3021        "ALGORITHM": AlgorithmProperty,
3022        "AUTO_INCREMENT": AutoIncrementProperty,
3023        "CHARACTER SET": CharacterSetProperty,
3024        "CLUSTERED_BY": ClusteredByProperty,
3025        "COLLATE": CollateProperty,
3026        "COMMENT": SchemaCommentProperty,
3027        "DEFINER": DefinerProperty,
3028        "DISTKEY": DistKeyProperty,
3029        "DISTRIBUTED_BY": DistributedByProperty,
3030        "DISTSTYLE": DistStyleProperty,
3031        "ENGINE": EngineProperty,
3032        "EXECUTE AS": ExecuteAsProperty,
3033        "FORMAT": FileFormatProperty,
3034        "LANGUAGE": LanguageProperty,
3035        "LOCATION": LocationProperty,
3036        "LOCK": LockProperty,
3037        "PARTITIONED_BY": PartitionedByProperty,
3038        "RETURNS": ReturnsProperty,
3039        "ROW_FORMAT": RowFormatProperty,
3040        "SORTKEY": SortKeyProperty,
3041    }
3042
3043    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3044
3045    # CREATE property locations
3046    # Form: schema specified
3047    #   create [POST_CREATE]
3048    #     table a [POST_NAME]
3049    #     (b int) [POST_SCHEMA]
3050    #     with ([POST_WITH])
3051    #     index (b) [POST_INDEX]
3052    #
3053    # Form: alias selection
3054    #   create [POST_CREATE]
3055    #     table a [POST_NAME]
3056    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3057    #     index (c) [POST_INDEX]
3058    class Location(AutoName):
3059        POST_CREATE = auto()
3060        POST_NAME = auto()
3061        POST_SCHEMA = auto()
3062        POST_WITH = auto()
3063        POST_ALIAS = auto()
3064        POST_EXPRESSION = auto()
3065        POST_INDEX = auto()
3066        UNSUPPORTED = auto()
3067
3068    @classmethod
3069    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3070        expressions = []
3071        for key, value in properties_dict.items():
3072            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3073            if property_cls:
3074                expressions.append(property_cls(this=convert(value)))
3075            else:
3076                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3077
3078        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistributedByProperty'>: 'DISTRIBUTED_BY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3068    @classmethod
3069    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3070        expressions = []
3071        for key, value in properties_dict.items():
3072            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3073            if property_cls:
3074                expressions.append(property_cls(this=convert(value)))
3075            else:
3076                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3077
3078        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3058    class Location(AutoName):
3059        POST_CREATE = auto()
3060        POST_NAME = auto()
3061        POST_SCHEMA = auto()
3062        POST_WITH = auto()
3063        POST_ALIAS = auto()
3064        POST_EXPRESSION = auto()
3065        POST_INDEX = auto()
3066        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):
3081class Qualify(Expression):
3082    pass
key = 'qualify'
class InputOutputFormat(Expression):
3085class InputOutputFormat(Expression):
3086    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3090class Return(Expression):
3091    pass
key = 'return'
class Reference(Expression):
3094class Reference(Expression):
3095    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3098class Tuple(Expression):
3099    arg_types = {"expressions": False}
3100
3101    def isin(
3102        self,
3103        *expressions: t.Any,
3104        query: t.Optional[ExpOrStr] = None,
3105        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3106        copy: bool = True,
3107        **opts,
3108    ) -> In:
3109        return In(
3110            this=maybe_copy(self, copy),
3111            expressions=[convert(e, copy=copy) for e in expressions],
3112            query=maybe_parse(query, copy=copy, **opts) if query else None,
3113            unnest=(
3114                Unnest(
3115                    expressions=[
3116                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3117                        for e in ensure_list(unnest)
3118                    ]
3119                )
3120                if unnest
3121                else None
3122            ),
3123        )
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:
3101    def isin(
3102        self,
3103        *expressions: t.Any,
3104        query: t.Optional[ExpOrStr] = None,
3105        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3106        copy: bool = True,
3107        **opts,
3108    ) -> In:
3109        return In(
3110            this=maybe_copy(self, copy),
3111            expressions=[convert(e, copy=copy) for e in expressions],
3112            query=maybe_parse(query, copy=copy, **opts) if query else None,
3113            unnest=(
3114                Unnest(
3115                    expressions=[
3116                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3117                        for e in ensure_list(unnest)
3118                    ]
3119                )
3120                if unnest
3121                else None
3122            ),
3123        )
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):
3154class QueryOption(Expression):
3155    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3159class WithTableHint(Expression):
3160    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3164class IndexTableHint(Expression):
3165    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3169class HistoricalData(Expression):
3170    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3173class Table(Expression):
3174    arg_types = {
3175        "this": False,
3176        "alias": False,
3177        "db": False,
3178        "catalog": False,
3179        "laterals": False,
3180        "joins": False,
3181        "pivots": False,
3182        "hints": False,
3183        "system_time": False,
3184        "version": False,
3185        "format": False,
3186        "pattern": False,
3187        "ordinality": False,
3188        "when": False,
3189        "only": False,
3190        "partition": False,
3191        "changes": False,
3192        "rows_from": False,
3193        "sample": False,
3194    }
3195
3196    @property
3197    def name(self) -> str:
3198        if isinstance(self.this, Func):
3199            return ""
3200        return self.this.name
3201
3202    @property
3203    def db(self) -> str:
3204        return self.text("db")
3205
3206    @property
3207    def catalog(self) -> str:
3208        return self.text("catalog")
3209
3210    @property
3211    def selects(self) -> t.List[Expression]:
3212        return []
3213
3214    @property
3215    def named_selects(self) -> t.List[str]:
3216        return []
3217
3218    @property
3219    def parts(self) -> t.List[Expression]:
3220        """Return the parts of a table in order catalog, db, table."""
3221        parts: t.List[Expression] = []
3222
3223        for arg in ("catalog", "db", "this"):
3224            part = self.args.get(arg)
3225
3226            if isinstance(part, Dot):
3227                parts.extend(part.flatten())
3228            elif isinstance(part, Expression):
3229                parts.append(part)
3230
3231        return parts
3232
3233    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3234        parts = self.parts
3235        last_part = parts[-1]
3236
3237        if isinstance(last_part, Identifier):
3238            col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3239        else:
3240            # This branch will be reached if a function or array is wrapped in a `Table`
3241            col = last_part
3242
3243        alias = self.args.get("alias")
3244        if alias:
3245            col = alias_(col, alias.this, copy=copy)
3246
3247        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
3196    @property
3197    def name(self) -> str:
3198        if isinstance(self.this, Func):
3199            return ""
3200        return self.this.name
db: str
3202    @property
3203    def db(self) -> str:
3204        return self.text("db")
catalog: str
3206    @property
3207    def catalog(self) -> str:
3208        return self.text("catalog")
selects: List[Expression]
3210    @property
3211    def selects(self) -> t.List[Expression]:
3212        return []
named_selects: List[str]
3214    @property
3215    def named_selects(self) -> t.List[str]:
3216        return []
parts: List[Expression]
3218    @property
3219    def parts(self) -> t.List[Expression]:
3220        """Return the parts of a table in order catalog, db, table."""
3221        parts: t.List[Expression] = []
3222
3223        for arg in ("catalog", "db", "this"):
3224            part = self.args.get(arg)
3225
3226            if isinstance(part, Dot):
3227                parts.extend(part.flatten())
3228            elif isinstance(part, Expression):
3229                parts.append(part)
3230
3231        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3233    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3234        parts = self.parts
3235        last_part = parts[-1]
3236
3237        if isinstance(last_part, Identifier):
3238            col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3239        else:
3240            # This branch will be reached if a function or array is wrapped in a `Table`
3241            col = last_part
3242
3243        alias = self.args.get("alias")
3244        if alias:
3245            col = alias_(col, alias.this, copy=copy)
3246
3247        return col
key = 'table'
class SetOperation(Query):
3250class SetOperation(Query):
3251    arg_types = {
3252        "with": False,
3253        "this": True,
3254        "expression": True,
3255        "distinct": False,
3256        "by_name": False,
3257        **QUERY_MODIFIERS,
3258    }
3259
3260    def select(
3261        self: S,
3262        *expressions: t.Optional[ExpOrStr],
3263        append: bool = True,
3264        dialect: DialectType = None,
3265        copy: bool = True,
3266        **opts,
3267    ) -> S:
3268        this = maybe_copy(self, copy)
3269        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3270        this.expression.unnest().select(
3271            *expressions, append=append, dialect=dialect, copy=False, **opts
3272        )
3273        return this
3274
3275    @property
3276    def named_selects(self) -> t.List[str]:
3277        return self.this.unnest().named_selects
3278
3279    @property
3280    def is_star(self) -> bool:
3281        return self.this.is_star or self.expression.is_star
3282
3283    @property
3284    def selects(self) -> t.List[Expression]:
3285        return self.this.unnest().selects
3286
3287    @property
3288    def left(self) -> Query:
3289        return self.this
3290
3291    @property
3292    def right(self) -> Query:
3293        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3260    def select(
3261        self: S,
3262        *expressions: t.Optional[ExpOrStr],
3263        append: bool = True,
3264        dialect: DialectType = None,
3265        copy: bool = True,
3266        **opts,
3267    ) -> S:
3268        this = maybe_copy(self, copy)
3269        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3270        this.expression.unnest().select(
3271            *expressions, append=append, dialect=dialect, copy=False, **opts
3272        )
3273        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]
3275    @property
3276    def named_selects(self) -> t.List[str]:
3277        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3279    @property
3280    def is_star(self) -> bool:
3281        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3283    @property
3284    def selects(self) -> t.List[Expression]:
3285        return self.this.unnest().selects

Returns the query's projections.

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

Set the table to update.

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

The modified Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3352    def set_(
3353        self,
3354        *expressions: ExpOrStr,
3355        append: bool = True,
3356        dialect: DialectType = None,
3357        copy: bool = True,
3358        **opts,
3359    ) -> Update:
3360        """
3361        Append to or set the SET expressions.
3362
3363        Example:
3364            >>> Update().table("my_table").set_("x = 1").sql()
3365            'UPDATE my_table SET x = 1'
3366
3367        Args:
3368            *expressions: the SQL code strings to parse.
3369                If `Expression` instance(s) are passed, they will be used as-is.
3370                Multiple expressions are combined with a comma.
3371            append: if `True`, add the new expressions to any existing SET expressions.
3372                Otherwise, this resets the expressions.
3373            dialect: the dialect used to parse the input expressions.
3374            copy: if `False`, modify this expression instance in-place.
3375            opts: other options to use to parse the input expressions.
3376        """
3377        return _apply_list_builder(
3378            *expressions,
3379            instance=self,
3380            arg="expressions",
3381            append=append,
3382            into=Expression,
3383            prefix=None,
3384            dialect=dialect,
3385            copy=copy,
3386            **opts,
3387        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3389    def where(
3390        self,
3391        *expressions: t.Optional[ExpOrStr],
3392        append: bool = True,
3393        dialect: DialectType = None,
3394        copy: bool = True,
3395        **opts,
3396    ) -> Select:
3397        """
3398        Append to or set the WHERE expressions.
3399
3400        Example:
3401            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3402            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3403
3404        Args:
3405            *expressions: the SQL code strings to parse.
3406                If an `Expression` instance is passed, it will be used as-is.
3407                Multiple expressions are combined with an AND operator.
3408            append: if `True`, AND the new expressions to any existing expression.
3409                Otherwise, this resets the expression.
3410            dialect: the dialect used to parse the input expressions.
3411            copy: if `False`, modify this expression instance in-place.
3412            opts: other options to use to parse the input expressions.
3413
3414        Returns:
3415            Select: the modified expression.
3416        """
3417        return _apply_conjunction_builder(
3418            *expressions,
3419            instance=self,
3420            arg="where",
3421            append=append,
3422            into=Where,
3423            dialect=dialect,
3424            copy=copy,
3425            **opts,
3426        )

Append to or set the WHERE expressions.

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

Select: the modified expression.

def from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3428    def from_(
3429        self,
3430        expression: t.Optional[ExpOrStr] = None,
3431        dialect: DialectType = None,
3432        copy: bool = True,
3433        **opts,
3434    ) -> Update:
3435        """
3436        Set the FROM expression.
3437
3438        Example:
3439            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3440            'UPDATE my_table SET x = 1 FROM baz'
3441
3442        Args:
3443            expression : the SQL code strings to parse.
3444                If a `From` instance is passed, this is used as-is.
3445                If another `Expression` instance is passed, it will be wrapped in a `From`.
3446                If nothing is passed in then a from is not applied to the expression
3447            dialect: the dialect used to parse the input expression.
3448            copy: if `False`, modify this expression instance in-place.
3449            opts: other options to use to parse the input expressions.
3450
3451        Returns:
3452            The modified Update expression.
3453        """
3454        if not expression:
3455            return maybe_copy(self, copy)
3456
3457        return _apply_builder(
3458            expression=expression,
3459            instance=self,
3460            arg="from",
3461            into=From,
3462            prefix="FROM",
3463            dialect=dialect,
3464            copy=copy,
3465            **opts,
3466        )

Set the FROM expression.

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

The modified Update expression.

def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3468    def with_(
3469        self,
3470        alias: ExpOrStr,
3471        as_: ExpOrStr,
3472        recursive: t.Optional[bool] = None,
3473        materialized: t.Optional[bool] = None,
3474        append: bool = True,
3475        dialect: DialectType = None,
3476        copy: bool = True,
3477        **opts,
3478    ) -> Update:
3479        """
3480        Append to or set the common table expressions.
3481
3482        Example:
3483            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3484            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3485
3486        Args:
3487            alias: the SQL code string to parse as the table name.
3488                If an `Expression` instance is passed, this is used as-is.
3489            as_: the SQL code string to parse as the table expression.
3490                If an `Expression` instance is passed, it will be used as-is.
3491            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3492            materialized: set the MATERIALIZED part of the expression.
3493            append: if `True`, add to any existing expressions.
3494                Otherwise, this resets the expressions.
3495            dialect: the dialect used to parse the input expression.
3496            copy: if `False`, modify this expression instance in-place.
3497            opts: other options to use to parse the input expressions.
3498
3499        Returns:
3500            The modified expression.
3501        """
3502        return _apply_cte_builder(
3503            self,
3504            alias,
3505            as_,
3506            recursive=recursive,
3507            materialized=materialized,
3508            append=append,
3509            dialect=dialect,
3510            copy=copy,
3511            **opts,
3512        )

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

Set the FROM expression.

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

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3592    def group_by(
3593        self,
3594        *expressions: t.Optional[ExpOrStr],
3595        append: bool = True,
3596        dialect: DialectType = None,
3597        copy: bool = True,
3598        **opts,
3599    ) -> Select:
3600        """
3601        Set the GROUP BY expression.
3602
3603        Example:
3604            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3605            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3606
3607        Args:
3608            *expressions: the SQL code strings to parse.
3609                If a `Group` instance is passed, this is used as-is.
3610                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3611                If nothing is passed in then a group by is not applied to the expression
3612            append: if `True`, add to any existing expressions.
3613                Otherwise, this flattens all the `Group` expression into a single expression.
3614            dialect: the dialect used to parse the input expression.
3615            copy: if `False`, modify this expression instance in-place.
3616            opts: other options to use to parse the input expressions.
3617
3618        Returns:
3619            The modified Select expression.
3620        """
3621        if not expressions:
3622            return self if not copy else self.copy()
3623
3624        return _apply_child_list_builder(
3625            *expressions,
3626            instance=self,
3627            arg="group",
3628            append=append,
3629            copy=copy,
3630            prefix="GROUP BY",
3631            into=Group,
3632            dialect=dialect,
3633            **opts,
3634        )

Set the GROUP BY expression.

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

The modified Select expression.

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

Set the SORT BY expression.

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

The modified Select expression.

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

Set the CLUSTER BY expression.

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

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3716    def select(
3717        self,
3718        *expressions: t.Optional[ExpOrStr],
3719        append: bool = True,
3720        dialect: DialectType = None,
3721        copy: bool = True,
3722        **opts,
3723    ) -> Select:
3724        return _apply_list_builder(
3725            *expressions,
3726            instance=self,
3727            arg="expressions",
3728            append=append,
3729            dialect=dialect,
3730            into=Expression,
3731            copy=copy,
3732            **opts,
3733        )

Append to or set the SELECT expressions.

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

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3735    def lateral(
3736        self,
3737        *expressions: t.Optional[ExpOrStr],
3738        append: bool = True,
3739        dialect: DialectType = None,
3740        copy: bool = True,
3741        **opts,
3742    ) -> Select:
3743        """
3744        Append to or set the LATERAL expressions.
3745
3746        Example:
3747            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3748            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3749
3750        Args:
3751            *expressions: the SQL code strings to parse.
3752                If an `Expression` instance is passed, it will be used as-is.
3753            append: if `True`, add to any existing expressions.
3754                Otherwise, this resets the expressions.
3755            dialect: the dialect used to parse the input expressions.
3756            copy: if `False`, modify this expression instance in-place.
3757            opts: other options to use to parse the input expressions.
3758
3759        Returns:
3760            The modified Select expression.
3761        """
3762        return _apply_list_builder(
3763            *expressions,
3764            instance=self,
3765            arg="laterals",
3766            append=append,
3767            into=Lateral,
3768            prefix="LATERAL VIEW",
3769            dialect=dialect,
3770            copy=copy,
3771            **opts,
3772        )

Append to or set the LATERAL expressions.

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

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3774    def join(
3775        self,
3776        expression: ExpOrStr,
3777        on: t.Optional[ExpOrStr] = None,
3778        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3779        append: bool = True,
3780        join_type: t.Optional[str] = None,
3781        join_alias: t.Optional[Identifier | str] = None,
3782        dialect: DialectType = None,
3783        copy: bool = True,
3784        **opts,
3785    ) -> Select:
3786        """
3787        Append to or set the JOIN expressions.
3788
3789        Example:
3790            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3791            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3792
3793            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3794            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3795
3796            Use `join_type` to change the type of join:
3797
3798            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3799            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3800
3801        Args:
3802            expression: the SQL code string to parse.
3803                If an `Expression` instance is passed, it will be used as-is.
3804            on: optionally specify the join "on" criteria as a SQL string.
3805                If an `Expression` instance is passed, it will be used as-is.
3806            using: optionally specify the join "using" criteria as a SQL string.
3807                If an `Expression` instance is passed, it will be used as-is.
3808            append: if `True`, add to any existing expressions.
3809                Otherwise, this resets the expressions.
3810            join_type: if set, alter the parsed join type.
3811            join_alias: an optional alias for the joined source.
3812            dialect: the dialect used to parse the input expressions.
3813            copy: if `False`, modify this expression instance in-place.
3814            opts: other options to use to parse the input expressions.
3815
3816        Returns:
3817            Select: the modified expression.
3818        """
3819        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3820
3821        try:
3822            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3823        except ParseError:
3824            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3825
3826        join = expression if isinstance(expression, Join) else Join(this=expression)
3827
3828        if isinstance(join.this, Select):
3829            join.this.replace(join.this.subquery())
3830
3831        if join_type:
3832            method: t.Optional[Token]
3833            side: t.Optional[Token]
3834            kind: t.Optional[Token]
3835
3836            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3837
3838            if method:
3839                join.set("method", method.text)
3840            if side:
3841                join.set("side", side.text)
3842            if kind:
3843                join.set("kind", kind.text)
3844
3845        if on:
3846            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3847            join.set("on", on)
3848
3849        if using:
3850            join = _apply_list_builder(
3851                *ensure_list(using),
3852                instance=join,
3853                arg="using",
3854                append=append,
3855                copy=copy,
3856                into=Identifier,
3857                **opts,
3858            )
3859
3860        if join_alias:
3861            join.set("this", alias_(join.this, join_alias, table=True))
3862
3863        return _apply_list_builder(
3864            join,
3865            instance=self,
3866            arg="joins",
3867            append=append,
3868            copy=copy,
3869            **opts,
3870        )

Append to or set the JOIN expressions.

Example:
>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
>>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
'SELECT 1 FROM a JOIN b USING (x, y, z)'

Use join_type to change the type of join:

>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • join_type: if set, alter the parsed join type.
  • join_alias: an optional alias for the joined source.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3872    def where(
3873        self,
3874        *expressions: t.Optional[ExpOrStr],
3875        append: bool = True,
3876        dialect: DialectType = None,
3877        copy: bool = True,
3878        **opts,
3879    ) -> Select:
3880        """
3881        Append to or set the WHERE expressions.
3882
3883        Example:
3884            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3885            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3886
3887        Args:
3888            *expressions: the SQL code strings to parse.
3889                If an `Expression` instance is passed, it will be used as-is.
3890                Multiple expressions are combined with an AND operator.
3891            append: if `True`, AND the new expressions to any existing expression.
3892                Otherwise, this resets the expression.
3893            dialect: the dialect used to parse the input expressions.
3894            copy: if `False`, modify this expression instance in-place.
3895            opts: other options to use to parse the input expressions.
3896
3897        Returns:
3898            Select: the modified expression.
3899        """
3900        return _apply_conjunction_builder(
3901            *expressions,
3902            instance=self,
3903            arg="where",
3904            append=append,
3905            into=Where,
3906            dialect=dialect,
3907            copy=copy,
3908            **opts,
3909        )

Append to or set the WHERE expressions.

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

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3911    def having(
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        Append to or set the HAVING expressions.
3921
3922        Example:
3923            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3924            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3925
3926        Args:
3927            *expressions: the SQL code strings to parse.
3928                If an `Expression` instance is passed, it will be used as-is.
3929                Multiple expressions are combined with an AND operator.
3930            append: if `True`, AND the new expressions to any existing expression.
3931                Otherwise, this resets the expression.
3932            dialect: the dialect used to parse the input expressions.
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_conjunction_builder(
3940            *expressions,
3941            instance=self,
3942            arg="having",
3943            append=append,
3944            into=Having,
3945            dialect=dialect,
3946            copy=copy,
3947            **opts,
3948        )

Append to or set the HAVING expressions.

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

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3950    def window(
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="windows",
3962            append=append,
3963            into=Window,
3964            dialect=dialect,
3965            copy=copy,
3966            **opts,
3967        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3969    def qualify(
3970        self,
3971        *expressions: t.Optional[ExpOrStr],
3972        append: bool = True,
3973        dialect: DialectType = None,
3974        copy: bool = True,
3975        **opts,
3976    ) -> Select:
3977        return _apply_conjunction_builder(
3978            *expressions,
3979            instance=self,
3980            arg="qualify",
3981            append=append,
3982            into=Qualify,
3983            dialect=dialect,
3984            copy=copy,
3985            **opts,
3986        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3988    def distinct(
3989        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3990    ) -> Select:
3991        """
3992        Set the OFFSET expression.
3993
3994        Example:
3995            >>> Select().from_("tbl").select("x").distinct().sql()
3996            'SELECT DISTINCT x FROM tbl'
3997
3998        Args:
3999            ons: the expressions to distinct on
4000            distinct: whether the Select should be distinct
4001            copy: if `False`, modify this expression instance in-place.
4002
4003        Returns:
4004            Select: the modified expression.
4005        """
4006        instance = maybe_copy(self, copy)
4007        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4008        instance.set("distinct", Distinct(on=on) if distinct else None)
4009        return instance

Set the OFFSET expression.

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

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4011    def ctas(
4012        self,
4013        table: ExpOrStr,
4014        properties: t.Optional[t.Dict] = None,
4015        dialect: DialectType = None,
4016        copy: bool = True,
4017        **opts,
4018    ) -> Create:
4019        """
4020        Convert this expression to a CREATE TABLE AS statement.
4021
4022        Example:
4023            >>> Select().select("*").from_("tbl").ctas("x").sql()
4024            'CREATE TABLE x AS SELECT * FROM tbl'
4025
4026        Args:
4027            table: the SQL code string to parse as the table name.
4028                If another `Expression` instance is passed, it will be used as-is.
4029            properties: an optional mapping of table properties
4030            dialect: the dialect used to parse the input table.
4031            copy: if `False`, modify this expression instance in-place.
4032            opts: other options to use to parse the input table.
4033
4034        Returns:
4035            The new Create expression.
4036        """
4037        instance = maybe_copy(self, copy)
4038        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4039
4040        properties_expression = None
4041        if properties:
4042            properties_expression = Properties.from_dict(properties)
4043
4044        return Create(
4045            this=table_expression,
4046            kind="TABLE",
4047            expression=instance,
4048            properties=properties_expression,
4049        )

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:
4051    def lock(self, update: bool = True, copy: bool = True) -> Select:
4052        """
4053        Set the locking read mode for this expression.
4054
4055        Examples:
4056            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4057            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4058
4059            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4060            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4061
4062        Args:
4063            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4064            copy: if `False`, modify this expression instance in-place.
4065
4066        Returns:
4067            The modified expression.
4068        """
4069        inst = maybe_copy(self, copy)
4070        inst.set("locks", [Lock(update=update)])
4071
4072        return inst

Set the locking read mode for this expression.

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

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
4074    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4075        """
4076        Set hints for this expression.
4077
4078        Examples:
4079            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4080            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4081
4082        Args:
4083            hints: The SQL code strings to parse as the hints.
4084                If an `Expression` instance is passed, it will be used as-is.
4085            dialect: The dialect used to parse the hints.
4086            copy: If `False`, modify this expression instance in-place.
4087
4088        Returns:
4089            The modified expression.
4090        """
4091        inst = maybe_copy(self, copy)
4092        inst.set(
4093            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4094        )
4095
4096        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]
4098    @property
4099    def named_selects(self) -> t.List[str]:
4100        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
4102    @property
4103    def is_star(self) -> bool:
4104        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4106    @property
4107    def selects(self) -> t.List[Expression]:
4108        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4114class Subquery(DerivedTable, Query):
4115    arg_types = {
4116        "this": True,
4117        "alias": False,
4118        "with": False,
4119        **QUERY_MODIFIERS,
4120    }
4121
4122    def unnest(self):
4123        """Returns the first non subquery."""
4124        expression = self
4125        while isinstance(expression, Subquery):
4126            expression = expression.this
4127        return expression
4128
4129    def unwrap(self) -> Subquery:
4130        expression = self
4131        while expression.same_parent and expression.is_wrapper:
4132            expression = t.cast(Subquery, expression.parent)
4133        return expression
4134
4135    def select(
4136        self,
4137        *expressions: t.Optional[ExpOrStr],
4138        append: bool = True,
4139        dialect: DialectType = None,
4140        copy: bool = True,
4141        **opts,
4142    ) -> Subquery:
4143        this = maybe_copy(self, copy)
4144        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4145        return this
4146
4147    @property
4148    def is_wrapper(self) -> bool:
4149        """
4150        Whether this Subquery acts as a simple wrapper around another expression.
4151
4152        SELECT * FROM (((SELECT * FROM t)))
4153                      ^
4154                      This corresponds to a "wrapper" Subquery node
4155        """
4156        return all(v is None for k, v in self.args.items() if k != "this")
4157
4158    @property
4159    def is_star(self) -> bool:
4160        return self.this.is_star
4161
4162    @property
4163    def output_name(self) -> str:
4164        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):
4122    def unnest(self):
4123        """Returns the first non subquery."""
4124        expression = self
4125        while isinstance(expression, Subquery):
4126            expression = expression.this
4127        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4129    def unwrap(self) -> Subquery:
4130        expression = self
4131        while expression.same_parent and expression.is_wrapper:
4132            expression = t.cast(Subquery, expression.parent)
4133        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4135    def select(
4136        self,
4137        *expressions: t.Optional[ExpOrStr],
4138        append: bool = True,
4139        dialect: DialectType = None,
4140        copy: bool = True,
4141        **opts,
4142    ) -> Subquery:
4143        this = maybe_copy(self, copy)
4144        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4145        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
4147    @property
4148    def is_wrapper(self) -> bool:
4149        """
4150        Whether this Subquery acts as a simple wrapper around another expression.
4151
4152        SELECT * FROM (((SELECT * FROM t)))
4153                      ^
4154                      This corresponds to a "wrapper" Subquery node
4155        """
4156        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
4158    @property
4159    def is_star(self) -> bool:
4160        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4162    @property
4163    def output_name(self) -> str:
4164        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):
4167class TableSample(Expression):
4168    arg_types = {
4169        "expressions": False,
4170        "method": False,
4171        "bucket_numerator": False,
4172        "bucket_denominator": False,
4173        "bucket_field": False,
4174        "percent": False,
4175        "rows": False,
4176        "size": False,
4177        "seed": False,
4178    }
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):
4181class Tag(Expression):
4182    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4183
4184    arg_types = {
4185        "this": False,
4186        "prefix": False,
4187        "postfix": False,
4188    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4193class Pivot(Expression):
4194    arg_types = {
4195        "this": False,
4196        "alias": False,
4197        "expressions": False,
4198        "field": False,
4199        "unpivot": False,
4200        "using": False,
4201        "group": False,
4202        "columns": False,
4203        "include_nulls": False,
4204        "default_on_null": False,
4205    }
4206
4207    @property
4208    def unpivot(self) -> bool:
4209        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False}
unpivot: bool
4207    @property
4208    def unpivot(self) -> bool:
4209        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
4212class Window(Condition):
4213    arg_types = {
4214        "this": True,
4215        "partition_by": False,
4216        "order": False,
4217        "spec": False,
4218        "alias": False,
4219        "over": False,
4220        "first": False,
4221    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4224class WindowSpec(Expression):
4225    arg_types = {
4226        "kind": False,
4227        "start": False,
4228        "start_side": False,
4229        "end": False,
4230        "end_side": False,
4231    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4234class PreWhere(Expression):
4235    pass
key = 'prewhere'
class Where(Expression):
4238class Where(Expression):
4239    pass
key = 'where'
class Star(Expression):
4242class Star(Expression):
4243    arg_types = {"except": False, "replace": False, "rename": False}
4244
4245    @property
4246    def name(self) -> str:
4247        return "*"
4248
4249    @property
4250    def output_name(self) -> str:
4251        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4245    @property
4246    def name(self) -> str:
4247        return "*"
output_name: str
4249    @property
4250    def output_name(self) -> str:
4251        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):
4254class Parameter(Condition):
4255    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4258class SessionParameter(Condition):
4259    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4262class Placeholder(Condition):
4263    arg_types = {"this": False, "kind": False}
4264
4265    @property
4266    def name(self) -> str:
4267        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4265    @property
4266    def name(self) -> str:
4267        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4270class Null(Condition):
4271    arg_types: t.Dict[str, t.Any] = {}
4272
4273    @property
4274    def name(self) -> str:
4275        return "NULL"
4276
4277    def to_py(self) -> Lit[None]:
4278        return None
arg_types: Dict[str, Any] = {}
name: str
4273    @property
4274    def name(self) -> str:
4275        return "NULL"
def to_py(self) -> Literal[None]:
4277    def to_py(self) -> Lit[None]:
4278        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4281class Boolean(Condition):
4282    def to_py(self) -> bool:
4283        return self.this
def to_py(self) -> bool:
4282    def to_py(self) -> bool:
4283        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4286class DataTypeParam(Expression):
4287    arg_types = {"this": True, "expression": False}
4288
4289    @property
4290    def name(self) -> str:
4291        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4289    @property
4290    def name(self) -> str:
4291        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4296class DataType(Expression):
4297    arg_types = {
4298        "this": True,
4299        "expressions": False,
4300        "nested": False,
4301        "values": False,
4302        "prefix": False,
4303        "kind": False,
4304        "nullable": False,
4305    }
4306
4307    class Type(AutoName):
4308        ARRAY = auto()
4309        AGGREGATEFUNCTION = auto()
4310        SIMPLEAGGREGATEFUNCTION = auto()
4311        BIGDECIMAL = auto()
4312        BIGINT = auto()
4313        BIGSERIAL = auto()
4314        BINARY = auto()
4315        BIT = auto()
4316        BOOLEAN = auto()
4317        BPCHAR = auto()
4318        CHAR = auto()
4319        DATE = auto()
4320        DATE32 = auto()
4321        DATEMULTIRANGE = auto()
4322        DATERANGE = auto()
4323        DATETIME = auto()
4324        DATETIME64 = auto()
4325        DECIMAL = auto()
4326        DECIMAL32 = auto()
4327        DECIMAL64 = auto()
4328        DECIMAL128 = auto()
4329        DECIMAL256 = auto()
4330        DOUBLE = auto()
4331        ENUM = auto()
4332        ENUM8 = auto()
4333        ENUM16 = auto()
4334        FIXEDSTRING = auto()
4335        FLOAT = auto()
4336        GEOGRAPHY = auto()
4337        GEOMETRY = auto()
4338        POINT = auto()
4339        RING = auto()
4340        LINESTRING = auto()
4341        MULTILINESTRING = auto()
4342        POLYGON = auto()
4343        MULTIPOLYGON = auto()
4344        HLLSKETCH = auto()
4345        HSTORE = auto()
4346        IMAGE = auto()
4347        INET = auto()
4348        INT = auto()
4349        INT128 = auto()
4350        INT256 = auto()
4351        INT4MULTIRANGE = auto()
4352        INT4RANGE = auto()
4353        INT8MULTIRANGE = auto()
4354        INT8RANGE = auto()
4355        INTERVAL = auto()
4356        IPADDRESS = auto()
4357        IPPREFIX = auto()
4358        IPV4 = auto()
4359        IPV6 = auto()
4360        JSON = auto()
4361        JSONB = auto()
4362        LIST = auto()
4363        LONGBLOB = auto()
4364        LONGTEXT = auto()
4365        LOWCARDINALITY = auto()
4366        MAP = auto()
4367        MEDIUMBLOB = auto()
4368        MEDIUMINT = auto()
4369        MEDIUMTEXT = auto()
4370        MONEY = auto()
4371        NAME = auto()
4372        NCHAR = auto()
4373        NESTED = auto()
4374        NULL = auto()
4375        NUMMULTIRANGE = auto()
4376        NUMRANGE = auto()
4377        NVARCHAR = auto()
4378        OBJECT = auto()
4379        RANGE = auto()
4380        ROWVERSION = auto()
4381        SERIAL = auto()
4382        SET = auto()
4383        SMALLINT = auto()
4384        SMALLMONEY = auto()
4385        SMALLSERIAL = auto()
4386        STRUCT = auto()
4387        SUPER = auto()
4388        TEXT = auto()
4389        TINYBLOB = auto()
4390        TINYTEXT = auto()
4391        TIME = auto()
4392        TIMETZ = auto()
4393        TIMESTAMP = auto()
4394        TIMESTAMPNTZ = auto()
4395        TIMESTAMPLTZ = auto()
4396        TIMESTAMPTZ = auto()
4397        TIMESTAMP_S = auto()
4398        TIMESTAMP_MS = auto()
4399        TIMESTAMP_NS = auto()
4400        TINYINT = auto()
4401        TSMULTIRANGE = auto()
4402        TSRANGE = auto()
4403        TSTZMULTIRANGE = auto()
4404        TSTZRANGE = auto()
4405        UBIGINT = auto()
4406        UINT = auto()
4407        UINT128 = auto()
4408        UINT256 = auto()
4409        UMEDIUMINT = auto()
4410        UDECIMAL = auto()
4411        UNION = auto()
4412        UNIQUEIDENTIFIER = auto()
4413        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4414        USERDEFINED = "USER-DEFINED"
4415        USMALLINT = auto()
4416        UTINYINT = auto()
4417        UUID = auto()
4418        VARBINARY = auto()
4419        VARCHAR = auto()
4420        VARIANT = auto()
4421        VECTOR = auto()
4422        XML = auto()
4423        YEAR = auto()
4424        TDIGEST = auto()
4425
4426    STRUCT_TYPES = {
4427        Type.NESTED,
4428        Type.OBJECT,
4429        Type.STRUCT,
4430        Type.UNION,
4431    }
4432
4433    ARRAY_TYPES = {
4434        Type.ARRAY,
4435        Type.LIST,
4436    }
4437
4438    NESTED_TYPES = {
4439        *STRUCT_TYPES,
4440        *ARRAY_TYPES,
4441        Type.MAP,
4442    }
4443
4444    TEXT_TYPES = {
4445        Type.CHAR,
4446        Type.NCHAR,
4447        Type.NVARCHAR,
4448        Type.TEXT,
4449        Type.VARCHAR,
4450        Type.NAME,
4451    }
4452
4453    SIGNED_INTEGER_TYPES = {
4454        Type.BIGINT,
4455        Type.INT,
4456        Type.INT128,
4457        Type.INT256,
4458        Type.MEDIUMINT,
4459        Type.SMALLINT,
4460        Type.TINYINT,
4461    }
4462
4463    UNSIGNED_INTEGER_TYPES = {
4464        Type.UBIGINT,
4465        Type.UINT,
4466        Type.UINT128,
4467        Type.UINT256,
4468        Type.UMEDIUMINT,
4469        Type.USMALLINT,
4470        Type.UTINYINT,
4471    }
4472
4473    INTEGER_TYPES = {
4474        *SIGNED_INTEGER_TYPES,
4475        *UNSIGNED_INTEGER_TYPES,
4476        Type.BIT,
4477    }
4478
4479    FLOAT_TYPES = {
4480        Type.DOUBLE,
4481        Type.FLOAT,
4482    }
4483
4484    REAL_TYPES = {
4485        *FLOAT_TYPES,
4486        Type.BIGDECIMAL,
4487        Type.DECIMAL,
4488        Type.DECIMAL32,
4489        Type.DECIMAL64,
4490        Type.DECIMAL128,
4491        Type.DECIMAL256,
4492        Type.MONEY,
4493        Type.SMALLMONEY,
4494        Type.UDECIMAL,
4495    }
4496
4497    NUMERIC_TYPES = {
4498        *INTEGER_TYPES,
4499        *REAL_TYPES,
4500    }
4501
4502    TEMPORAL_TYPES = {
4503        Type.DATE,
4504        Type.DATE32,
4505        Type.DATETIME,
4506        Type.DATETIME64,
4507        Type.TIME,
4508        Type.TIMESTAMP,
4509        Type.TIMESTAMPNTZ,
4510        Type.TIMESTAMPLTZ,
4511        Type.TIMESTAMPTZ,
4512        Type.TIMESTAMP_MS,
4513        Type.TIMESTAMP_NS,
4514        Type.TIMESTAMP_S,
4515        Type.TIMETZ,
4516    }
4517
4518    @classmethod
4519    def build(
4520        cls,
4521        dtype: DATA_TYPE,
4522        dialect: DialectType = None,
4523        udt: bool = False,
4524        copy: bool = True,
4525        **kwargs,
4526    ) -> DataType:
4527        """
4528        Constructs a DataType object.
4529
4530        Args:
4531            dtype: the data type of interest.
4532            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4533            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4534                DataType, thus creating a user-defined type.
4535            copy: whether to copy the data type.
4536            kwargs: additional arguments to pass in the constructor of DataType.
4537
4538        Returns:
4539            The constructed DataType object.
4540        """
4541        from sqlglot import parse_one
4542
4543        if isinstance(dtype, str):
4544            if dtype.upper() == "UNKNOWN":
4545                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4546
4547            try:
4548                data_type_exp = parse_one(
4549                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4550                )
4551            except ParseError:
4552                if udt:
4553                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4554                raise
4555        elif isinstance(dtype, DataType.Type):
4556            data_type_exp = DataType(this=dtype)
4557        elif isinstance(dtype, DataType):
4558            return maybe_copy(dtype, copy)
4559        else:
4560            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4561
4562        return DataType(**{**data_type_exp.args, **kwargs})
4563
4564    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4565        """
4566        Checks whether this DataType matches one of the provided data types. Nested types or precision
4567        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4568
4569        Args:
4570            dtypes: the data types to compare this DataType to.
4571            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4572                If false, it means that NULLABLE<INT> is equivalent to INT.
4573
4574        Returns:
4575            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4576        """
4577        self_is_nullable = self.args.get("nullable")
4578        for dtype in dtypes:
4579            other_type = DataType.build(dtype, copy=False, udt=True)
4580            other_is_nullable = other_type.args.get("nullable")
4581            if (
4582                other_type.expressions
4583                or (check_nullable and (self_is_nullable or other_is_nullable))
4584                or self.this == DataType.Type.USERDEFINED
4585                or other_type.this == DataType.Type.USERDEFINED
4586            ):
4587                matches = self == other_type
4588            else:
4589                matches = self.this == other_type.this
4590
4591            if matches:
4592                return True
4593        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.UNION: 'UNION'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.MAP: 'MAP'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}
NUMERIC_TYPES = {<Type.BIT: 'BIT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT256: 'UINT256'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.INT256: 'INT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.UBIGINT: 'UBIGINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.MONEY: 'MONEY'>, <Type.INT128: 'INT128'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.BIGINT: 'BIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.TINYINT: 'TINYINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE: 'DATE'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4518    @classmethod
4519    def build(
4520        cls,
4521        dtype: DATA_TYPE,
4522        dialect: DialectType = None,
4523        udt: bool = False,
4524        copy: bool = True,
4525        **kwargs,
4526    ) -> DataType:
4527        """
4528        Constructs a DataType object.
4529
4530        Args:
4531            dtype: the data type of interest.
4532            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4533            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4534                DataType, thus creating a user-defined type.
4535            copy: whether to copy the data type.
4536            kwargs: additional arguments to pass in the constructor of DataType.
4537
4538        Returns:
4539            The constructed DataType object.
4540        """
4541        from sqlglot import parse_one
4542
4543        if isinstance(dtype, str):
4544            if dtype.upper() == "UNKNOWN":
4545                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4546
4547            try:
4548                data_type_exp = parse_one(
4549                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4550                )
4551            except ParseError:
4552                if udt:
4553                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4554                raise
4555        elif isinstance(dtype, DataType.Type):
4556            data_type_exp = DataType(this=dtype)
4557        elif isinstance(dtype, DataType):
4558            return maybe_copy(dtype, copy)
4559        else:
4560            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4561
4562        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4564    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4565        """
4566        Checks whether this DataType matches one of the provided data types. Nested types or precision
4567        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4568
4569        Args:
4570            dtypes: the data types to compare this DataType to.
4571            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4572                If false, it means that NULLABLE<INT> is equivalent to INT.
4573
4574        Returns:
4575            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4576        """
4577        self_is_nullable = self.args.get("nullable")
4578        for dtype in dtypes:
4579            other_type = DataType.build(dtype, copy=False, udt=True)
4580            other_is_nullable = other_type.args.get("nullable")
4581            if (
4582                other_type.expressions
4583                or (check_nullable and (self_is_nullable or other_is_nullable))
4584                or self.this == DataType.Type.USERDEFINED
4585                or other_type.this == DataType.Type.USERDEFINED
4586            ):
4587                matches = self == other_type
4588            else:
4589                matches = self.this == other_type.this
4590
4591            if matches:
4592                return True
4593        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):
4307    class Type(AutoName):
4308        ARRAY = auto()
4309        AGGREGATEFUNCTION = auto()
4310        SIMPLEAGGREGATEFUNCTION = auto()
4311        BIGDECIMAL = auto()
4312        BIGINT = auto()
4313        BIGSERIAL = auto()
4314        BINARY = auto()
4315        BIT = auto()
4316        BOOLEAN = auto()
4317        BPCHAR = auto()
4318        CHAR = auto()
4319        DATE = auto()
4320        DATE32 = auto()
4321        DATEMULTIRANGE = auto()
4322        DATERANGE = auto()
4323        DATETIME = auto()
4324        DATETIME64 = auto()
4325        DECIMAL = auto()
4326        DECIMAL32 = auto()
4327        DECIMAL64 = auto()
4328        DECIMAL128 = auto()
4329        DECIMAL256 = auto()
4330        DOUBLE = auto()
4331        ENUM = auto()
4332        ENUM8 = auto()
4333        ENUM16 = auto()
4334        FIXEDSTRING = auto()
4335        FLOAT = auto()
4336        GEOGRAPHY = auto()
4337        GEOMETRY = auto()
4338        POINT = auto()
4339        RING = auto()
4340        LINESTRING = auto()
4341        MULTILINESTRING = auto()
4342        POLYGON = auto()
4343        MULTIPOLYGON = auto()
4344        HLLSKETCH = auto()
4345        HSTORE = auto()
4346        IMAGE = auto()
4347        INET = auto()
4348        INT = auto()
4349        INT128 = auto()
4350        INT256 = auto()
4351        INT4MULTIRANGE = auto()
4352        INT4RANGE = auto()
4353        INT8MULTIRANGE = auto()
4354        INT8RANGE = auto()
4355        INTERVAL = auto()
4356        IPADDRESS = auto()
4357        IPPREFIX = auto()
4358        IPV4 = auto()
4359        IPV6 = auto()
4360        JSON = auto()
4361        JSONB = auto()
4362        LIST = auto()
4363        LONGBLOB = auto()
4364        LONGTEXT = auto()
4365        LOWCARDINALITY = auto()
4366        MAP = auto()
4367        MEDIUMBLOB = auto()
4368        MEDIUMINT = auto()
4369        MEDIUMTEXT = auto()
4370        MONEY = auto()
4371        NAME = auto()
4372        NCHAR = auto()
4373        NESTED = auto()
4374        NULL = auto()
4375        NUMMULTIRANGE = auto()
4376        NUMRANGE = auto()
4377        NVARCHAR = auto()
4378        OBJECT = auto()
4379        RANGE = auto()
4380        ROWVERSION = auto()
4381        SERIAL = auto()
4382        SET = auto()
4383        SMALLINT = auto()
4384        SMALLMONEY = auto()
4385        SMALLSERIAL = auto()
4386        STRUCT = auto()
4387        SUPER = auto()
4388        TEXT = auto()
4389        TINYBLOB = auto()
4390        TINYTEXT = auto()
4391        TIME = auto()
4392        TIMETZ = auto()
4393        TIMESTAMP = auto()
4394        TIMESTAMPNTZ = auto()
4395        TIMESTAMPLTZ = auto()
4396        TIMESTAMPTZ = auto()
4397        TIMESTAMP_S = auto()
4398        TIMESTAMP_MS = auto()
4399        TIMESTAMP_NS = auto()
4400        TINYINT = auto()
4401        TSMULTIRANGE = auto()
4402        TSRANGE = auto()
4403        TSTZMULTIRANGE = auto()
4404        TSTZRANGE = auto()
4405        UBIGINT = auto()
4406        UINT = auto()
4407        UINT128 = auto()
4408        UINT256 = auto()
4409        UMEDIUMINT = auto()
4410        UDECIMAL = auto()
4411        UNION = auto()
4412        UNIQUEIDENTIFIER = auto()
4413        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4414        USERDEFINED = "USER-DEFINED"
4415        USMALLINT = auto()
4416        UTINYINT = auto()
4417        UUID = auto()
4418        VARBINARY = auto()
4419        VARCHAR = auto()
4420        VARIANT = auto()
4421        VECTOR = auto()
4422        XML = auto()
4423        YEAR = auto()
4424        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNION = <Type.UNION: 'UNION'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4600class PseudoType(DataType):
4601    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4605class ObjectIdentifier(DataType):
4606    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4610class SubqueryPredicate(Predicate):
4611    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4614class All(SubqueryPredicate):
4615    pass
key = 'all'
class Any(SubqueryPredicate):
4618class Any(SubqueryPredicate):
4619    pass
key = 'any'
class Command(Expression):
4624class Command(Expression):
4625    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4628class Transaction(Expression):
4629    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4632class Commit(Expression):
4633    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4636class Rollback(Expression):
4637    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4640class Alter(Expression):
4641    arg_types = {
4642        "this": True,
4643        "kind": True,
4644        "actions": True,
4645        "exists": False,
4646        "only": False,
4647        "options": False,
4648        "cluster": False,
4649        "not_valid": False,
4650    }
4651
4652    @property
4653    def kind(self) -> t.Optional[str]:
4654        kind = self.args.get("kind")
4655        return kind and kind.upper()
4656
4657    @property
4658    def actions(self) -> t.List[Expression]:
4659        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]
4652    @property
4653    def kind(self) -> t.Optional[str]:
4654        kind = self.args.get("kind")
4655        return kind and kind.upper()
actions: List[Expression]
4657    @property
4658    def actions(self) -> t.List[Expression]:
4659        return self.args.get("actions") or []
key = 'alter'
class AddConstraint(Expression):
4662class AddConstraint(Expression):
4663    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4666class DropPartition(Expression):
4667    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4671class ReplacePartition(Expression):
4672    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4676class Binary(Condition):
4677    arg_types = {"this": True, "expression": True}
4678
4679    @property
4680    def left(self) -> Expression:
4681        return self.this
4682
4683    @property
4684    def right(self) -> Expression:
4685        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4679    @property
4680    def left(self) -> Expression:
4681        return self.this
right: Expression
4683    @property
4684    def right(self) -> Expression:
4685        return self.expression
key = 'binary'
class Add(Binary):
4688class Add(Binary):
4689    pass
key = 'add'
class Connector(Binary):
4692class Connector(Binary):
4693    pass
key = 'connector'
class And(Connector):
4696class And(Connector):
4697    pass
key = 'and'
class Or(Connector):
4700class Or(Connector):
4701    pass
key = 'or'
class BitwiseAnd(Binary):
4704class BitwiseAnd(Binary):
4705    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4708class BitwiseLeftShift(Binary):
4709    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4712class BitwiseOr(Binary):
4713    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4716class BitwiseRightShift(Binary):
4717    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4720class BitwiseXor(Binary):
4721    pass
key = 'bitwisexor'
class Div(Binary):
4724class Div(Binary):
4725    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):
4728class Overlaps(Binary):
4729    pass
key = 'overlaps'
class Dot(Binary):
4732class Dot(Binary):
4733    @property
4734    def is_star(self) -> bool:
4735        return self.expression.is_star
4736
4737    @property
4738    def name(self) -> str:
4739        return self.expression.name
4740
4741    @property
4742    def output_name(self) -> str:
4743        return self.name
4744
4745    @classmethod
4746    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4747        """Build a Dot object with a sequence of expressions."""
4748        if len(expressions) < 2:
4749            raise ValueError("Dot requires >= 2 expressions.")
4750
4751        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4752
4753    @property
4754    def parts(self) -> t.List[Expression]:
4755        """Return the parts of a table / column in order catalog, db, table."""
4756        this, *parts = self.flatten()
4757
4758        parts.reverse()
4759
4760        for arg in COLUMN_PARTS:
4761            part = this.args.get(arg)
4762
4763            if isinstance(part, Expression):
4764                parts.append(part)
4765
4766        parts.reverse()
4767        return parts
is_star: bool
4733    @property
4734    def is_star(self) -> bool:
4735        return self.expression.is_star

Checks whether an expression is a star.

name: str
4737    @property
4738    def name(self) -> str:
4739        return self.expression.name
output_name: str
4741    @property
4742    def output_name(self) -> str:
4743        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:
4745    @classmethod
4746    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4747        """Build a Dot object with a sequence of expressions."""
4748        if len(expressions) < 2:
4749            raise ValueError("Dot requires >= 2 expressions.")
4750
4751        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]
4753    @property
4754    def parts(self) -> t.List[Expression]:
4755        """Return the parts of a table / column in order catalog, db, table."""
4756        this, *parts = self.flatten()
4757
4758        parts.reverse()
4759
4760        for arg in COLUMN_PARTS:
4761            part = this.args.get(arg)
4762
4763            if isinstance(part, Expression):
4764                parts.append(part)
4765
4766        parts.reverse()
4767        return parts

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

key = 'dot'
class DPipe(Binary):
4770class DPipe(Binary):
4771    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4774class EQ(Binary, Predicate):
4775    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4778class NullSafeEQ(Binary, Predicate):
4779    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4782class NullSafeNEQ(Binary, Predicate):
4783    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4787class PropertyEQ(Binary):
4788    pass
key = 'propertyeq'
class Distance(Binary):
4791class Distance(Binary):
4792    pass
key = 'distance'
class Escape(Binary):
4795class Escape(Binary):
4796    pass
key = 'escape'
class Glob(Binary, Predicate):
4799class Glob(Binary, Predicate):
4800    pass
key = 'glob'
class GT(Binary, Predicate):
4803class GT(Binary, Predicate):
4804    pass
key = 'gt'
class GTE(Binary, Predicate):
4807class GTE(Binary, Predicate):
4808    pass
key = 'gte'
class ILike(Binary, Predicate):
4811class ILike(Binary, Predicate):
4812    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4815class ILikeAny(Binary, Predicate):
4816    pass
key = 'ilikeany'
class IntDiv(Binary):
4819class IntDiv(Binary):
4820    pass
key = 'intdiv'
class Is(Binary, Predicate):
4823class Is(Binary, Predicate):
4824    pass
key = 'is'
class Kwarg(Binary):
4827class Kwarg(Binary):
4828    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4831class Like(Binary, Predicate):
4832    pass
key = 'like'
class LikeAny(Binary, Predicate):
4835class LikeAny(Binary, Predicate):
4836    pass
key = 'likeany'
class LT(Binary, Predicate):
4839class LT(Binary, Predicate):
4840    pass
key = 'lt'
class LTE(Binary, Predicate):
4843class LTE(Binary, Predicate):
4844    pass
key = 'lte'
class Mod(Binary):
4847class Mod(Binary):
4848    pass
key = 'mod'
class Mul(Binary):
4851class Mul(Binary):
4852    pass
key = 'mul'
class NEQ(Binary, Predicate):
4855class NEQ(Binary, Predicate):
4856    pass
key = 'neq'
class Operator(Binary):
4860class Operator(Binary):
4861    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4864class SimilarTo(Binary, Predicate):
4865    pass
key = 'similarto'
class Slice(Binary):
4868class Slice(Binary):
4869    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4872class Sub(Binary):
4873    pass
key = 'sub'
class Unary(Condition):
4878class Unary(Condition):
4879    pass
key = 'unary'
class BitwiseNot(Unary):
4882class BitwiseNot(Unary):
4883    pass
key = 'bitwisenot'
class Not(Unary):
4886class Not(Unary):
4887    pass
key = 'not'
class Paren(Unary):
4890class Paren(Unary):
4891    @property
4892    def output_name(self) -> str:
4893        return self.this.name
output_name: str
4891    @property
4892    def output_name(self) -> str:
4893        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):
4896class Neg(Unary):
4897    def to_py(self) -> int | Decimal:
4898        if self.is_number:
4899            return self.this.to_py() * -1
4900        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4897    def to_py(self) -> int | Decimal:
4898        if self.is_number:
4899            return self.this.to_py() * -1
4900        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4903class Alias(Expression):
4904    arg_types = {"this": True, "alias": False}
4905
4906    @property
4907    def output_name(self) -> str:
4908        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4906    @property
4907    def output_name(self) -> str:
4908        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):
4913class PivotAlias(Alias):
4914    pass
key = 'pivotalias'
class PivotAny(Expression):
4919class PivotAny(Expression):
4920    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4923class Aliases(Expression):
4924    arg_types = {"this": True, "expressions": True}
4925
4926    @property
4927    def aliases(self):
4928        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4926    @property
4927    def aliases(self):
4928        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4932class AtIndex(Expression):
4933    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4936class AtTimeZone(Expression):
4937    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4940class FromTimeZone(Expression):
4941    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4944class Between(Predicate):
4945    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4948class Bracket(Condition):
4949    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4950    arg_types = {
4951        "this": True,
4952        "expressions": True,
4953        "offset": False,
4954        "safe": False,
4955        "returns_list_for_maps": False,
4956    }
4957
4958    @property
4959    def output_name(self) -> str:
4960        if len(self.expressions) == 1:
4961            return self.expressions[0].output_name
4962
4963        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4958    @property
4959    def output_name(self) -> str:
4960        if len(self.expressions) == 1:
4961            return self.expressions[0].output_name
4962
4963        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):
4966class Distinct(Expression):
4967    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4970class In(Predicate):
4971    arg_types = {
4972        "this": True,
4973        "expressions": False,
4974        "query": False,
4975        "unnest": False,
4976        "field": False,
4977        "is_global": False,
4978    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4982class ForIn(Expression):
4983    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4986class TimeUnit(Expression):
4987    """Automatically converts unit arg into a var."""
4988
4989    arg_types = {"unit": False}
4990
4991    UNABBREVIATED_UNIT_NAME = {
4992        "D": "DAY",
4993        "H": "HOUR",
4994        "M": "MINUTE",
4995        "MS": "MILLISECOND",
4996        "NS": "NANOSECOND",
4997        "Q": "QUARTER",
4998        "S": "SECOND",
4999        "US": "MICROSECOND",
5000        "W": "WEEK",
5001        "Y": "YEAR",
5002    }
5003
5004    VAR_LIKE = (Column, Literal, Var)
5005
5006    def __init__(self, **args):
5007        unit = args.get("unit")
5008        if isinstance(unit, self.VAR_LIKE):
5009            args["unit"] = Var(
5010                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5011            )
5012        elif isinstance(unit, Week):
5013            unit.set("this", Var(this=unit.this.name.upper()))
5014
5015        super().__init__(**args)
5016
5017    @property
5018    def unit(self) -> t.Optional[Var | IntervalSpan]:
5019        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5006    def __init__(self, **args):
5007        unit = args.get("unit")
5008        if isinstance(unit, self.VAR_LIKE):
5009            args["unit"] = Var(
5010                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5011            )
5012        elif isinstance(unit, Week):
5013            unit.set("this", Var(this=unit.this.name.upper()))
5014
5015        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]
5017    @property
5018    def unit(self) -> t.Optional[Var | IntervalSpan]:
5019        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5022class IntervalOp(TimeUnit):
5023    arg_types = {"unit": False, "expression": True}
5024
5025    def interval(self):
5026        return Interval(
5027            this=self.expression.copy(),
5028            unit=self.unit.copy() if self.unit else None,
5029        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5025    def interval(self):
5026        return Interval(
5027            this=self.expression.copy(),
5028            unit=self.unit.copy() if self.unit else None,
5029        )
key = 'intervalop'
class IntervalSpan(DataType):
5035class IntervalSpan(DataType):
5036    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5039class Interval(TimeUnit):
5040    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5043class IgnoreNulls(Expression):
5044    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5047class RespectNulls(Expression):
5048    pass
key = 'respectnulls'
class HavingMax(Expression):
5052class HavingMax(Expression):
5053    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5057class Func(Condition):
5058    """
5059    The base class for all function expressions.
5060
5061    Attributes:
5062        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5063            treated as a variable length argument and the argument's value will be stored as a list.
5064        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5065            function expression. These values are used to map this node to a name during parsing as
5066            well as to provide the function's name during SQL string generation. By default the SQL
5067            name is set to the expression's class name transformed to snake case.
5068    """
5069
5070    is_var_len_args = False
5071
5072    @classmethod
5073    def from_arg_list(cls, args):
5074        if cls.is_var_len_args:
5075            all_arg_keys = list(cls.arg_types)
5076            # If this function supports variable length argument treat the last argument as such.
5077            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5078            num_non_var = len(non_var_len_arg_keys)
5079
5080            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5081            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5082        else:
5083            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5084
5085        return cls(**args_dict)
5086
5087    @classmethod
5088    def sql_names(cls):
5089        if cls is Func:
5090            raise NotImplementedError(
5091                "SQL name is only supported by concrete function implementations"
5092            )
5093        if "_sql_names" not in cls.__dict__:
5094            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5095        return cls._sql_names
5096
5097    @classmethod
5098    def sql_name(cls):
5099        return cls.sql_names()[0]
5100
5101    @classmethod
5102    def default_parser_mappings(cls):
5103        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):
5072    @classmethod
5073    def from_arg_list(cls, args):
5074        if cls.is_var_len_args:
5075            all_arg_keys = list(cls.arg_types)
5076            # If this function supports variable length argument treat the last argument as such.
5077            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5078            num_non_var = len(non_var_len_arg_keys)
5079
5080            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5081            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5082        else:
5083            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5084
5085        return cls(**args_dict)
@classmethod
def sql_names(cls):
5087    @classmethod
5088    def sql_names(cls):
5089        if cls is Func:
5090            raise NotImplementedError(
5091                "SQL name is only supported by concrete function implementations"
5092            )
5093        if "_sql_names" not in cls.__dict__:
5094            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5095        return cls._sql_names
@classmethod
def sql_name(cls):
5097    @classmethod
5098    def sql_name(cls):
5099        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5101    @classmethod
5102    def default_parser_mappings(cls):
5103        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5106class AggFunc(Func):
5107    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5110class ParameterizedAgg(AggFunc):
5111    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5114class Abs(Func):
5115    pass
key = 'abs'
class ArgMax(AggFunc):
5118class ArgMax(AggFunc):
5119    arg_types = {"this": True, "expression": True, "count": False}
5120    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5123class ArgMin(AggFunc):
5124    arg_types = {"this": True, "expression": True, "count": False}
5125    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5128class ApproxTopK(AggFunc):
5129    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5132class Flatten(Func):
5133    pass
key = 'flatten'
class Transform(Func):
5137class Transform(Func):
5138    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5141class Anonymous(Func):
5142    arg_types = {"this": True, "expressions": False}
5143    is_var_len_args = True
5144
5145    @property
5146    def name(self) -> str:
5147        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
5145    @property
5146    def name(self) -> str:
5147        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5150class AnonymousAggFunc(AggFunc):
5151    arg_types = {"this": True, "expressions": False}
5152    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5156class CombinedAggFunc(AnonymousAggFunc):
5157    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5160class CombinedParameterizedAgg(ParameterizedAgg):
5161    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5166class Hll(AggFunc):
5167    arg_types = {"this": True, "expressions": False}
5168    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5171class ApproxDistinct(AggFunc):
5172    arg_types = {"this": True, "accuracy": False}
5173    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5176class Apply(Func):
5177    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5180class Array(Func):
5181    arg_types = {"expressions": False, "bracket_notation": False}
5182    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5186class ToArray(Func):
5187    pass
key = 'toarray'
class List(Func):
5191class List(Func):
5192    arg_types = {"expressions": False}
5193    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5197class Pad(Func):
5198    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):
5203class ToChar(Func):
5204    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5209class ToNumber(Func):
5210    arg_types = {
5211        "this": True,
5212        "format": False,
5213        "nlsparam": False,
5214        "precision": False,
5215        "scale": False,
5216    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5220class ToDouble(Func):
5221    arg_types = {
5222        "this": True,
5223        "format": False,
5224    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5227class Columns(Func):
5228    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5232class Convert(Func):
5233    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5236class ConvertTimezone(Func):
5237    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
5240class GenerateSeries(Func):
5241    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):
5247class ExplodingGenerateSeries(GenerateSeries):
5248    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5251class ArrayAgg(AggFunc):
5252    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5255class ArrayUniqueAgg(AggFunc):
5256    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5259class ArrayAll(Func):
5260    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5264class ArrayAny(Func):
5265    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5268class ArrayConcat(Func):
5269    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5270    arg_types = {"this": True, "expressions": False}
5271    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5274class ArrayConstructCompact(Func):
5275    arg_types = {"expressions": True}
5276    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5279class ArrayContains(Binary, Func):
5280    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5283class ArrayContainsAll(Binary, Func):
5284    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5287class ArrayFilter(Func):
5288    arg_types = {"this": True, "expression": True}
5289    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5292class ArrayToString(Func):
5293    arg_types = {"this": True, "expression": True, "null": False}
5294    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5298class String(Func):
5299    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5302class StringToArray(Func):
5303    arg_types = {"this": True, "expression": True, "null": False}
5304    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5307class ArrayOverlaps(Binary, Func):
5308    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5311class ArraySize(Func):
5312    arg_types = {"this": True, "expression": False}
5313    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5316class ArraySort(Func):
5317    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5320class ArraySum(Func):
5321    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5324class ArrayUnionAgg(AggFunc):
5325    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5328class Avg(AggFunc):
5329    pass
key = 'avg'
class AnyValue(AggFunc):
5332class AnyValue(AggFunc):
5333    pass
key = 'anyvalue'
class Lag(AggFunc):
5336class Lag(AggFunc):
5337    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5340class Lead(AggFunc):
5341    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5346class First(AggFunc):
5347    pass
key = 'first'
class Last(AggFunc):
5350class Last(AggFunc):
5351    pass
key = 'last'
class FirstValue(AggFunc):
5354class FirstValue(AggFunc):
5355    pass
key = 'firstvalue'
class LastValue(AggFunc):
5358class LastValue(AggFunc):
5359    pass
key = 'lastvalue'
class NthValue(AggFunc):
5362class NthValue(AggFunc):
5363    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5366class Case(Func):
5367    arg_types = {"this": False, "ifs": True, "default": False}
5368
5369    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5370        instance = maybe_copy(self, copy)
5371        instance.append(
5372            "ifs",
5373            If(
5374                this=maybe_parse(condition, copy=copy, **opts),
5375                true=maybe_parse(then, copy=copy, **opts),
5376            ),
5377        )
5378        return instance
5379
5380    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5381        instance = maybe_copy(self, copy)
5382        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5383        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:
5369    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5370        instance = maybe_copy(self, copy)
5371        instance.append(
5372            "ifs",
5373            If(
5374                this=maybe_parse(condition, copy=copy, **opts),
5375                true=maybe_parse(then, copy=copy, **opts),
5376            ),
5377        )
5378        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5380    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5381        instance = maybe_copy(self, copy)
5382        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5383        return instance
key = 'case'
class Cast(Func):
5386class Cast(Func):
5387    arg_types = {
5388        "this": True,
5389        "to": True,
5390        "format": False,
5391        "safe": False,
5392        "action": False,
5393    }
5394
5395    @property
5396    def name(self) -> str:
5397        return self.this.name
5398
5399    @property
5400    def to(self) -> DataType:
5401        return self.args["to"]
5402
5403    @property
5404    def output_name(self) -> str:
5405        return self.name
5406
5407    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5408        """
5409        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5410        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5411        array<int> != array<float>.
5412
5413        Args:
5414            dtypes: the data types to compare this Cast's DataType to.
5415
5416        Returns:
5417            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5418        """
5419        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5395    @property
5396    def name(self) -> str:
5397        return self.this.name
to: DataType
5399    @property
5400    def to(self) -> DataType:
5401        return self.args["to"]
output_name: str
5403    @property
5404    def output_name(self) -> str:
5405        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
5407    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5408        """
5409        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5410        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5411        array<int> != array<float>.
5412
5413        Args:
5414            dtypes: the data types to compare this Cast's DataType to.
5415
5416        Returns:
5417            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5418        """
5419        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):
5422class TryCast(Cast):
5423    pass
key = 'trycast'
class Try(Func):
5426class Try(Func):
5427    pass
key = 'try'
class CastToStrType(Func):
5430class CastToStrType(Func):
5431    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5434class Collate(Binary, Func):
5435    pass
key = 'collate'
class Ceil(Func):
5438class Ceil(Func):
5439    arg_types = {"this": True, "decimals": False}
5440    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5443class Coalesce(Func):
5444    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5445    is_var_len_args = True
5446    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5449class Chr(Func):
5450    arg_types = {"expressions": True, "charset": False}
5451    is_var_len_args = True
5452    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5455class Concat(Func):
5456    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5457    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5460class ConcatWs(Concat):
5461    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5464class Contains(Func):
5465    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5469class ConnectByRoot(Func):
5470    pass
key = 'connectbyroot'
class Count(AggFunc):
5473class Count(AggFunc):
5474    arg_types = {"this": False, "expressions": False, "big_int": False}
5475    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5478class CountIf(AggFunc):
5479    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5483class Cbrt(Func):
5484    pass
key = 'cbrt'
class CurrentDate(Func):
5487class CurrentDate(Func):
5488    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5491class CurrentDatetime(Func):
5492    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5495class CurrentTime(Func):
5496    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5499class CurrentTimestamp(Func):
5500    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5503class CurrentUser(Func):
5504    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5507class DateAdd(Func, IntervalOp):
5508    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5511class DateSub(Func, IntervalOp):
5512    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5515class DateDiff(Func, TimeUnit):
5516    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5517    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5520class DateTrunc(Func):
5521    arg_types = {"unit": True, "this": True, "zone": False}
5522
5523    def __init__(self, **args):
5524        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5525        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5526        unabbreviate = args.pop("unabbreviate", True)
5527
5528        unit = args.get("unit")
5529        if isinstance(unit, TimeUnit.VAR_LIKE):
5530            unit_name = unit.name.upper()
5531            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5532                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5533
5534            args["unit"] = Literal.string(unit_name)
5535        elif isinstance(unit, Week):
5536            unit.set("this", Literal.string(unit.this.name.upper()))
5537
5538        super().__init__(**args)
5539
5540    @property
5541    def unit(self) -> Expression:
5542        return self.args["unit"]
DateTrunc(**args)
5523    def __init__(self, **args):
5524        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5525        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5526        unabbreviate = args.pop("unabbreviate", True)
5527
5528        unit = args.get("unit")
5529        if isinstance(unit, TimeUnit.VAR_LIKE):
5530            unit_name = unit.name.upper()
5531            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5532                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5533
5534            args["unit"] = Literal.string(unit_name)
5535        elif isinstance(unit, Week):
5536            unit.set("this", Literal.string(unit.this.name.upper()))
5537
5538        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5540    @property
5541    def unit(self) -> Expression:
5542        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5547class Datetime(Func):
5548    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5551class DatetimeAdd(Func, IntervalOp):
5552    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5555class DatetimeSub(Func, IntervalOp):
5556    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5559class DatetimeDiff(Func, TimeUnit):
5560    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5563class DatetimeTrunc(Func, TimeUnit):
5564    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5567class DayOfWeek(Func):
5568    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5573class DayOfWeekIso(Func):
5574    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5577class DayOfMonth(Func):
5578    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5581class DayOfYear(Func):
5582    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5585class ToDays(Func):
5586    pass
key = 'todays'
class WeekOfYear(Func):
5589class WeekOfYear(Func):
5590    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5593class MonthsBetween(Func):
5594    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5597class MakeInterval(Func):
5598    arg_types = {
5599        "year": False,
5600        "month": False,
5601        "day": False,
5602        "hour": False,
5603        "minute": False,
5604        "second": False,
5605    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5608class LastDay(Func, TimeUnit):
5609    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5610    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5613class Extract(Func):
5614    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5617class Exists(Func, SubqueryPredicate):
5618    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5621class Timestamp(Func):
5622    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5625class TimestampAdd(Func, TimeUnit):
5626    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5629class TimestampSub(Func, TimeUnit):
5630    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5633class TimestampDiff(Func, TimeUnit):
5634    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5635    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5638class TimestampTrunc(Func, TimeUnit):
5639    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5642class TimeAdd(Func, TimeUnit):
5643    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5646class TimeSub(Func, TimeUnit):
5647    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5650class TimeDiff(Func, TimeUnit):
5651    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5654class TimeTrunc(Func, TimeUnit):
5655    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5658class DateFromParts(Func):
5659    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5660    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5663class TimeFromParts(Func):
5664    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5665    arg_types = {
5666        "hour": True,
5667        "min": True,
5668        "sec": True,
5669        "nano": False,
5670        "fractions": False,
5671        "precision": False,
5672    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5675class DateStrToDate(Func):
5676    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5679class DateToDateStr(Func):
5680    pass
key = 'datetodatestr'
class DateToDi(Func):
5683class DateToDi(Func):
5684    pass
key = 'datetodi'
class Date(Func):
5688class Date(Func):
5689    arg_types = {"this": False, "zone": False, "expressions": False}
5690    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5693class Day(Func):
5694    pass
key = 'day'
class Decode(Func):
5697class Decode(Func):
5698    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5701class DiToDate(Func):
5702    pass
key = 'ditodate'
class Encode(Func):
5705class Encode(Func):
5706    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5709class Exp(Func):
5710    pass
key = 'exp'
class Explode(Func, UDTF):
5714class Explode(Func, UDTF):
5715    arg_types = {"this": True, "expressions": False}
5716    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5720class Inline(Func):
5721    pass
key = 'inline'
class ExplodeOuter(Explode):
5724class ExplodeOuter(Explode):
5725    pass
key = 'explodeouter'
class Posexplode(Explode):
5728class Posexplode(Explode):
5729    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5732class PosexplodeOuter(Posexplode, ExplodeOuter):
5733    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5736class Unnest(Func, UDTF):
5737    arg_types = {
5738        "expressions": True,
5739        "alias": False,
5740        "offset": False,
5741        "explode_array": False,
5742    }
5743
5744    @property
5745    def selects(self) -> t.List[Expression]:
5746        columns = super().selects
5747        offset = self.args.get("offset")
5748        if offset:
5749            columns = columns + [to_identifier("offset") if offset is True else offset]
5750        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5744    @property
5745    def selects(self) -> t.List[Expression]:
5746        columns = super().selects
5747        offset = self.args.get("offset")
5748        if offset:
5749            columns = columns + [to_identifier("offset") if offset is True else offset]
5750        return columns
key = 'unnest'
class Floor(Func):
5753class Floor(Func):
5754    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5757class FromBase64(Func):
5758    pass
key = 'frombase64'
class ToBase64(Func):
5761class ToBase64(Func):
5762    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5766class FromISO8601Timestamp(Func):
5767    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5770class GapFill(Func):
5771    arg_types = {
5772        "this": True,
5773        "ts_column": True,
5774        "bucket_width": True,
5775        "partitioning_columns": False,
5776        "value_columns": False,
5777        "origin": False,
5778        "ignore_nulls": False,
5779    }
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):
5783class GenerateDateArray(Func):
5784    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5788class GenerateTimestampArray(Func):
5789    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5792class Greatest(Func):
5793    arg_types = {"this": True, "expressions": False}
5794    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5799class OverflowTruncateBehavior(Expression):
5800    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5803class GroupConcat(AggFunc):
5804    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5807class Hex(Func):
5808    pass
key = 'hex'
class LowerHex(Hex):
5811class LowerHex(Hex):
5812    pass
key = 'lowerhex'
class Xor(Connector, Func):
5815class Xor(Connector, Func):
5816    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5819class If(Func):
5820    arg_types = {"this": True, "true": True, "false": False}
5821    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5824class Nullif(Func):
5825    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5828class Initcap(Func):
5829    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5832class IsNan(Func):
5833    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
5837class Int64(Func):
5838    pass
key = 'int64'
class IsInf(Func):
5841class IsInf(Func):
5842    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5846class JSON(Expression):
5847    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5850class JSONPath(Expression):
5851    arg_types = {"expressions": True, "escape": False}
5852
5853    @property
5854    def output_name(self) -> str:
5855        last_segment = self.expressions[-1].this
5856        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5853    @property
5854    def output_name(self) -> str:
5855        last_segment = self.expressions[-1].this
5856        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):
5859class JSONPathPart(Expression):
5860    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5863class JSONPathFilter(JSONPathPart):
5864    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5867class JSONPathKey(JSONPathPart):
5868    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5871class JSONPathRecursive(JSONPathPart):
5872    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5875class JSONPathRoot(JSONPathPart):
5876    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5879class JSONPathScript(JSONPathPart):
5880    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5883class JSONPathSlice(JSONPathPart):
5884    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5887class JSONPathSelector(JSONPathPart):
5888    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5891class JSONPathSubscript(JSONPathPart):
5892    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5895class JSONPathUnion(JSONPathPart):
5896    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5899class JSONPathWildcard(JSONPathPart):
5900    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5903class FormatJson(Expression):
5904    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5907class JSONKeyValue(Expression):
5908    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5911class JSONObject(Func):
5912    arg_types = {
5913        "expressions": False,
5914        "null_handling": False,
5915        "unique_keys": False,
5916        "return_type": False,
5917        "encoding": False,
5918    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5921class JSONObjectAgg(AggFunc):
5922    arg_types = {
5923        "expressions": False,
5924        "null_handling": False,
5925        "unique_keys": False,
5926        "return_type": False,
5927        "encoding": False,
5928    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5932class JSONArray(Func):
5933    arg_types = {
5934        "expressions": True,
5935        "null_handling": False,
5936        "return_type": False,
5937        "strict": False,
5938    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5942class JSONArrayAgg(Func):
5943    arg_types = {
5944        "this": True,
5945        "order": False,
5946        "null_handling": False,
5947        "return_type": False,
5948        "strict": False,
5949    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5952class JSONExists(Func):
5953    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):
5958class JSONColumnDef(Expression):
5959    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):
5962class JSONSchema(Expression):
5963    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5967class JSONValue(Expression):
5968    arg_types = {
5969        "this": True,
5970        "path": True,
5971        "returning": False,
5972        "on_condition": False,
5973    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
5976class JSONValueArray(Func):
5977    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
5981class JSONTable(Func):
5982    arg_types = {
5983        "this": True,
5984        "schema": True,
5985        "path": False,
5986        "error_handling": False,
5987        "empty_handling": False,
5988    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5992class ObjectInsert(Func):
5993    arg_types = {
5994        "this": True,
5995        "key": True,
5996        "value": True,
5997        "update_flag": False,
5998    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6001class OpenJSONColumnDef(Expression):
6002    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):
6005class OpenJSON(Func):
6006    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6009class JSONBContains(Binary, Func):
6010    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6013class JSONBExists(Func):
6014    arg_types = {"this": True, "path": True}
6015    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6018class JSONExtract(Binary, Func):
6019    arg_types = {
6020        "this": True,
6021        "expression": True,
6022        "only_json_types": False,
6023        "expressions": False,
6024        "variant_extract": False,
6025        "json_query": False,
6026        "option": False,
6027    }
6028    _sql_names = ["JSON_EXTRACT"]
6029    is_var_len_args = True
6030
6031    @property
6032    def output_name(self) -> str:
6033        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False, 'json_query': False, 'option': False}
is_var_len_args = True
output_name: str
6031    @property
6032    def output_name(self) -> str:
6033        return self.expression.output_name if not self.expressions else ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextract'
class JSONExtractArray(Func):
6036class JSONExtractArray(Func):
6037    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6040class JSONExtractScalar(Binary, Func):
6041    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6042    _sql_names = ["JSON_EXTRACT_SCALAR"]
6043    is_var_len_args = True
6044
6045    @property
6046    def output_name(self) -> str:
6047        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
6045    @property
6046    def output_name(self) -> str:
6047        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):
6050class JSONBExtract(Binary, Func):
6051    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6054class JSONBExtractScalar(Binary, Func):
6055    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6058class JSONFormat(Func):
6059    arg_types = {"this": False, "options": False}
6060    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6064class JSONArrayContains(Binary, Predicate, Func):
6065    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6068class ParseJSON(Func):
6069    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6070    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6071    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6072    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6075class Least(Func):
6076    arg_types = {"this": True, "expressions": False}
6077    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6080class Left(Func):
6081    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6088class Length(Func):
6089    arg_types = {"this": True, "binary": False}
6090    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
6093class Levenshtein(Func):
6094    arg_types = {
6095        "this": True,
6096        "expression": False,
6097        "ins_cost": False,
6098        "del_cost": False,
6099        "sub_cost": False,
6100        "max_dist": False,
6101    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6104class Ln(Func):
6105    pass
key = 'ln'
class Log(Func):
6108class Log(Func):
6109    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6112class LogicalOr(AggFunc):
6113    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6116class LogicalAnd(AggFunc):
6117    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6120class Lower(Func):
6121    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6124class Map(Func):
6125    arg_types = {"keys": False, "values": False}
6126
6127    @property
6128    def keys(self) -> t.List[Expression]:
6129        keys = self.args.get("keys")
6130        return keys.expressions if keys else []
6131
6132    @property
6133    def values(self) -> t.List[Expression]:
6134        values = self.args.get("values")
6135        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6127    @property
6128    def keys(self) -> t.List[Expression]:
6129        keys = self.args.get("keys")
6130        return keys.expressions if keys else []
values: List[Expression]
6132    @property
6133    def values(self) -> t.List[Expression]:
6134        values = self.args.get("values")
6135        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6139class ToMap(Func):
6140    pass
key = 'tomap'
class MapFromEntries(Func):
6143class MapFromEntries(Func):
6144    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6148class ScopeResolution(Expression):
6149    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6152class Stream(Expression):
6153    pass
key = 'stream'
class StarMap(Func):
6156class StarMap(Func):
6157    pass
key = 'starmap'
class VarMap(Func):
6160class VarMap(Func):
6161    arg_types = {"keys": True, "values": True}
6162    is_var_len_args = True
6163
6164    @property
6165    def keys(self) -> t.List[Expression]:
6166        return self.args["keys"].expressions
6167
6168    @property
6169    def values(self) -> t.List[Expression]:
6170        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6164    @property
6165    def keys(self) -> t.List[Expression]:
6166        return self.args["keys"].expressions
values: List[Expression]
6168    @property
6169    def values(self) -> t.List[Expression]:
6170        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6174class MatchAgainst(Func):
6175    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6178class Max(AggFunc):
6179    arg_types = {"this": True, "expressions": False}
6180    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6183class MD5(Func):
6184    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6188class MD5Digest(Func):
6189    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6192class Median(AggFunc):
6193    pass
key = 'median'
class Min(AggFunc):
6196class Min(AggFunc):
6197    arg_types = {"this": True, "expressions": False}
6198    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6201class Month(Func):
6202    pass
key = 'month'
class AddMonths(Func):
6205class AddMonths(Func):
6206    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6209class Nvl2(Func):
6210    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6213class Normalize(Func):
6214    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6217class Overlay(Func):
6218    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):
6222class Predict(Func):
6223    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6226class Pow(Binary, Func):
6227    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6230class PercentileCont(AggFunc):
6231    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6234class PercentileDisc(AggFunc):
6235    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6238class Quantile(AggFunc):
6239    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6242class ApproxQuantile(Quantile):
6243    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):
6246class Quarter(Func):
6247    pass
key = 'quarter'
class Rand(Func):
6252class Rand(Func):
6253    _sql_names = ["RAND", "RANDOM"]
6254    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6257class Randn(Func):
6258    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6261class RangeN(Func):
6262    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6265class ReadCSV(Func):
6266    _sql_names = ["READ_CSV"]
6267    is_var_len_args = True
6268    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6271class Reduce(Func):
6272    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):
6275class RegexpExtract(Func):
6276    arg_types = {
6277        "this": True,
6278        "expression": True,
6279        "position": False,
6280        "occurrence": False,
6281        "parameters": False,
6282        "group": False,
6283    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6286class RegexpExtractAll(Func):
6287    arg_types = {
6288        "this": True,
6289        "expression": True,
6290        "position": False,
6291        "occurrence": False,
6292        "parameters": False,
6293        "group": False,
6294    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6297class RegexpReplace(Func):
6298    arg_types = {
6299        "this": True,
6300        "expression": True,
6301        "replacement": False,
6302        "position": False,
6303        "occurrence": False,
6304        "modifiers": False,
6305    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6308class RegexpLike(Binary, Func):
6309    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6312class RegexpILike(Binary, Func):
6313    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6318class RegexpSplit(Func):
6319    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6322class Repeat(Func):
6323    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6328class Round(Func):
6329    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6332class RowNumber(Func):
6333    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6336class SafeDivide(Func):
6337    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6340class SHA(Func):
6341    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6344class SHA2(Func):
6345    _sql_names = ["SHA2"]
6346    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6349class Sign(Func):
6350    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6353class SortArray(Func):
6354    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6357class Split(Func):
6358    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6362class SplitPart(Func):
6363    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6368class Substring(Func):
6369    _sql_names = ["SUBSTRING", "SUBSTR"]
6370    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6373class StandardHash(Func):
6374    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6377class StartsWith(Func):
6378    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6379    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6382class StrPosition(Func):
6383    arg_types = {
6384        "this": True,
6385        "substr": True,
6386        "position": False,
6387        "instance": False,
6388    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6391class StrToDate(Func):
6392    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6395class StrToTime(Func):
6396    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):
6401class StrToUnix(Func):
6402    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6407class StrToMap(Func):
6408    arg_types = {
6409        "this": True,
6410        "pair_delim": False,
6411        "key_value_delim": False,
6412        "duplicate_resolution_callback": False,
6413    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6416class NumberToStr(Func):
6417    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6420class FromBase(Func):
6421    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6424class Struct(Func):
6425    arg_types = {"expressions": False}
6426    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6429class StructExtract(Func):
6430    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6435class Stuff(Func):
6436    _sql_names = ["STUFF", "INSERT"]
6437    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):
6440class Sum(AggFunc):
6441    pass
key = 'sum'
class Sqrt(Func):
6444class Sqrt(Func):
6445    pass
key = 'sqrt'
class Stddev(AggFunc):
6448class Stddev(AggFunc):
6449    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6452class StddevPop(AggFunc):
6453    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6456class StddevSamp(AggFunc):
6457    pass
key = 'stddevsamp'
class Time(Func):
6461class Time(Func):
6462    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6465class TimeToStr(Func):
6466    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):
6469class TimeToTimeStr(Func):
6470    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6473class TimeToUnix(Func):
6474    pass
key = 'timetounix'
class TimeStrToDate(Func):
6477class TimeStrToDate(Func):
6478    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6481class TimeStrToTime(Func):
6482    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6485class TimeStrToUnix(Func):
6486    pass
key = 'timestrtounix'
class Trim(Func):
6489class Trim(Func):
6490    arg_types = {
6491        "this": True,
6492        "expression": False,
6493        "position": False,
6494        "collation": False,
6495    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6498class TsOrDsAdd(Func, TimeUnit):
6499    # return_type is used to correctly cast the arguments of this expression when transpiling it
6500    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6501
6502    @property
6503    def return_type(self) -> DataType:
6504        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
6502    @property
6503    def return_type(self) -> DataType:
6504        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6507class TsOrDsDiff(Func, TimeUnit):
6508    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6511class TsOrDsToDateStr(Func):
6512    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6515class TsOrDsToDate(Func):
6516    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6519class TsOrDsToDatetime(Func):
6520    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6523class TsOrDsToTime(Func):
6524    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6527class TsOrDsToTimestamp(Func):
6528    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6531class TsOrDiToDi(Func):
6532    pass
key = 'tsorditodi'
class Unhex(Func):
6535class Unhex(Func):
6536    pass
key = 'unhex'
class UnixDate(Func):
6540class UnixDate(Func):
6541    pass
key = 'unixdate'
class UnixToStr(Func):
6544class UnixToStr(Func):
6545    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6550class UnixToTime(Func):
6551    arg_types = {
6552        "this": True,
6553        "scale": False,
6554        "zone": False,
6555        "hours": False,
6556        "minutes": False,
6557        "format": False,
6558    }
6559
6560    SECONDS = Literal.number(0)
6561    DECIS = Literal.number(1)
6562    CENTIS = Literal.number(2)
6563    MILLIS = Literal.number(3)
6564    DECIMILLIS = Literal.number(4)
6565    CENTIMILLIS = Literal.number(5)
6566    MICROS = Literal.number(6)
6567    DECIMICROS = Literal.number(7)
6568    CENTIMICROS = Literal.number(8)
6569    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):
6572class UnixToTimeStr(Func):
6573    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6576class UnixSeconds(Func):
6577    pass
key = 'unixseconds'
class Uuid(Func):
6580class Uuid(Func):
6581    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6582
6583    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6586class TimestampFromParts(Func):
6587    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6588    arg_types = {
6589        "year": True,
6590        "month": True,
6591        "day": True,
6592        "hour": True,
6593        "min": True,
6594        "sec": True,
6595        "nano": False,
6596        "zone": False,
6597        "milli": False,
6598    }
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):
6601class Upper(Func):
6602    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6605class Corr(Binary, AggFunc):
6606    pass
key = 'corr'
class Variance(AggFunc):
6609class Variance(AggFunc):
6610    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6613class VariancePop(AggFunc):
6614    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6617class CovarSamp(Binary, AggFunc):
6618    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6621class CovarPop(Binary, AggFunc):
6622    pass
key = 'covarpop'
class Week(Func):
6625class Week(Func):
6626    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6629class XMLTable(Func):
6630    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
arg_types = {'this': True, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class Year(Func):
6633class Year(Func):
6634    pass
key = 'year'
class Use(Expression):
6637class Use(Expression):
6638    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6641class Merge(DML):
6642    arg_types = {
6643        "this": True,
6644        "using": True,
6645        "on": True,
6646        "expressions": True,
6647        "with": False,
6648        "returning": False,
6649    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6652class When(Func):
6653    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class NextValueFor(Func):
6658class NextValueFor(Func):
6659    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6664class Semicolon(Expression):
6665    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'J_S_O_N_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_SECONDS': <class 'UnixSeconds'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'UUID': <class 'Uuid'>, 'GEN_RANDOM_UUID': <class 'Uuid'>, 'GENERATE_UUID': <class 'Uuid'>, 'UUID_STRING': <class 'Uuid'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6705def maybe_parse(
6706    sql_or_expression: ExpOrStr,
6707    *,
6708    into: t.Optional[IntoType] = None,
6709    dialect: DialectType = None,
6710    prefix: t.Optional[str] = None,
6711    copy: bool = False,
6712    **opts,
6713) -> Expression:
6714    """Gracefully handle a possible string or expression.
6715
6716    Example:
6717        >>> maybe_parse("1")
6718        Literal(this=1, is_string=False)
6719        >>> maybe_parse(to_identifier("x"))
6720        Identifier(this=x, quoted=False)
6721
6722    Args:
6723        sql_or_expression: the SQL code string or an expression
6724        into: the SQLGlot Expression to parse into
6725        dialect: the dialect used to parse the input expressions (in the case that an
6726            input expression is a SQL string).
6727        prefix: a string to prefix the sql with before it gets parsed
6728            (automatically includes a space)
6729        copy: whether to copy the expression.
6730        **opts: other options to use to parse the input expressions (again, in the case
6731            that an input expression is a SQL string).
6732
6733    Returns:
6734        Expression: the parsed or given expression.
6735    """
6736    if isinstance(sql_or_expression, Expression):
6737        if copy:
6738            return sql_or_expression.copy()
6739        return sql_or_expression
6740
6741    if sql_or_expression is None:
6742        raise ParseError("SQL cannot be None")
6743
6744    import sqlglot
6745
6746    sql = str(sql_or_expression)
6747    if prefix:
6748        sql = f"{prefix} {sql}"
6749
6750    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):
6761def maybe_copy(instance, copy=True):
6762    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7006def union(
7007    *expressions: ExpOrStr,
7008    distinct: bool = True,
7009    dialect: DialectType = None,
7010    copy: bool = True,
7011    **opts,
7012) -> Union:
7013    """
7014    Initializes a syntax tree for the `UNION` operation.
7015
7016    Example:
7017        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7018        'SELECT * FROM foo UNION SELECT * FROM bla'
7019
7020    Args:
7021        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7022            If `Expression` instances are passed, they will be used as-is.
7023        distinct: set the DISTINCT flag if and only if this is true.
7024        dialect: the dialect used to parse the input expression.
7025        copy: whether to copy the expression.
7026        opts: other options to use to parse the input expressions.
7027
7028    Returns:
7029        The new Union instance.
7030    """
7031    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7032    return _apply_set_operation(
7033        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7034    )

Initializes a syntax tree for the UNION operation.

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

The new Union instance.

def intersect( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7037def intersect(
7038    *expressions: ExpOrStr,
7039    distinct: bool = True,
7040    dialect: DialectType = None,
7041    copy: bool = True,
7042    **opts,
7043) -> Intersect:
7044    """
7045    Initializes a syntax tree for the `INTERSECT` operation.
7046
7047    Example:
7048        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7049        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7050
7051    Args:
7052        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7053            If `Expression` instances are passed, they will be used as-is.
7054        distinct: set the DISTINCT flag if and only if this is true.
7055        dialect: the dialect used to parse the input expression.
7056        copy: whether to copy the expression.
7057        opts: other options to use to parse the input expressions.
7058
7059    Returns:
7060        The new Intersect instance.
7061    """
7062    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7063    return _apply_set_operation(
7064        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7065    )

Initializes a syntax tree for the INTERSECT operation.

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

The new Intersect instance.

def except_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7068def except_(
7069    *expressions: ExpOrStr,
7070    distinct: bool = True,
7071    dialect: DialectType = None,
7072    copy: bool = True,
7073    **opts,
7074) -> Except:
7075    """
7076    Initializes a syntax tree for the `EXCEPT` operation.
7077
7078    Example:
7079        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7080        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7081
7082    Args:
7083        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7084            If `Expression` instances are passed, they will be used as-is.
7085        distinct: set the DISTINCT flag if and only if this is true.
7086        dialect: the dialect used to parse the input expression.
7087        copy: whether to copy the expression.
7088        opts: other options to use to parse the input expressions.
7089
7090    Returns:
7091        The new Except instance.
7092    """
7093    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7094    return _apply_set_operation(
7095        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7096    )

Initializes a syntax tree for the EXCEPT operation.

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

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7099def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7100    """
7101    Initializes a syntax tree from one or multiple SELECT expressions.
7102
7103    Example:
7104        >>> select("col1", "col2").from_("tbl").sql()
7105        'SELECT col1, col2 FROM tbl'
7106
7107    Args:
7108        *expressions: the SQL code string to parse as the expressions of a
7109            SELECT statement. If an Expression instance is passed, this is used as-is.
7110        dialect: the dialect used to parse the input expressions (in the case that an
7111            input expression is a SQL string).
7112        **opts: other options to use to parse the input expressions (again, in the case
7113            that an input expression is a SQL string).
7114
7115    Returns:
7116        Select: the syntax tree for the SELECT statement.
7117    """
7118    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

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

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7121def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7122    """
7123    Initializes a syntax tree from a FROM expression.
7124
7125    Example:
7126        >>> from_("tbl").select("col1", "col2").sql()
7127        'SELECT col1, col2 FROM tbl'
7128
7129    Args:
7130        *expression: the SQL code string to parse as the FROM expressions of a
7131            SELECT statement. If an Expression instance is passed, this is used as-is.
7132        dialect: the dialect used to parse the input expression (in the case that the
7133            input expression is a SQL string).
7134        **opts: other options to use to parse the input expressions (again, in the case
7135            that the input expression is a SQL string).
7136
7137    Returns:
7138        Select: the syntax tree for the SELECT statement.
7139    """
7140    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

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

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Update:
7143def update(
7144    table: str | Table,
7145    properties: t.Optional[dict] = None,
7146    where: t.Optional[ExpOrStr] = None,
7147    from_: t.Optional[ExpOrStr] = None,
7148    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7149    dialect: DialectType = None,
7150    **opts,
7151) -> Update:
7152    """
7153    Creates an update statement.
7154
7155    Example:
7156        >>> 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()
7157        "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"
7158
7159    Args:
7160        properties: dictionary of properties to SET which are
7161            auto converted to sql objects eg None -> NULL
7162        where: sql conditional parsed into a WHERE statement
7163        from_: sql statement parsed into a FROM statement
7164        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7165        dialect: the dialect used to parse the input expressions.
7166        **opts: other options to use to parse the input expressions.
7167
7168    Returns:
7169        Update: the syntax tree for the UPDATE statement.
7170    """
7171    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7172    if properties:
7173        update_expr.set(
7174            "expressions",
7175            [
7176                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7177                for k, v in properties.items()
7178            ],
7179        )
7180    if from_:
7181        update_expr.set(
7182            "from",
7183            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7184        )
7185    if isinstance(where, Condition):
7186        where = Where(this=where)
7187    if where:
7188        update_expr.set(
7189            "where",
7190            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7191        )
7192    if with_:
7193        cte_list = [
7194            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7195            for alias, qry in with_.items()
7196        ]
7197        update_expr.set(
7198            "with",
7199            With(expressions=cte_list),
7200        )
7201    return update_expr

Creates an update statement.

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

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Delete:
7204def delete(
7205    table: ExpOrStr,
7206    where: t.Optional[ExpOrStr] = None,
7207    returning: t.Optional[ExpOrStr] = None,
7208    dialect: DialectType = None,
7209    **opts,
7210) -> Delete:
7211    """
7212    Builds a delete statement.
7213
7214    Example:
7215        >>> delete("my_table", where="id > 1").sql()
7216        'DELETE FROM my_table WHERE id > 1'
7217
7218    Args:
7219        where: sql conditional parsed into a WHERE statement
7220        returning: sql conditional parsed into a RETURNING statement
7221        dialect: the dialect used to parse the input expressions.
7222        **opts: other options to use to parse the input expressions.
7223
7224    Returns:
7225        Delete: the syntax tree for the DELETE statement.
7226    """
7227    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7228    if where:
7229        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7230    if returning:
7231        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7232    return delete_expr

Builds a delete statement.

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

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7235def insert(
7236    expression: ExpOrStr,
7237    into: ExpOrStr,
7238    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7239    overwrite: t.Optional[bool] = None,
7240    returning: t.Optional[ExpOrStr] = None,
7241    dialect: DialectType = None,
7242    copy: bool = True,
7243    **opts,
7244) -> Insert:
7245    """
7246    Builds an INSERT statement.
7247
7248    Example:
7249        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7250        'INSERT INTO tbl VALUES (1, 2, 3)'
7251
7252    Args:
7253        expression: the sql string or expression of the INSERT statement
7254        into: the tbl to insert data to.
7255        columns: optionally the table's column names.
7256        overwrite: whether to INSERT OVERWRITE or not.
7257        returning: sql conditional parsed into a RETURNING statement
7258        dialect: the dialect used to parse the input expressions.
7259        copy: whether to copy the expression.
7260        **opts: other options to use to parse the input expressions.
7261
7262    Returns:
7263        Insert: the syntax tree for the INSERT statement.
7264    """
7265    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7266    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7267
7268    if columns:
7269        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7270
7271    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7272
7273    if returning:
7274        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7275
7276    return insert

Builds an INSERT statement.

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

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7279def merge(
7280    *when_exprs: ExpOrStr,
7281    into: ExpOrStr,
7282    using: ExpOrStr,
7283    on: ExpOrStr,
7284    returning: t.Optional[ExpOrStr] = None,
7285    dialect: DialectType = None,
7286    copy: bool = True,
7287    **opts,
7288) -> Merge:
7289    """
7290    Builds a MERGE statement.
7291
7292    Example:
7293        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7294        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7295        ...       into="my_table",
7296        ...       using="source_table",
7297        ...       on="my_table.id = source_table.id").sql()
7298        '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)'
7299
7300    Args:
7301        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7302        into: The target table to merge data into.
7303        using: The source table to merge data from.
7304        on: The join condition for the merge.
7305        returning: The columns to return from the merge.
7306        dialect: The dialect used to parse the input expressions.
7307        copy: Whether to copy the expression.
7308        **opts: Other options to use to parse the input expressions.
7309
7310    Returns:
7311        Merge: The syntax tree for the MERGE statement.
7312    """
7313    merge = Merge(
7314        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7315        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7316        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7317        expressions=[
7318            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
7319            for when_expr in when_exprs
7320        ],
7321    )
7322    if returning:
7323        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7324
7325    return merge

Builds a MERGE statement.

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

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7328def condition(
7329    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7330) -> Condition:
7331    """
7332    Initialize a logical condition expression.
7333
7334    Example:
7335        >>> condition("x=1").sql()
7336        'x = 1'
7337
7338        This is helpful for composing larger logical syntax trees:
7339        >>> where = condition("x=1")
7340        >>> where = where.and_("y=1")
7341        >>> Select().from_("tbl").select("*").where(where).sql()
7342        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7343
7344    Args:
7345        *expression: the SQL code string to parse.
7346            If an Expression instance is passed, this is used as-is.
7347        dialect: the dialect used to parse the input expression (in the case that the
7348            input expression is a SQL string).
7349        copy: Whether to copy `expression` (only applies to expressions).
7350        **opts: other options to use to parse the input expressions (again, in the case
7351            that the input expression is a SQL string).
7352
7353    Returns:
7354        The new Condition instance
7355    """
7356    return maybe_parse(
7357        expression,
7358        into=Condition,
7359        dialect=dialect,
7360        copy=copy,
7361        **opts,
7362    )

Initialize a logical condition expression.

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

This is helpful for composing larger logical syntax trees:

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

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7365def and_(
7366    *expressions: t.Optional[ExpOrStr],
7367    dialect: DialectType = None,
7368    copy: bool = True,
7369    wrap: bool = True,
7370    **opts,
7371) -> Condition:
7372    """
7373    Combine multiple conditions with an AND logical operator.
7374
7375    Example:
7376        >>> and_("x=1", and_("y=1", "z=1")).sql()
7377        'x = 1 AND (y = 1 AND z = 1)'
7378
7379    Args:
7380        *expressions: the SQL code strings to parse.
7381            If an Expression instance is passed, this is used as-is.
7382        dialect: the dialect used to parse the input expression.
7383        copy: whether to copy `expressions` (only applies to Expressions).
7384        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7385            precedence issues, but can be turned off when the produced AST is too deep and
7386            causes recursion-related issues.
7387        **opts: other options to use to parse the input expressions.
7388
7389    Returns:
7390        The new condition
7391    """
7392    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an AND logical operator.

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

The new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7395def or_(
7396    *expressions: t.Optional[ExpOrStr],
7397    dialect: DialectType = None,
7398    copy: bool = True,
7399    wrap: bool = True,
7400    **opts,
7401) -> Condition:
7402    """
7403    Combine multiple conditions with an OR logical operator.
7404
7405    Example:
7406        >>> or_("x=1", or_("y=1", "z=1")).sql()
7407        'x = 1 OR (y = 1 OR z = 1)'
7408
7409    Args:
7410        *expressions: the SQL code strings to parse.
7411            If an Expression instance is passed, this is used as-is.
7412        dialect: the dialect used to parse the input expression.
7413        copy: whether to copy `expressions` (only applies to Expressions).
7414        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7415            precedence issues, but can be turned off when the produced AST is too deep and
7416            causes recursion-related issues.
7417        **opts: other options to use to parse the input expressions.
7418
7419    Returns:
7420        The new condition
7421    """
7422    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an OR logical operator.

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

The new condition

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7425def xor(
7426    *expressions: t.Optional[ExpOrStr],
7427    dialect: DialectType = None,
7428    copy: bool = True,
7429    wrap: bool = True,
7430    **opts,
7431) -> Condition:
7432    """
7433    Combine multiple conditions with an XOR logical operator.
7434
7435    Example:
7436        >>> xor("x=1", xor("y=1", "z=1")).sql()
7437        'x = 1 XOR (y = 1 XOR z = 1)'
7438
7439    Args:
7440        *expressions: the SQL code strings to parse.
7441            If an Expression instance is passed, this is used as-is.
7442        dialect: the dialect used to parse the input expression.
7443        copy: whether to copy `expressions` (only applies to Expressions).
7444        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7445            precedence issues, but can be turned off when the produced AST is too deep and
7446            causes recursion-related issues.
7447        **opts: other options to use to parse the input expressions.
7448
7449    Returns:
7450        The new condition
7451    """
7452    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an XOR logical operator.

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

The new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7455def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7456    """
7457    Wrap a condition with a NOT operator.
7458
7459    Example:
7460        >>> not_("this_suit='black'").sql()
7461        "NOT this_suit = 'black'"
7462
7463    Args:
7464        expression: the SQL code string to parse.
7465            If an Expression instance is passed, this is used as-is.
7466        dialect: the dialect used to parse the input expression.
7467        copy: whether to copy the expression or not.
7468        **opts: other options to use to parse the input expressions.
7469
7470    Returns:
7471        The new condition.
7472    """
7473    this = condition(
7474        expression,
7475        dialect=dialect,
7476        copy=copy,
7477        **opts,
7478    )
7479    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:
7482def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7483    """
7484    Wrap an expression in parentheses.
7485
7486    Example:
7487        >>> paren("5 + 3").sql()
7488        '(5 + 3)'
7489
7490    Args:
7491        expression: the SQL code string to parse.
7492            If an Expression instance is passed, this is used as-is.
7493        copy: whether to copy the expression or not.
7494
7495    Returns:
7496        The wrapped expression.
7497    """
7498    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):
7514def to_identifier(name, quoted=None, copy=True):
7515    """Builds an identifier.
7516
7517    Args:
7518        name: The name to turn into an identifier.
7519        quoted: Whether to force quote the identifier.
7520        copy: Whether to copy name if it's an Identifier.
7521
7522    Returns:
7523        The identifier ast node.
7524    """
7525
7526    if name is None:
7527        return None
7528
7529    if isinstance(name, Identifier):
7530        identifier = maybe_copy(name, copy)
7531    elif isinstance(name, str):
7532        identifier = Identifier(
7533            this=name,
7534            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7535        )
7536    else:
7537        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7538    return identifier

Builds an identifier.

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

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
7541def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7542    """
7543    Parses a given string into an identifier.
7544
7545    Args:
7546        name: The name to parse into an identifier.
7547        dialect: The dialect to parse against.
7548
7549    Returns:
7550        The identifier ast node.
7551    """
7552    try:
7553        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7554    except (ParseError, TokenError):
7555        expression = to_identifier(name)
7556
7557    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*([0-9]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
7563def to_interval(interval: str | Literal) -> Interval:
7564    """Builds an interval expression from a string like '1 day' or '5 months'."""
7565    if isinstance(interval, Literal):
7566        if not interval.is_string:
7567            raise ValueError("Invalid interval string.")
7568
7569        interval = interval.this
7570
7571    interval = maybe_parse(f"INTERVAL {interval}")
7572    assert isinstance(interval, Interval)
7573    return interval

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

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
7576def to_table(
7577    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7578) -> Table:
7579    """
7580    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7581    If a table is passed in then that table is returned.
7582
7583    Args:
7584        sql_path: a `[catalog].[schema].[table]` string.
7585        dialect: the source dialect according to which the table name will be parsed.
7586        copy: Whether to copy a table if it is passed in.
7587        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7588
7589    Returns:
7590        A table expression.
7591    """
7592    if isinstance(sql_path, Table):
7593        return maybe_copy(sql_path, copy=copy)
7594
7595    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7596
7597    for k, v in kwargs.items():
7598        table.set(k, v)
7599
7600    return table

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

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

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
7603def to_column(
7604    sql_path: str | Column,
7605    quoted: t.Optional[bool] = None,
7606    dialect: DialectType = None,
7607    copy: bool = True,
7608    **kwargs,
7609) -> Column:
7610    """
7611    Create a column from a `[table].[column]` sql path. Table is optional.
7612    If a column is passed in then that column is returned.
7613
7614    Args:
7615        sql_path: a `[table].[column]` string.
7616        quoted: Whether or not to force quote identifiers.
7617        dialect: the source dialect according to which the column name will be parsed.
7618        copy: Whether to copy a column if it is passed in.
7619        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7620
7621    Returns:
7622        A column expression.
7623    """
7624    if isinstance(sql_path, Column):
7625        return maybe_copy(sql_path, copy=copy)
7626
7627    try:
7628        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7629    except ParseError:
7630        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7631
7632    for k, v in kwargs.items():
7633        col.set(k, v)
7634
7635    if quoted:
7636        for i in col.find_all(Identifier):
7637            i.set("quoted", True)
7638
7639    return col

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

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

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
7642def alias_(
7643    expression: ExpOrStr,
7644    alias: t.Optional[str | Identifier],
7645    table: bool | t.Sequence[str | Identifier] = False,
7646    quoted: t.Optional[bool] = None,
7647    dialect: DialectType = None,
7648    copy: bool = True,
7649    **opts,
7650):
7651    """Create an Alias expression.
7652
7653    Example:
7654        >>> alias_('foo', 'bar').sql()
7655        'foo AS bar'
7656
7657        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7658        '(SELECT 1, 2) AS bar(a, b)'
7659
7660    Args:
7661        expression: the SQL code strings to parse.
7662            If an Expression instance is passed, this is used as-is.
7663        alias: the alias name to use. If the name has
7664            special characters it is quoted.
7665        table: Whether to create a table alias, can also be a list of columns.
7666        quoted: whether to quote the alias
7667        dialect: the dialect used to parse the input expression.
7668        copy: Whether to copy the expression.
7669        **opts: other options to use to parse the input expressions.
7670
7671    Returns:
7672        Alias: the aliased expression
7673    """
7674    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7675    alias = to_identifier(alias, quoted=quoted)
7676
7677    if table:
7678        table_alias = TableAlias(this=alias)
7679        exp.set("alias", table_alias)
7680
7681        if not isinstance(table, bool):
7682            for column in table:
7683                table_alias.append("columns", to_identifier(column, quoted=quoted))
7684
7685        return exp
7686
7687    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7688    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7689    # for the complete Window expression.
7690    #
7691    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7692
7693    if "alias" in exp.arg_types and not isinstance(exp, Window):
7694        exp.set("alias", alias)
7695        return exp
7696    return Alias(this=exp, alias=alias)

Create an Alias expression.

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

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7699def subquery(
7700    expression: ExpOrStr,
7701    alias: t.Optional[Identifier | str] = None,
7702    dialect: DialectType = None,
7703    **opts,
7704) -> Select:
7705    """
7706    Build a subquery expression that's selected from.
7707
7708    Example:
7709        >>> subquery('select x from tbl', 'bar').select('x').sql()
7710        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7711
7712    Args:
7713        expression: the SQL code strings to parse.
7714            If an Expression instance is passed, this is used as-is.
7715        alias: the alias name to use.
7716        dialect: the dialect used to parse the input expression.
7717        **opts: other options to use to parse the input expressions.
7718
7719    Returns:
7720        A new Select instance with the subquery expression included.
7721    """
7722
7723    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7724    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):
7755def column(
7756    col,
7757    table=None,
7758    db=None,
7759    catalog=None,
7760    *,
7761    fields=None,
7762    quoted=None,
7763    copy=True,
7764):
7765    """
7766    Build a Column.
7767
7768    Args:
7769        col: Column name.
7770        table: Table name.
7771        db: Database name.
7772        catalog: Catalog name.
7773        fields: Additional fields using dots.
7774        quoted: Whether to force quotes on the column's identifiers.
7775        copy: Whether to copy identifiers if passed in.
7776
7777    Returns:
7778        The new Column instance.
7779    """
7780    this = Column(
7781        this=to_identifier(col, quoted=quoted, copy=copy),
7782        table=to_identifier(table, quoted=quoted, copy=copy),
7783        db=to_identifier(db, quoted=quoted, copy=copy),
7784        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7785    )
7786
7787    if fields:
7788        this = Dot.build(
7789            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7790        )
7791    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Cast:
7794def cast(
7795    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7796) -> Cast:
7797    """Cast an expression to a data type.
7798
7799    Example:
7800        >>> cast('x + 1', 'int').sql()
7801        'CAST(x + 1 AS INT)'
7802
7803    Args:
7804        expression: The expression to cast.
7805        to: The datatype to cast to.
7806        copy: Whether to copy the supplied expressions.
7807        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7808            - The expression to be cast is already a exp.Cast expression
7809            - The existing cast is to a type that is logically equivalent to new type
7810
7811            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7812            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7813            and instead just return the original expression `CAST(x as DATETIME)`.
7814
7815            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7816            mapping is applied in the target dialect generator.
7817
7818    Returns:
7819        The new Cast instance.
7820    """
7821    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7822    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7823
7824    # dont re-cast if the expression is already a cast to the correct type
7825    if isinstance(expr, Cast):
7826        from sqlglot.dialects.dialect import Dialect
7827
7828        target_dialect = Dialect.get_or_raise(dialect)
7829        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7830
7831        existing_cast_type: DataType.Type = expr.to.this
7832        new_cast_type: DataType.Type = data_type.this
7833        types_are_equivalent = type_mapping.get(
7834            existing_cast_type, existing_cast_type.value
7835        ) == type_mapping.get(new_cast_type, new_cast_type.value)
7836        if expr.is_type(data_type) or types_are_equivalent:
7837            return expr
7838
7839    expr = Cast(this=expr, to=data_type)
7840    expr.type = data_type
7841
7842    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:
7845def table_(
7846    table: Identifier | str,
7847    db: t.Optional[Identifier | str] = None,
7848    catalog: t.Optional[Identifier | str] = None,
7849    quoted: t.Optional[bool] = None,
7850    alias: t.Optional[Identifier | str] = None,
7851) -> Table:
7852    """Build a Table.
7853
7854    Args:
7855        table: Table name.
7856        db: Database name.
7857        catalog: Catalog name.
7858        quote: Whether to force quotes on the table's identifiers.
7859        alias: Table's alias.
7860
7861    Returns:
7862        The new Table instance.
7863    """
7864    return Table(
7865        this=to_identifier(table, quoted=quoted) if table else None,
7866        db=to_identifier(db, quoted=quoted) if db else None,
7867        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7868        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7869    )

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:
7872def values(
7873    values: t.Iterable[t.Tuple[t.Any, ...]],
7874    alias: t.Optional[str] = None,
7875    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7876) -> Values:
7877    """Build VALUES statement.
7878
7879    Example:
7880        >>> values([(1, '2')]).sql()
7881        "VALUES (1, '2')"
7882
7883    Args:
7884        values: values statements that will be converted to SQL
7885        alias: optional alias
7886        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7887         If either are provided then an alias is also required.
7888
7889    Returns:
7890        Values: the Values expression object
7891    """
7892    if columns and not alias:
7893        raise ValueError("Alias is required when providing columns")
7894
7895    return Values(
7896        expressions=[convert(tup) for tup in values],
7897        alias=(
7898            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7899            if columns
7900            else (TableAlias(this=to_identifier(alias)) if alias else None)
7901        ),
7902    )

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:
7905def var(name: t.Optional[ExpOrStr]) -> Var:
7906    """Build a SQL variable.
7907
7908    Example:
7909        >>> repr(var('x'))
7910        'Var(this=x)'
7911
7912        >>> repr(var(column('x', table='y')))
7913        'Var(this=x)'
7914
7915    Args:
7916        name: The name of the var or an expression who's name will become the var.
7917
7918    Returns:
7919        The new variable node.
7920    """
7921    if not name:
7922        raise ValueError("Cannot convert empty name into var.")
7923
7924    if isinstance(name, Expression):
7925        name = name.name
7926    return Var(this=name)

Build a SQL variable.

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

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
7929def rename_table(
7930    old_name: str | Table,
7931    new_name: str | Table,
7932    dialect: DialectType = None,
7933) -> Alter:
7934    """Build ALTER TABLE... RENAME... expression
7935
7936    Args:
7937        old_name: The old name of the table
7938        new_name: The new name of the table
7939        dialect: The dialect to parse the table.
7940
7941    Returns:
7942        Alter table expression
7943    """
7944    old_table = to_table(old_name, dialect=dialect)
7945    new_table = to_table(new_name, dialect=dialect)
7946    return Alter(
7947        this=old_table,
7948        kind="TABLE",
7949        actions=[
7950            AlterRename(this=new_table),
7951        ],
7952    )

Build ALTER TABLE... RENAME... expression

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

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
7955def rename_column(
7956    table_name: str | Table,
7957    old_column_name: str | Column,
7958    new_column_name: str | Column,
7959    exists: t.Optional[bool] = None,
7960    dialect: DialectType = None,
7961) -> Alter:
7962    """Build ALTER TABLE... RENAME COLUMN... expression
7963
7964    Args:
7965        table_name: Name of the table
7966        old_column: The old name of the column
7967        new_column: The new name of the column
7968        exists: Whether to add the `IF EXISTS` clause
7969        dialect: The dialect to parse the table/column.
7970
7971    Returns:
7972        Alter table expression
7973    """
7974    table = to_table(table_name, dialect=dialect)
7975    old_column = to_column(old_column_name, dialect=dialect)
7976    new_column = to_column(new_column_name, dialect=dialect)
7977    return Alter(
7978        this=table,
7979        kind="TABLE",
7980        actions=[
7981            RenameColumn(this=old_column, to=new_column, exists=exists),
7982        ],
7983    )

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:
7986def convert(value: t.Any, copy: bool = False) -> Expression:
7987    """Convert a python value into an expression object.
7988
7989    Raises an error if a conversion is not possible.
7990
7991    Args:
7992        value: A python object.
7993        copy: Whether to copy `value` (only applies to Expressions and collections).
7994
7995    Returns:
7996        The equivalent expression object.
7997    """
7998    if isinstance(value, Expression):
7999        return maybe_copy(value, copy)
8000    if isinstance(value, str):
8001        return Literal.string(value)
8002    if isinstance(value, bool):
8003        return Boolean(this=value)
8004    if value is None or (isinstance(value, float) and math.isnan(value)):
8005        return null()
8006    if isinstance(value, numbers.Number):
8007        return Literal.number(value)
8008    if isinstance(value, bytes):
8009        return HexString(this=value.hex())
8010    if isinstance(value, datetime.datetime):
8011        datetime_literal = Literal.string(value.isoformat(sep=" "))
8012
8013        tz = None
8014        if value.tzinfo:
8015            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8016            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8017            tz = Literal.string(str(value.tzinfo))
8018
8019        return TimeStrToTime(this=datetime_literal, zone=tz)
8020    if isinstance(value, datetime.date):
8021        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8022        return DateStrToDate(this=date_literal)
8023    if isinstance(value, tuple):
8024        if hasattr(value, "_fields"):
8025            return Struct(
8026                expressions=[
8027                    PropertyEQ(
8028                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8029                    )
8030                    for k in value._fields
8031                ]
8032            )
8033        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8034    if isinstance(value, list):
8035        return Array(expressions=[convert(v, copy=copy) for v in value])
8036    if isinstance(value, dict):
8037        return Map(
8038            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8039            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8040        )
8041    if hasattr(value, "__dict__"):
8042        return Struct(
8043            expressions=[
8044                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8045                for k, v in value.__dict__.items()
8046            ]
8047        )
8048    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:
8051def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8052    """
8053    Replace children of an expression with the result of a lambda fun(child) -> exp.
8054    """
8055    for k, v in tuple(expression.args.items()):
8056        is_list_arg = type(v) is list
8057
8058        child_nodes = v if is_list_arg else [v]
8059        new_child_nodes = []
8060
8061        for cn in child_nodes:
8062            if isinstance(cn, Expression):
8063                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8064                    new_child_nodes.append(child_node)
8065            else:
8066                new_child_nodes.append(cn)
8067
8068        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:
8071def replace_tree(
8072    expression: Expression,
8073    fun: t.Callable,
8074    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8075) -> Expression:
8076    """
8077    Replace an entire tree with the result of function calls on each node.
8078
8079    This will be traversed in reverse dfs, so leaves first.
8080    If new nodes are created as a result of function calls, they will also be traversed.
8081    """
8082    stack = list(expression.dfs(prune=prune))
8083
8084    while stack:
8085        node = stack.pop()
8086        new_node = fun(node)
8087
8088        if new_node is not node:
8089            node.replace(new_node)
8090
8091            if isinstance(new_node, Expression):
8092                stack.append(new_node)
8093
8094    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]:
8097def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8098    """
8099    Return all table names referenced through columns in an expression.
8100
8101    Example:
8102        >>> import sqlglot
8103        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8104        ['a', 'c']
8105
8106    Args:
8107        expression: expression to find table names.
8108        exclude: a table name to exclude
8109
8110    Returns:
8111        A list of unique names.
8112    """
8113    return {
8114        table
8115        for table in (column.table for column in expression.find_all(Column))
8116        if table and table != exclude
8117    }

Return all table names referenced through columns in an expression.

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

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
8120def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8121    """Get the full name of a table as a string.
8122
8123    Args:
8124        table: Table expression node or string.
8125        dialect: The dialect to generate the table name for.
8126        identify: Determines when an identifier should be quoted. Possible values are:
8127            False (default): Never quote, except in cases where it's mandatory by the dialect.
8128            True: Always quote.
8129
8130    Examples:
8131        >>> from sqlglot import exp, parse_one
8132        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8133        'a.b.c'
8134
8135    Returns:
8136        The table name.
8137    """
8138
8139    table = maybe_parse(table, into=Table, dialect=dialect)
8140
8141    if not table:
8142        raise ValueError(f"Cannot parse {table}")
8143
8144    return ".".join(
8145        (
8146            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8147            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8148            else part.name
8149        )
8150        for part in table.parts
8151    )

Get the full name of a table as a string.

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

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
8154def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8155    """Returns a case normalized table name without quotes.
8156
8157    Args:
8158        table: the table to normalize
8159        dialect: the dialect to use for normalization rules
8160        copy: whether to copy the expression.
8161
8162    Examples:
8163        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8164        'A-B.c'
8165    """
8166    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8167
8168    return ".".join(
8169        p.name
8170        for p in normalize_identifiers(
8171            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8172        ).parts
8173    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8176def replace_tables(
8177    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8178) -> E:
8179    """Replace all tables in expression according to the mapping.
8180
8181    Args:
8182        expression: expression node to be transformed and replaced.
8183        mapping: mapping of table names.
8184        dialect: the dialect of the mapping table
8185        copy: whether to copy the expression.
8186
8187    Examples:
8188        >>> from sqlglot import exp, parse_one
8189        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8190        'SELECT * FROM c /* a.b */'
8191
8192    Returns:
8193        The mapped expression.
8194    """
8195
8196    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8197
8198    def _replace_tables(node: Expression) -> Expression:
8199        if isinstance(node, Table):
8200            original = normalize_table_name(node, dialect=dialect)
8201            new_name = mapping.get(original)
8202
8203            if new_name:
8204                table = to_table(
8205                    new_name,
8206                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8207                    dialect=dialect,
8208                )
8209                table.add_comments([original])
8210                return table
8211        return node
8212
8213    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:
8216def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8217    """Replace placeholders in an expression.
8218
8219    Args:
8220        expression: expression node to be transformed and replaced.
8221        args: positional names that will substitute unnamed placeholders in the given order.
8222        kwargs: keyword arguments that will substitute named placeholders.
8223
8224    Examples:
8225        >>> from sqlglot import exp, parse_one
8226        >>> replace_placeholders(
8227        ...     parse_one("select * from :tbl where ? = ?"),
8228        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8229        ... ).sql()
8230        "SELECT * FROM foo WHERE str_col = 'b'"
8231
8232    Returns:
8233        The mapped expression.
8234    """
8235
8236    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8237        if isinstance(node, Placeholder):
8238            if node.this:
8239                new_name = kwargs.get(node.this)
8240                if new_name is not None:
8241                    return convert(new_name)
8242            else:
8243                try:
8244                    return convert(next(args))
8245                except StopIteration:
8246                    pass
8247        return node
8248
8249    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

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

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8252def expand(
8253    expression: Expression,
8254    sources: t.Dict[str, Query],
8255    dialect: DialectType = None,
8256    copy: bool = True,
8257) -> Expression:
8258    """Transforms an expression by expanding all referenced sources into subqueries.
8259
8260    Examples:
8261        >>> from sqlglot import parse_one
8262        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8263        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8264
8265        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8266        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8267
8268    Args:
8269        expression: The expression to expand.
8270        sources: A dictionary of name to Queries.
8271        dialect: The dialect of the sources dict.
8272        copy: Whether to copy the expression during transformation. Defaults to True.
8273
8274    Returns:
8275        The transformed expression.
8276    """
8277    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8278
8279    def _expand(node: Expression):
8280        if isinstance(node, Table):
8281            name = normalize_table_name(node, dialect=dialect)
8282            source = sources.get(name)
8283            if source:
8284                subquery = source.subquery(node.alias or name)
8285                subquery.comments = [f"source: {name}"]
8286                return subquery.transform(_expand, copy=False)
8287        return node
8288
8289    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

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

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
8292def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8293    """
8294    Returns a Func expression.
8295
8296    Examples:
8297        >>> func("abs", 5).sql()
8298        'ABS(5)'
8299
8300        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8301        'CAST(5 AS DOUBLE)'
8302
8303    Args:
8304        name: the name of the function to build.
8305        args: the args used to instantiate the function of interest.
8306        copy: whether to copy the argument expressions.
8307        dialect: the source dialect.
8308        kwargs: the kwargs used to instantiate the function of interest.
8309
8310    Note:
8311        The arguments `args` and `kwargs` are mutually exclusive.
8312
8313    Returns:
8314        An instance of the function of interest, or an anonymous function, if `name` doesn't
8315        correspond to an existing `sqlglot.expressions.Func` class.
8316    """
8317    if args and kwargs:
8318        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8319
8320    from sqlglot.dialects.dialect import Dialect
8321
8322    dialect = Dialect.get_or_raise(dialect)
8323
8324    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8325    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8326
8327    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8328    if constructor:
8329        if converted:
8330            if "dialect" in constructor.__code__.co_varnames:
8331                function = constructor(converted, dialect=dialect)
8332            else:
8333                function = constructor(converted)
8334        elif constructor.__name__ == "from_arg_list":
8335            function = constructor.__self__(**kwargs)  # type: ignore
8336        else:
8337            constructor = FUNCTION_BY_NAME.get(name.upper())
8338            if constructor:
8339                function = constructor(**kwargs)
8340            else:
8341                raise ValueError(
8342                    f"Unable to convert '{name}' into a Func. Either manually construct "
8343                    "the Func expression of interest or parse the function call."
8344                )
8345    else:
8346        kwargs = kwargs or {"expressions": converted}
8347        function = Anonymous(this=name, **kwargs)
8348
8349    for error_message in function.error_messages(converted):
8350        raise ValueError(error_message)
8351
8352    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:
8355def case(
8356    expression: t.Optional[ExpOrStr] = None,
8357    **opts,
8358) -> Case:
8359    """
8360    Initialize a CASE statement.
8361
8362    Example:
8363        case().when("a = 1", "foo").else_("bar")
8364
8365    Args:
8366        expression: Optionally, the input expression (not all dialects support this)
8367        **opts: Extra keyword arguments for parsing `expression`
8368    """
8369    if expression is not None:
8370        this = maybe_parse(expression, **opts)
8371    else:
8372        this = None
8373    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

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

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
8376def array(
8377    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8378) -> Array:
8379    """
8380    Returns an array.
8381
8382    Examples:
8383        >>> array(1, 'x').sql()
8384        'ARRAY(1, x)'
8385
8386    Args:
8387        expressions: the expressions to add to the array.
8388        copy: whether to copy the argument expressions.
8389        dialect: the source dialect.
8390        kwargs: the kwargs used to instantiate the function of interest.
8391
8392    Returns:
8393        An array expression.
8394    """
8395    return Array(
8396        expressions=[
8397            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8398            for expression in expressions
8399        ]
8400    )

Returns an array.

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

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
8403def tuple_(
8404    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8405) -> Tuple:
8406    """
8407    Returns an tuple.
8408
8409    Examples:
8410        >>> tuple_(1, 'x').sql()
8411        '(1, x)'
8412
8413    Args:
8414        expressions: the expressions to add to the tuple.
8415        copy: whether to copy the argument expressions.
8416        dialect: the source dialect.
8417        kwargs: the kwargs used to instantiate the function of interest.
8418
8419    Returns:
8420        A tuple expression.
8421    """
8422    return Tuple(
8423        expressions=[
8424            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8425            for expression in expressions
8426        ]
8427    )

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:
8430def true() -> Boolean:
8431    """
8432    Returns a true Boolean expression.
8433    """
8434    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8437def false() -> Boolean:
8438    """
8439    Returns a false Boolean expression.
8440    """
8441    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8444def null() -> Null:
8445    """
8446    Returns a Null expression.
8447    """
8448    return Null()

Returns a Null expression.

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