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

Returns the depth of this tree.

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

Returns the parent select statement.

same_parent: bool
469    @property
470    def same_parent(self) -> bool:
471        """Returns if the parent is the same class as itself."""
472        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
474    def root(self) -> Expression:
475        """
476        Returns the root expression of this tree.
477        """
478        expression = self
479        while expression.parent:
480            expression = expression.parent
481        return expression

Returns the root expression of this tree.

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

Returns the first non parenthesis child or self.

def unalias(self):
558    def unalias(self):
559        """
560        Returns the inner expression if this is an Alias.
561        """
562        if isinstance(self, Alias):
563            return self.this
564        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
566    def unnest_operands(self):
567        """
568        Returns unnested operands as a tuple.
569        """
570        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

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

Logical conditions like x AND y, or simply x

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

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

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

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

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

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

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

selects: List[Expression]
1173    @property
1174    def selects(self) -> t.List[Expression]:
1175        """Returns the query's projections."""
1176        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

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

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

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

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

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):
1410class Create(DDL):
1411    arg_types = {
1412        "with": False,
1413        "this": True,
1414        "kind": True,
1415        "expression": False,
1416        "exists": False,
1417        "properties": False,
1418        "replace": False,
1419        "refresh": False,
1420        "unique": False,
1421        "indexes": False,
1422        "no_schema_binding": False,
1423        "begin": False,
1424        "end": False,
1425        "clone": False,
1426        "concurrently": False,
1427        "clustered": False,
1428    }
1429
1430    @property
1431    def kind(self) -> t.Optional[str]:
1432        kind = self.args.get("kind")
1433        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]
1430    @property
1431    def kind(self) -> t.Optional[str]:
1432        kind = self.args.get("kind")
1433        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1436class SequenceProperties(Expression):
1437    arg_types = {
1438        "increment": False,
1439        "minvalue": False,
1440        "maxvalue": False,
1441        "cache": False,
1442        "start": False,
1443        "owned": False,
1444        "options": False,
1445    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1448class TruncateTable(Expression):
1449    arg_types = {
1450        "expressions": True,
1451        "is_database": False,
1452        "exists": False,
1453        "only": False,
1454        "cluster": False,
1455        "identity": False,
1456        "option": False,
1457        "partition": False,
1458    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1464class Clone(Expression):
1465    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1468class Describe(Expression):
1469    arg_types = {
1470        "this": True,
1471        "style": False,
1472        "kind": False,
1473        "expressions": False,
1474        "partition": False,
1475    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False}
key = 'describe'
class Summarize(Expression):
1479class Summarize(Expression):
1480    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1483class Kill(Expression):
1484    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1487class Pragma(Expression):
1488    pass
key = 'pragma'
class Declare(Expression):
1491class Declare(Expression):
1492    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1495class DeclareItem(Expression):
1496    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1499class Set(Expression):
1500    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1503class Heredoc(Expression):
1504    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1507class SetItem(Expression):
1508    arg_types = {
1509        "this": False,
1510        "expressions": False,
1511        "kind": False,
1512        "collate": False,  # MySQL SET NAMES statement
1513        "global": False,
1514    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1517class Show(Expression):
1518    arg_types = {
1519        "this": True,
1520        "history": False,
1521        "terse": False,
1522        "target": False,
1523        "offset": False,
1524        "starts_with": False,
1525        "limit": False,
1526        "from": False,
1527        "like": False,
1528        "where": False,
1529        "db": False,
1530        "scope": False,
1531        "scope_kind": False,
1532        "full": False,
1533        "mutex": False,
1534        "query": False,
1535        "channel": False,
1536        "global": False,
1537        "log": False,
1538        "position": False,
1539        "types": False,
1540    }
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):
1543class UserDefinedFunction(Expression):
1544    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1547class CharacterSet(Expression):
1548    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1551class With(Expression):
1552    arg_types = {"expressions": True, "recursive": False}
1553
1554    @property
1555    def recursive(self) -> bool:
1556        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1554    @property
1555    def recursive(self) -> bool:
1556        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1559class WithinGroup(Expression):
1560    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1565class CTE(DerivedTable):
1566    arg_types = {
1567        "this": True,
1568        "alias": True,
1569        "scalar": False,
1570        "materialized": False,
1571    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1574class ProjectionDef(Expression):
1575    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1578class TableAlias(Expression):
1579    arg_types = {"this": False, "columns": False}
1580
1581    @property
1582    def columns(self):
1583        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1581    @property
1582    def columns(self):
1583        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1586class BitString(Condition):
1587    pass
key = 'bitstring'
class HexString(Condition):
1590class HexString(Condition):
1591    pass
key = 'hexstring'
class ByteString(Condition):
1594class ByteString(Condition):
1595    pass
key = 'bytestring'
class RawString(Condition):
1598class RawString(Condition):
1599    pass
key = 'rawstring'
class UnicodeString(Condition):
1602class UnicodeString(Condition):
1603    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1606class Column(Condition):
1607    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1608
1609    @property
1610    def table(self) -> str:
1611        return self.text("table")
1612
1613    @property
1614    def db(self) -> str:
1615        return self.text("db")
1616
1617    @property
1618    def catalog(self) -> str:
1619        return self.text("catalog")
1620
1621    @property
1622    def output_name(self) -> str:
1623        return self.name
1624
1625    @property
1626    def parts(self) -> t.List[Identifier]:
1627        """Return the parts of a column in order catalog, db, table, name."""
1628        return [
1629            t.cast(Identifier, self.args[part])
1630            for part in ("catalog", "db", "table", "this")
1631            if self.args.get(part)
1632        ]
1633
1634    def to_dot(self) -> Dot | Identifier:
1635        """Converts the column into a dot expression."""
1636        parts = self.parts
1637        parent = self.parent
1638
1639        while parent:
1640            if isinstance(parent, Dot):
1641                parts.append(parent.expression)
1642            parent = parent.parent
1643
1644        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
1609    @property
1610    def table(self) -> str:
1611        return self.text("table")
db: str
1613    @property
1614    def db(self) -> str:
1615        return self.text("db")
catalog: str
1617    @property
1618    def catalog(self) -> str:
1619        return self.text("catalog")
output_name: str
1621    @property
1622    def output_name(self) -> str:
1623        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]
1625    @property
1626    def parts(self) -> t.List[Identifier]:
1627        """Return the parts of a column in order catalog, db, table, name."""
1628        return [
1629            t.cast(Identifier, self.args[part])
1630            for part in ("catalog", "db", "table", "this")
1631            if self.args.get(part)
1632        ]

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

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

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1647class ColumnPosition(Expression):
1648    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1651class ColumnDef(Expression):
1652    arg_types = {
1653        "this": True,
1654        "kind": False,
1655        "constraints": False,
1656        "exists": False,
1657        "position": False,
1658    }
1659
1660    @property
1661    def constraints(self) -> t.List[ColumnConstraint]:
1662        return self.args.get("constraints") or []
1663
1664    @property
1665    def kind(self) -> t.Optional[DataType]:
1666        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1660    @property
1661    def constraints(self) -> t.List[ColumnConstraint]:
1662        return self.args.get("constraints") or []
kind: Optional[DataType]
1664    @property
1665    def kind(self) -> t.Optional[DataType]:
1666        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1669class AlterColumn(Expression):
1670    arg_types = {
1671        "this": True,
1672        "dtype": False,
1673        "collate": False,
1674        "using": False,
1675        "default": False,
1676        "drop": False,
1677        "comment": False,
1678        "allow_null": False,
1679    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1683class AlterDistStyle(Expression):
1684    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1687class AlterSortKey(Expression):
1688    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1691class AlterSet(Expression):
1692    arg_types = {
1693        "expressions": False,
1694        "option": False,
1695        "tablespace": False,
1696        "access_method": False,
1697        "file_format": False,
1698        "copy_options": False,
1699        "tag": False,
1700        "location": False,
1701        "serde": False,
1702    }
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):
1705class RenameColumn(Expression):
1706    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1709class AlterRename(Expression):
1710    pass
key = 'alterrename'
class SwapTable(Expression):
1713class SwapTable(Expression):
1714    pass
key = 'swaptable'
class Comment(Expression):
1717class Comment(Expression):
1718    arg_types = {
1719        "this": True,
1720        "kind": True,
1721        "expression": True,
1722        "exists": False,
1723        "materialized": False,
1724    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1727class Comprehension(Expression):
1728    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):
1732class MergeTreeTTLAction(Expression):
1733    arg_types = {
1734        "this": True,
1735        "delete": False,
1736        "recompress": False,
1737        "to_disk": False,
1738        "to_volume": False,
1739    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1743class MergeTreeTTL(Expression):
1744    arg_types = {
1745        "expressions": True,
1746        "where": False,
1747        "group": False,
1748        "aggregates": False,
1749    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1753class IndexConstraintOption(Expression):
1754    arg_types = {
1755        "key_block_size": False,
1756        "using": False,
1757        "parser": False,
1758        "comment": False,
1759        "visible": False,
1760        "engine_attr": False,
1761        "secondary_engine_attr": False,
1762    }
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):
1765class ColumnConstraint(Expression):
1766    arg_types = {"this": False, "kind": True}
1767
1768    @property
1769    def kind(self) -> ColumnConstraintKind:
1770        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1768    @property
1769    def kind(self) -> ColumnConstraintKind:
1770        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1773class ColumnConstraintKind(Expression):
1774    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1777class AutoIncrementColumnConstraint(ColumnConstraintKind):
1778    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1781class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1782    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1785class CaseSpecificColumnConstraint(ColumnConstraintKind):
1786    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1789class CharacterSetColumnConstraint(ColumnConstraintKind):
1790    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1793class CheckColumnConstraint(ColumnConstraintKind):
1794    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1797class ClusteredColumnConstraint(ColumnConstraintKind):
1798    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1801class CollateColumnConstraint(ColumnConstraintKind):
1802    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1805class CommentColumnConstraint(ColumnConstraintKind):
1806    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1809class CompressColumnConstraint(ColumnConstraintKind):
1810    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1813class DateFormatColumnConstraint(ColumnConstraintKind):
1814    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1817class DefaultColumnConstraint(ColumnConstraintKind):
1818    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1821class EncodeColumnConstraint(ColumnConstraintKind):
1822    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1826class ExcludeColumnConstraint(ColumnConstraintKind):
1827    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1830class EphemeralColumnConstraint(ColumnConstraintKind):
1831    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1834class WithOperator(Expression):
1835    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1838class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1839    # this: True -> ALWAYS, this: False -> BY DEFAULT
1840    arg_types = {
1841        "this": False,
1842        "expression": False,
1843        "on_null": False,
1844        "start": False,
1845        "increment": False,
1846        "minvalue": False,
1847        "maxvalue": False,
1848        "cycle": False,
1849    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1852class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1853    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1858class IndexColumnConstraint(ColumnConstraintKind):
1859    arg_types = {
1860        "this": False,
1861        "expressions": False,
1862        "kind": False,
1863        "index_type": False,
1864        "options": False,
1865        "expression": False,  # Clickhouse
1866        "granularity": False,
1867    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1870class InlineLengthColumnConstraint(ColumnConstraintKind):
1871    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1874class NonClusteredColumnConstraint(ColumnConstraintKind):
1875    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1878class NotForReplicationColumnConstraint(ColumnConstraintKind):
1879    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1883class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1884    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1887class NotNullColumnConstraint(ColumnConstraintKind):
1888    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1892class OnUpdateColumnConstraint(ColumnConstraintKind):
1893    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1897class TagColumnConstraint(ColumnConstraintKind):
1898    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1902class TransformColumnConstraint(ColumnConstraintKind):
1903    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1906class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1907    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1910class TitleColumnConstraint(ColumnConstraintKind):
1911    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1914class UniqueColumnConstraint(ColumnConstraintKind):
1915    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):
1918class UppercaseColumnConstraint(ColumnConstraintKind):
1919    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1922class PathColumnConstraint(ColumnConstraintKind):
1923    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1927class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1928    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1933class ComputedColumnConstraint(ColumnConstraintKind):
1934    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1937class Constraint(Expression):
1938    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1941class Delete(DML):
1942    arg_types = {
1943        "with": False,
1944        "this": False,
1945        "using": False,
1946        "where": False,
1947        "returning": False,
1948        "limit": False,
1949        "tables": False,  # Multiple-Table Syntax (MySQL)
1950        "cluster": False,  # Clickhouse
1951    }
1952
1953    def delete(
1954        self,
1955        table: ExpOrStr,
1956        dialect: DialectType = None,
1957        copy: bool = True,
1958        **opts,
1959    ) -> Delete:
1960        """
1961        Create a DELETE expression or replace the table on an existing DELETE expression.
1962
1963        Example:
1964            >>> delete("tbl").sql()
1965            'DELETE FROM tbl'
1966
1967        Args:
1968            table: the table from which to delete.
1969            dialect: the dialect used to parse the input expression.
1970            copy: if `False`, modify this expression instance in-place.
1971            opts: other options to use to parse the input expressions.
1972
1973        Returns:
1974            Delete: the modified expression.
1975        """
1976        return _apply_builder(
1977            expression=table,
1978            instance=self,
1979            arg="this",
1980            dialect=dialect,
1981            into=Table,
1982            copy=copy,
1983            **opts,
1984        )
1985
1986    def where(
1987        self,
1988        *expressions: t.Optional[ExpOrStr],
1989        append: bool = True,
1990        dialect: DialectType = None,
1991        copy: bool = True,
1992        **opts,
1993    ) -> Delete:
1994        """
1995        Append to or set the WHERE expressions.
1996
1997        Example:
1998            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1999            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2000
2001        Args:
2002            *expressions: the SQL code strings to parse.
2003                If an `Expression` instance is passed, it will be used as-is.
2004                Multiple expressions are combined with an AND operator.
2005            append: if `True`, AND the new expressions to any existing expression.
2006                Otherwise, this resets the expression.
2007            dialect: the dialect used to parse the input expressions.
2008            copy: if `False`, modify this expression instance in-place.
2009            opts: other options to use to parse the input expressions.
2010
2011        Returns:
2012            Delete: the modified expression.
2013        """
2014        return _apply_conjunction_builder(
2015            *expressions,
2016            instance=self,
2017            arg="where",
2018            append=append,
2019            into=Where,
2020            dialect=dialect,
2021            copy=copy,
2022            **opts,
2023        )
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:
1953    def delete(
1954        self,
1955        table: ExpOrStr,
1956        dialect: DialectType = None,
1957        copy: bool = True,
1958        **opts,
1959    ) -> Delete:
1960        """
1961        Create a DELETE expression or replace the table on an existing DELETE expression.
1962
1963        Example:
1964            >>> delete("tbl").sql()
1965            'DELETE FROM tbl'
1966
1967        Args:
1968            table: the table from which to delete.
1969            dialect: the dialect used to parse the input expression.
1970            copy: if `False`, modify this expression instance in-place.
1971            opts: other options to use to parse the input expressions.
1972
1973        Returns:
1974            Delete: the modified expression.
1975        """
1976        return _apply_builder(
1977            expression=table,
1978            instance=self,
1979            arg="this",
1980            dialect=dialect,
1981            into=Table,
1982            copy=copy,
1983            **opts,
1984        )

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

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

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):
2262class ConditionalInsert(Expression):
2263    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2266class MultitableInserts(Expression):
2267    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2270class OnConflict(Expression):
2271    arg_types = {
2272        "duplicate": False,
2273        "expressions": False,
2274        "action": False,
2275        "conflict_keys": False,
2276        "constraint": False,
2277    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2280class OnCondition(Expression):
2281    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2284class Returning(Expression):
2285    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2289class Introducer(Expression):
2290    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2294class National(Expression):
2295    pass
key = 'national'
class LoadData(Expression):
2298class LoadData(Expression):
2299    arg_types = {
2300        "this": True,
2301        "local": False,
2302        "overwrite": False,
2303        "inpath": True,
2304        "partition": False,
2305        "input_format": False,
2306        "serde": False,
2307    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2310class Partition(Expression):
2311    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2314class PartitionRange(Expression):
2315    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2319class PartitionId(Expression):
2320    pass
key = 'partitionid'
class Fetch(Expression):
2323class Fetch(Expression):
2324    arg_types = {
2325        "direction": False,
2326        "count": False,
2327        "percent": False,
2328        "with_ties": False,
2329    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2332class Grant(Expression):
2333    arg_types = {
2334        "privileges": True,
2335        "kind": False,
2336        "securable": True,
2337        "principals": True,
2338        "grant_option": False,
2339    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2342class Group(Expression):
2343    arg_types = {
2344        "expressions": False,
2345        "grouping_sets": False,
2346        "cube": False,
2347        "rollup": False,
2348        "totals": False,
2349        "all": False,
2350    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2353class Cube(Expression):
2354    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2357class Rollup(Expression):
2358    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2361class GroupingSets(Expression):
2362    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2365class Lambda(Expression):
2366    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2369class Limit(Expression):
2370    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):
2373class Literal(Condition):
2374    arg_types = {"this": True, "is_string": True}
2375
2376    @property
2377    def hashable_args(self) -> t.Any:
2378        return (self.this, self.args.get("is_string"))
2379
2380    @classmethod
2381    def number(cls, number) -> Literal:
2382        return cls(this=str(number), is_string=False)
2383
2384    @classmethod
2385    def string(cls, string) -> Literal:
2386        return cls(this=str(string), is_string=True)
2387
2388    @property
2389    def output_name(self) -> str:
2390        return self.name
2391
2392    def to_py(self) -> int | str | Decimal:
2393        if self.is_number:
2394            try:
2395                return int(self.this)
2396            except ValueError:
2397                return Decimal(self.this)
2398        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2376    @property
2377    def hashable_args(self) -> t.Any:
2378        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2380    @classmethod
2381    def number(cls, number) -> Literal:
2382        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2384    @classmethod
2385    def string(cls, string) -> Literal:
2386        return cls(this=str(string), is_string=True)
output_name: str
2388    @property
2389    def output_name(self) -> str:
2390        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:
2392    def to_py(self) -> int | str | Decimal:
2393        if self.is_number:
2394            try:
2395                return int(self.this)
2396            except ValueError:
2397                return Decimal(self.this)
2398        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2401class Join(Expression):
2402    arg_types = {
2403        "this": True,
2404        "on": False,
2405        "side": False,
2406        "kind": False,
2407        "using": False,
2408        "method": False,
2409        "global": False,
2410        "hint": False,
2411        "match_condition": False,  # Snowflake
2412        "expressions": False,
2413    }
2414
2415    @property
2416    def method(self) -> str:
2417        return self.text("method").upper()
2418
2419    @property
2420    def kind(self) -> str:
2421        return self.text("kind").upper()
2422
2423    @property
2424    def side(self) -> str:
2425        return self.text("side").upper()
2426
2427    @property
2428    def hint(self) -> str:
2429        return self.text("hint").upper()
2430
2431    @property
2432    def alias_or_name(self) -> str:
2433        return self.this.alias_or_name
2434
2435    def on(
2436        self,
2437        *expressions: t.Optional[ExpOrStr],
2438        append: bool = True,
2439        dialect: DialectType = None,
2440        copy: bool = True,
2441        **opts,
2442    ) -> Join:
2443        """
2444        Append to or set the ON expressions.
2445
2446        Example:
2447            >>> import sqlglot
2448            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2449            'JOIN x ON y = 1'
2450
2451        Args:
2452            *expressions: the SQL code strings to parse.
2453                If an `Expression` instance is passed, it will be used as-is.
2454                Multiple expressions are combined with an AND operator.
2455            append: if `True`, AND the new expressions to any existing expression.
2456                Otherwise, this resets the expression.
2457            dialect: the dialect used to parse the input expressions.
2458            copy: if `False`, modify this expression instance in-place.
2459            opts: other options to use to parse the input expressions.
2460
2461        Returns:
2462            The modified Join expression.
2463        """
2464        join = _apply_conjunction_builder(
2465            *expressions,
2466            instance=self,
2467            arg="on",
2468            append=append,
2469            dialect=dialect,
2470            copy=copy,
2471            **opts,
2472        )
2473
2474        if join.kind == "CROSS":
2475            join.set("kind", None)
2476
2477        return join
2478
2479    def using(
2480        self,
2481        *expressions: t.Optional[ExpOrStr],
2482        append: bool = True,
2483        dialect: DialectType = None,
2484        copy: bool = True,
2485        **opts,
2486    ) -> Join:
2487        """
2488        Append to or set the USING expressions.
2489
2490        Example:
2491            >>> import sqlglot
2492            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2493            'JOIN x USING (foo, bla)'
2494
2495        Args:
2496            *expressions: the SQL code strings to parse.
2497                If an `Expression` instance is passed, it will be used as-is.
2498            append: if `True`, concatenate the new expressions to the existing "using" list.
2499                Otherwise, this resets the expression.
2500            dialect: the dialect used to parse the input expressions.
2501            copy: if `False`, modify this expression instance in-place.
2502            opts: other options to use to parse the input expressions.
2503
2504        Returns:
2505            The modified Join expression.
2506        """
2507        join = _apply_list_builder(
2508            *expressions,
2509            instance=self,
2510            arg="using",
2511            append=append,
2512            dialect=dialect,
2513            copy=copy,
2514            **opts,
2515        )
2516
2517        if join.kind == "CROSS":
2518            join.set("kind", None)
2519
2520        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
2415    @property
2416    def method(self) -> str:
2417        return self.text("method").upper()
kind: str
2419    @property
2420    def kind(self) -> str:
2421        return self.text("kind").upper()
side: str
2423    @property
2424    def side(self) -> str:
2425        return self.text("side").upper()
hint: str
2427    @property
2428    def hint(self) -> str:
2429        return self.text("hint").upper()
alias_or_name: str
2431    @property
2432    def alias_or_name(self) -> str:
2433        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:
2435    def on(
2436        self,
2437        *expressions: t.Optional[ExpOrStr],
2438        append: bool = True,
2439        dialect: DialectType = None,
2440        copy: bool = True,
2441        **opts,
2442    ) -> Join:
2443        """
2444        Append to or set the ON expressions.
2445
2446        Example:
2447            >>> import sqlglot
2448            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2449            'JOIN x ON y = 1'
2450
2451        Args:
2452            *expressions: the SQL code strings to parse.
2453                If an `Expression` instance is passed, it will be used as-is.
2454                Multiple expressions are combined with an AND operator.
2455            append: if `True`, AND the new expressions to any existing expression.
2456                Otherwise, this resets the expression.
2457            dialect: the dialect used to parse the input expressions.
2458            copy: if `False`, modify this expression instance in-place.
2459            opts: other options to use to parse the input expressions.
2460
2461        Returns:
2462            The modified Join expression.
2463        """
2464        join = _apply_conjunction_builder(
2465            *expressions,
2466            instance=self,
2467            arg="on",
2468            append=append,
2469            dialect=dialect,
2470            copy=copy,
2471            **opts,
2472        )
2473
2474        if join.kind == "CROSS":
2475            join.set("kind", None)
2476
2477        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:
2479    def using(
2480        self,
2481        *expressions: t.Optional[ExpOrStr],
2482        append: bool = True,
2483        dialect: DialectType = None,
2484        copy: bool = True,
2485        **opts,
2486    ) -> Join:
2487        """
2488        Append to or set the USING expressions.
2489
2490        Example:
2491            >>> import sqlglot
2492            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2493            'JOIN x USING (foo, bla)'
2494
2495        Args:
2496            *expressions: the SQL code strings to parse.
2497                If an `Expression` instance is passed, it will be used as-is.
2498            append: if `True`, concatenate the new expressions to the existing "using" list.
2499                Otherwise, this resets the expression.
2500            dialect: the dialect used to parse the input expressions.
2501            copy: if `False`, modify this expression instance in-place.
2502            opts: other options to use to parse the input expressions.
2503
2504        Returns:
2505            The modified Join expression.
2506        """
2507        join = _apply_list_builder(
2508            *expressions,
2509            instance=self,
2510            arg="using",
2511            append=append,
2512            dialect=dialect,
2513            copy=copy,
2514            **opts,
2515        )
2516
2517        if join.kind == "CROSS":
2518            join.set("kind", None)
2519
2520        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):
2523class Lateral(UDTF):
2524    arg_types = {
2525        "this": True,
2526        "view": False,
2527        "outer": False,
2528        "alias": False,
2529        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2530    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2533class MatchRecognizeMeasure(Expression):
2534    arg_types = {
2535        "this": True,
2536        "window_frame": False,
2537    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2540class MatchRecognize(Expression):
2541    arg_types = {
2542        "partition_by": False,
2543        "order": False,
2544        "measures": False,
2545        "rows": False,
2546        "after": False,
2547        "pattern": False,
2548        "define": False,
2549        "alias": False,
2550    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2555class Final(Expression):
2556    pass
key = 'final'
class Offset(Expression):
2559class Offset(Expression):
2560    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2563class Order(Expression):
2564    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2568class WithFill(Expression):
2569    arg_types = {
2570        "from": False,
2571        "to": False,
2572        "step": False,
2573        "interpolate": False,
2574    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2579class Cluster(Order):
2580    pass
key = 'cluster'
class Distribute(Order):
2583class Distribute(Order):
2584    pass
key = 'distribute'
class Sort(Order):
2587class Sort(Order):
2588    pass
key = 'sort'
class Ordered(Expression):
2591class Ordered(Expression):
2592    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):
2595class Property(Expression):
2596    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2599class GrantPrivilege(Expression):
2600    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2603class GrantPrincipal(Expression):
2604    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2607class AllowedValuesProperty(Expression):
2608    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2611class AlgorithmProperty(Property):
2612    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2615class AutoIncrementProperty(Property):
2616    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2620class AutoRefreshProperty(Property):
2621    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2624class BackupProperty(Property):
2625    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2628class BlockCompressionProperty(Property):
2629    arg_types = {
2630        "autotemp": False,
2631        "always": False,
2632        "default": False,
2633        "manual": False,
2634        "never": False,
2635    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2638class CharacterSetProperty(Property):
2639    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2642class ChecksumProperty(Property):
2643    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2646class CollateProperty(Property):
2647    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2650class CopyGrantsProperty(Property):
2651    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2654class DataBlocksizeProperty(Property):
2655    arg_types = {
2656        "size": False,
2657        "units": False,
2658        "minimum": False,
2659        "maximum": False,
2660        "default": False,
2661    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2664class DataDeletionProperty(Property):
2665    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):
2668class DefinerProperty(Property):
2669    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2672class DistKeyProperty(Property):
2673    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2678class DistributedByProperty(Property):
2679    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):
2682class DistStyleProperty(Property):
2683    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2686class DuplicateKeyProperty(Property):
2687    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2690class EngineProperty(Property):
2691    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2694class HeapProperty(Property):
2695    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2698class ToTableProperty(Property):
2699    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2702class ExecuteAsProperty(Property):
2703    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2706class ExternalProperty(Property):
2707    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2710class FallbackProperty(Property):
2711    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2714class FileFormatProperty(Property):
2715    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2718class FreespaceProperty(Property):
2719    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2722class GlobalProperty(Property):
2723    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2726class IcebergProperty(Property):
2727    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2730class InheritsProperty(Property):
2731    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2734class InputModelProperty(Property):
2735    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2738class OutputModelProperty(Property):
2739    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2742class IsolatedLoadingProperty(Property):
2743    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2746class JournalProperty(Property):
2747    arg_types = {
2748        "no": False,
2749        "dual": False,
2750        "before": False,
2751        "local": False,
2752        "after": False,
2753    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2756class LanguageProperty(Property):
2757    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2761class ClusteredByProperty(Property):
2762    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2765class DictProperty(Property):
2766    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2769class DictSubProperty(Property):
2770    pass
key = 'dictsubproperty'
class DictRange(Property):
2773class DictRange(Property):
2774    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2777class DynamicProperty(Property):
2778    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2783class OnCluster(Property):
2784    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2788class EmptyProperty(Property):
2789    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2792class LikeProperty(Property):
2793    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2796class LocationProperty(Property):
2797    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2800class LockProperty(Property):
2801    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2804class LockingProperty(Property):
2805    arg_types = {
2806        "this": False,
2807        "kind": True,
2808        "for_or_in": False,
2809        "lock_type": True,
2810        "override": False,
2811    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2814class LogProperty(Property):
2815    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2818class MaterializedProperty(Property):
2819    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2822class MergeBlockRatioProperty(Property):
2823    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):
2826class NoPrimaryIndexProperty(Property):
2827    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2830class OnProperty(Property):
2831    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2834class OnCommitProperty(Property):
2835    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2838class PartitionedByProperty(Property):
2839    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2843class PartitionBoundSpec(Expression):
2844    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2845    arg_types = {
2846        "this": False,
2847        "expression": False,
2848        "from_expressions": False,
2849        "to_expressions": False,
2850    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2853class PartitionedOfProperty(Property):
2854    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2855    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2858class StreamingTableProperty(Property):
2859    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2862class RemoteWithConnectionModelProperty(Property):
2863    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2866class ReturnsProperty(Property):
2867    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):
2870class StrictProperty(Property):
2871    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2874class RowFormatProperty(Property):
2875    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2878class RowFormatDelimitedProperty(Property):
2879    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2880    arg_types = {
2881        "fields": False,
2882        "escaped": False,
2883        "collection_items": False,
2884        "map_keys": False,
2885        "lines": False,
2886        "null": False,
2887        "serde": False,
2888    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2891class RowFormatSerdeProperty(Property):
2892    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2896class QueryTransform(Expression):
2897    arg_types = {
2898        "expressions": True,
2899        "command_script": True,
2900        "schema": False,
2901        "row_format_before": False,
2902        "record_writer": False,
2903        "row_format_after": False,
2904        "record_reader": False,
2905    }
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):
2908class SampleProperty(Property):
2909    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2913class SecurityProperty(Property):
2914    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2917class SchemaCommentProperty(Property):
2918    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2921class SerdeProperties(Property):
2922    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2925class SetProperty(Property):
2926    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2929class SharingProperty(Property):
2930    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2933class SetConfigProperty(Property):
2934    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2937class SettingsProperty(Property):
2938    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2941class SortKeyProperty(Property):
2942    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2945class SqlReadWriteProperty(Property):
2946    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2949class SqlSecurityProperty(Property):
2950    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2953class StabilityProperty(Property):
2954    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2957class TemporaryProperty(Property):
2958    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2961class SecureProperty(Property):
2962    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2965class TransformModelProperty(Property):
2966    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2969class TransientProperty(Property):
2970    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2973class UnloggedProperty(Property):
2974    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2978class ViewAttributeProperty(Property):
2979    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2982class VolatileProperty(Property):
2983    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2986class WithDataProperty(Property):
2987    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2990class WithJournalTableProperty(Property):
2991    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2994class WithSchemaBindingProperty(Property):
2995    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2998class WithSystemVersioningProperty(Property):
2999    arg_types = {
3000        "on": False,
3001        "this": False,
3002        "data_consistency": False,
3003        "retention_period": False,
3004        "with": True,
3005    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3008class WithProcedureOptions(Property):
3009    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class Properties(Expression):
3012class Properties(Expression):
3013    arg_types = {"expressions": True}
3014
3015    NAME_TO_PROPERTY = {
3016        "ALGORITHM": AlgorithmProperty,
3017        "AUTO_INCREMENT": AutoIncrementProperty,
3018        "CHARACTER SET": CharacterSetProperty,
3019        "CLUSTERED_BY": ClusteredByProperty,
3020        "COLLATE": CollateProperty,
3021        "COMMENT": SchemaCommentProperty,
3022        "DEFINER": DefinerProperty,
3023        "DISTKEY": DistKeyProperty,
3024        "DISTRIBUTED_BY": DistributedByProperty,
3025        "DISTSTYLE": DistStyleProperty,
3026        "ENGINE": EngineProperty,
3027        "EXECUTE AS": ExecuteAsProperty,
3028        "FORMAT": FileFormatProperty,
3029        "LANGUAGE": LanguageProperty,
3030        "LOCATION": LocationProperty,
3031        "LOCK": LockProperty,
3032        "PARTITIONED_BY": PartitionedByProperty,
3033        "RETURNS": ReturnsProperty,
3034        "ROW_FORMAT": RowFormatProperty,
3035        "SORTKEY": SortKeyProperty,
3036    }
3037
3038    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3039
3040    # CREATE property locations
3041    # Form: schema specified
3042    #   create [POST_CREATE]
3043    #     table a [POST_NAME]
3044    #     (b int) [POST_SCHEMA]
3045    #     with ([POST_WITH])
3046    #     index (b) [POST_INDEX]
3047    #
3048    # Form: alias selection
3049    #   create [POST_CREATE]
3050    #     table a [POST_NAME]
3051    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3052    #     index (c) [POST_INDEX]
3053    class Location(AutoName):
3054        POST_CREATE = auto()
3055        POST_NAME = auto()
3056        POST_SCHEMA = auto()
3057        POST_WITH = auto()
3058        POST_ALIAS = auto()
3059        POST_EXPRESSION = auto()
3060        POST_INDEX = auto()
3061        UNSUPPORTED = auto()
3062
3063    @classmethod
3064    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3065        expressions = []
3066        for key, value in properties_dict.items():
3067            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3068            if property_cls:
3069                expressions.append(property_cls(this=convert(value)))
3070            else:
3071                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3072
3073        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:
3063    @classmethod
3064    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3065        expressions = []
3066        for key, value in properties_dict.items():
3067            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3068            if property_cls:
3069                expressions.append(property_cls(this=convert(value)))
3070            else:
3071                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3072
3073        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3053    class Location(AutoName):
3054        POST_CREATE = auto()
3055        POST_NAME = auto()
3056        POST_SCHEMA = auto()
3057        POST_WITH = auto()
3058        POST_ALIAS = auto()
3059        POST_EXPRESSION = auto()
3060        POST_INDEX = auto()
3061        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):
3076class Qualify(Expression):
3077    pass
key = 'qualify'
class InputOutputFormat(Expression):
3080class InputOutputFormat(Expression):
3081    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3085class Return(Expression):
3086    pass
key = 'return'
class Reference(Expression):
3089class Reference(Expression):
3090    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3093class Tuple(Expression):
3094    arg_types = {"expressions": False}
3095
3096    def isin(
3097        self,
3098        *expressions: t.Any,
3099        query: t.Optional[ExpOrStr] = None,
3100        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3101        copy: bool = True,
3102        **opts,
3103    ) -> In:
3104        return In(
3105            this=maybe_copy(self, copy),
3106            expressions=[convert(e, copy=copy) for e in expressions],
3107            query=maybe_parse(query, copy=copy, **opts) if query else None,
3108            unnest=(
3109                Unnest(
3110                    expressions=[
3111                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3112                        for e in ensure_list(unnest)
3113                    ]
3114                )
3115                if unnest
3116                else None
3117            ),
3118        )
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:
3096    def isin(
3097        self,
3098        *expressions: t.Any,
3099        query: t.Optional[ExpOrStr] = None,
3100        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3101        copy: bool = True,
3102        **opts,
3103    ) -> In:
3104        return In(
3105            this=maybe_copy(self, copy),
3106            expressions=[convert(e, copy=copy) for e in expressions],
3107            query=maybe_parse(query, copy=copy, **opts) if query else None,
3108            unnest=(
3109                Unnest(
3110                    expressions=[
3111                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3112                        for e in ensure_list(unnest)
3113                    ]
3114                )
3115                if unnest
3116                else None
3117            ),
3118        )
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):
3149class QueryOption(Expression):
3150    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3154class WithTableHint(Expression):
3155    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3159class IndexTableHint(Expression):
3160    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3164class HistoricalData(Expression):
3165    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3168class Table(Expression):
3169    arg_types = {
3170        "this": False,
3171        "alias": False,
3172        "db": False,
3173        "catalog": False,
3174        "laterals": False,
3175        "joins": False,
3176        "pivots": False,
3177        "hints": False,
3178        "system_time": False,
3179        "version": False,
3180        "format": False,
3181        "pattern": False,
3182        "ordinality": False,
3183        "when": False,
3184        "only": False,
3185        "partition": False,
3186        "changes": False,
3187        "rows_from": False,
3188        "sample": False,
3189    }
3190
3191    @property
3192    def name(self) -> str:
3193        if isinstance(self.this, Func):
3194            return ""
3195        return self.this.name
3196
3197    @property
3198    def db(self) -> str:
3199        return self.text("db")
3200
3201    @property
3202    def catalog(self) -> str:
3203        return self.text("catalog")
3204
3205    @property
3206    def selects(self) -> t.List[Expression]:
3207        return []
3208
3209    @property
3210    def named_selects(self) -> t.List[str]:
3211        return []
3212
3213    @property
3214    def parts(self) -> t.List[Expression]:
3215        """Return the parts of a table in order catalog, db, table."""
3216        parts: t.List[Expression] = []
3217
3218        for arg in ("catalog", "db", "this"):
3219            part = self.args.get(arg)
3220
3221            if isinstance(part, Dot):
3222                parts.extend(part.flatten())
3223            elif isinstance(part, Expression):
3224                parts.append(part)
3225
3226        return parts
3227
3228    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3229        parts = self.parts
3230        last_part = parts[-1]
3231
3232        if isinstance(last_part, Identifier):
3233            col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3234        else:
3235            # This branch will be reached if a function or array is wrapped in a `Table`
3236            col = last_part
3237
3238        alias = self.args.get("alias")
3239        if alias:
3240            col = alias_(col, alias.this, copy=copy)
3241
3242        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
3191    @property
3192    def name(self) -> str:
3193        if isinstance(self.this, Func):
3194            return ""
3195        return self.this.name
db: str
3197    @property
3198    def db(self) -> str:
3199        return self.text("db")
catalog: str
3201    @property
3202    def catalog(self) -> str:
3203        return self.text("catalog")
selects: List[Expression]
3205    @property
3206    def selects(self) -> t.List[Expression]:
3207        return []
named_selects: List[str]
3209    @property
3210    def named_selects(self) -> t.List[str]:
3211        return []
parts: List[Expression]
3213    @property
3214    def parts(self) -> t.List[Expression]:
3215        """Return the parts of a table in order catalog, db, table."""
3216        parts: t.List[Expression] = []
3217
3218        for arg in ("catalog", "db", "this"):
3219            part = self.args.get(arg)
3220
3221            if isinstance(part, Dot):
3222                parts.extend(part.flatten())
3223            elif isinstance(part, Expression):
3224                parts.append(part)
3225
3226        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3228    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3229        parts = self.parts
3230        last_part = parts[-1]
3231
3232        if isinstance(last_part, Identifier):
3233            col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3234        else:
3235            # This branch will be reached if a function or array is wrapped in a `Table`
3236            col = last_part
3237
3238        alias = self.args.get("alias")
3239        if alias:
3240            col = alias_(col, alias.this, copy=copy)
3241
3242        return col
key = 'table'
class SetOperation(Query):
3245class SetOperation(Query):
3246    arg_types = {
3247        "with": False,
3248        "this": True,
3249        "expression": True,
3250        "distinct": False,
3251        "by_name": False,
3252        **QUERY_MODIFIERS,
3253    }
3254
3255    def select(
3256        self: S,
3257        *expressions: t.Optional[ExpOrStr],
3258        append: bool = True,
3259        dialect: DialectType = None,
3260        copy: bool = True,
3261        **opts,
3262    ) -> S:
3263        this = maybe_copy(self, copy)
3264        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3265        this.expression.unnest().select(
3266            *expressions, append=append, dialect=dialect, copy=False, **opts
3267        )
3268        return this
3269
3270    @property
3271    def named_selects(self) -> t.List[str]:
3272        return self.this.unnest().named_selects
3273
3274    @property
3275    def is_star(self) -> bool:
3276        return self.this.is_star or self.expression.is_star
3277
3278    @property
3279    def selects(self) -> t.List[Expression]:
3280        return self.this.unnest().selects
3281
3282    @property
3283    def left(self) -> Query:
3284        return self.this
3285
3286    @property
3287    def right(self) -> Query:
3288        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:
3255    def select(
3256        self: S,
3257        *expressions: t.Optional[ExpOrStr],
3258        append: bool = True,
3259        dialect: DialectType = None,
3260        copy: bool = True,
3261        **opts,
3262    ) -> S:
3263        this = maybe_copy(self, copy)
3264        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3265        this.expression.unnest().select(
3266            *expressions, append=append, dialect=dialect, copy=False, **opts
3267        )
3268        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]
3270    @property
3271    def named_selects(self) -> t.List[str]:
3272        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3274    @property
3275    def is_star(self) -> bool:
3276        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3278    @property
3279    def selects(self) -> t.List[Expression]:
3280        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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:
3711    def select(
3712        self,
3713        *expressions: t.Optional[ExpOrStr],
3714        append: bool = True,
3715        dialect: DialectType = None,
3716        copy: bool = True,
3717        **opts,
3718    ) -> Select:
3719        return _apply_list_builder(
3720            *expressions,
3721            instance=self,
3722            arg="expressions",
3723            append=append,
3724            dialect=dialect,
3725            into=Expression,
3726            copy=copy,
3727            **opts,
3728        )

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

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

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

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

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:
3945    def window(
3946        self,
3947        *expressions: t.Optional[ExpOrStr],
3948        append: bool = True,
3949        dialect: DialectType = None,
3950        copy: bool = True,
3951        **opts,
3952    ) -> Select:
3953        return _apply_list_builder(
3954            *expressions,
3955            instance=self,
3956            arg="windows",
3957            append=append,
3958            into=Window,
3959            dialect=dialect,
3960            copy=copy,
3961            **opts,
3962        )
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:
3964    def qualify(
3965        self,
3966        *expressions: t.Optional[ExpOrStr],
3967        append: bool = True,
3968        dialect: DialectType = None,
3969        copy: bool = True,
3970        **opts,
3971    ) -> Select:
3972        return _apply_conjunction_builder(
3973            *expressions,
3974            instance=self,
3975            arg="qualify",
3976            append=append,
3977            into=Qualify,
3978            dialect=dialect,
3979            copy=copy,
3980            **opts,
3981        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3983    def distinct(
3984        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3985    ) -> Select:
3986        """
3987        Set the OFFSET expression.
3988
3989        Example:
3990            >>> Select().from_("tbl").select("x").distinct().sql()
3991            'SELECT DISTINCT x FROM tbl'
3992
3993        Args:
3994            ons: the expressions to distinct on
3995            distinct: whether the Select should be distinct
3996            copy: if `False`, modify this expression instance in-place.
3997
3998        Returns:
3999            Select: the modified expression.
4000        """
4001        instance = maybe_copy(self, copy)
4002        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4003        instance.set("distinct", Distinct(on=on) if distinct else None)
4004        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:
4006    def ctas(
4007        self,
4008        table: ExpOrStr,
4009        properties: t.Optional[t.Dict] = None,
4010        dialect: DialectType = None,
4011        copy: bool = True,
4012        **opts,
4013    ) -> Create:
4014        """
4015        Convert this expression to a CREATE TABLE AS statement.
4016
4017        Example:
4018            >>> Select().select("*").from_("tbl").ctas("x").sql()
4019            'CREATE TABLE x AS SELECT * FROM tbl'
4020
4021        Args:
4022            table: the SQL code string to parse as the table name.
4023                If another `Expression` instance is passed, it will be used as-is.
4024            properties: an optional mapping of table properties
4025            dialect: the dialect used to parse the input table.
4026            copy: if `False`, modify this expression instance in-place.
4027            opts: other options to use to parse the input table.
4028
4029        Returns:
4030            The new Create expression.
4031        """
4032        instance = maybe_copy(self, copy)
4033        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4034
4035        properties_expression = None
4036        if properties:
4037            properties_expression = Properties.from_dict(properties)
4038
4039        return Create(
4040            this=table_expression,
4041            kind="TABLE",
4042            expression=instance,
4043            properties=properties_expression,
4044        )

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:
4046    def lock(self, update: bool = True, copy: bool = True) -> Select:
4047        """
4048        Set the locking read mode for this expression.
4049
4050        Examples:
4051            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4052            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4053
4054            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4055            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4056
4057        Args:
4058            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4059            copy: if `False`, modify this expression instance in-place.
4060
4061        Returns:
4062            The modified expression.
4063        """
4064        inst = maybe_copy(self, copy)
4065        inst.set("locks", [Lock(update=update)])
4066
4067        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:
4069    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4070        """
4071        Set hints for this expression.
4072
4073        Examples:
4074            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4075            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4076
4077        Args:
4078            hints: The SQL code strings to parse as the hints.
4079                If an `Expression` instance is passed, it will be used as-is.
4080            dialect: The dialect used to parse the hints.
4081            copy: If `False`, modify this expression instance in-place.
4082
4083        Returns:
4084            The modified expression.
4085        """
4086        inst = maybe_copy(self, copy)
4087        inst.set(
4088            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4089        )
4090
4091        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]
4093    @property
4094    def named_selects(self) -> t.List[str]:
4095        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
4097    @property
4098    def is_star(self) -> bool:
4099        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4101    @property
4102    def selects(self) -> t.List[Expression]:
4103        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
4124    def unwrap(self) -> Subquery:
4125        expression = self
4126        while expression.same_parent and expression.is_wrapper:
4127            expression = t.cast(Subquery, expression.parent)
4128        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:
4130    def select(
4131        self,
4132        *expressions: t.Optional[ExpOrStr],
4133        append: bool = True,
4134        dialect: DialectType = None,
4135        copy: bool = True,
4136        **opts,
4137    ) -> Subquery:
4138        this = maybe_copy(self, copy)
4139        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4140        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
4142    @property
4143    def is_wrapper(self) -> bool:
4144        """
4145        Whether this Subquery acts as a simple wrapper around another expression.
4146
4147        SELECT * FROM (((SELECT * FROM t)))
4148                      ^
4149                      This corresponds to a "wrapper" Subquery node
4150        """
4151        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
4153    @property
4154    def is_star(self) -> bool:
4155        return self.this.is_star

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4188class Pivot(Expression):
4189    arg_types = {
4190        "this": False,
4191        "alias": False,
4192        "expressions": False,
4193        "field": False,
4194        "unpivot": False,
4195        "using": False,
4196        "group": False,
4197        "columns": False,
4198        "include_nulls": False,
4199        "default_on_null": False,
4200    }
4201
4202    @property
4203    def unpivot(self) -> bool:
4204        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
4202    @property
4203    def unpivot(self) -> bool:
4204        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
4207class Window(Condition):
4208    arg_types = {
4209        "this": True,
4210        "partition_by": False,
4211        "order": False,
4212        "spec": False,
4213        "alias": False,
4214        "over": False,
4215        "first": False,
4216    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4219class WindowSpec(Expression):
4220    arg_types = {
4221        "kind": False,
4222        "start": False,
4223        "start_side": False,
4224        "end": False,
4225        "end_side": False,
4226    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4229class PreWhere(Expression):
4230    pass
key = 'prewhere'
class Where(Expression):
4233class Where(Expression):
4234    pass
key = 'where'
class Star(Expression):
4237class Star(Expression):
4238    arg_types = {"except": False, "replace": False, "rename": False}
4239
4240    @property
4241    def name(self) -> str:
4242        return "*"
4243
4244    @property
4245    def output_name(self) -> str:
4246        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4240    @property
4241    def name(self) -> str:
4242        return "*"
output_name: str
4244    @property
4245    def output_name(self) -> str:
4246        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):
4249class Parameter(Condition):
4250    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4253class SessionParameter(Condition):
4254    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4257class Placeholder(Condition):
4258    arg_types = {"this": False, "kind": False}
4259
4260    @property
4261    def name(self) -> str:
4262        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4260    @property
4261    def name(self) -> str:
4262        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4265class Null(Condition):
4266    arg_types: t.Dict[str, t.Any] = {}
4267
4268    @property
4269    def name(self) -> str:
4270        return "NULL"
4271
4272    def to_py(self) -> Lit[None]:
4273        return None
arg_types: Dict[str, Any] = {}
name: str
4268    @property
4269    def name(self) -> str:
4270        return "NULL"
def to_py(self) -> Literal[None]:
4272    def to_py(self) -> Lit[None]:
4273        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4276class Boolean(Condition):
4277    def to_py(self) -> bool:
4278        return self.this
def to_py(self) -> bool:
4277    def to_py(self) -> bool:
4278        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4765class DPipe(Binary):
4766    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4769class EQ(Binary, Predicate):
4770    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4773class NullSafeEQ(Binary, Predicate):
4774    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4777class NullSafeNEQ(Binary, Predicate):
4778    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4782class PropertyEQ(Binary):
4783    pass
key = 'propertyeq'
class Distance(Binary):
4786class Distance(Binary):
4787    pass
key = 'distance'
class Escape(Binary):
4790class Escape(Binary):
4791    pass
key = 'escape'
class Glob(Binary, Predicate):
4794class Glob(Binary, Predicate):
4795    pass
key = 'glob'
class GT(Binary, Predicate):
4798class GT(Binary, Predicate):
4799    pass
key = 'gt'
class GTE(Binary, Predicate):
4802class GTE(Binary, Predicate):
4803    pass
key = 'gte'
class ILike(Binary, Predicate):
4806class ILike(Binary, Predicate):
4807    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4810class ILikeAny(Binary, Predicate):
4811    pass
key = 'ilikeany'
class IntDiv(Binary):
4814class IntDiv(Binary):
4815    pass
key = 'intdiv'
class Is(Binary, Predicate):
4818class Is(Binary, Predicate):
4819    pass
key = 'is'
class Kwarg(Binary):
4822class Kwarg(Binary):
4823    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4826class Like(Binary, Predicate):
4827    pass
key = 'like'
class LikeAny(Binary, Predicate):
4830class LikeAny(Binary, Predicate):
4831    pass
key = 'likeany'
class LT(Binary, Predicate):
4834class LT(Binary, Predicate):
4835    pass
key = 'lt'
class LTE(Binary, Predicate):
4838class LTE(Binary, Predicate):
4839    pass
key = 'lte'
class Mod(Binary):
4842class Mod(Binary):
4843    pass
key = 'mod'
class Mul(Binary):
4846class Mul(Binary):
4847    pass
key = 'mul'
class NEQ(Binary, Predicate):
4850class NEQ(Binary, Predicate):
4851    pass
key = 'neq'
class Operator(Binary):
4855class Operator(Binary):
4856    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4859class SimilarTo(Binary, Predicate):
4860    pass
key = 'similarto'
class Slice(Binary):
4863class Slice(Binary):
4864    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4867class Sub(Binary):
4868    pass
key = 'sub'
class Unary(Condition):
4873class Unary(Condition):
4874    pass
key = 'unary'
class BitwiseNot(Unary):
4877class BitwiseNot(Unary):
4878    pass
key = 'bitwisenot'
class Not(Unary):
4881class Not(Unary):
4882    pass
key = 'not'
class Paren(Unary):
4885class Paren(Unary):
4886    @property
4887    def output_name(self) -> str:
4888        return self.this.name
output_name: str
4886    @property
4887    def output_name(self) -> str:
4888        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):
4891class Neg(Unary):
4892    def to_py(self) -> int | Decimal:
4893        if self.is_number:
4894            return self.this.to_py() * -1
4895        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4892    def to_py(self) -> int | Decimal:
4893        if self.is_number:
4894            return self.this.to_py() * -1
4895        return super().to_py()

Returns a Python object equivalent of the SQL node.

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

Automatically converts unit arg into a var.

TimeUnit(**args)
5001    def __init__(self, **args):
5002        unit = args.get("unit")
5003        if isinstance(unit, self.VAR_LIKE):
5004            args["unit"] = Var(
5005                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5006            )
5007        elif isinstance(unit, Week):
5008            unit.set("this", Var(this=unit.this.name.upper()))
5009
5010        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]
5012    @property
5013    def unit(self) -> t.Optional[Var | IntervalSpan]:
5014        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5017class IntervalOp(TimeUnit):
5018    arg_types = {"unit": False, "expression": True}
5019
5020    def interval(self):
5021        return Interval(
5022            this=self.expression.copy(),
5023            unit=self.unit.copy() if self.unit else None,
5024        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5020    def interval(self):
5021        return Interval(
5022            this=self.expression.copy(),
5023            unit=self.unit.copy() if self.unit else None,
5024        )
key = 'intervalop'
class IntervalSpan(DataType):
5030class IntervalSpan(DataType):
5031    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5034class Interval(TimeUnit):
5035    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5038class IgnoreNulls(Expression):
5039    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5042class RespectNulls(Expression):
5043    pass
key = 'respectnulls'
class HavingMax(Expression):
5047class HavingMax(Expression):
5048    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5052class Func(Condition):
5053    """
5054    The base class for all function expressions.
5055
5056    Attributes:
5057        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5058            treated as a variable length argument and the argument's value will be stored as a list.
5059        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5060            function expression. These values are used to map this node to a name during parsing as
5061            well as to provide the function's name during SQL string generation. By default the SQL
5062            name is set to the expression's class name transformed to snake case.
5063    """
5064
5065    is_var_len_args = False
5066
5067    @classmethod
5068    def from_arg_list(cls, args):
5069        if cls.is_var_len_args:
5070            all_arg_keys = list(cls.arg_types)
5071            # If this function supports variable length argument treat the last argument as such.
5072            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5073            num_non_var = len(non_var_len_arg_keys)
5074
5075            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5076            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5077        else:
5078            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5079
5080        return cls(**args_dict)
5081
5082    @classmethod
5083    def sql_names(cls):
5084        if cls is Func:
5085            raise NotImplementedError(
5086                "SQL name is only supported by concrete function implementations"
5087            )
5088        if "_sql_names" not in cls.__dict__:
5089            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5090        return cls._sql_names
5091
5092    @classmethod
5093    def sql_name(cls):
5094        return cls.sql_names()[0]
5095
5096    @classmethod
5097    def default_parser_mappings(cls):
5098        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):
5067    @classmethod
5068    def from_arg_list(cls, args):
5069        if cls.is_var_len_args:
5070            all_arg_keys = list(cls.arg_types)
5071            # If this function supports variable length argument treat the last argument as such.
5072            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5073            num_non_var = len(non_var_len_arg_keys)
5074
5075            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5076            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5077        else:
5078            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5079
5080        return cls(**args_dict)
@classmethod
def sql_names(cls):
5082    @classmethod
5083    def sql_names(cls):
5084        if cls is Func:
5085            raise NotImplementedError(
5086                "SQL name is only supported by concrete function implementations"
5087            )
5088        if "_sql_names" not in cls.__dict__:
5089            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5090        return cls._sql_names
@classmethod
def sql_name(cls):
5092    @classmethod
5093    def sql_name(cls):
5094        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5096    @classmethod
5097    def default_parser_mappings(cls):
5098        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5101class AggFunc(Func):
5102    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5105class ParameterizedAgg(AggFunc):
5106    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5109class Abs(Func):
5110    pass
key = 'abs'
class ArgMax(AggFunc):
5113class ArgMax(AggFunc):
5114    arg_types = {"this": True, "expression": True, "count": False}
5115    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5118class ArgMin(AggFunc):
5119    arg_types = {"this": True, "expression": True, "count": False}
5120    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5123class ApproxTopK(AggFunc):
5124    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5127class Flatten(Func):
5128    pass
key = 'flatten'
class Transform(Func):
5132class Transform(Func):
5133    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5136class Anonymous(Func):
5137    arg_types = {"this": True, "expressions": False}
5138    is_var_len_args = True
5139
5140    @property
5141    def name(self) -> str:
5142        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
5140    @property
5141    def name(self) -> str:
5142        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5145class AnonymousAggFunc(AggFunc):
5146    arg_types = {"this": True, "expressions": False}
5147    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5151class CombinedAggFunc(AnonymousAggFunc):
5152    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5155class CombinedParameterizedAgg(ParameterizedAgg):
5156    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):
5161class Hll(AggFunc):
5162    arg_types = {"this": True, "expressions": False}
5163    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5166class ApproxDistinct(AggFunc):
5167    arg_types = {"this": True, "accuracy": False}
5168    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5171class Apply(Func):
5172    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5175class Array(Func):
5176    arg_types = {"expressions": False, "bracket_notation": False}
5177    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5181class ToArray(Func):
5182    pass
key = 'toarray'
class List(Func):
5186class List(Func):
5187    arg_types = {"expressions": False}
5188    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5192class Pad(Func):
5193    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):
5198class ToChar(Func):
5199    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5204class ToNumber(Func):
5205    arg_types = {
5206        "this": True,
5207        "format": False,
5208        "nlsparam": False,
5209        "precision": False,
5210        "scale": False,
5211    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5215class ToDouble(Func):
5216    arg_types = {
5217        "this": True,
5218        "format": False,
5219    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5222class Columns(Func):
5223    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5227class Convert(Func):
5228    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5231class ConvertTimezone(Func):
5232    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):
5235class GenerateSeries(Func):
5236    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):
5242class ExplodingGenerateSeries(GenerateSeries):
5243    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5246class ArrayAgg(AggFunc):
5247    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5250class ArrayUniqueAgg(AggFunc):
5251    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5254class ArrayAll(Func):
5255    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5259class ArrayAny(Func):
5260    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5263class ArrayConcat(Func):
5264    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5265    arg_types = {"this": True, "expressions": False}
5266    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5269class ArrayConstructCompact(Func):
5270    arg_types = {"expressions": True}
5271    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5274class ArrayContains(Binary, Func):
5275    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5278class ArrayContainsAll(Binary, Func):
5279    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5282class ArrayFilter(Func):
5283    arg_types = {"this": True, "expression": True}
5284    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5287class ArrayToString(Func):
5288    arg_types = {"this": True, "expression": True, "null": False}
5289    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5293class String(Func):
5294    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5297class StringToArray(Func):
5298    arg_types = {"this": True, "expression": True, "null": False}
5299    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5302class ArrayOverlaps(Binary, Func):
5303    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5306class ArraySize(Func):
5307    arg_types = {"this": True, "expression": False}
5308    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5311class ArraySort(Func):
5312    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5315class ArraySum(Func):
5316    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5319class ArrayUnionAgg(AggFunc):
5320    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5323class Avg(AggFunc):
5324    pass
key = 'avg'
class AnyValue(AggFunc):
5327class AnyValue(AggFunc):
5328    pass
key = 'anyvalue'
class Lag(AggFunc):
5331class Lag(AggFunc):
5332    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5335class Lead(AggFunc):
5336    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5341class First(AggFunc):
5342    pass
key = 'first'
class Last(AggFunc):
5345class Last(AggFunc):
5346    pass
key = 'last'
class FirstValue(AggFunc):
5349class FirstValue(AggFunc):
5350    pass
key = 'firstvalue'
class LastValue(AggFunc):
5353class LastValue(AggFunc):
5354    pass
key = 'lastvalue'
class NthValue(AggFunc):
5357class NthValue(AggFunc):
5358    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5361class Case(Func):
5362    arg_types = {"this": False, "ifs": True, "default": False}
5363
5364    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5365        instance = maybe_copy(self, copy)
5366        instance.append(
5367            "ifs",
5368            If(
5369                this=maybe_parse(condition, copy=copy, **opts),
5370                true=maybe_parse(then, copy=copy, **opts),
5371            ),
5372        )
5373        return instance
5374
5375    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5376        instance = maybe_copy(self, copy)
5377        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5378        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:
5364    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5365        instance = maybe_copy(self, copy)
5366        instance.append(
5367            "ifs",
5368            If(
5369                this=maybe_parse(condition, copy=copy, **opts),
5370                true=maybe_parse(then, copy=copy, **opts),
5371            ),
5372        )
5373        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5375    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5376        instance = maybe_copy(self, copy)
5377        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5378        return instance
key = 'case'
class Cast(Func):
5381class Cast(Func):
5382    arg_types = {
5383        "this": True,
5384        "to": True,
5385        "format": False,
5386        "safe": False,
5387        "action": False,
5388    }
5389
5390    @property
5391    def name(self) -> str:
5392        return self.this.name
5393
5394    @property
5395    def to(self) -> DataType:
5396        return self.args["to"]
5397
5398    @property
5399    def output_name(self) -> str:
5400        return self.name
5401
5402    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5403        """
5404        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5405        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5406        array<int> != array<float>.
5407
5408        Args:
5409            dtypes: the data types to compare this Cast's DataType to.
5410
5411        Returns:
5412            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5413        """
5414        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5390    @property
5391    def name(self) -> str:
5392        return self.this.name
to: DataType
5394    @property
5395    def to(self) -> DataType:
5396        return self.args["to"]
output_name: str
5398    @property
5399    def output_name(self) -> str:
5400        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:
5402    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5403        """
5404        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5405        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5406        array<int> != array<float>.
5407
5408        Args:
5409            dtypes: the data types to compare this Cast's DataType to.
5410
5411        Returns:
5412            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5413        """
5414        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):
5417class TryCast(Cast):
5418    pass
key = 'trycast'
class Try(Func):
5421class Try(Func):
5422    pass
key = 'try'
class CastToStrType(Func):
5425class CastToStrType(Func):
5426    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5429class Collate(Binary, Func):
5430    pass
key = 'collate'
class Ceil(Func):
5433class Ceil(Func):
5434    arg_types = {"this": True, "decimals": False}
5435    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5438class Coalesce(Func):
5439    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5440    is_var_len_args = True
5441    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5444class Chr(Func):
5445    arg_types = {"expressions": True, "charset": False}
5446    is_var_len_args = True
5447    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5450class Concat(Func):
5451    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5452    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5455class ConcatWs(Concat):
5456    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5460class ConnectByRoot(Func):
5461    pass
key = 'connectbyroot'
class Count(AggFunc):
5464class Count(AggFunc):
5465    arg_types = {"this": False, "expressions": False, "big_int": False}
5466    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5469class CountIf(AggFunc):
5470    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5474class Cbrt(Func):
5475    pass
key = 'cbrt'
class CurrentDate(Func):
5478class CurrentDate(Func):
5479    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5482class CurrentDatetime(Func):
5483    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5486class CurrentTime(Func):
5487    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5490class CurrentTimestamp(Func):
5491    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5494class CurrentUser(Func):
5495    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5498class DateAdd(Func, IntervalOp):
5499    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5502class DateSub(Func, IntervalOp):
5503    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5506class DateDiff(Func, TimeUnit):
5507    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5508    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5511class DateTrunc(Func):
5512    arg_types = {"unit": True, "this": True, "zone": False}
5513
5514    def __init__(self, **args):
5515        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5516        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5517        unabbreviate = args.pop("unabbreviate", True)
5518
5519        unit = args.get("unit")
5520        if isinstance(unit, TimeUnit.VAR_LIKE):
5521            unit_name = unit.name.upper()
5522            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5523                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5524
5525            args["unit"] = Literal.string(unit_name)
5526        elif isinstance(unit, Week):
5527            unit.set("this", Literal.string(unit.this.name.upper()))
5528
5529        super().__init__(**args)
5530
5531    @property
5532    def unit(self) -> Expression:
5533        return self.args["unit"]
DateTrunc(**args)
5514    def __init__(self, **args):
5515        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5516        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5517        unabbreviate = args.pop("unabbreviate", True)
5518
5519        unit = args.get("unit")
5520        if isinstance(unit, TimeUnit.VAR_LIKE):
5521            unit_name = unit.name.upper()
5522            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5523                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5524
5525            args["unit"] = Literal.string(unit_name)
5526        elif isinstance(unit, Week):
5527            unit.set("this", Literal.string(unit.this.name.upper()))
5528
5529        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5531    @property
5532    def unit(self) -> Expression:
5533        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5538class Datetime(Func):
5539    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5542class DatetimeAdd(Func, IntervalOp):
5543    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5546class DatetimeSub(Func, IntervalOp):
5547    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5550class DatetimeDiff(Func, TimeUnit):
5551    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5554class DatetimeTrunc(Func, TimeUnit):
5555    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5558class DayOfWeek(Func):
5559    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5564class DayOfWeekIso(Func):
5565    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5568class DayOfMonth(Func):
5569    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5572class DayOfYear(Func):
5573    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5576class ToDays(Func):
5577    pass
key = 'todays'
class WeekOfYear(Func):
5580class WeekOfYear(Func):
5581    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5584class MonthsBetween(Func):
5585    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5588class LastDay(Func, TimeUnit):
5589    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5590    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5593class Extract(Func):
5594    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5597class Exists(Func, SubqueryPredicate):
5598    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5601class Timestamp(Func):
5602    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5605class TimestampAdd(Func, TimeUnit):
5606    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5609class TimestampSub(Func, TimeUnit):
5610    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5613class TimestampDiff(Func, TimeUnit):
5614    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5615    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5618class TimestampTrunc(Func, TimeUnit):
5619    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5622class TimeAdd(Func, TimeUnit):
5623    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5626class TimeSub(Func, TimeUnit):
5627    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5630class TimeDiff(Func, TimeUnit):
5631    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5634class TimeTrunc(Func, TimeUnit):
5635    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5638class DateFromParts(Func):
5639    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5640    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5643class TimeFromParts(Func):
5644    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5645    arg_types = {
5646        "hour": True,
5647        "min": True,
5648        "sec": True,
5649        "nano": False,
5650        "fractions": False,
5651        "precision": False,
5652    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5655class DateStrToDate(Func):
5656    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5659class DateToDateStr(Func):
5660    pass
key = 'datetodatestr'
class DateToDi(Func):
5663class DateToDi(Func):
5664    pass
key = 'datetodi'
class Date(Func):
5668class Date(Func):
5669    arg_types = {"this": False, "zone": False, "expressions": False}
5670    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5673class Day(Func):
5674    pass
key = 'day'
class Decode(Func):
5677class Decode(Func):
5678    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5681class DiToDate(Func):
5682    pass
key = 'ditodate'
class Encode(Func):
5685class Encode(Func):
5686    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5689class Exp(Func):
5690    pass
key = 'exp'
class Explode(Func, UDTF):
5694class Explode(Func, UDTF):
5695    arg_types = {"this": True, "expressions": False}
5696    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5700class Inline(Func):
5701    pass
key = 'inline'
class ExplodeOuter(Explode):
5704class ExplodeOuter(Explode):
5705    pass
key = 'explodeouter'
class Posexplode(Explode):
5708class Posexplode(Explode):
5709    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5712class PosexplodeOuter(Posexplode, ExplodeOuter):
5713    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5716class Unnest(Func, UDTF):
5717    arg_types = {
5718        "expressions": True,
5719        "alias": False,
5720        "offset": False,
5721        "explode_array": False,
5722    }
5723
5724    @property
5725    def selects(self) -> t.List[Expression]:
5726        columns = super().selects
5727        offset = self.args.get("offset")
5728        if offset:
5729            columns = columns + [to_identifier("offset") if offset is True else offset]
5730        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5724    @property
5725    def selects(self) -> t.List[Expression]:
5726        columns = super().selects
5727        offset = self.args.get("offset")
5728        if offset:
5729            columns = columns + [to_identifier("offset") if offset is True else offset]
5730        return columns
key = 'unnest'
class Floor(Func):
5733class Floor(Func):
5734    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5737class FromBase64(Func):
5738    pass
key = 'frombase64'
class ToBase64(Func):
5741class ToBase64(Func):
5742    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5746class FromISO8601Timestamp(Func):
5747    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5750class GapFill(Func):
5751    arg_types = {
5752        "this": True,
5753        "ts_column": True,
5754        "bucket_width": True,
5755        "partitioning_columns": False,
5756        "value_columns": False,
5757        "origin": False,
5758        "ignore_nulls": False,
5759    }
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):
5763class GenerateDateArray(Func):
5764    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5768class GenerateTimestampArray(Func):
5769    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5772class Greatest(Func):
5773    arg_types = {"this": True, "expressions": False}
5774    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5779class OverflowTruncateBehavior(Expression):
5780    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5783class GroupConcat(AggFunc):
5784    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5787class Hex(Func):
5788    pass
key = 'hex'
class LowerHex(Hex):
5791class LowerHex(Hex):
5792    pass
key = 'lowerhex'
class Xor(Connector, Func):
5795class Xor(Connector, Func):
5796    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5799class If(Func):
5800    arg_types = {"this": True, "true": True, "false": False}
5801    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5804class Nullif(Func):
5805    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5808class Initcap(Func):
5809    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5812class IsNan(Func):
5813    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5816class IsInf(Func):
5817    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5821class JSON(Expression):
5822    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5825class JSONPath(Expression):
5826    arg_types = {"expressions": True, "escape": False}
5827
5828    @property
5829    def output_name(self) -> str:
5830        last_segment = self.expressions[-1].this
5831        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5828    @property
5829    def output_name(self) -> str:
5830        last_segment = self.expressions[-1].this
5831        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):
5834class JSONPathPart(Expression):
5835    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5838class JSONPathFilter(JSONPathPart):
5839    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5842class JSONPathKey(JSONPathPart):
5843    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5846class JSONPathRecursive(JSONPathPart):
5847    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5850class JSONPathRoot(JSONPathPart):
5851    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5854class JSONPathScript(JSONPathPart):
5855    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5858class JSONPathSlice(JSONPathPart):
5859    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5862class JSONPathSelector(JSONPathPart):
5863    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5866class JSONPathSubscript(JSONPathPart):
5867    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5870class JSONPathUnion(JSONPathPart):
5871    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5874class JSONPathWildcard(JSONPathPart):
5875    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5878class FormatJson(Expression):
5879    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5882class JSONKeyValue(Expression):
5883    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5886class JSONObject(Func):
5887    arg_types = {
5888        "expressions": False,
5889        "null_handling": False,
5890        "unique_keys": False,
5891        "return_type": False,
5892        "encoding": False,
5893    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5896class JSONObjectAgg(AggFunc):
5897    arg_types = {
5898        "expressions": False,
5899        "null_handling": False,
5900        "unique_keys": False,
5901        "return_type": False,
5902        "encoding": False,
5903    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5907class JSONArray(Func):
5908    arg_types = {
5909        "expressions": True,
5910        "null_handling": False,
5911        "return_type": False,
5912        "strict": False,
5913    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5917class JSONArrayAgg(Func):
5918    arg_types = {
5919        "this": True,
5920        "order": False,
5921        "null_handling": False,
5922        "return_type": False,
5923        "strict": False,
5924    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5927class JSONExists(Func):
5928    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):
5933class JSONColumnDef(Expression):
5934    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):
5937class JSONSchema(Expression):
5938    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5942class JSONValue(Expression):
5943    arg_types = {
5944        "this": True,
5945        "path": True,
5946        "returning": False,
5947        "on_condition": False,
5948    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
5951class JSONValueArray(Func):
5952    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
5956class JSONTable(Func):
5957    arg_types = {
5958        "this": True,
5959        "schema": True,
5960        "path": False,
5961        "error_handling": False,
5962        "empty_handling": False,
5963    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5967class ObjectInsert(Func):
5968    arg_types = {
5969        "this": True,
5970        "key": True,
5971        "value": True,
5972        "update_flag": False,
5973    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5976class OpenJSONColumnDef(Expression):
5977    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):
5980class OpenJSON(Func):
5981    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5984class JSONBContains(Binary, Func):
5985    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
5988class JSONBExists(Func):
5989    arg_types = {"this": True, "path": True}
5990    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
5993class JSONExtract(Binary, Func):
5994    arg_types = {
5995        "this": True,
5996        "expression": True,
5997        "only_json_types": False,
5998        "expressions": False,
5999        "variant_extract": False,
6000        "json_query": False,
6001        "option": False,
6002    }
6003    _sql_names = ["JSON_EXTRACT"]
6004    is_var_len_args = True
6005
6006    @property
6007    def output_name(self) -> str:
6008        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
6006    @property
6007    def output_name(self) -> str:
6008        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):
6011class JSONExtractArray(Func):
6012    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6015class JSONExtractScalar(Binary, Func):
6016    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6017    _sql_names = ["JSON_EXTRACT_SCALAR"]
6018    is_var_len_args = True
6019
6020    @property
6021    def output_name(self) -> str:
6022        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
6020    @property
6021    def output_name(self) -> str:
6022        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):
6025class JSONBExtract(Binary, Func):
6026    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6029class JSONBExtractScalar(Binary, Func):
6030    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6033class JSONFormat(Func):
6034    arg_types = {"this": False, "options": False}
6035    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6039class JSONArrayContains(Binary, Predicate, Func):
6040    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6043class ParseJSON(Func):
6044    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6045    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6046    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6047    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6050class Least(Func):
6051    arg_types = {"this": True, "expressions": False}
6052    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6055class Left(Func):
6056    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6063class Length(Func):
6064    arg_types = {"this": True, "binary": False}
6065    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
6068class Levenshtein(Func):
6069    arg_types = {
6070        "this": True,
6071        "expression": False,
6072        "ins_cost": False,
6073        "del_cost": False,
6074        "sub_cost": False,
6075        "max_dist": False,
6076    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6079class Ln(Func):
6080    pass
key = 'ln'
class Log(Func):
6083class Log(Func):
6084    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6087class LogicalOr(AggFunc):
6088    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6091class LogicalAnd(AggFunc):
6092    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6095class Lower(Func):
6096    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6099class Map(Func):
6100    arg_types = {"keys": False, "values": False}
6101
6102    @property
6103    def keys(self) -> t.List[Expression]:
6104        keys = self.args.get("keys")
6105        return keys.expressions if keys else []
6106
6107    @property
6108    def values(self) -> t.List[Expression]:
6109        values = self.args.get("values")
6110        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6102    @property
6103    def keys(self) -> t.List[Expression]:
6104        keys = self.args.get("keys")
6105        return keys.expressions if keys else []
values: List[Expression]
6107    @property
6108    def values(self) -> t.List[Expression]:
6109        values = self.args.get("values")
6110        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6114class ToMap(Func):
6115    pass
key = 'tomap'
class MapFromEntries(Func):
6118class MapFromEntries(Func):
6119    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6123class ScopeResolution(Expression):
6124    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6127class Stream(Expression):
6128    pass
key = 'stream'
class StarMap(Func):
6131class StarMap(Func):
6132    pass
key = 'starmap'
class VarMap(Func):
6135class VarMap(Func):
6136    arg_types = {"keys": True, "values": True}
6137    is_var_len_args = True
6138
6139    @property
6140    def keys(self) -> t.List[Expression]:
6141        return self.args["keys"].expressions
6142
6143    @property
6144    def values(self) -> t.List[Expression]:
6145        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6139    @property
6140    def keys(self) -> t.List[Expression]:
6141        return self.args["keys"].expressions
values: List[Expression]
6143    @property
6144    def values(self) -> t.List[Expression]:
6145        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6149class MatchAgainst(Func):
6150    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6153class Max(AggFunc):
6154    arg_types = {"this": True, "expressions": False}
6155    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6158class MD5(Func):
6159    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6163class MD5Digest(Func):
6164    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6167class Median(AggFunc):
6168    pass
key = 'median'
class Min(AggFunc):
6171class Min(AggFunc):
6172    arg_types = {"this": True, "expressions": False}
6173    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6176class Month(Func):
6177    pass
key = 'month'
class AddMonths(Func):
6180class AddMonths(Func):
6181    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6184class Nvl2(Func):
6185    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6188class Normalize(Func):
6189    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6192class Overlay(Func):
6193    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):
6197class Predict(Func):
6198    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6201class Pow(Binary, Func):
6202    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6205class PercentileCont(AggFunc):
6206    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6209class PercentileDisc(AggFunc):
6210    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6213class Quantile(AggFunc):
6214    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6217class ApproxQuantile(Quantile):
6218    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):
6221class Quarter(Func):
6222    pass
key = 'quarter'
class Rand(Func):
6227class Rand(Func):
6228    _sql_names = ["RAND", "RANDOM"]
6229    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6232class Randn(Func):
6233    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6236class RangeN(Func):
6237    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6240class ReadCSV(Func):
6241    _sql_names = ["READ_CSV"]
6242    is_var_len_args = True
6243    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6246class Reduce(Func):
6247    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):
6250class RegexpExtract(Func):
6251    arg_types = {
6252        "this": True,
6253        "expression": True,
6254        "position": False,
6255        "occurrence": False,
6256        "parameters": False,
6257        "group": False,
6258    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6261class RegexpExtractAll(Func):
6262    arg_types = {
6263        "this": True,
6264        "expression": True,
6265        "position": False,
6266        "occurrence": False,
6267        "parameters": False,
6268        "group": False,
6269    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6272class RegexpReplace(Func):
6273    arg_types = {
6274        "this": True,
6275        "expression": True,
6276        "replacement": False,
6277        "position": False,
6278        "occurrence": False,
6279        "modifiers": False,
6280    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6283class RegexpLike(Binary, Func):
6284    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6287class RegexpILike(Binary, Func):
6288    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6293class RegexpSplit(Func):
6294    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6297class Repeat(Func):
6298    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6303class Round(Func):
6304    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6307class RowNumber(Func):
6308    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
6311class SafeDivide(Func):
6312    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6315class SHA(Func):
6316    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6319class SHA2(Func):
6320    _sql_names = ["SHA2"]
6321    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6324class Sign(Func):
6325    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6328class SortArray(Func):
6329    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6332class Split(Func):
6333    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6337class SplitPart(Func):
6338    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6343class Substring(Func):
6344    _sql_names = ["SUBSTRING", "SUBSTR"]
6345    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6348class StandardHash(Func):
6349    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6352class StartsWith(Func):
6353    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6354    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6357class StrPosition(Func):
6358    arg_types = {
6359        "this": True,
6360        "substr": True,
6361        "position": False,
6362        "instance": False,
6363    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6366class StrToDate(Func):
6367    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6370class StrToTime(Func):
6371    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):
6376class StrToUnix(Func):
6377    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6382class StrToMap(Func):
6383    arg_types = {
6384        "this": True,
6385        "pair_delim": False,
6386        "key_value_delim": False,
6387        "duplicate_resolution_callback": False,
6388    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6391class NumberToStr(Func):
6392    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6395class FromBase(Func):
6396    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6399class Struct(Func):
6400    arg_types = {"expressions": False}
6401    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6404class StructExtract(Func):
6405    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6410class Stuff(Func):
6411    _sql_names = ["STUFF", "INSERT"]
6412    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):
6415class Sum(AggFunc):
6416    pass
key = 'sum'
class Sqrt(Func):
6419class Sqrt(Func):
6420    pass
key = 'sqrt'
class Stddev(AggFunc):
6423class Stddev(AggFunc):
6424    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6427class StddevPop(AggFunc):
6428    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6431class StddevSamp(AggFunc):
6432    pass
key = 'stddevsamp'
class Time(Func):
6436class Time(Func):
6437    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6440class TimeToStr(Func):
6441    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):
6444class TimeToTimeStr(Func):
6445    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6448class TimeToUnix(Func):
6449    pass
key = 'timetounix'
class TimeStrToDate(Func):
6452class TimeStrToDate(Func):
6453    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6456class TimeStrToTime(Func):
6457    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6460class TimeStrToUnix(Func):
6461    pass
key = 'timestrtounix'
class Trim(Func):
6464class Trim(Func):
6465    arg_types = {
6466        "this": True,
6467        "expression": False,
6468        "position": False,
6469        "collation": False,
6470    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6473class TsOrDsAdd(Func, TimeUnit):
6474    # return_type is used to correctly cast the arguments of this expression when transpiling it
6475    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6476
6477    @property
6478    def return_type(self) -> DataType:
6479        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
6477    @property
6478    def return_type(self) -> DataType:
6479        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6482class TsOrDsDiff(Func, TimeUnit):
6483    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6486class TsOrDsToDateStr(Func):
6487    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6490class TsOrDsToDate(Func):
6491    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6494class TsOrDsToTime(Func):
6495    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6498class TsOrDsToTimestamp(Func):
6499    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6502class TsOrDiToDi(Func):
6503    pass
key = 'tsorditodi'
class Unhex(Func):
6506class Unhex(Func):
6507    pass
key = 'unhex'
class UnixDate(Func):
6511class UnixDate(Func):
6512    pass
key = 'unixdate'
class UnixToStr(Func):
6515class UnixToStr(Func):
6516    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6521class UnixToTime(Func):
6522    arg_types = {
6523        "this": True,
6524        "scale": False,
6525        "zone": False,
6526        "hours": False,
6527        "minutes": False,
6528        "format": False,
6529    }
6530
6531    SECONDS = Literal.number(0)
6532    DECIS = Literal.number(1)
6533    CENTIS = Literal.number(2)
6534    MILLIS = Literal.number(3)
6535    DECIMILLIS = Literal.number(4)
6536    CENTIMILLIS = Literal.number(5)
6537    MICROS = Literal.number(6)
6538    DECIMICROS = Literal.number(7)
6539    CENTIMICROS = Literal.number(8)
6540    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):
6543class UnixToTimeStr(Func):
6544    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6547class UnixSeconds(Func):
6548    pass
key = 'unixseconds'
class Uuid(Func):
6551class Uuid(Func):
6552    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6553
6554    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6557class TimestampFromParts(Func):
6558    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6559    arg_types = {
6560        "year": True,
6561        "month": True,
6562        "day": True,
6563        "hour": True,
6564        "min": True,
6565        "sec": True,
6566        "nano": False,
6567        "zone": False,
6568        "milli": False,
6569    }
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):
6572class Upper(Func):
6573    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6576class Corr(Binary, AggFunc):
6577    pass
key = 'corr'
class Variance(AggFunc):
6580class Variance(AggFunc):
6581    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6584class VariancePop(AggFunc):
6585    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6588class CovarSamp(Binary, AggFunc):
6589    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6592class CovarPop(Binary, AggFunc):
6593    pass
key = 'covarpop'
class Week(Func):
6596class Week(Func):
6597    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6600class XMLTable(Func):
6601    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):
6604class Year(Func):
6605    pass
key = 'year'
class Use(Expression):
6608class Use(Expression):
6609    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6612class Merge(DML):
6613    arg_types = {
6614        "this": True,
6615        "using": True,
6616        "on": True,
6617        "expressions": True,
6618        "with": False,
6619        "returning": False,
6620    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6623class When(Func):
6624    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):
6629class NextValueFor(Func):
6630    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6635class Semicolon(Expression):
6636    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 '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 '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 '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 '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'>, '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'>, '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'>, '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_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:
6676def maybe_parse(
6677    sql_or_expression: ExpOrStr,
6678    *,
6679    into: t.Optional[IntoType] = None,
6680    dialect: DialectType = None,
6681    prefix: t.Optional[str] = None,
6682    copy: bool = False,
6683    **opts,
6684) -> Expression:
6685    """Gracefully handle a possible string or expression.
6686
6687    Example:
6688        >>> maybe_parse("1")
6689        Literal(this=1, is_string=False)
6690        >>> maybe_parse(to_identifier("x"))
6691        Identifier(this=x, quoted=False)
6692
6693    Args:
6694        sql_or_expression: the SQL code string or an expression
6695        into: the SQLGlot Expression to parse into
6696        dialect: the dialect used to parse the input expressions (in the case that an
6697            input expression is a SQL string).
6698        prefix: a string to prefix the sql with before it gets parsed
6699            (automatically includes a space)
6700        copy: whether to copy the expression.
6701        **opts: other options to use to parse the input expressions (again, in the case
6702            that an input expression is a SQL string).
6703
6704    Returns:
6705        Expression: the parsed or given expression.
6706    """
6707    if isinstance(sql_or_expression, Expression):
6708        if copy:
6709            return sql_or_expression.copy()
6710        return sql_or_expression
6711
6712    if sql_or_expression is None:
6713        raise ParseError("SQL cannot be None")
6714
6715    import sqlglot
6716
6717    sql = str(sql_or_expression)
6718    if prefix:
6719        sql = f"{prefix} {sql}"
6720
6721    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):
6732def maybe_copy(instance, copy=True):
6733    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:
6969def union(
6970    *expressions: ExpOrStr,
6971    distinct: bool = True,
6972    dialect: DialectType = None,
6973    copy: bool = True,
6974    **opts,
6975) -> Union:
6976    """
6977    Initializes a syntax tree for the `UNION` operation.
6978
6979    Example:
6980        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6981        'SELECT * FROM foo UNION SELECT * FROM bla'
6982
6983    Args:
6984        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
6985            If `Expression` instances are passed, they will be used as-is.
6986        distinct: set the DISTINCT flag if and only if this is true.
6987        dialect: the dialect used to parse the input expression.
6988        copy: whether to copy the expression.
6989        opts: other options to use to parse the input expressions.
6990
6991    Returns:
6992        The new Union instance.
6993    """
6994    assert len(expressions) >= 2, "At least two expressions are required by `union`."
6995    return _apply_set_operation(
6996        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
6997    )

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:
7000def intersect(
7001    *expressions: ExpOrStr,
7002    distinct: bool = True,
7003    dialect: DialectType = None,
7004    copy: bool = True,
7005    **opts,
7006) -> Intersect:
7007    """
7008    Initializes a syntax tree for the `INTERSECT` operation.
7009
7010    Example:
7011        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7012        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7013
7014    Args:
7015        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7016            If `Expression` instances are passed, they will be used as-is.
7017        distinct: set the DISTINCT flag if and only if this is true.
7018        dialect: the dialect used to parse the input expression.
7019        copy: whether to copy the expression.
7020        opts: other options to use to parse the input expressions.
7021
7022    Returns:
7023        The new Intersect instance.
7024    """
7025    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7026    return _apply_set_operation(
7027        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7028    )

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:
7031def except_(
7032    *expressions: ExpOrStr,
7033    distinct: bool = True,
7034    dialect: DialectType = None,
7035    copy: bool = True,
7036    **opts,
7037) -> Except:
7038    """
7039    Initializes a syntax tree for the `EXCEPT` operation.
7040
7041    Example:
7042        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7043        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7044
7045    Args:
7046        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7047            If `Expression` instances are passed, they will be used as-is.
7048        distinct: set the DISTINCT flag if and only if this is true.
7049        dialect: the dialect used to parse the input expression.
7050        copy: whether to copy the expression.
7051        opts: other options to use to parse the input expressions.
7052
7053    Returns:
7054        The new Except instance.
7055    """
7056    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7057    return _apply_set_operation(
7058        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7059    )

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:
7062def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7063    """
7064    Initializes a syntax tree from one or multiple SELECT expressions.
7065
7066    Example:
7067        >>> select("col1", "col2").from_("tbl").sql()
7068        'SELECT col1, col2 FROM tbl'
7069
7070    Args:
7071        *expressions: the SQL code string to parse as the expressions of a
7072            SELECT statement. If an Expression instance is passed, this is used as-is.
7073        dialect: the dialect used to parse the input expressions (in the case that an
7074            input expression is a SQL string).
7075        **opts: other options to use to parse the input expressions (again, in the case
7076            that an input expression is a SQL string).
7077
7078    Returns:
7079        Select: the syntax tree for the SELECT statement.
7080    """
7081    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:
7084def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7085    """
7086    Initializes a syntax tree from a FROM expression.
7087
7088    Example:
7089        >>> from_("tbl").select("col1", "col2").sql()
7090        'SELECT col1, col2 FROM tbl'
7091
7092    Args:
7093        *expression: the SQL code string to parse as the FROM expressions of a
7094            SELECT statement. If an Expression instance is passed, this is used as-is.
7095        dialect: the dialect used to parse the input expression (in the case that the
7096            input expression is a SQL string).
7097        **opts: other options to use to parse the input expressions (again, in the case
7098            that the input expression is a SQL string).
7099
7100    Returns:
7101        Select: the syntax tree for the SELECT statement.
7102    """
7103    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:
7106def update(
7107    table: str | Table,
7108    properties: t.Optional[dict] = None,
7109    where: t.Optional[ExpOrStr] = None,
7110    from_: t.Optional[ExpOrStr] = None,
7111    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7112    dialect: DialectType = None,
7113    **opts,
7114) -> Update:
7115    """
7116    Creates an update statement.
7117
7118    Example:
7119        >>> 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()
7120        "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"
7121
7122    Args:
7123        properties: dictionary of properties to SET which are
7124            auto converted to sql objects eg None -> NULL
7125        where: sql conditional parsed into a WHERE statement
7126        from_: sql statement parsed into a FROM statement
7127        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7128        dialect: the dialect used to parse the input expressions.
7129        **opts: other options to use to parse the input expressions.
7130
7131    Returns:
7132        Update: the syntax tree for the UPDATE statement.
7133    """
7134    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7135    if properties:
7136        update_expr.set(
7137            "expressions",
7138            [
7139                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7140                for k, v in properties.items()
7141            ],
7142        )
7143    if from_:
7144        update_expr.set(
7145            "from",
7146            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7147        )
7148    if isinstance(where, Condition):
7149        where = Where(this=where)
7150    if where:
7151        update_expr.set(
7152            "where",
7153            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7154        )
7155    if with_:
7156        cte_list = [
7157            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7158            for alias, qry in with_.items()
7159        ]
7160        update_expr.set(
7161            "with",
7162            With(expressions=cte_list),
7163        )
7164    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:
7167def delete(
7168    table: ExpOrStr,
7169    where: t.Optional[ExpOrStr] = None,
7170    returning: t.Optional[ExpOrStr] = None,
7171    dialect: DialectType = None,
7172    **opts,
7173) -> Delete:
7174    """
7175    Builds a delete statement.
7176
7177    Example:
7178        >>> delete("my_table", where="id > 1").sql()
7179        'DELETE FROM my_table WHERE id > 1'
7180
7181    Args:
7182        where: sql conditional parsed into a WHERE statement
7183        returning: sql conditional parsed into a RETURNING statement
7184        dialect: the dialect used to parse the input expressions.
7185        **opts: other options to use to parse the input expressions.
7186
7187    Returns:
7188        Delete: the syntax tree for the DELETE statement.
7189    """
7190    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7191    if where:
7192        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7193    if returning:
7194        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7195    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:
7198def insert(
7199    expression: ExpOrStr,
7200    into: ExpOrStr,
7201    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7202    overwrite: t.Optional[bool] = None,
7203    returning: t.Optional[ExpOrStr] = None,
7204    dialect: DialectType = None,
7205    copy: bool = True,
7206    **opts,
7207) -> Insert:
7208    """
7209    Builds an INSERT statement.
7210
7211    Example:
7212        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7213        'INSERT INTO tbl VALUES (1, 2, 3)'
7214
7215    Args:
7216        expression: the sql string or expression of the INSERT statement
7217        into: the tbl to insert data to.
7218        columns: optionally the table's column names.
7219        overwrite: whether to INSERT OVERWRITE or not.
7220        returning: sql conditional parsed into a RETURNING statement
7221        dialect: the dialect used to parse the input expressions.
7222        copy: whether to copy the expression.
7223        **opts: other options to use to parse the input expressions.
7224
7225    Returns:
7226        Insert: the syntax tree for the INSERT statement.
7227    """
7228    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7229    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7230
7231    if columns:
7232        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7233
7234    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7235
7236    if returning:
7237        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7238
7239    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:
7242def merge(
7243    *when_exprs: ExpOrStr,
7244    into: ExpOrStr,
7245    using: ExpOrStr,
7246    on: ExpOrStr,
7247    returning: t.Optional[ExpOrStr] = None,
7248    dialect: DialectType = None,
7249    copy: bool = True,
7250    **opts,
7251) -> Merge:
7252    """
7253    Builds a MERGE statement.
7254
7255    Example:
7256        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7257        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7258        ...       into="my_table",
7259        ...       using="source_table",
7260        ...       on="my_table.id = source_table.id").sql()
7261        '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)'
7262
7263    Args:
7264        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7265        into: The target table to merge data into.
7266        using: The source table to merge data from.
7267        on: The join condition for the merge.
7268        returning: The columns to return from the merge.
7269        dialect: The dialect used to parse the input expressions.
7270        copy: Whether to copy the expression.
7271        **opts: Other options to use to parse the input expressions.
7272
7273    Returns:
7274        Merge: The syntax tree for the MERGE statement.
7275    """
7276    merge = Merge(
7277        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7278        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7279        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7280        expressions=[
7281            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
7282            for when_expr in when_exprs
7283        ],
7284    )
7285    if returning:
7286        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7287
7288    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:
7291def condition(
7292    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7293) -> Condition:
7294    """
7295    Initialize a logical condition expression.
7296
7297    Example:
7298        >>> condition("x=1").sql()
7299        'x = 1'
7300
7301        This is helpful for composing larger logical syntax trees:
7302        >>> where = condition("x=1")
7303        >>> where = where.and_("y=1")
7304        >>> Select().from_("tbl").select("*").where(where).sql()
7305        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7306
7307    Args:
7308        *expression: the SQL code string to parse.
7309            If an Expression instance is passed, this is used as-is.
7310        dialect: the dialect used to parse the input expression (in the case that the
7311            input expression is a SQL string).
7312        copy: Whether to copy `expression` (only applies to expressions).
7313        **opts: other options to use to parse the input expressions (again, in the case
7314            that the input expression is a SQL string).
7315
7316    Returns:
7317        The new Condition instance
7318    """
7319    return maybe_parse(
7320        expression,
7321        into=Condition,
7322        dialect=dialect,
7323        copy=copy,
7324        **opts,
7325    )

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:
7328def and_(
7329    *expressions: t.Optional[ExpOrStr],
7330    dialect: DialectType = None,
7331    copy: bool = True,
7332    wrap: bool = True,
7333    **opts,
7334) -> Condition:
7335    """
7336    Combine multiple conditions with an AND logical operator.
7337
7338    Example:
7339        >>> and_("x=1", and_("y=1", "z=1")).sql()
7340        'x = 1 AND (y = 1 AND z = 1)'
7341
7342    Args:
7343        *expressions: the SQL code strings to parse.
7344            If an Expression instance is passed, this is used as-is.
7345        dialect: the dialect used to parse the input expression.
7346        copy: whether to copy `expressions` (only applies to Expressions).
7347        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7348            precedence issues, but can be turned off when the produced AST is too deep and
7349            causes recursion-related issues.
7350        **opts: other options to use to parse the input expressions.
7351
7352    Returns:
7353        The new condition
7354    """
7355    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:
7358def or_(
7359    *expressions: t.Optional[ExpOrStr],
7360    dialect: DialectType = None,
7361    copy: bool = True,
7362    wrap: bool = True,
7363    **opts,
7364) -> Condition:
7365    """
7366    Combine multiple conditions with an OR logical operator.
7367
7368    Example:
7369        >>> or_("x=1", or_("y=1", "z=1")).sql()
7370        'x = 1 OR (y = 1 OR z = 1)'
7371
7372    Args:
7373        *expressions: the SQL code strings to parse.
7374            If an Expression instance is passed, this is used as-is.
7375        dialect: the dialect used to parse the input expression.
7376        copy: whether to copy `expressions` (only applies to Expressions).
7377        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7378            precedence issues, but can be turned off when the produced AST is too deep and
7379            causes recursion-related issues.
7380        **opts: other options to use to parse the input expressions.
7381
7382    Returns:
7383        The new condition
7384    """
7385    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:
7388def xor(
7389    *expressions: t.Optional[ExpOrStr],
7390    dialect: DialectType = None,
7391    copy: bool = True,
7392    wrap: bool = True,
7393    **opts,
7394) -> Condition:
7395    """
7396    Combine multiple conditions with an XOR logical operator.
7397
7398    Example:
7399        >>> xor("x=1", xor("y=1", "z=1")).sql()
7400        'x = 1 XOR (y = 1 XOR z = 1)'
7401
7402    Args:
7403        *expressions: the SQL code strings to parse.
7404            If an Expression instance is passed, this is used as-is.
7405        dialect: the dialect used to parse the input expression.
7406        copy: whether to copy `expressions` (only applies to Expressions).
7407        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7408            precedence issues, but can be turned off when the produced AST is too deep and
7409            causes recursion-related issues.
7410        **opts: other options to use to parse the input expressions.
7411
7412    Returns:
7413        The new condition
7414    """
7415    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:
7418def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7419    """
7420    Wrap a condition with a NOT operator.
7421
7422    Example:
7423        >>> not_("this_suit='black'").sql()
7424        "NOT this_suit = 'black'"
7425
7426    Args:
7427        expression: the SQL code string to parse.
7428            If an Expression instance is passed, this is used as-is.
7429        dialect: the dialect used to parse the input expression.
7430        copy: whether to copy the expression or not.
7431        **opts: other options to use to parse the input expressions.
7432
7433    Returns:
7434        The new condition.
7435    """
7436    this = condition(
7437        expression,
7438        dialect=dialect,
7439        copy=copy,
7440        **opts,
7441    )
7442    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:
7445def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7446    """
7447    Wrap an expression in parentheses.
7448
7449    Example:
7450        >>> paren("5 + 3").sql()
7451        '(5 + 3)'
7452
7453    Args:
7454        expression: the SQL code string to parse.
7455            If an Expression instance is passed, this is used as-is.
7456        copy: whether to copy the expression or not.
7457
7458    Returns:
7459        The wrapped expression.
7460    """
7461    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):
7477def to_identifier(name, quoted=None, copy=True):
7478    """Builds an identifier.
7479
7480    Args:
7481        name: The name to turn into an identifier.
7482        quoted: Whether to force quote the identifier.
7483        copy: Whether to copy name if it's an Identifier.
7484
7485    Returns:
7486        The identifier ast node.
7487    """
7488
7489    if name is None:
7490        return None
7491
7492    if isinstance(name, Identifier):
7493        identifier = maybe_copy(name, copy)
7494    elif isinstance(name, str):
7495        identifier = Identifier(
7496            this=name,
7497            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7498        )
7499    else:
7500        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7501    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:
7504def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7505    """
7506    Parses a given string into an identifier.
7507
7508    Args:
7509        name: The name to parse into an identifier.
7510        dialect: The dialect to parse against.
7511
7512    Returns:
7513        The identifier ast node.
7514    """
7515    try:
7516        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7517    except (ParseError, TokenError):
7518        expression = to_identifier(name)
7519
7520    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:
7526def to_interval(interval: str | Literal) -> Interval:
7527    """Builds an interval expression from a string like '1 day' or '5 months'."""
7528    if isinstance(interval, Literal):
7529        if not interval.is_string:
7530            raise ValueError("Invalid interval string.")
7531
7532        interval = interval.this
7533
7534    interval = maybe_parse(f"INTERVAL {interval}")
7535    assert isinstance(interval, Interval)
7536    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:
7539def to_table(
7540    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7541) -> Table:
7542    """
7543    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7544    If a table is passed in then that table is returned.
7545
7546    Args:
7547        sql_path: a `[catalog].[schema].[table]` string.
7548        dialect: the source dialect according to which the table name will be parsed.
7549        copy: Whether to copy a table if it is passed in.
7550        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7551
7552    Returns:
7553        A table expression.
7554    """
7555    if isinstance(sql_path, Table):
7556        return maybe_copy(sql_path, copy=copy)
7557
7558    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7559
7560    for k, v in kwargs.items():
7561        table.set(k, v)
7562
7563    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:
7566def to_column(
7567    sql_path: str | Column,
7568    quoted: t.Optional[bool] = None,
7569    dialect: DialectType = None,
7570    copy: bool = True,
7571    **kwargs,
7572) -> Column:
7573    """
7574    Create a column from a `[table].[column]` sql path. Table is optional.
7575    If a column is passed in then that column is returned.
7576
7577    Args:
7578        sql_path: a `[table].[column]` string.
7579        quoted: Whether or not to force quote identifiers.
7580        dialect: the source dialect according to which the column name will be parsed.
7581        copy: Whether to copy a column if it is passed in.
7582        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7583
7584    Returns:
7585        A column expression.
7586    """
7587    if isinstance(sql_path, Column):
7588        return maybe_copy(sql_path, copy=copy)
7589
7590    try:
7591        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7592    except ParseError:
7593        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7594
7595    for k, v in kwargs.items():
7596        col.set(k, v)
7597
7598    if quoted:
7599        for i in col.find_all(Identifier):
7600            i.set("quoted", True)
7601
7602    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):
7605def alias_(
7606    expression: ExpOrStr,
7607    alias: t.Optional[str | Identifier],
7608    table: bool | t.Sequence[str | Identifier] = False,
7609    quoted: t.Optional[bool] = None,
7610    dialect: DialectType = None,
7611    copy: bool = True,
7612    **opts,
7613):
7614    """Create an Alias expression.
7615
7616    Example:
7617        >>> alias_('foo', 'bar').sql()
7618        'foo AS bar'
7619
7620        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7621        '(SELECT 1, 2) AS bar(a, b)'
7622
7623    Args:
7624        expression: the SQL code strings to parse.
7625            If an Expression instance is passed, this is used as-is.
7626        alias: the alias name to use. If the name has
7627            special characters it is quoted.
7628        table: Whether to create a table alias, can also be a list of columns.
7629        quoted: whether to quote the alias
7630        dialect: the dialect used to parse the input expression.
7631        copy: Whether to copy the expression.
7632        **opts: other options to use to parse the input expressions.
7633
7634    Returns:
7635        Alias: the aliased expression
7636    """
7637    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7638    alias = to_identifier(alias, quoted=quoted)
7639
7640    if table:
7641        table_alias = TableAlias(this=alias)
7642        exp.set("alias", table_alias)
7643
7644        if not isinstance(table, bool):
7645            for column in table:
7646                table_alias.append("columns", to_identifier(column, quoted=quoted))
7647
7648        return exp
7649
7650    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7651    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7652    # for the complete Window expression.
7653    #
7654    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7655
7656    if "alias" in exp.arg_types and not isinstance(exp, Window):
7657        exp.set("alias", alias)
7658        return exp
7659    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:
7662def subquery(
7663    expression: ExpOrStr,
7664    alias: t.Optional[Identifier | str] = None,
7665    dialect: DialectType = None,
7666    **opts,
7667) -> Select:
7668    """
7669    Build a subquery expression that's selected from.
7670
7671    Example:
7672        >>> subquery('select x from tbl', 'bar').select('x').sql()
7673        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7674
7675    Args:
7676        expression: the SQL code strings to parse.
7677            If an Expression instance is passed, this is used as-is.
7678        alias: the alias name to use.
7679        dialect: the dialect used to parse the input expression.
7680        **opts: other options to use to parse the input expressions.
7681
7682    Returns:
7683        A new Select instance with the subquery expression included.
7684    """
7685
7686    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7687    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):
7718def column(
7719    col,
7720    table=None,
7721    db=None,
7722    catalog=None,
7723    *,
7724    fields=None,
7725    quoted=None,
7726    copy=True,
7727):
7728    """
7729    Build a Column.
7730
7731    Args:
7732        col: Column name.
7733        table: Table name.
7734        db: Database name.
7735        catalog: Catalog name.
7736        fields: Additional fields using dots.
7737        quoted: Whether to force quotes on the column's identifiers.
7738        copy: Whether to copy identifiers if passed in.
7739
7740    Returns:
7741        The new Column instance.
7742    """
7743    this = Column(
7744        this=to_identifier(col, quoted=quoted, copy=copy),
7745        table=to_identifier(table, quoted=quoted, copy=copy),
7746        db=to_identifier(db, quoted=quoted, copy=copy),
7747        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7748    )
7749
7750    if fields:
7751        this = Dot.build(
7752            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7753        )
7754    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:
7757def cast(
7758    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7759) -> Cast:
7760    """Cast an expression to a data type.
7761
7762    Example:
7763        >>> cast('x + 1', 'int').sql()
7764        'CAST(x + 1 AS INT)'
7765
7766    Args:
7767        expression: The expression to cast.
7768        to: The datatype to cast to.
7769        copy: Whether to copy the supplied expressions.
7770        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7771            - The expression to be cast is already a exp.Cast expression
7772            - The existing cast is to a type that is logically equivalent to new type
7773
7774            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7775            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7776            and instead just return the original expression `CAST(x as DATETIME)`.
7777
7778            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7779            mapping is applied in the target dialect generator.
7780
7781    Returns:
7782        The new Cast instance.
7783    """
7784    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7785    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7786
7787    # dont re-cast if the expression is already a cast to the correct type
7788    if isinstance(expr, Cast):
7789        from sqlglot.dialects.dialect import Dialect
7790
7791        target_dialect = Dialect.get_or_raise(dialect)
7792        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7793
7794        existing_cast_type: DataType.Type = expr.to.this
7795        new_cast_type: DataType.Type = data_type.this
7796        types_are_equivalent = type_mapping.get(
7797            existing_cast_type, existing_cast_type
7798        ) == type_mapping.get(new_cast_type, new_cast_type)
7799        if expr.is_type(data_type) or types_are_equivalent:
7800            return expr
7801
7802    expr = Cast(this=expr, to=data_type)
7803    expr.type = data_type
7804
7805    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:
7808def table_(
7809    table: Identifier | str,
7810    db: t.Optional[Identifier | str] = None,
7811    catalog: t.Optional[Identifier | str] = None,
7812    quoted: t.Optional[bool] = None,
7813    alias: t.Optional[Identifier | str] = None,
7814) -> Table:
7815    """Build a Table.
7816
7817    Args:
7818        table: Table name.
7819        db: Database name.
7820        catalog: Catalog name.
7821        quote: Whether to force quotes on the table's identifiers.
7822        alias: Table's alias.
7823
7824    Returns:
7825        The new Table instance.
7826    """
7827    return Table(
7828        this=to_identifier(table, quoted=quoted) if table else None,
7829        db=to_identifier(db, quoted=quoted) if db else None,
7830        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7831        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7832    )

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:
7835def values(
7836    values: t.Iterable[t.Tuple[t.Any, ...]],
7837    alias: t.Optional[str] = None,
7838    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7839) -> Values:
7840    """Build VALUES statement.
7841
7842    Example:
7843        >>> values([(1, '2')]).sql()
7844        "VALUES (1, '2')"
7845
7846    Args:
7847        values: values statements that will be converted to SQL
7848        alias: optional alias
7849        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7850         If either are provided then an alias is also required.
7851
7852    Returns:
7853        Values: the Values expression object
7854    """
7855    if columns and not alias:
7856        raise ValueError("Alias is required when providing columns")
7857
7858    return Values(
7859        expressions=[convert(tup) for tup in values],
7860        alias=(
7861            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7862            if columns
7863            else (TableAlias(this=to_identifier(alias)) if alias else None)
7864        ),
7865    )

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:
7868def var(name: t.Optional[ExpOrStr]) -> Var:
7869    """Build a SQL variable.
7870
7871    Example:
7872        >>> repr(var('x'))
7873        'Var(this=x)'
7874
7875        >>> repr(var(column('x', table='y')))
7876        'Var(this=x)'
7877
7878    Args:
7879        name: The name of the var or an expression who's name will become the var.
7880
7881    Returns:
7882        The new variable node.
7883    """
7884    if not name:
7885        raise ValueError("Cannot convert empty name into var.")
7886
7887    if isinstance(name, Expression):
7888        name = name.name
7889    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:
7892def rename_table(
7893    old_name: str | Table,
7894    new_name: str | Table,
7895    dialect: DialectType = None,
7896) -> Alter:
7897    """Build ALTER TABLE... RENAME... expression
7898
7899    Args:
7900        old_name: The old name of the table
7901        new_name: The new name of the table
7902        dialect: The dialect to parse the table.
7903
7904    Returns:
7905        Alter table expression
7906    """
7907    old_table = to_table(old_name, dialect=dialect)
7908    new_table = to_table(new_name, dialect=dialect)
7909    return Alter(
7910        this=old_table,
7911        kind="TABLE",
7912        actions=[
7913            AlterRename(this=new_table),
7914        ],
7915    )

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:
7918def rename_column(
7919    table_name: str | Table,
7920    old_column_name: str | Column,
7921    new_column_name: str | Column,
7922    exists: t.Optional[bool] = None,
7923    dialect: DialectType = None,
7924) -> Alter:
7925    """Build ALTER TABLE... RENAME COLUMN... expression
7926
7927    Args:
7928        table_name: Name of the table
7929        old_column: The old name of the column
7930        new_column: The new name of the column
7931        exists: Whether to add the `IF EXISTS` clause
7932        dialect: The dialect to parse the table/column.
7933
7934    Returns:
7935        Alter table expression
7936    """
7937    table = to_table(table_name, dialect=dialect)
7938    old_column = to_column(old_column_name, dialect=dialect)
7939    new_column = to_column(new_column_name, dialect=dialect)
7940    return Alter(
7941        this=table,
7942        kind="TABLE",
7943        actions=[
7944            RenameColumn(this=old_column, to=new_column, exists=exists),
7945        ],
7946    )

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:
7949def convert(value: t.Any, copy: bool = False) -> Expression:
7950    """Convert a python value into an expression object.
7951
7952    Raises an error if a conversion is not possible.
7953
7954    Args:
7955        value: A python object.
7956        copy: Whether to copy `value` (only applies to Expressions and collections).
7957
7958    Returns:
7959        The equivalent expression object.
7960    """
7961    if isinstance(value, Expression):
7962        return maybe_copy(value, copy)
7963    if isinstance(value, str):
7964        return Literal.string(value)
7965    if isinstance(value, bool):
7966        return Boolean(this=value)
7967    if value is None or (isinstance(value, float) and math.isnan(value)):
7968        return null()
7969    if isinstance(value, numbers.Number):
7970        return Literal.number(value)
7971    if isinstance(value, bytes):
7972        return HexString(this=value.hex())
7973    if isinstance(value, datetime.datetime):
7974        datetime_literal = Literal.string(value.isoformat(sep=" "))
7975
7976        tz = None
7977        if value.tzinfo:
7978            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
7979            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
7980            tz = Literal.string(str(value.tzinfo))
7981
7982        return TimeStrToTime(this=datetime_literal, zone=tz)
7983    if isinstance(value, datetime.date):
7984        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7985        return DateStrToDate(this=date_literal)
7986    if isinstance(value, tuple):
7987        if hasattr(value, "_fields"):
7988            return Struct(
7989                expressions=[
7990                    PropertyEQ(
7991                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7992                    )
7993                    for k in value._fields
7994                ]
7995            )
7996        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7997    if isinstance(value, list):
7998        return Array(expressions=[convert(v, copy=copy) for v in value])
7999    if isinstance(value, dict):
8000        return Map(
8001            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8002            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8003        )
8004    if hasattr(value, "__dict__"):
8005        return Struct(
8006            expressions=[
8007                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8008                for k, v in value.__dict__.items()
8009            ]
8010        )
8011    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:
8014def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8015    """
8016    Replace children of an expression with the result of a lambda fun(child) -> exp.
8017    """
8018    for k, v in tuple(expression.args.items()):
8019        is_list_arg = type(v) is list
8020
8021        child_nodes = v if is_list_arg else [v]
8022        new_child_nodes = []
8023
8024        for cn in child_nodes:
8025            if isinstance(cn, Expression):
8026                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8027                    new_child_nodes.append(child_node)
8028            else:
8029                new_child_nodes.append(cn)
8030
8031        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:
8034def replace_tree(
8035    expression: Expression,
8036    fun: t.Callable,
8037    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8038) -> Expression:
8039    """
8040    Replace an entire tree with the result of function calls on each node.
8041
8042    This will be traversed in reverse dfs, so leaves first.
8043    If new nodes are created as a result of function calls, they will also be traversed.
8044    """
8045    stack = list(expression.dfs(prune=prune))
8046
8047    while stack:
8048        node = stack.pop()
8049        new_node = fun(node)
8050
8051        if new_node is not node:
8052            node.replace(new_node)
8053
8054            if isinstance(new_node, Expression):
8055                stack.append(new_node)
8056
8057    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]:
8060def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8061    """
8062    Return all table names referenced through columns in an expression.
8063
8064    Example:
8065        >>> import sqlglot
8066        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8067        ['a', 'c']
8068
8069    Args:
8070        expression: expression to find table names.
8071        exclude: a table name to exclude
8072
8073    Returns:
8074        A list of unique names.
8075    """
8076    return {
8077        table
8078        for table in (column.table for column in expression.find_all(Column))
8079        if table and table != exclude
8080    }

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:
8083def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8084    """Get the full name of a table as a string.
8085
8086    Args:
8087        table: Table expression node or string.
8088        dialect: The dialect to generate the table name for.
8089        identify: Determines when an identifier should be quoted. Possible values are:
8090            False (default): Never quote, except in cases where it's mandatory by the dialect.
8091            True: Always quote.
8092
8093    Examples:
8094        >>> from sqlglot import exp, parse_one
8095        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8096        'a.b.c'
8097
8098    Returns:
8099        The table name.
8100    """
8101
8102    table = maybe_parse(table, into=Table, dialect=dialect)
8103
8104    if not table:
8105        raise ValueError(f"Cannot parse {table}")
8106
8107    return ".".join(
8108        (
8109            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8110            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8111            else part.name
8112        )
8113        for part in table.parts
8114    )

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:
8117def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8118    """Returns a case normalized table name without quotes.
8119
8120    Args:
8121        table: the table to normalize
8122        dialect: the dialect to use for normalization rules
8123        copy: whether to copy the expression.
8124
8125    Examples:
8126        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8127        'A-B.c'
8128    """
8129    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8130
8131    return ".".join(
8132        p.name
8133        for p in normalize_identifiers(
8134            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8135        ).parts
8136    )

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:
8139def replace_tables(
8140    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8141) -> E:
8142    """Replace all tables in expression according to the mapping.
8143
8144    Args:
8145        expression: expression node to be transformed and replaced.
8146        mapping: mapping of table names.
8147        dialect: the dialect of the mapping table
8148        copy: whether to copy the expression.
8149
8150    Examples:
8151        >>> from sqlglot import exp, parse_one
8152        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8153        'SELECT * FROM c /* a.b */'
8154
8155    Returns:
8156        The mapped expression.
8157    """
8158
8159    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8160
8161    def _replace_tables(node: Expression) -> Expression:
8162        if isinstance(node, Table):
8163            original = normalize_table_name(node, dialect=dialect)
8164            new_name = mapping.get(original)
8165
8166            if new_name:
8167                table = to_table(
8168                    new_name,
8169                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8170                    dialect=dialect,
8171                )
8172                table.add_comments([original])
8173                return table
8174        return node
8175
8176    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:
8179def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8180    """Replace placeholders in an expression.
8181
8182    Args:
8183        expression: expression node to be transformed and replaced.
8184        args: positional names that will substitute unnamed placeholders in the given order.
8185        kwargs: keyword arguments that will substitute named placeholders.
8186
8187    Examples:
8188        >>> from sqlglot import exp, parse_one
8189        >>> replace_placeholders(
8190        ...     parse_one("select * from :tbl where ? = ?"),
8191        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8192        ... ).sql()
8193        "SELECT * FROM foo WHERE str_col = 'b'"
8194
8195    Returns:
8196        The mapped expression.
8197    """
8198
8199    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8200        if isinstance(node, Placeholder):
8201            if node.this:
8202                new_name = kwargs.get(node.this)
8203                if new_name is not None:
8204                    return convert(new_name)
8205            else:
8206                try:
8207                    return convert(next(args))
8208                except StopIteration:
8209                    pass
8210        return node
8211
8212    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:
8215def expand(
8216    expression: Expression,
8217    sources: t.Dict[str, Query],
8218    dialect: DialectType = None,
8219    copy: bool = True,
8220) -> Expression:
8221    """Transforms an expression by expanding all referenced sources into subqueries.
8222
8223    Examples:
8224        >>> from sqlglot import parse_one
8225        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8226        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8227
8228        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8229        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8230
8231    Args:
8232        expression: The expression to expand.
8233        sources: A dictionary of name to Queries.
8234        dialect: The dialect of the sources dict.
8235        copy: Whether to copy the expression during transformation. Defaults to True.
8236
8237    Returns:
8238        The transformed expression.
8239    """
8240    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8241
8242    def _expand(node: Expression):
8243        if isinstance(node, Table):
8244            name = normalize_table_name(node, dialect=dialect)
8245            source = sources.get(name)
8246            if source:
8247                subquery = source.subquery(node.alias or name)
8248                subquery.comments = [f"source: {name}"]
8249                return subquery.transform(_expand, copy=False)
8250        return node
8251
8252    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:
8255def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8256    """
8257    Returns a Func expression.
8258
8259    Examples:
8260        >>> func("abs", 5).sql()
8261        'ABS(5)'
8262
8263        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8264        'CAST(5 AS DOUBLE)'
8265
8266    Args:
8267        name: the name of the function to build.
8268        args: the args used to instantiate the function of interest.
8269        copy: whether to copy the argument expressions.
8270        dialect: the source dialect.
8271        kwargs: the kwargs used to instantiate the function of interest.
8272
8273    Note:
8274        The arguments `args` and `kwargs` are mutually exclusive.
8275
8276    Returns:
8277        An instance of the function of interest, or an anonymous function, if `name` doesn't
8278        correspond to an existing `sqlglot.expressions.Func` class.
8279    """
8280    if args and kwargs:
8281        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8282
8283    from sqlglot.dialects.dialect import Dialect
8284
8285    dialect = Dialect.get_or_raise(dialect)
8286
8287    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8288    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8289
8290    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8291    if constructor:
8292        if converted:
8293            if "dialect" in constructor.__code__.co_varnames:
8294                function = constructor(converted, dialect=dialect)
8295            else:
8296                function = constructor(converted)
8297        elif constructor.__name__ == "from_arg_list":
8298            function = constructor.__self__(**kwargs)  # type: ignore
8299        else:
8300            constructor = FUNCTION_BY_NAME.get(name.upper())
8301            if constructor:
8302                function = constructor(**kwargs)
8303            else:
8304                raise ValueError(
8305                    f"Unable to convert '{name}' into a Func. Either manually construct "
8306                    "the Func expression of interest or parse the function call."
8307                )
8308    else:
8309        kwargs = kwargs or {"expressions": converted}
8310        function = Anonymous(this=name, **kwargs)
8311
8312    for error_message in function.error_messages(converted):
8313        raise ValueError(error_message)
8314
8315    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:
8318def case(
8319    expression: t.Optional[ExpOrStr] = None,
8320    **opts,
8321) -> Case:
8322    """
8323    Initialize a CASE statement.
8324
8325    Example:
8326        case().when("a = 1", "foo").else_("bar")
8327
8328    Args:
8329        expression: Optionally, the input expression (not all dialects support this)
8330        **opts: Extra keyword arguments for parsing `expression`
8331    """
8332    if expression is not None:
8333        this = maybe_parse(expression, **opts)
8334    else:
8335        this = None
8336    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:
8339def array(
8340    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8341) -> Array:
8342    """
8343    Returns an array.
8344
8345    Examples:
8346        >>> array(1, 'x').sql()
8347        'ARRAY(1, x)'
8348
8349    Args:
8350        expressions: the expressions to add to the array.
8351        copy: whether to copy the argument expressions.
8352        dialect: the source dialect.
8353        kwargs: the kwargs used to instantiate the function of interest.
8354
8355    Returns:
8356        An array expression.
8357    """
8358    return Array(
8359        expressions=[
8360            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8361            for expression in expressions
8362        ]
8363    )

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:
8366def tuple_(
8367    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8368) -> Tuple:
8369    """
8370    Returns an tuple.
8371
8372    Examples:
8373        >>> tuple_(1, 'x').sql()
8374        '(1, x)'
8375
8376    Args:
8377        expressions: the expressions to add to the tuple.
8378        copy: whether to copy the argument expressions.
8379        dialect: the source dialect.
8380        kwargs: the kwargs used to instantiate the function of interest.
8381
8382    Returns:
8383        A tuple expression.
8384    """
8385    return Tuple(
8386        expressions=[
8387            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8388            for expression in expressions
8389        ]
8390    )

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:
8393def true() -> Boolean:
8394    """
8395    Returns a true Boolean expression.
8396    """
8397    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8400def false() -> Boolean:
8401    """
8402    Returns a false Boolean expression.
8403    """
8404    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8407def null() -> Null:
8408    """
8409    Returns a Null expression.
8410    """
8411    return Null()

Returns a Null expression.

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