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

The new Or condition.

def not_(self, copy: bool = True):
818    def not_(self, copy: bool = True):
819        """
820        Wrap this condition with NOT.
821
822        Example:
823            >>> condition("x=1").not_().sql()
824            'NOT x = 1'
825
826        Args:
827            copy: whether to copy this object.
828
829        Returns:
830            The new Not instance.
831        """
832        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:
834    def as_(
835        self,
836        alias: str | Identifier,
837        quoted: t.Optional[bool] = None,
838        dialect: DialectType = None,
839        copy: bool = True,
840        **opts,
841    ) -> Alias:
842        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:
867    def isin(
868        self,
869        *expressions: t.Any,
870        query: t.Optional[ExpOrStr] = None,
871        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
872        copy: bool = True,
873        **opts,
874    ) -> In:
875        subquery = maybe_parse(query, copy=copy, **opts) if query else None
876        if subquery and not isinstance(subquery, Subquery):
877            subquery = subquery.subquery(copy=False)
878
879        return In(
880            this=maybe_copy(self, copy),
881            expressions=[convert(e, copy=copy) for e in expressions],
882            query=subquery,
883            unnest=(
884                Unnest(
885                    expressions=[
886                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
887                        for e in ensure_list(unnest)
888                    ]
889                )
890                if unnest
891                else None
892            ),
893        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
895    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
896        return Between(
897            this=maybe_copy(self, copy),
898            low=convert(low, copy=copy, **opts),
899            high=convert(high, copy=copy, **opts),
900        )
def is_( self, other: Union[str, Expression]) -> Is:
902    def is_(self, other: ExpOrStr) -> Is:
903        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
905    def like(self, other: ExpOrStr) -> Like:
906        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
908    def ilike(self, other: ExpOrStr) -> ILike:
909        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
911    def eq(self, other: t.Any) -> EQ:
912        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
914    def neq(self, other: t.Any) -> NEQ:
915        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
917    def rlike(self, other: ExpOrStr) -> RegexpLike:
918        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
920    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
921        div = self._binop(Div, other)
922        div.args["typed"] = typed
923        div.args["safe"] = safe
924        return div
def asc(self, nulls_first: bool = True) -> Ordered:
926    def asc(self, nulls_first: bool = True) -> Ordered:
927        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
929    def desc(self, nulls_first: bool = False) -> Ordered:
930        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):
1013class Condition(Expression):
1014    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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

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

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

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

selects: List[Expression]
1165    @property
1166    def selects(self) -> t.List[Expression]:
1167        """Returns the query's projections."""
1168        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

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

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

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

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

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

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

def to_dot(self) -> Dot | Identifier:
1626    def to_dot(self) -> Dot | Identifier:
1627        """Converts the column into a dot expression."""
1628        parts = self.parts
1629        parent = self.parent
1630
1631        while parent:
1632            if isinstance(parent, Dot):
1633                parts.append(parent.expression)
1634            parent = parent.parent
1635
1636        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

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

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

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

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):
2254class ConditionalInsert(Expression):
2255    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2258class MultitableInserts(Expression):
2259    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2262class OnConflict(Expression):
2263    arg_types = {
2264        "duplicate": False,
2265        "expressions": False,
2266        "action": False,
2267        "conflict_keys": False,
2268        "constraint": False,
2269    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2272class OnCondition(Expression):
2273    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2276class Returning(Expression):
2277    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2281class Introducer(Expression):
2282    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2286class National(Expression):
2287    pass
key = 'national'
class LoadData(Expression):
2290class LoadData(Expression):
2291    arg_types = {
2292        "this": True,
2293        "local": False,
2294        "overwrite": False,
2295        "inpath": True,
2296        "partition": False,
2297        "input_format": False,
2298        "serde": False,
2299    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2302class Partition(Expression):
2303    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2306class PartitionRange(Expression):
2307    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2311class PartitionId(Expression):
2312    pass
key = 'partitionid'
class Fetch(Expression):
2315class Fetch(Expression):
2316    arg_types = {
2317        "direction": False,
2318        "count": False,
2319        "percent": False,
2320        "with_ties": False,
2321    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2324class Grant(Expression):
2325    arg_types = {
2326        "privileges": True,
2327        "kind": False,
2328        "securable": True,
2329        "principals": True,
2330        "grant_option": False,
2331    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2334class Group(Expression):
2335    arg_types = {
2336        "expressions": False,
2337        "grouping_sets": False,
2338        "cube": False,
2339        "rollup": False,
2340        "totals": False,
2341        "all": False,
2342    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2345class Cube(Expression):
2346    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2349class Rollup(Expression):
2350    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2353class GroupingSets(Expression):
2354    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2357class Lambda(Expression):
2358    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2361class Limit(Expression):
2362    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):
2365class Literal(Condition):
2366    arg_types = {"this": True, "is_string": True}
2367
2368    @property
2369    def hashable_args(self) -> t.Any:
2370        return (self.this, self.args.get("is_string"))
2371
2372    @classmethod
2373    def number(cls, number) -> Literal:
2374        return cls(this=str(number), is_string=False)
2375
2376    @classmethod
2377    def string(cls, string) -> Literal:
2378        return cls(this=str(string), is_string=True)
2379
2380    @property
2381    def output_name(self) -> str:
2382        return self.name
2383
2384    def to_py(self) -> int | str | Decimal:
2385        if self.is_number:
2386            try:
2387                return int(self.this)
2388            except ValueError:
2389                return Decimal(self.this)
2390        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2368    @property
2369    def hashable_args(self) -> t.Any:
2370        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2372    @classmethod
2373    def number(cls, number) -> Literal:
2374        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2376    @classmethod
2377    def string(cls, string) -> Literal:
2378        return cls(this=str(string), is_string=True)
output_name: str
2380    @property
2381    def output_name(self) -> str:
2382        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:
2384    def to_py(self) -> int | str | Decimal:
2385        if self.is_number:
2386            try:
2387                return int(self.this)
2388            except ValueError:
2389                return Decimal(self.this)
2390        return self.this

Returns a Python object equivalent of the SQL node.

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

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

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

Returns the output names of the query's projections.

is_star: bool
3266    @property
3267    def is_star(self) -> bool:
3268        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3270    @property
3271    def selects(self) -> t.List[Expression]:
3272        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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:
3703    def select(
3704        self,
3705        *expressions: t.Optional[ExpOrStr],
3706        append: bool = True,
3707        dialect: DialectType = None,
3708        copy: bool = True,
3709        **opts,
3710    ) -> Select:
3711        return _apply_list_builder(
3712            *expressions,
3713            instance=self,
3714            arg="expressions",
3715            append=append,
3716            dialect=dialect,
3717            into=Expression,
3718            copy=copy,
3719            **opts,
3720        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
4093    @property
4094    def selects(self) -> t.List[Expression]:
4095        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

output_name: str
4149    @property
4150    def output_name(self) -> str:
4151        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):
4154class TableSample(Expression):
4155    arg_types = {
4156        "expressions": False,
4157        "method": False,
4158        "bucket_numerator": False,
4159        "bucket_denominator": False,
4160        "bucket_field": False,
4161        "percent": False,
4162        "rows": False,
4163        "size": False,
4164        "seed": False,
4165    }
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):
4168class Tag(Expression):
4169    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4170
4171    arg_types = {
4172        "this": False,
4173        "prefix": False,
4174        "postfix": False,
4175    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4180class Pivot(Expression):
4181    arg_types = {
4182        "this": False,
4183        "alias": False,
4184        "expressions": False,
4185        "field": False,
4186        "unpivot": False,
4187        "using": False,
4188        "group": False,
4189        "columns": False,
4190        "include_nulls": False,
4191        "default_on_null": False,
4192    }
4193
4194    @property
4195    def unpivot(self) -> bool:
4196        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
4194    @property
4195    def unpivot(self) -> bool:
4196        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
4199class Window(Condition):
4200    arg_types = {
4201        "this": True,
4202        "partition_by": False,
4203        "order": False,
4204        "spec": False,
4205        "alias": False,
4206        "over": False,
4207        "first": False,
4208    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4211class WindowSpec(Expression):
4212    arg_types = {
4213        "kind": False,
4214        "start": False,
4215        "start_side": False,
4216        "end": False,
4217        "end_side": False,
4218    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4221class PreWhere(Expression):
4222    pass
key = 'prewhere'
class Where(Expression):
4225class Where(Expression):
4226    pass
key = 'where'
class Star(Expression):
4229class Star(Expression):
4230    arg_types = {"except": False, "replace": False, "rename": False}
4231
4232    @property
4233    def name(self) -> str:
4234        return "*"
4235
4236    @property
4237    def output_name(self) -> str:
4238        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4232    @property
4233    def name(self) -> str:
4234        return "*"
output_name: str
4236    @property
4237    def output_name(self) -> str:
4238        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):
4241class Parameter(Condition):
4242    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4245class SessionParameter(Condition):
4246    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4249class Placeholder(Condition):
4250    arg_types = {"this": False, "kind": False}
4251
4252    @property
4253    def name(self) -> str:
4254        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4252    @property
4253    def name(self) -> str:
4254        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4257class Null(Condition):
4258    arg_types: t.Dict[str, t.Any] = {}
4259
4260    @property
4261    def name(self) -> str:
4262        return "NULL"
4263
4264    def to_py(self) -> Lit[None]:
4265        return None
arg_types: Dict[str, Any] = {}
name: str
4260    @property
4261    def name(self) -> str:
4262        return "NULL"
def to_py(self) -> Literal[None]:
4264    def to_py(self) -> Lit[None]:
4265        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4268class Boolean(Condition):
4269    def to_py(self) -> bool:
4270        return self.this
def to_py(self) -> bool:
4269    def to_py(self) -> bool:
4270        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4759class DPipe(Binary):
4760    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4763class EQ(Binary, Predicate):
4764    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4767class NullSafeEQ(Binary, Predicate):
4768    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4771class NullSafeNEQ(Binary, Predicate):
4772    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4776class PropertyEQ(Binary):
4777    pass
key = 'propertyeq'
class Distance(Binary):
4780class Distance(Binary):
4781    pass
key = 'distance'
class Escape(Binary):
4784class Escape(Binary):
4785    pass
key = 'escape'
class Glob(Binary, Predicate):
4788class Glob(Binary, Predicate):
4789    pass
key = 'glob'
class GT(Binary, Predicate):
4792class GT(Binary, Predicate):
4793    pass
key = 'gt'
class GTE(Binary, Predicate):
4796class GTE(Binary, Predicate):
4797    pass
key = 'gte'
class ILike(Binary, Predicate):
4800class ILike(Binary, Predicate):
4801    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4804class ILikeAny(Binary, Predicate):
4805    pass
key = 'ilikeany'
class IntDiv(Binary):
4808class IntDiv(Binary):
4809    pass
key = 'intdiv'
class Is(Binary, Predicate):
4812class Is(Binary, Predicate):
4813    pass
key = 'is'
class Kwarg(Binary):
4816class Kwarg(Binary):
4817    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4820class Like(Binary, Predicate):
4821    pass
key = 'like'
class LikeAny(Binary, Predicate):
4824class LikeAny(Binary, Predicate):
4825    pass
key = 'likeany'
class LT(Binary, Predicate):
4828class LT(Binary, Predicate):
4829    pass
key = 'lt'
class LTE(Binary, Predicate):
4832class LTE(Binary, Predicate):
4833    pass
key = 'lte'
class Mod(Binary):
4836class Mod(Binary):
4837    pass
key = 'mod'
class Mul(Binary):
4840class Mul(Binary):
4841    pass
key = 'mul'
class NEQ(Binary, Predicate):
4844class NEQ(Binary, Predicate):
4845    pass
key = 'neq'
class Operator(Binary):
4849class Operator(Binary):
4850    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4853class SimilarTo(Binary, Predicate):
4854    pass
key = 'similarto'
class Slice(Binary):
4857class Slice(Binary):
4858    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4861class Sub(Binary):
4862    pass
key = 'sub'
class Unary(Condition):
4867class Unary(Condition):
4868    pass
key = 'unary'
class BitwiseNot(Unary):
4871class BitwiseNot(Unary):
4872    pass
key = 'bitwisenot'
class Not(Unary):
4875class Not(Unary):
4876    pass
key = 'not'
class Paren(Unary):
4879class Paren(Unary):
4880    @property
4881    def output_name(self) -> str:
4882        return self.this.name
output_name: str
4880    @property
4881    def output_name(self) -> str:
4882        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):
4885class Neg(Unary):
4886    def to_py(self) -> int | Decimal:
4887        if self.is_number:
4888            return self.this.to_py() * -1
4889        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4886    def to_py(self) -> int | Decimal:
4887        if self.is_number:
4888            return self.this.to_py() * -1
4889        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4892class Alias(Expression):
4893    arg_types = {"this": True, "alias": False}
4894
4895    @property
4896    def output_name(self) -> str:
4897        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4895    @property
4896    def output_name(self) -> str:
4897        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):
4902class PivotAlias(Alias):
4903    pass
key = 'pivotalias'
class PivotAny(Expression):
4908class PivotAny(Expression):
4909    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4912class Aliases(Expression):
4913    arg_types = {"this": True, "expressions": True}
4914
4915    @property
4916    def aliases(self):
4917        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4915    @property
4916    def aliases(self):
4917        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4921class AtIndex(Expression):
4922    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4925class AtTimeZone(Expression):
4926    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4929class FromTimeZone(Expression):
4930    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4933class Between(Predicate):
4934    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4937class Bracket(Condition):
4938    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4939    arg_types = {
4940        "this": True,
4941        "expressions": True,
4942        "offset": False,
4943        "safe": False,
4944        "returns_list_for_maps": False,
4945    }
4946
4947    @property
4948    def output_name(self) -> str:
4949        if len(self.expressions) == 1:
4950            return self.expressions[0].output_name
4951
4952        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4947    @property
4948    def output_name(self) -> str:
4949        if len(self.expressions) == 1:
4950            return self.expressions[0].output_name
4951
4952        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):
4955class Distinct(Expression):
4956    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4959class In(Predicate):
4960    arg_types = {
4961        "this": True,
4962        "expressions": False,
4963        "query": False,
4964        "unnest": False,
4965        "field": False,
4966        "is_global": False,
4967    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4971class ForIn(Expression):
4972    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4975class TimeUnit(Expression):
4976    """Automatically converts unit arg into a var."""
4977
4978    arg_types = {"unit": False}
4979
4980    UNABBREVIATED_UNIT_NAME = {
4981        "D": "DAY",
4982        "H": "HOUR",
4983        "M": "MINUTE",
4984        "MS": "MILLISECOND",
4985        "NS": "NANOSECOND",
4986        "Q": "QUARTER",
4987        "S": "SECOND",
4988        "US": "MICROSECOND",
4989        "W": "WEEK",
4990        "Y": "YEAR",
4991    }
4992
4993    VAR_LIKE = (Column, Literal, Var)
4994
4995    def __init__(self, **args):
4996        unit = args.get("unit")
4997        if isinstance(unit, self.VAR_LIKE):
4998            args["unit"] = Var(
4999                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5000            )
5001        elif isinstance(unit, Week):
5002            unit.set("this", Var(this=unit.this.name.upper()))
5003
5004        super().__init__(**args)
5005
5006    @property
5007    def unit(self) -> t.Optional[Var | IntervalSpan]:
5008        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4995    def __init__(self, **args):
4996        unit = args.get("unit")
4997        if isinstance(unit, self.VAR_LIKE):
4998            args["unit"] = Var(
4999                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5000            )
5001        elif isinstance(unit, Week):
5002            unit.set("this", Var(this=unit.this.name.upper()))
5003
5004        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]
5006    @property
5007    def unit(self) -> t.Optional[Var | IntervalSpan]:
5008        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5011class IntervalOp(TimeUnit):
5012    arg_types = {"unit": False, "expression": True}
5013
5014    def interval(self):
5015        return Interval(
5016            this=self.expression.copy(),
5017            unit=self.unit.copy() if self.unit else None,
5018        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5014    def interval(self):
5015        return Interval(
5016            this=self.expression.copy(),
5017            unit=self.unit.copy() if self.unit else None,
5018        )
key = 'intervalop'
class IntervalSpan(DataType):
5024class IntervalSpan(DataType):
5025    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5028class Interval(TimeUnit):
5029    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5032class IgnoreNulls(Expression):
5033    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5036class RespectNulls(Expression):
5037    pass
key = 'respectnulls'
class HavingMax(Expression):
5041class HavingMax(Expression):
5042    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5046class Func(Condition):
5047    """
5048    The base class for all function expressions.
5049
5050    Attributes:
5051        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5052            treated as a variable length argument and the argument's value will be stored as a list.
5053        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5054            function expression. These values are used to map this node to a name during parsing as
5055            well as to provide the function's name during SQL string generation. By default the SQL
5056            name is set to the expression's class name transformed to snake case.
5057    """
5058
5059    is_var_len_args = False
5060
5061    @classmethod
5062    def from_arg_list(cls, args):
5063        if cls.is_var_len_args:
5064            all_arg_keys = list(cls.arg_types)
5065            # If this function supports variable length argument treat the last argument as such.
5066            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5067            num_non_var = len(non_var_len_arg_keys)
5068
5069            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5070            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5071        else:
5072            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5073
5074        return cls(**args_dict)
5075
5076    @classmethod
5077    def sql_names(cls):
5078        if cls is Func:
5079            raise NotImplementedError(
5080                "SQL name is only supported by concrete function implementations"
5081            )
5082        if "_sql_names" not in cls.__dict__:
5083            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5084        return cls._sql_names
5085
5086    @classmethod
5087    def sql_name(cls):
5088        return cls.sql_names()[0]
5089
5090    @classmethod
5091    def default_parser_mappings(cls):
5092        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):
5061    @classmethod
5062    def from_arg_list(cls, args):
5063        if cls.is_var_len_args:
5064            all_arg_keys = list(cls.arg_types)
5065            # If this function supports variable length argument treat the last argument as such.
5066            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5067            num_non_var = len(non_var_len_arg_keys)
5068
5069            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5070            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5071        else:
5072            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5073
5074        return cls(**args_dict)
@classmethod
def sql_names(cls):
5076    @classmethod
5077    def sql_names(cls):
5078        if cls is Func:
5079            raise NotImplementedError(
5080                "SQL name is only supported by concrete function implementations"
5081            )
5082        if "_sql_names" not in cls.__dict__:
5083            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5084        return cls._sql_names
@classmethod
def sql_name(cls):
5086    @classmethod
5087    def sql_name(cls):
5088        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5090    @classmethod
5091    def default_parser_mappings(cls):
5092        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5095class AggFunc(Func):
5096    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5099class ParameterizedAgg(AggFunc):
5100    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5103class Abs(Func):
5104    pass
key = 'abs'
class ArgMax(AggFunc):
5107class ArgMax(AggFunc):
5108    arg_types = {"this": True, "expression": True, "count": False}
5109    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5112class ArgMin(AggFunc):
5113    arg_types = {"this": True, "expression": True, "count": False}
5114    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5117class ApproxTopK(AggFunc):
5118    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5121class Flatten(Func):
5122    pass
key = 'flatten'
class Transform(Func):
5126class Transform(Func):
5127    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5130class Anonymous(Func):
5131    arg_types = {"this": True, "expressions": False}
5132    is_var_len_args = True
5133
5134    @property
5135    def name(self) -> str:
5136        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
5134    @property
5135    def name(self) -> str:
5136        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5139class AnonymousAggFunc(AggFunc):
5140    arg_types = {"this": True, "expressions": False}
5141    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5145class CombinedAggFunc(AnonymousAggFunc):
5146    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5149class CombinedParameterizedAgg(ParameterizedAgg):
5150    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):
5155class Hll(AggFunc):
5156    arg_types = {"this": True, "expressions": False}
5157    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5160class ApproxDistinct(AggFunc):
5161    arg_types = {"this": True, "accuracy": False}
5162    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5165class Apply(Func):
5166    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5169class Array(Func):
5170    arg_types = {"expressions": False, "bracket_notation": False}
5171    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5175class ToArray(Func):
5176    pass
key = 'toarray'
class List(Func):
5180class List(Func):
5181    arg_types = {"expressions": False}
5182    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5186class Pad(Func):
5187    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):
5192class ToChar(Func):
5193    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5198class ToNumber(Func):
5199    arg_types = {
5200        "this": True,
5201        "format": False,
5202        "nlsparam": False,
5203        "precision": False,
5204        "scale": False,
5205    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5209class ToDouble(Func):
5210    arg_types = {
5211        "this": True,
5212        "format": False,
5213    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5216class Columns(Func):
5217    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5221class Convert(Func):
5222    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5225class ConvertTimezone(Func):
5226    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):
5229class GenerateSeries(Func):
5230    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):
5236class ExplodingGenerateSeries(GenerateSeries):
5237    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5240class ArrayAgg(AggFunc):
5241    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5244class ArrayUniqueAgg(AggFunc):
5245    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5248class ArrayAll(Func):
5249    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5253class ArrayAny(Func):
5254    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5257class ArrayConcat(Func):
5258    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5259    arg_types = {"this": True, "expressions": False}
5260    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5263class ArrayConstructCompact(Func):
5264    arg_types = {"expressions": True}
5265    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5268class ArrayContains(Binary, Func):
5269    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5272class ArrayContainsAll(Binary, Func):
5273    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5276class ArrayFilter(Func):
5277    arg_types = {"this": True, "expression": True}
5278    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5281class ArrayToString(Func):
5282    arg_types = {"this": True, "expression": True, "null": False}
5283    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
5286class StringToArray(Func):
5287    arg_types = {"this": True, "expression": True, "null": False}
5288    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5291class ArrayOverlaps(Binary, Func):
5292    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5295class ArraySize(Func):
5296    arg_types = {"this": True, "expression": False}
5297    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5300class ArraySort(Func):
5301    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5304class ArraySum(Func):
5305    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5308class ArrayUnionAgg(AggFunc):
5309    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5312class Avg(AggFunc):
5313    pass
key = 'avg'
class AnyValue(AggFunc):
5316class AnyValue(AggFunc):
5317    pass
key = 'anyvalue'
class Lag(AggFunc):
5320class Lag(AggFunc):
5321    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5324class Lead(AggFunc):
5325    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5330class First(AggFunc):
5331    pass
key = 'first'
class Last(AggFunc):
5334class Last(AggFunc):
5335    pass
key = 'last'
class FirstValue(AggFunc):
5338class FirstValue(AggFunc):
5339    pass
key = 'firstvalue'
class LastValue(AggFunc):
5342class LastValue(AggFunc):
5343    pass
key = 'lastvalue'
class NthValue(AggFunc):
5346class NthValue(AggFunc):
5347    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5350class Case(Func):
5351    arg_types = {"this": False, "ifs": True, "default": False}
5352
5353    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5354        instance = maybe_copy(self, copy)
5355        instance.append(
5356            "ifs",
5357            If(
5358                this=maybe_parse(condition, copy=copy, **opts),
5359                true=maybe_parse(then, copy=copy, **opts),
5360            ),
5361        )
5362        return instance
5363
5364    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5365        instance = maybe_copy(self, copy)
5366        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5367        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:
5353    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5354        instance = maybe_copy(self, copy)
5355        instance.append(
5356            "ifs",
5357            If(
5358                this=maybe_parse(condition, copy=copy, **opts),
5359                true=maybe_parse(then, copy=copy, **opts),
5360            ),
5361        )
5362        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5364    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5365        instance = maybe_copy(self, copy)
5366        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5367        return instance
key = 'case'
class Cast(Func):
5370class Cast(Func):
5371    arg_types = {
5372        "this": True,
5373        "to": True,
5374        "format": False,
5375        "safe": False,
5376        "action": False,
5377    }
5378
5379    @property
5380    def name(self) -> str:
5381        return self.this.name
5382
5383    @property
5384    def to(self) -> DataType:
5385        return self.args["to"]
5386
5387    @property
5388    def output_name(self) -> str:
5389        return self.name
5390
5391    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5392        """
5393        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5394        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5395        array<int> != array<float>.
5396
5397        Args:
5398            dtypes: the data types to compare this Cast's DataType to.
5399
5400        Returns:
5401            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5402        """
5403        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5379    @property
5380    def name(self) -> str:
5381        return self.this.name
to: DataType
5383    @property
5384    def to(self) -> DataType:
5385        return self.args["to"]
output_name: str
5387    @property
5388    def output_name(self) -> str:
5389        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:
5391    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5392        """
5393        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5394        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5395        array<int> != array<float>.
5396
5397        Args:
5398            dtypes: the data types to compare this Cast's DataType to.
5399
5400        Returns:
5401            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5402        """
5403        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):
5406class TryCast(Cast):
5407    pass
key = 'trycast'
class Try(Func):
5410class Try(Func):
5411    pass
key = 'try'
class CastToStrType(Func):
5414class CastToStrType(Func):
5415    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5418class Collate(Binary, Func):
5419    pass
key = 'collate'
class Ceil(Func):
5422class Ceil(Func):
5423    arg_types = {"this": True, "decimals": False}
5424    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5427class Coalesce(Func):
5428    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5429    is_var_len_args = True
5430    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5433class Chr(Func):
5434    arg_types = {"expressions": True, "charset": False}
5435    is_var_len_args = True
5436    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5439class Concat(Func):
5440    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5441    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5444class ConcatWs(Concat):
5445    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5449class ConnectByRoot(Func):
5450    pass
key = 'connectbyroot'
class Count(AggFunc):
5453class Count(AggFunc):
5454    arg_types = {"this": False, "expressions": False, "big_int": False}
5455    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5458class CountIf(AggFunc):
5459    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5463class Cbrt(Func):
5464    pass
key = 'cbrt'
class CurrentDate(Func):
5467class CurrentDate(Func):
5468    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5471class CurrentDatetime(Func):
5472    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5475class CurrentTime(Func):
5476    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5479class CurrentTimestamp(Func):
5480    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5483class CurrentUser(Func):
5484    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5487class DateAdd(Func, IntervalOp):
5488    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5491class DateSub(Func, IntervalOp):
5492    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5495class DateDiff(Func, TimeUnit):
5496    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5497    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5500class DateTrunc(Func):
5501    arg_types = {"unit": True, "this": True, "zone": False}
5502
5503    def __init__(self, **args):
5504        unit = args.get("unit")
5505        if isinstance(unit, TimeUnit.VAR_LIKE):
5506            args["unit"] = Literal.string(
5507                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5508            )
5509        elif isinstance(unit, Week):
5510            unit.set("this", Literal.string(unit.this.name.upper()))
5511
5512        super().__init__(**args)
5513
5514    @property
5515    def unit(self) -> Expression:
5516        return self.args["unit"]
DateTrunc(**args)
5503    def __init__(self, **args):
5504        unit = args.get("unit")
5505        if isinstance(unit, TimeUnit.VAR_LIKE):
5506            args["unit"] = Literal.string(
5507                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5508            )
5509        elif isinstance(unit, Week):
5510            unit.set("this", Literal.string(unit.this.name.upper()))
5511
5512        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5514    @property
5515    def unit(self) -> Expression:
5516        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5521class Datetime(Func):
5522    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5525class DatetimeAdd(Func, IntervalOp):
5526    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5529class DatetimeSub(Func, IntervalOp):
5530    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5533class DatetimeDiff(Func, TimeUnit):
5534    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5537class DatetimeTrunc(Func, TimeUnit):
5538    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5541class DayOfWeek(Func):
5542    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5547class DayOfWeekIso(Func):
5548    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5551class DayOfMonth(Func):
5552    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5555class DayOfYear(Func):
5556    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5559class ToDays(Func):
5560    pass
key = 'todays'
class WeekOfYear(Func):
5563class WeekOfYear(Func):
5564    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5567class MonthsBetween(Func):
5568    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5571class LastDay(Func, TimeUnit):
5572    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5573    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5576class Extract(Func):
5577    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5580class Timestamp(Func):
5581    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5584class TimestampAdd(Func, TimeUnit):
5585    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5588class TimestampSub(Func, TimeUnit):
5589    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5592class TimestampDiff(Func, TimeUnit):
5593    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5594    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5597class TimestampTrunc(Func, TimeUnit):
5598    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5601class TimeAdd(Func, TimeUnit):
5602    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5605class TimeSub(Func, TimeUnit):
5606    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5609class TimeDiff(Func, TimeUnit):
5610    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5613class TimeTrunc(Func, TimeUnit):
5614    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5617class DateFromParts(Func):
5618    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5619    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5622class TimeFromParts(Func):
5623    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5624    arg_types = {
5625        "hour": True,
5626        "min": True,
5627        "sec": True,
5628        "nano": False,
5629        "fractions": False,
5630        "precision": False,
5631    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5634class DateStrToDate(Func):
5635    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5638class DateToDateStr(Func):
5639    pass
key = 'datetodatestr'
class DateToDi(Func):
5642class DateToDi(Func):
5643    pass
key = 'datetodi'
class Date(Func):
5647class Date(Func):
5648    arg_types = {"this": False, "zone": False, "expressions": False}
5649    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5652class Day(Func):
5653    pass
key = 'day'
class Decode(Func):
5656class Decode(Func):
5657    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5660class DiToDate(Func):
5661    pass
key = 'ditodate'
class Encode(Func):
5664class Encode(Func):
5665    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5668class Exp(Func):
5669    pass
key = 'exp'
class Explode(Func, UDTF):
5673class Explode(Func, UDTF):
5674    arg_types = {"this": True, "expressions": False}
5675    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5679class Inline(Func):
5680    pass
key = 'inline'
class ExplodeOuter(Explode):
5683class ExplodeOuter(Explode):
5684    pass
key = 'explodeouter'
class Posexplode(Explode):
5687class Posexplode(Explode):
5688    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5691class PosexplodeOuter(Posexplode, ExplodeOuter):
5692    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5695class Unnest(Func, UDTF):
5696    arg_types = {
5697        "expressions": True,
5698        "alias": False,
5699        "offset": False,
5700        "explode_array": False,
5701    }
5702
5703    @property
5704    def selects(self) -> t.List[Expression]:
5705        columns = super().selects
5706        offset = self.args.get("offset")
5707        if offset:
5708            columns = columns + [to_identifier("offset") if offset is True else offset]
5709        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5703    @property
5704    def selects(self) -> t.List[Expression]:
5705        columns = super().selects
5706        offset = self.args.get("offset")
5707        if offset:
5708            columns = columns + [to_identifier("offset") if offset is True else offset]
5709        return columns
key = 'unnest'
class Floor(Func):
5712class Floor(Func):
5713    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5716class FromBase64(Func):
5717    pass
key = 'frombase64'
class ToBase64(Func):
5720class ToBase64(Func):
5721    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5725class FromISO8601Timestamp(Func):
5726    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5729class GapFill(Func):
5730    arg_types = {
5731        "this": True,
5732        "ts_column": True,
5733        "bucket_width": True,
5734        "partitioning_columns": False,
5735        "value_columns": False,
5736        "origin": False,
5737        "ignore_nulls": False,
5738    }
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):
5742class GenerateDateArray(Func):
5743    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5747class GenerateTimestampArray(Func):
5748    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5751class Greatest(Func):
5752    arg_types = {"this": True, "expressions": False}
5753    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5756class GroupConcat(AggFunc):
5757    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5760class Hex(Func):
5761    pass
key = 'hex'
class LowerHex(Hex):
5764class LowerHex(Hex):
5765    pass
key = 'lowerhex'
class Xor(Connector, Func):
5768class Xor(Connector, Func):
5769    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5772class If(Func):
5773    arg_types = {"this": True, "true": True, "false": False}
5774    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5777class Nullif(Func):
5778    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5781class Initcap(Func):
5782    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5785class IsNan(Func):
5786    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5789class IsInf(Func):
5790    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5794class JSON(Expression):
5795    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5798class JSONPath(Expression):
5799    arg_types = {"expressions": True, "escape": False}
5800
5801    @property
5802    def output_name(self) -> str:
5803        last_segment = self.expressions[-1].this
5804        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5801    @property
5802    def output_name(self) -> str:
5803        last_segment = self.expressions[-1].this
5804        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):
5807class JSONPathPart(Expression):
5808    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5811class JSONPathFilter(JSONPathPart):
5812    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5815class JSONPathKey(JSONPathPart):
5816    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5819class JSONPathRecursive(JSONPathPart):
5820    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5823class JSONPathRoot(JSONPathPart):
5824    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5827class JSONPathScript(JSONPathPart):
5828    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5831class JSONPathSlice(JSONPathPart):
5832    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5835class JSONPathSelector(JSONPathPart):
5836    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5839class JSONPathSubscript(JSONPathPart):
5840    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5843class JSONPathUnion(JSONPathPart):
5844    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5847class JSONPathWildcard(JSONPathPart):
5848    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5851class FormatJson(Expression):
5852    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5855class JSONKeyValue(Expression):
5856    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5859class JSONObject(Func):
5860    arg_types = {
5861        "expressions": False,
5862        "null_handling": False,
5863        "unique_keys": False,
5864        "return_type": False,
5865        "encoding": False,
5866    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5869class JSONObjectAgg(AggFunc):
5870    arg_types = {
5871        "expressions": False,
5872        "null_handling": False,
5873        "unique_keys": False,
5874        "return_type": False,
5875        "encoding": False,
5876    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5880class JSONArray(Func):
5881    arg_types = {
5882        "expressions": True,
5883        "null_handling": False,
5884        "return_type": False,
5885        "strict": False,
5886    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5890class JSONArrayAgg(Func):
5891    arg_types = {
5892        "this": True,
5893        "order": False,
5894        "null_handling": False,
5895        "return_type": False,
5896        "strict": False,
5897    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5900class JSONExists(Func):
5901    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):
5906class JSONColumnDef(Expression):
5907    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):
5910class JSONSchema(Expression):
5911    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5915class JSONValue(Expression):
5916    arg_types = {
5917        "this": True,
5918        "path": True,
5919        "returning": False,
5920        "on_condition": False,
5921    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONTable(Func):
5925class JSONTable(Func):
5926    arg_types = {
5927        "this": True,
5928        "schema": True,
5929        "path": False,
5930        "error_handling": False,
5931        "empty_handling": False,
5932    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5936class ObjectInsert(Func):
5937    arg_types = {
5938        "this": True,
5939        "key": True,
5940        "value": True,
5941        "update_flag": False,
5942    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5945class OpenJSONColumnDef(Expression):
5946    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):
5949class OpenJSON(Func):
5950    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5953class JSONBContains(Binary, Func):
5954    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5957class JSONExtract(Binary, Func):
5958    arg_types = {
5959        "this": True,
5960        "expression": True,
5961        "only_json_types": False,
5962        "expressions": False,
5963        "variant_extract": False,
5964        "json_query": False,
5965        "option": False,
5966    }
5967    _sql_names = ["JSON_EXTRACT"]
5968    is_var_len_args = True
5969
5970    @property
5971    def output_name(self) -> str:
5972        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
5970    @property
5971    def output_name(self) -> str:
5972        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 JSONExtractScalar(Binary, Func):
5975class JSONExtractScalar(Binary, Func):
5976    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5977    _sql_names = ["JSON_EXTRACT_SCALAR"]
5978    is_var_len_args = True
5979
5980    @property
5981    def output_name(self) -> str:
5982        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
5980    @property
5981    def output_name(self) -> str:
5982        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):
5985class JSONBExtract(Binary, Func):
5986    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5989class JSONBExtractScalar(Binary, Func):
5990    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5993class JSONFormat(Func):
5994    arg_types = {"this": False, "options": False}
5995    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5999class JSONArrayContains(Binary, Predicate, Func):
6000    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6003class ParseJSON(Func):
6004    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6005    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6006    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6007    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6010class Least(Func):
6011    arg_types = {"this": True, "expressions": False}
6012    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6015class Left(Func):
6016    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6023class Length(Func):
6024    arg_types = {"this": True, "binary": False}
6025    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
6028class Levenshtein(Func):
6029    arg_types = {
6030        "this": True,
6031        "expression": False,
6032        "ins_cost": False,
6033        "del_cost": False,
6034        "sub_cost": False,
6035    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
6038class Ln(Func):
6039    pass
key = 'ln'
class Log(Func):
6042class Log(Func):
6043    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6046class LogicalOr(AggFunc):
6047    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6050class LogicalAnd(AggFunc):
6051    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6054class Lower(Func):
6055    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6058class Map(Func):
6059    arg_types = {"keys": False, "values": False}
6060
6061    @property
6062    def keys(self) -> t.List[Expression]:
6063        keys = self.args.get("keys")
6064        return keys.expressions if keys else []
6065
6066    @property
6067    def values(self) -> t.List[Expression]:
6068        values = self.args.get("values")
6069        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6061    @property
6062    def keys(self) -> t.List[Expression]:
6063        keys = self.args.get("keys")
6064        return keys.expressions if keys else []
values: List[Expression]
6066    @property
6067    def values(self) -> t.List[Expression]:
6068        values = self.args.get("values")
6069        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6073class ToMap(Func):
6074    pass
key = 'tomap'
class MapFromEntries(Func):
6077class MapFromEntries(Func):
6078    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6082class ScopeResolution(Expression):
6083    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6086class Stream(Expression):
6087    pass
key = 'stream'
class StarMap(Func):
6090class StarMap(Func):
6091    pass
key = 'starmap'
class VarMap(Func):
6094class VarMap(Func):
6095    arg_types = {"keys": True, "values": True}
6096    is_var_len_args = True
6097
6098    @property
6099    def keys(self) -> t.List[Expression]:
6100        return self.args["keys"].expressions
6101
6102    @property
6103    def values(self) -> t.List[Expression]:
6104        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6098    @property
6099    def keys(self) -> t.List[Expression]:
6100        return self.args["keys"].expressions
values: List[Expression]
6102    @property
6103    def values(self) -> t.List[Expression]:
6104        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6108class MatchAgainst(Func):
6109    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6112class Max(AggFunc):
6113    arg_types = {"this": True, "expressions": False}
6114    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6117class MD5(Func):
6118    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6122class MD5Digest(Func):
6123    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
6126class Min(AggFunc):
6127    arg_types = {"this": True, "expressions": False}
6128    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6131class Month(Func):
6132    pass
key = 'month'
class AddMonths(Func):
6135class AddMonths(Func):
6136    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6139class Nvl2(Func):
6140    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6143class Normalize(Func):
6144    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6147class Overlay(Func):
6148    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):
6152class Predict(Func):
6153    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6156class Pow(Binary, Func):
6157    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6160class PercentileCont(AggFunc):
6161    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6164class PercentileDisc(AggFunc):
6165    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6168class Quantile(AggFunc):
6169    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6172class ApproxQuantile(Quantile):
6173    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):
6176class Quarter(Func):
6177    pass
key = 'quarter'
class Rand(Func):
6182class Rand(Func):
6183    _sql_names = ["RAND", "RANDOM"]
6184    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6187class Randn(Func):
6188    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6191class RangeN(Func):
6192    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6195class ReadCSV(Func):
6196    _sql_names = ["READ_CSV"]
6197    is_var_len_args = True
6198    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6201class Reduce(Func):
6202    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):
6205class RegexpExtract(Func):
6206    arg_types = {
6207        "this": True,
6208        "expression": True,
6209        "position": False,
6210        "occurrence": False,
6211        "parameters": False,
6212        "group": False,
6213    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
6216class RegexpReplace(Func):
6217    arg_types = {
6218        "this": True,
6219        "expression": True,
6220        "replacement": False,
6221        "position": False,
6222        "occurrence": False,
6223        "modifiers": False,
6224    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6227class RegexpLike(Binary, Func):
6228    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6231class RegexpILike(Binary, Func):
6232    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6237class RegexpSplit(Func):
6238    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6241class Repeat(Func):
6242    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6247class Round(Func):
6248    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6251class RowNumber(Func):
6252    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
6255class SafeDivide(Func):
6256    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6259class SHA(Func):
6260    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6263class SHA2(Func):
6264    _sql_names = ["SHA2"]
6265    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6268class Sign(Func):
6269    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6272class SortArray(Func):
6273    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6276class Split(Func):
6277    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6281class SplitPart(Func):
6282    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6287class Substring(Func):
6288    _sql_names = ["SUBSTRING", "SUBSTR"]
6289    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6292class StandardHash(Func):
6293    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6296class StartsWith(Func):
6297    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6298    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6301class StrPosition(Func):
6302    arg_types = {
6303        "this": True,
6304        "substr": True,
6305        "position": False,
6306        "instance": False,
6307    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6310class StrToDate(Func):
6311    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6314class StrToTime(Func):
6315    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):
6320class StrToUnix(Func):
6321    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6326class StrToMap(Func):
6327    arg_types = {
6328        "this": True,
6329        "pair_delim": False,
6330        "key_value_delim": False,
6331        "duplicate_resolution_callback": False,
6332    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6335class NumberToStr(Func):
6336    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6339class FromBase(Func):
6340    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6343class Struct(Func):
6344    arg_types = {"expressions": False}
6345    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6348class StructExtract(Func):
6349    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6354class Stuff(Func):
6355    _sql_names = ["STUFF", "INSERT"]
6356    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):
6359class Sum(AggFunc):
6360    pass
key = 'sum'
class Sqrt(Func):
6363class Sqrt(Func):
6364    pass
key = 'sqrt'
class Stddev(AggFunc):
6367class Stddev(AggFunc):
6368    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6371class StddevPop(AggFunc):
6372    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6375class StddevSamp(AggFunc):
6376    pass
key = 'stddevsamp'
class Time(Func):
6380class Time(Func):
6381    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6384class TimeToStr(Func):
6385    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):
6388class TimeToTimeStr(Func):
6389    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6392class TimeToUnix(Func):
6393    pass
key = 'timetounix'
class TimeStrToDate(Func):
6396class TimeStrToDate(Func):
6397    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6400class TimeStrToTime(Func):
6401    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6404class TimeStrToUnix(Func):
6405    pass
key = 'timestrtounix'
class Trim(Func):
6408class Trim(Func):
6409    arg_types = {
6410        "this": True,
6411        "expression": False,
6412        "position": False,
6413        "collation": False,
6414    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6417class TsOrDsAdd(Func, TimeUnit):
6418    # return_type is used to correctly cast the arguments of this expression when transpiling it
6419    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6420
6421    @property
6422    def return_type(self) -> DataType:
6423        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
6421    @property
6422    def return_type(self) -> DataType:
6423        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6426class TsOrDsDiff(Func, TimeUnit):
6427    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6430class TsOrDsToDateStr(Func):
6431    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6434class TsOrDsToDate(Func):
6435    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6438class TsOrDsToTime(Func):
6439    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6442class TsOrDsToTimestamp(Func):
6443    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6446class TsOrDiToDi(Func):
6447    pass
key = 'tsorditodi'
class Unhex(Func):
6450class Unhex(Func):
6451    pass
key = 'unhex'
class UnixDate(Func):
6455class UnixDate(Func):
6456    pass
key = 'unixdate'
class UnixToStr(Func):
6459class UnixToStr(Func):
6460    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6465class UnixToTime(Func):
6466    arg_types = {
6467        "this": True,
6468        "scale": False,
6469        "zone": False,
6470        "hours": False,
6471        "minutes": False,
6472        "format": False,
6473    }
6474
6475    SECONDS = Literal.number(0)
6476    DECIS = Literal.number(1)
6477    CENTIS = Literal.number(2)
6478    MILLIS = Literal.number(3)
6479    DECIMILLIS = Literal.number(4)
6480    CENTIMILLIS = Literal.number(5)
6481    MICROS = Literal.number(6)
6482    DECIMICROS = Literal.number(7)
6483    CENTIMICROS = Literal.number(8)
6484    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):
6487class UnixToTimeStr(Func):
6488    pass
key = 'unixtotimestr'
class Uuid(Func):
6491class Uuid(Func):
6492    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6493
6494    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6497class TimestampFromParts(Func):
6498    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6499    arg_types = {
6500        "year": True,
6501        "month": True,
6502        "day": True,
6503        "hour": True,
6504        "min": True,
6505        "sec": True,
6506        "nano": False,
6507        "zone": False,
6508        "milli": False,
6509    }
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):
6512class Upper(Func):
6513    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6516class Corr(Binary, AggFunc):
6517    pass
key = 'corr'
class Variance(AggFunc):
6520class Variance(AggFunc):
6521    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6524class VariancePop(AggFunc):
6525    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6528class CovarSamp(Binary, AggFunc):
6529    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6532class CovarPop(Binary, AggFunc):
6533    pass
key = 'covarpop'
class Week(Func):
6536class Week(Func):
6537    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6540class XMLTable(Func):
6541    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):
6544class Year(Func):
6545    pass
key = 'year'
class Use(Expression):
6548class Use(Expression):
6549    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6552class Merge(DML):
6553    arg_types = {
6554        "this": True,
6555        "using": True,
6556        "on": True,
6557        "expressions": True,
6558        "with": False,
6559        "returning": False,
6560    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6563class When(Func):
6564    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):
6569class NextValueFor(Func):
6570    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6575class Semicolon(Expression):
6576    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 '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 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <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 '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 '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 '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 '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'>, '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_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, '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'>, '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'>, '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_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_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_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:
6616def maybe_parse(
6617    sql_or_expression: ExpOrStr,
6618    *,
6619    into: t.Optional[IntoType] = None,
6620    dialect: DialectType = None,
6621    prefix: t.Optional[str] = None,
6622    copy: bool = False,
6623    **opts,
6624) -> Expression:
6625    """Gracefully handle a possible string or expression.
6626
6627    Example:
6628        >>> maybe_parse("1")
6629        Literal(this=1, is_string=False)
6630        >>> maybe_parse(to_identifier("x"))
6631        Identifier(this=x, quoted=False)
6632
6633    Args:
6634        sql_or_expression: the SQL code string or an expression
6635        into: the SQLGlot Expression to parse into
6636        dialect: the dialect used to parse the input expressions (in the case that an
6637            input expression is a SQL string).
6638        prefix: a string to prefix the sql with before it gets parsed
6639            (automatically includes a space)
6640        copy: whether to copy the expression.
6641        **opts: other options to use to parse the input expressions (again, in the case
6642            that an input expression is a SQL string).
6643
6644    Returns:
6645        Expression: the parsed or given expression.
6646    """
6647    if isinstance(sql_or_expression, Expression):
6648        if copy:
6649            return sql_or_expression.copy()
6650        return sql_or_expression
6651
6652    if sql_or_expression is None:
6653        raise ParseError("SQL cannot be None")
6654
6655    import sqlglot
6656
6657    sql = str(sql_or_expression)
6658    if prefix:
6659        sql = f"{prefix} {sql}"
6660
6661    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):
6672def maybe_copy(instance, copy=True):
6673    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:
6908def union(
6909    *expressions: ExpOrStr,
6910    distinct: bool = True,
6911    dialect: DialectType = None,
6912    copy: bool = True,
6913    **opts,
6914) -> Union:
6915    """
6916    Initializes a syntax tree for the `UNION` operation.
6917
6918    Example:
6919        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6920        'SELECT * FROM foo UNION SELECT * FROM bla'
6921
6922    Args:
6923        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
6924            If `Expression` instances are passed, they will be used as-is.
6925        distinct: set the DISTINCT flag if and only if this is true.
6926        dialect: the dialect used to parse the input expression.
6927        copy: whether to copy the expression.
6928        opts: other options to use to parse the input expressions.
6929
6930    Returns:
6931        The new Union instance.
6932    """
6933    assert len(expressions) >= 2, "At least two expressions are required by `union`."
6934    return _apply_set_operation(
6935        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
6936    )

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:
6939def intersect(
6940    *expressions: ExpOrStr,
6941    distinct: bool = True,
6942    dialect: DialectType = None,
6943    copy: bool = True,
6944    **opts,
6945) -> Intersect:
6946    """
6947    Initializes a syntax tree for the `INTERSECT` operation.
6948
6949    Example:
6950        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6951        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6952
6953    Args:
6954        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
6955            If `Expression` instances are passed, they will be used as-is.
6956        distinct: set the DISTINCT flag if and only if this is true.
6957        dialect: the dialect used to parse the input expression.
6958        copy: whether to copy the expression.
6959        opts: other options to use to parse the input expressions.
6960
6961    Returns:
6962        The new Intersect instance.
6963    """
6964    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
6965    return _apply_set_operation(
6966        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
6967    )

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:
6970def except_(
6971    *expressions: ExpOrStr,
6972    distinct: bool = True,
6973    dialect: DialectType = None,
6974    copy: bool = True,
6975    **opts,
6976) -> Except:
6977    """
6978    Initializes a syntax tree for the `EXCEPT` operation.
6979
6980    Example:
6981        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6982        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6983
6984    Args:
6985        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
6986            If `Expression` instances are passed, they will be used as-is.
6987        distinct: set the DISTINCT flag if and only if this is true.
6988        dialect: the dialect used to parse the input expression.
6989        copy: whether to copy the expression.
6990        opts: other options to use to parse the input expressions.
6991
6992    Returns:
6993        The new Except instance.
6994    """
6995    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
6996    return _apply_set_operation(
6997        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
6998    )

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:
7001def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7002    """
7003    Initializes a syntax tree from one or multiple SELECT expressions.
7004
7005    Example:
7006        >>> select("col1", "col2").from_("tbl").sql()
7007        'SELECT col1, col2 FROM tbl'
7008
7009    Args:
7010        *expressions: the SQL code string to parse as the expressions of a
7011            SELECT statement. If an Expression instance is passed, this is used as-is.
7012        dialect: the dialect used to parse the input expressions (in the case that an
7013            input expression is a SQL string).
7014        **opts: other options to use to parse the input expressions (again, in the case
7015            that an input expression is a SQL string).
7016
7017    Returns:
7018        Select: the syntax tree for the SELECT statement.
7019    """
7020    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:
7023def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7024    """
7025    Initializes a syntax tree from a FROM expression.
7026
7027    Example:
7028        >>> from_("tbl").select("col1", "col2").sql()
7029        'SELECT col1, col2 FROM tbl'
7030
7031    Args:
7032        *expression: the SQL code string to parse as the FROM expressions of a
7033            SELECT statement. If an Expression instance is passed, this is used as-is.
7034        dialect: the dialect used to parse the input expression (in the case that the
7035            input expression is a SQL string).
7036        **opts: other options to use to parse the input expressions (again, in the case
7037            that the input expression is a SQL string).
7038
7039    Returns:
7040        Select: the syntax tree for the SELECT statement.
7041    """
7042    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:
7045def update(
7046    table: str | Table,
7047    properties: t.Optional[dict] = None,
7048    where: t.Optional[ExpOrStr] = None,
7049    from_: t.Optional[ExpOrStr] = None,
7050    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7051    dialect: DialectType = None,
7052    **opts,
7053) -> Update:
7054    """
7055    Creates an update statement.
7056
7057    Example:
7058        >>> 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()
7059        "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"
7060
7061    Args:
7062        properties: dictionary of properties to SET which are
7063            auto converted to sql objects eg None -> NULL
7064        where: sql conditional parsed into a WHERE statement
7065        from_: sql statement parsed into a FROM statement
7066        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7067        dialect: the dialect used to parse the input expressions.
7068        **opts: other options to use to parse the input expressions.
7069
7070    Returns:
7071        Update: the syntax tree for the UPDATE statement.
7072    """
7073    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7074    if properties:
7075        update_expr.set(
7076            "expressions",
7077            [
7078                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7079                for k, v in properties.items()
7080            ],
7081        )
7082    if from_:
7083        update_expr.set(
7084            "from",
7085            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7086        )
7087    if isinstance(where, Condition):
7088        where = Where(this=where)
7089    if where:
7090        update_expr.set(
7091            "where",
7092            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7093        )
7094    if with_:
7095        cte_list = [
7096            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7097            for alias, qry in with_.items()
7098        ]
7099        update_expr.set(
7100            "with",
7101            With(expressions=cte_list),
7102        )
7103    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:
7106def delete(
7107    table: ExpOrStr,
7108    where: t.Optional[ExpOrStr] = None,
7109    returning: t.Optional[ExpOrStr] = None,
7110    dialect: DialectType = None,
7111    **opts,
7112) -> Delete:
7113    """
7114    Builds a delete statement.
7115
7116    Example:
7117        >>> delete("my_table", where="id > 1").sql()
7118        'DELETE FROM my_table WHERE id > 1'
7119
7120    Args:
7121        where: sql conditional parsed into a WHERE statement
7122        returning: sql conditional parsed into a RETURNING statement
7123        dialect: the dialect used to parse the input expressions.
7124        **opts: other options to use to parse the input expressions.
7125
7126    Returns:
7127        Delete: the syntax tree for the DELETE statement.
7128    """
7129    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7130    if where:
7131        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7132    if returning:
7133        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7134    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:
7137def insert(
7138    expression: ExpOrStr,
7139    into: ExpOrStr,
7140    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7141    overwrite: t.Optional[bool] = None,
7142    returning: t.Optional[ExpOrStr] = None,
7143    dialect: DialectType = None,
7144    copy: bool = True,
7145    **opts,
7146) -> Insert:
7147    """
7148    Builds an INSERT statement.
7149
7150    Example:
7151        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7152        'INSERT INTO tbl VALUES (1, 2, 3)'
7153
7154    Args:
7155        expression: the sql string or expression of the INSERT statement
7156        into: the tbl to insert data to.
7157        columns: optionally the table's column names.
7158        overwrite: whether to INSERT OVERWRITE or not.
7159        returning: sql conditional parsed into a RETURNING statement
7160        dialect: the dialect used to parse the input expressions.
7161        copy: whether to copy the expression.
7162        **opts: other options to use to parse the input expressions.
7163
7164    Returns:
7165        Insert: the syntax tree for the INSERT statement.
7166    """
7167    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7168    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7169
7170    if columns:
7171        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7172
7173    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7174
7175    if returning:
7176        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7177
7178    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:
7181def merge(
7182    *when_exprs: ExpOrStr,
7183    into: ExpOrStr,
7184    using: ExpOrStr,
7185    on: ExpOrStr,
7186    returning: t.Optional[ExpOrStr] = None,
7187    dialect: DialectType = None,
7188    copy: bool = True,
7189    **opts,
7190) -> Merge:
7191    """
7192    Builds a MERGE statement.
7193
7194    Example:
7195        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7196        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7197        ...       into="my_table",
7198        ...       using="source_table",
7199        ...       on="my_table.id = source_table.id").sql()
7200        '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)'
7201
7202    Args:
7203        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7204        into: The target table to merge data into.
7205        using: The source table to merge data from.
7206        on: The join condition for the merge.
7207        returning: The columns to return from the merge.
7208        dialect: The dialect used to parse the input expressions.
7209        copy: Whether to copy the expression.
7210        **opts: Other options to use to parse the input expressions.
7211
7212    Returns:
7213        Merge: The syntax tree for the MERGE statement.
7214    """
7215    merge = Merge(
7216        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7217        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7218        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7219        expressions=[
7220            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
7221            for when_expr in when_exprs
7222        ],
7223    )
7224    if returning:
7225        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7226
7227    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:
7230def condition(
7231    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7232) -> Condition:
7233    """
7234    Initialize a logical condition expression.
7235
7236    Example:
7237        >>> condition("x=1").sql()
7238        'x = 1'
7239
7240        This is helpful for composing larger logical syntax trees:
7241        >>> where = condition("x=1")
7242        >>> where = where.and_("y=1")
7243        >>> Select().from_("tbl").select("*").where(where).sql()
7244        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7245
7246    Args:
7247        *expression: the SQL code string to parse.
7248            If an Expression instance is passed, this is used as-is.
7249        dialect: the dialect used to parse the input expression (in the case that the
7250            input expression is a SQL string).
7251        copy: Whether to copy `expression` (only applies to expressions).
7252        **opts: other options to use to parse the input expressions (again, in the case
7253            that the input expression is a SQL string).
7254
7255    Returns:
7256        The new Condition instance
7257    """
7258    return maybe_parse(
7259        expression,
7260        into=Condition,
7261        dialect=dialect,
7262        copy=copy,
7263        **opts,
7264    )

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, **opts) -> Condition:
7267def and_(
7268    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7269) -> Condition:
7270    """
7271    Combine multiple conditions with an AND logical operator.
7272
7273    Example:
7274        >>> and_("x=1", and_("y=1", "z=1")).sql()
7275        'x = 1 AND (y = 1 AND z = 1)'
7276
7277    Args:
7278        *expressions: the SQL code strings to parse.
7279            If an Expression instance is passed, this is used as-is.
7280        dialect: the dialect used to parse the input expression.
7281        copy: whether to copy `expressions` (only applies to Expressions).
7282        **opts: other options to use to parse the input expressions.
7283
7284    Returns:
7285        The new condition
7286    """
7287    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **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).
  • **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, **opts) -> Condition:
7290def or_(
7291    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7292) -> Condition:
7293    """
7294    Combine multiple conditions with an OR logical operator.
7295
7296    Example:
7297        >>> or_("x=1", or_("y=1", "z=1")).sql()
7298        'x = 1 OR (y = 1 OR z = 1)'
7299
7300    Args:
7301        *expressions: the SQL code strings to parse.
7302            If an Expression instance is passed, this is used as-is.
7303        dialect: the dialect used to parse the input expression.
7304        copy: whether to copy `expressions` (only applies to Expressions).
7305        **opts: other options to use to parse the input expressions.
7306
7307    Returns:
7308        The new condition
7309    """
7310    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **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).
  • **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, **opts) -> Condition:
7313def xor(
7314    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7315) -> Condition:
7316    """
7317    Combine multiple conditions with an XOR logical operator.
7318
7319    Example:
7320        >>> xor("x=1", xor("y=1", "z=1")).sql()
7321        'x = 1 XOR (y = 1 XOR z = 1)'
7322
7323    Args:
7324        *expressions: the SQL code strings to parse.
7325            If an Expression instance is passed, this is used as-is.
7326        dialect: the dialect used to parse the input expression.
7327        copy: whether to copy `expressions` (only applies to Expressions).
7328        **opts: other options to use to parse the input expressions.
7329
7330    Returns:
7331        The new condition
7332    """
7333    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, **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).
  • **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:
7336def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7337    """
7338    Wrap a condition with a NOT operator.
7339
7340    Example:
7341        >>> not_("this_suit='black'").sql()
7342        "NOT this_suit = 'black'"
7343
7344    Args:
7345        expression: the SQL code string to parse.
7346            If an Expression instance is passed, this is used as-is.
7347        dialect: the dialect used to parse the input expression.
7348        copy: whether to copy the expression or not.
7349        **opts: other options to use to parse the input expressions.
7350
7351    Returns:
7352        The new condition.
7353    """
7354    this = condition(
7355        expression,
7356        dialect=dialect,
7357        copy=copy,
7358        **opts,
7359    )
7360    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:
7363def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7364    """
7365    Wrap an expression in parentheses.
7366
7367    Example:
7368        >>> paren("5 + 3").sql()
7369        '(5 + 3)'
7370
7371    Args:
7372        expression: the SQL code string to parse.
7373            If an Expression instance is passed, this is used as-is.
7374        copy: whether to copy the expression or not.
7375
7376    Returns:
7377        The wrapped expression.
7378    """
7379    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):
7395def to_identifier(name, quoted=None, copy=True):
7396    """Builds an identifier.
7397
7398    Args:
7399        name: The name to turn into an identifier.
7400        quoted: Whether to force quote the identifier.
7401        copy: Whether to copy name if it's an Identifier.
7402
7403    Returns:
7404        The identifier ast node.
7405    """
7406
7407    if name is None:
7408        return None
7409
7410    if isinstance(name, Identifier):
7411        identifier = maybe_copy(name, copy)
7412    elif isinstance(name, str):
7413        identifier = Identifier(
7414            this=name,
7415            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7416        )
7417    else:
7418        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7419    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:
7422def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7423    """
7424    Parses a given string into an identifier.
7425
7426    Args:
7427        name: The name to parse into an identifier.
7428        dialect: The dialect to parse against.
7429
7430    Returns:
7431        The identifier ast node.
7432    """
7433    try:
7434        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7435    except (ParseError, TokenError):
7436        expression = to_identifier(name)
7437
7438    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:
7444def to_interval(interval: str | Literal) -> Interval:
7445    """Builds an interval expression from a string like '1 day' or '5 months'."""
7446    if isinstance(interval, Literal):
7447        if not interval.is_string:
7448            raise ValueError("Invalid interval string.")
7449
7450        interval = interval.this
7451
7452    interval = maybe_parse(f"INTERVAL {interval}")
7453    assert isinstance(interval, Interval)
7454    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:
7457def to_table(
7458    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7459) -> Table:
7460    """
7461    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7462    If a table is passed in then that table is returned.
7463
7464    Args:
7465        sql_path: a `[catalog].[schema].[table]` string.
7466        dialect: the source dialect according to which the table name will be parsed.
7467        copy: Whether to copy a table if it is passed in.
7468        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7469
7470    Returns:
7471        A table expression.
7472    """
7473    if isinstance(sql_path, Table):
7474        return maybe_copy(sql_path, copy=copy)
7475
7476    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7477
7478    for k, v in kwargs.items():
7479        table.set(k, v)
7480
7481    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:
7484def to_column(
7485    sql_path: str | Column,
7486    quoted: t.Optional[bool] = None,
7487    dialect: DialectType = None,
7488    copy: bool = True,
7489    **kwargs,
7490) -> Column:
7491    """
7492    Create a column from a `[table].[column]` sql path. Table is optional.
7493    If a column is passed in then that column is returned.
7494
7495    Args:
7496        sql_path: a `[table].[column]` string.
7497        quoted: Whether or not to force quote identifiers.
7498        dialect: the source dialect according to which the column name will be parsed.
7499        copy: Whether to copy a column if it is passed in.
7500        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7501
7502    Returns:
7503        A column expression.
7504    """
7505    if isinstance(sql_path, Column):
7506        return maybe_copy(sql_path, copy=copy)
7507
7508    try:
7509        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7510    except ParseError:
7511        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7512
7513    for k, v in kwargs.items():
7514        col.set(k, v)
7515
7516    if quoted:
7517        for i in col.find_all(Identifier):
7518            i.set("quoted", True)
7519
7520    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):
7523def alias_(
7524    expression: ExpOrStr,
7525    alias: t.Optional[str | Identifier],
7526    table: bool | t.Sequence[str | Identifier] = False,
7527    quoted: t.Optional[bool] = None,
7528    dialect: DialectType = None,
7529    copy: bool = True,
7530    **opts,
7531):
7532    """Create an Alias expression.
7533
7534    Example:
7535        >>> alias_('foo', 'bar').sql()
7536        'foo AS bar'
7537
7538        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7539        '(SELECT 1, 2) AS bar(a, b)'
7540
7541    Args:
7542        expression: the SQL code strings to parse.
7543            If an Expression instance is passed, this is used as-is.
7544        alias: the alias name to use. If the name has
7545            special characters it is quoted.
7546        table: Whether to create a table alias, can also be a list of columns.
7547        quoted: whether to quote the alias
7548        dialect: the dialect used to parse the input expression.
7549        copy: Whether to copy the expression.
7550        **opts: other options to use to parse the input expressions.
7551
7552    Returns:
7553        Alias: the aliased expression
7554    """
7555    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7556    alias = to_identifier(alias, quoted=quoted)
7557
7558    if table:
7559        table_alias = TableAlias(this=alias)
7560        exp.set("alias", table_alias)
7561
7562        if not isinstance(table, bool):
7563            for column in table:
7564                table_alias.append("columns", to_identifier(column, quoted=quoted))
7565
7566        return exp
7567
7568    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7569    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7570    # for the complete Window expression.
7571    #
7572    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7573
7574    if "alias" in exp.arg_types and not isinstance(exp, Window):
7575        exp.set("alias", alias)
7576        return exp
7577    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:
7580def subquery(
7581    expression: ExpOrStr,
7582    alias: t.Optional[Identifier | str] = None,
7583    dialect: DialectType = None,
7584    **opts,
7585) -> Select:
7586    """
7587    Build a subquery expression that's selected from.
7588
7589    Example:
7590        >>> subquery('select x from tbl', 'bar').select('x').sql()
7591        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7592
7593    Args:
7594        expression: the SQL code strings to parse.
7595            If an Expression instance is passed, this is used as-is.
7596        alias: the alias name to use.
7597        dialect: the dialect used to parse the input expression.
7598        **opts: other options to use to parse the input expressions.
7599
7600    Returns:
7601        A new Select instance with the subquery expression included.
7602    """
7603
7604    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7605    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):
7636def column(
7637    col,
7638    table=None,
7639    db=None,
7640    catalog=None,
7641    *,
7642    fields=None,
7643    quoted=None,
7644    copy=True,
7645):
7646    """
7647    Build a Column.
7648
7649    Args:
7650        col: Column name.
7651        table: Table name.
7652        db: Database name.
7653        catalog: Catalog name.
7654        fields: Additional fields using dots.
7655        quoted: Whether to force quotes on the column's identifiers.
7656        copy: Whether to copy identifiers if passed in.
7657
7658    Returns:
7659        The new Column instance.
7660    """
7661    this = Column(
7662        this=to_identifier(col, quoted=quoted, copy=copy),
7663        table=to_identifier(table, quoted=quoted, copy=copy),
7664        db=to_identifier(db, quoted=quoted, copy=copy),
7665        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7666    )
7667
7668    if fields:
7669        this = Dot.build(
7670            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7671        )
7672    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:
7675def cast(
7676    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7677) -> Cast:
7678    """Cast an expression to a data type.
7679
7680    Example:
7681        >>> cast('x + 1', 'int').sql()
7682        'CAST(x + 1 AS INT)'
7683
7684    Args:
7685        expression: The expression to cast.
7686        to: The datatype to cast to.
7687        copy: Whether to copy the supplied expressions.
7688        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7689            - The expression to be cast is already a exp.Cast expression
7690            - The existing cast is to a type that is logically equivalent to new type
7691
7692            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7693            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7694            and instead just return the original expression `CAST(x as DATETIME)`.
7695
7696            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7697            mapping is applied in the target dialect generator.
7698
7699    Returns:
7700        The new Cast instance.
7701    """
7702    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7703    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7704
7705    # dont re-cast if the expression is already a cast to the correct type
7706    if isinstance(expr, Cast):
7707        from sqlglot.dialects.dialect import Dialect
7708
7709        target_dialect = Dialect.get_or_raise(dialect)
7710        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7711
7712        existing_cast_type: DataType.Type = expr.to.this
7713        new_cast_type: DataType.Type = data_type.this
7714        types_are_equivalent = type_mapping.get(
7715            existing_cast_type, existing_cast_type
7716        ) == type_mapping.get(new_cast_type, new_cast_type)
7717        if expr.is_type(data_type) or types_are_equivalent:
7718            return expr
7719
7720    expr = Cast(this=expr, to=data_type)
7721    expr.type = data_type
7722
7723    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:
7726def table_(
7727    table: Identifier | str,
7728    db: t.Optional[Identifier | str] = None,
7729    catalog: t.Optional[Identifier | str] = None,
7730    quoted: t.Optional[bool] = None,
7731    alias: t.Optional[Identifier | str] = None,
7732) -> Table:
7733    """Build a Table.
7734
7735    Args:
7736        table: Table name.
7737        db: Database name.
7738        catalog: Catalog name.
7739        quote: Whether to force quotes on the table's identifiers.
7740        alias: Table's alias.
7741
7742    Returns:
7743        The new Table instance.
7744    """
7745    return Table(
7746        this=to_identifier(table, quoted=quoted) if table else None,
7747        db=to_identifier(db, quoted=quoted) if db else None,
7748        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7749        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7750    )

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:
7753def values(
7754    values: t.Iterable[t.Tuple[t.Any, ...]],
7755    alias: t.Optional[str] = None,
7756    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7757) -> Values:
7758    """Build VALUES statement.
7759
7760    Example:
7761        >>> values([(1, '2')]).sql()
7762        "VALUES (1, '2')"
7763
7764    Args:
7765        values: values statements that will be converted to SQL
7766        alias: optional alias
7767        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7768         If either are provided then an alias is also required.
7769
7770    Returns:
7771        Values: the Values expression object
7772    """
7773    if columns and not alias:
7774        raise ValueError("Alias is required when providing columns")
7775
7776    return Values(
7777        expressions=[convert(tup) for tup in values],
7778        alias=(
7779            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7780            if columns
7781            else (TableAlias(this=to_identifier(alias)) if alias else None)
7782        ),
7783    )

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:
7786def var(name: t.Optional[ExpOrStr]) -> Var:
7787    """Build a SQL variable.
7788
7789    Example:
7790        >>> repr(var('x'))
7791        'Var(this=x)'
7792
7793        >>> repr(var(column('x', table='y')))
7794        'Var(this=x)'
7795
7796    Args:
7797        name: The name of the var or an expression who's name will become the var.
7798
7799    Returns:
7800        The new variable node.
7801    """
7802    if not name:
7803        raise ValueError("Cannot convert empty name into var.")
7804
7805    if isinstance(name, Expression):
7806        name = name.name
7807    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:
7810def rename_table(
7811    old_name: str | Table,
7812    new_name: str | Table,
7813    dialect: DialectType = None,
7814) -> Alter:
7815    """Build ALTER TABLE... RENAME... expression
7816
7817    Args:
7818        old_name: The old name of the table
7819        new_name: The new name of the table
7820        dialect: The dialect to parse the table.
7821
7822    Returns:
7823        Alter table expression
7824    """
7825    old_table = to_table(old_name, dialect=dialect)
7826    new_table = to_table(new_name, dialect=dialect)
7827    return Alter(
7828        this=old_table,
7829        kind="TABLE",
7830        actions=[
7831            AlterRename(this=new_table),
7832        ],
7833    )

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:
7836def rename_column(
7837    table_name: str | Table,
7838    old_column_name: str | Column,
7839    new_column_name: str | Column,
7840    exists: t.Optional[bool] = None,
7841    dialect: DialectType = None,
7842) -> Alter:
7843    """Build ALTER TABLE... RENAME COLUMN... expression
7844
7845    Args:
7846        table_name: Name of the table
7847        old_column: The old name of the column
7848        new_column: The new name of the column
7849        exists: Whether to add the `IF EXISTS` clause
7850        dialect: The dialect to parse the table/column.
7851
7852    Returns:
7853        Alter table expression
7854    """
7855    table = to_table(table_name, dialect=dialect)
7856    old_column = to_column(old_column_name, dialect=dialect)
7857    new_column = to_column(new_column_name, dialect=dialect)
7858    return Alter(
7859        this=table,
7860        kind="TABLE",
7861        actions=[
7862            RenameColumn(this=old_column, to=new_column, exists=exists),
7863        ],
7864    )

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:
7867def convert(value: t.Any, copy: bool = False) -> Expression:
7868    """Convert a python value into an expression object.
7869
7870    Raises an error if a conversion is not possible.
7871
7872    Args:
7873        value: A python object.
7874        copy: Whether to copy `value` (only applies to Expressions and collections).
7875
7876    Returns:
7877        The equivalent expression object.
7878    """
7879    if isinstance(value, Expression):
7880        return maybe_copy(value, copy)
7881    if isinstance(value, str):
7882        return Literal.string(value)
7883    if isinstance(value, bool):
7884        return Boolean(this=value)
7885    if value is None or (isinstance(value, float) and math.isnan(value)):
7886        return null()
7887    if isinstance(value, numbers.Number):
7888        return Literal.number(value)
7889    if isinstance(value, bytes):
7890        return HexString(this=value.hex())
7891    if isinstance(value, datetime.datetime):
7892        datetime_literal = Literal.string(value.isoformat(sep=" "))
7893
7894        tz = None
7895        if value.tzinfo:
7896            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
7897            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
7898            tz = Literal.string(str(value.tzinfo))
7899
7900        return TimeStrToTime(this=datetime_literal, zone=tz)
7901    if isinstance(value, datetime.date):
7902        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7903        return DateStrToDate(this=date_literal)
7904    if isinstance(value, tuple):
7905        if hasattr(value, "_fields"):
7906            return Struct(
7907                expressions=[
7908                    PropertyEQ(
7909                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7910                    )
7911                    for k in value._fields
7912                ]
7913            )
7914        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7915    if isinstance(value, list):
7916        return Array(expressions=[convert(v, copy=copy) for v in value])
7917    if isinstance(value, dict):
7918        return Map(
7919            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7920            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7921        )
7922    if hasattr(value, "__dict__"):
7923        return Struct(
7924            expressions=[
7925                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7926                for k, v in value.__dict__.items()
7927            ]
7928        )
7929    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:
7932def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7933    """
7934    Replace children of an expression with the result of a lambda fun(child) -> exp.
7935    """
7936    for k, v in tuple(expression.args.items()):
7937        is_list_arg = type(v) is list
7938
7939        child_nodes = v if is_list_arg else [v]
7940        new_child_nodes = []
7941
7942        for cn in child_nodes:
7943            if isinstance(cn, Expression):
7944                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7945                    new_child_nodes.append(child_node)
7946            else:
7947                new_child_nodes.append(cn)
7948
7949        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:
7952def replace_tree(
7953    expression: Expression,
7954    fun: t.Callable,
7955    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7956) -> Expression:
7957    """
7958    Replace an entire tree with the result of function calls on each node.
7959
7960    This will be traversed in reverse dfs, so leaves first.
7961    If new nodes are created as a result of function calls, they will also be traversed.
7962    """
7963    stack = list(expression.dfs(prune=prune))
7964
7965    while stack:
7966        node = stack.pop()
7967        new_node = fun(node)
7968
7969        if new_node is not node:
7970            node.replace(new_node)
7971
7972            if isinstance(new_node, Expression):
7973                stack.append(new_node)
7974
7975    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]:
7978def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7979    """
7980    Return all table names referenced through columns in an expression.
7981
7982    Example:
7983        >>> import sqlglot
7984        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7985        ['a', 'c']
7986
7987    Args:
7988        expression: expression to find table names.
7989        exclude: a table name to exclude
7990
7991    Returns:
7992        A list of unique names.
7993    """
7994    return {
7995        table
7996        for table in (column.table for column in expression.find_all(Column))
7997        if table and table != exclude
7998    }

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:
8001def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8002    """Get the full name of a table as a string.
8003
8004    Args:
8005        table: Table expression node or string.
8006        dialect: The dialect to generate the table name for.
8007        identify: Determines when an identifier should be quoted. Possible values are:
8008            False (default): Never quote, except in cases where it's mandatory by the dialect.
8009            True: Always quote.
8010
8011    Examples:
8012        >>> from sqlglot import exp, parse_one
8013        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8014        'a.b.c'
8015
8016    Returns:
8017        The table name.
8018    """
8019
8020    table = maybe_parse(table, into=Table, dialect=dialect)
8021
8022    if not table:
8023        raise ValueError(f"Cannot parse {table}")
8024
8025    return ".".join(
8026        (
8027            part.sql(dialect=dialect, identify=True, copy=False)
8028            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8029            else part.name
8030        )
8031        for part in table.parts
8032    )

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:
8035def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8036    """Returns a case normalized table name without quotes.
8037
8038    Args:
8039        table: the table to normalize
8040        dialect: the dialect to use for normalization rules
8041        copy: whether to copy the expression.
8042
8043    Examples:
8044        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8045        'A-B.c'
8046    """
8047    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8048
8049    return ".".join(
8050        p.name
8051        for p in normalize_identifiers(
8052            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8053        ).parts
8054    )

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:
8057def replace_tables(
8058    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8059) -> E:
8060    """Replace all tables in expression according to the mapping.
8061
8062    Args:
8063        expression: expression node to be transformed and replaced.
8064        mapping: mapping of table names.
8065        dialect: the dialect of the mapping table
8066        copy: whether to copy the expression.
8067
8068    Examples:
8069        >>> from sqlglot import exp, parse_one
8070        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8071        'SELECT * FROM c /* a.b */'
8072
8073    Returns:
8074        The mapped expression.
8075    """
8076
8077    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8078
8079    def _replace_tables(node: Expression) -> Expression:
8080        if isinstance(node, Table):
8081            original = normalize_table_name(node, dialect=dialect)
8082            new_name = mapping.get(original)
8083
8084            if new_name:
8085                table = to_table(
8086                    new_name,
8087                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8088                    dialect=dialect,
8089                )
8090                table.add_comments([original])
8091                return table
8092        return node
8093
8094    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:
8097def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8098    """Replace placeholders in an expression.
8099
8100    Args:
8101        expression: expression node to be transformed and replaced.
8102        args: positional names that will substitute unnamed placeholders in the given order.
8103        kwargs: keyword arguments that will substitute named placeholders.
8104
8105    Examples:
8106        >>> from sqlglot import exp, parse_one
8107        >>> replace_placeholders(
8108        ...     parse_one("select * from :tbl where ? = ?"),
8109        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8110        ... ).sql()
8111        "SELECT * FROM foo WHERE str_col = 'b'"
8112
8113    Returns:
8114        The mapped expression.
8115    """
8116
8117    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8118        if isinstance(node, Placeholder):
8119            if node.this:
8120                new_name = kwargs.get(node.this)
8121                if new_name is not None:
8122                    return convert(new_name)
8123            else:
8124                try:
8125                    return convert(next(args))
8126                except StopIteration:
8127                    pass
8128        return node
8129
8130    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:
8133def expand(
8134    expression: Expression,
8135    sources: t.Dict[str, Query],
8136    dialect: DialectType = None,
8137    copy: bool = True,
8138) -> Expression:
8139    """Transforms an expression by expanding all referenced sources into subqueries.
8140
8141    Examples:
8142        >>> from sqlglot import parse_one
8143        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8144        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8145
8146        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8147        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8148
8149    Args:
8150        expression: The expression to expand.
8151        sources: A dictionary of name to Queries.
8152        dialect: The dialect of the sources dict.
8153        copy: Whether to copy the expression during transformation. Defaults to True.
8154
8155    Returns:
8156        The transformed expression.
8157    """
8158    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8159
8160    def _expand(node: Expression):
8161        if isinstance(node, Table):
8162            name = normalize_table_name(node, dialect=dialect)
8163            source = sources.get(name)
8164            if source:
8165                subquery = source.subquery(node.alias or name)
8166                subquery.comments = [f"source: {name}"]
8167                return subquery.transform(_expand, copy=False)
8168        return node
8169
8170    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:
8173def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8174    """
8175    Returns a Func expression.
8176
8177    Examples:
8178        >>> func("abs", 5).sql()
8179        'ABS(5)'
8180
8181        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8182        'CAST(5 AS DOUBLE)'
8183
8184    Args:
8185        name: the name of the function to build.
8186        args: the args used to instantiate the function of interest.
8187        copy: whether to copy the argument expressions.
8188        dialect: the source dialect.
8189        kwargs: the kwargs used to instantiate the function of interest.
8190
8191    Note:
8192        The arguments `args` and `kwargs` are mutually exclusive.
8193
8194    Returns:
8195        An instance of the function of interest, or an anonymous function, if `name` doesn't
8196        correspond to an existing `sqlglot.expressions.Func` class.
8197    """
8198    if args and kwargs:
8199        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8200
8201    from sqlglot.dialects.dialect import Dialect
8202
8203    dialect = Dialect.get_or_raise(dialect)
8204
8205    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8206    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8207
8208    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8209    if constructor:
8210        if converted:
8211            if "dialect" in constructor.__code__.co_varnames:
8212                function = constructor(converted, dialect=dialect)
8213            else:
8214                function = constructor(converted)
8215        elif constructor.__name__ == "from_arg_list":
8216            function = constructor.__self__(**kwargs)  # type: ignore
8217        else:
8218            constructor = FUNCTION_BY_NAME.get(name.upper())
8219            if constructor:
8220                function = constructor(**kwargs)
8221            else:
8222                raise ValueError(
8223                    f"Unable to convert '{name}' into a Func. Either manually construct "
8224                    "the Func expression of interest or parse the function call."
8225                )
8226    else:
8227        kwargs = kwargs or {"expressions": converted}
8228        function = Anonymous(this=name, **kwargs)
8229
8230    for error_message in function.error_messages(converted):
8231        raise ValueError(error_message)
8232
8233    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:
8236def case(
8237    expression: t.Optional[ExpOrStr] = None,
8238    **opts,
8239) -> Case:
8240    """
8241    Initialize a CASE statement.
8242
8243    Example:
8244        case().when("a = 1", "foo").else_("bar")
8245
8246    Args:
8247        expression: Optionally, the input expression (not all dialects support this)
8248        **opts: Extra keyword arguments for parsing `expression`
8249    """
8250    if expression is not None:
8251        this = maybe_parse(expression, **opts)
8252    else:
8253        this = None
8254    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:
8257def array(
8258    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8259) -> Array:
8260    """
8261    Returns an array.
8262
8263    Examples:
8264        >>> array(1, 'x').sql()
8265        'ARRAY(1, x)'
8266
8267    Args:
8268        expressions: the expressions to add to the array.
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    Returns:
8274        An array expression.
8275    """
8276    return Array(
8277        expressions=[
8278            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8279            for expression in expressions
8280        ]
8281    )

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:
8284def tuple_(
8285    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8286) -> Tuple:
8287    """
8288    Returns an tuple.
8289
8290    Examples:
8291        >>> tuple_(1, 'x').sql()
8292        '(1, x)'
8293
8294    Args:
8295        expressions: the expressions to add to the tuple.
8296        copy: whether to copy the argument expressions.
8297        dialect: the source dialect.
8298        kwargs: the kwargs used to instantiate the function of interest.
8299
8300    Returns:
8301        A tuple expression.
8302    """
8303    return Tuple(
8304        expressions=[
8305            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8306            for expression in expressions
8307        ]
8308    )

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:
8311def true() -> Boolean:
8312    """
8313    Returns a true Boolean expression.
8314    """
8315    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8318def false() -> Boolean:
8319    """
8320    Returns a false Boolean expression.
8321    """
8322    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8325def null() -> Null:
8326    """
8327    Returns a Null expression.
8328    """
8329    return Null()

Returns a Null expression.

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