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

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

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):
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    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2524class MatchRecognizeMeasure(Expression):
2525    arg_types = {
2526        "this": True,
2527        "window_frame": False,
2528    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
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    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2546class Final(Expression):
2547    pass
key = 'final'
class Offset(Expression):
2550class Offset(Expression):
2551    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2554class Order(Expression):
2555    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2559class WithFill(Expression):
2560    arg_types = {
2561        "from": False,
2562        "to": False,
2563        "step": False,
2564        "interpolate": False,
2565    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2570class Cluster(Order):
2571    pass
key = 'cluster'
class Distribute(Order):
2574class Distribute(Order):
2575    pass
key = 'distribute'
class Sort(Order):
2578class Sort(Order):
2579    pass
key = 'sort'
class Ordered(Expression):
2582class Ordered(Expression):
2583    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):
2586class Property(Expression):
2587    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2590class GrantPrivilege(Expression):
2591    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2594class GrantPrincipal(Expression):
2595    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2598class AllowedValuesProperty(Expression):
2599    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2602class AlgorithmProperty(Property):
2603    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2606class AutoIncrementProperty(Property):
2607    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2611class AutoRefreshProperty(Property):
2612    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2615class BackupProperty(Property):
2616    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2619class BlockCompressionProperty(Property):
2620    arg_types = {
2621        "autotemp": False,
2622        "always": False,
2623        "default": False,
2624        "manual": False,
2625        "never": False,
2626    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2629class CharacterSetProperty(Property):
2630    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2633class ChecksumProperty(Property):
2634    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2637class CollateProperty(Property):
2638    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2641class CopyGrantsProperty(Property):
2642    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2645class DataBlocksizeProperty(Property):
2646    arg_types = {
2647        "size": False,
2648        "units": False,
2649        "minimum": False,
2650        "maximum": False,
2651        "default": False,
2652    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2655class DataDeletionProperty(Property):
2656    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):
2659class DefinerProperty(Property):
2660    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2663class DistKeyProperty(Property):
2664    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2669class DistributedByProperty(Property):
2670    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):
2673class DistStyleProperty(Property):
2674    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2677class DuplicateKeyProperty(Property):
2678    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2681class EngineProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2685class HeapProperty(Property):
2686    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2689class ToTableProperty(Property):
2690    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2693class ExecuteAsProperty(Property):
2694    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2697class ExternalProperty(Property):
2698    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2701class FallbackProperty(Property):
2702    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2705class FileFormatProperty(Property):
2706    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2709class FreespaceProperty(Property):
2710    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2713class GlobalProperty(Property):
2714    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2717class IcebergProperty(Property):
2718    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2721class InheritsProperty(Property):
2722    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2725class InputModelProperty(Property):
2726    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2729class OutputModelProperty(Property):
2730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2733class IsolatedLoadingProperty(Property):
2734    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2737class JournalProperty(Property):
2738    arg_types = {
2739        "no": False,
2740        "dual": False,
2741        "before": False,
2742        "local": False,
2743        "after": False,
2744    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2747class LanguageProperty(Property):
2748    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2752class ClusteredByProperty(Property):
2753    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2756class DictProperty(Property):
2757    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2760class DictSubProperty(Property):
2761    pass
key = 'dictsubproperty'
class DictRange(Property):
2764class DictRange(Property):
2765    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2768class DynamicProperty(Property):
2769    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2774class OnCluster(Property):
2775    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2779class EmptyProperty(Property):
2780    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2783class LikeProperty(Property):
2784    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2787class LocationProperty(Property):
2788    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2791class LockProperty(Property):
2792    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
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    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2805class LogProperty(Property):
2806    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2809class MaterializedProperty(Property):
2810    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2813class MergeBlockRatioProperty(Property):
2814    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):
2817class NoPrimaryIndexProperty(Property):
2818    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2821class OnProperty(Property):
2822    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2825class OnCommitProperty(Property):
2826    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2829class PartitionedByProperty(Property):
2830    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
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    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2844class PartitionedOfProperty(Property):
2845    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2846    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2849class StreamingTableProperty(Property):
2850    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2853class RemoteWithConnectionModelProperty(Property):
2854    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2857class ReturnsProperty(Property):
2858    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):
2861class StrictProperty(Property):
2862    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2865class RowFormatProperty(Property):
2866    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
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    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2882class RowFormatSerdeProperty(Property):
2883    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
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    }
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):
2899class SampleProperty(Property):
2900    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2904class SecurityProperty(Property):
2905    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2908class SchemaCommentProperty(Property):
2909    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2912class SerdeProperties(Property):
2913    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2916class SetProperty(Property):
2917    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2920class SharingProperty(Property):
2921    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2924class SetConfigProperty(Property):
2925    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2928class SettingsProperty(Property):
2929    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2932class SortKeyProperty(Property):
2933    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2936class SqlReadWriteProperty(Property):
2937    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2940class SqlSecurityProperty(Property):
2941    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2944class StabilityProperty(Property):
2945    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2948class TemporaryProperty(Property):
2949    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2952class SecureProperty(Property):
2953    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2956class TransformModelProperty(Property):
2957    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2960class TransientProperty(Property):
2961    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2964class UnloggedProperty(Property):
2965    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2969class ViewAttributeProperty(Property):
2970    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2973class VolatileProperty(Property):
2974    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2977class WithDataProperty(Property):
2978    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2981class WithJournalTableProperty(Property):
2982    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2985class WithSchemaBindingProperty(Property):
2986    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2989class WithSystemVersioningProperty(Property):
2990    arg_types = {
2991        "on": False,
2992        "this": False,
2993        "data_consistency": False,
2994        "retention_period": False,
2995        "with": True,
2996    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2999class Properties(Expression):
3000    arg_types = {"expressions": True}
3001
3002    NAME_TO_PROPERTY = {
3003        "ALGORITHM": AlgorithmProperty,
3004        "AUTO_INCREMENT": AutoIncrementProperty,
3005        "CHARACTER SET": CharacterSetProperty,
3006        "CLUSTERED_BY": ClusteredByProperty,
3007        "COLLATE": CollateProperty,
3008        "COMMENT": SchemaCommentProperty,
3009        "DEFINER": DefinerProperty,
3010        "DISTKEY": DistKeyProperty,
3011        "DISTRIBUTED_BY": DistributedByProperty,
3012        "DISTSTYLE": DistStyleProperty,
3013        "ENGINE": EngineProperty,
3014        "EXECUTE AS": ExecuteAsProperty,
3015        "FORMAT": FileFormatProperty,
3016        "LANGUAGE": LanguageProperty,
3017        "LOCATION": LocationProperty,
3018        "LOCK": LockProperty,
3019        "PARTITIONED_BY": PartitionedByProperty,
3020        "RETURNS": ReturnsProperty,
3021        "ROW_FORMAT": RowFormatProperty,
3022        "SORTKEY": SortKeyProperty,
3023    }
3024
3025    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3026
3027    # CREATE property locations
3028    # Form: schema specified
3029    #   create [POST_CREATE]
3030    #     table a [POST_NAME]
3031    #     (b int) [POST_SCHEMA]
3032    #     with ([POST_WITH])
3033    #     index (b) [POST_INDEX]
3034    #
3035    # Form: alias selection
3036    #   create [POST_CREATE]
3037    #     table a [POST_NAME]
3038    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3039    #     index (c) [POST_INDEX]
3040    class Location(AutoName):
3041        POST_CREATE = auto()
3042        POST_NAME = auto()
3043        POST_SCHEMA = auto()
3044        POST_WITH = auto()
3045        POST_ALIAS = auto()
3046        POST_EXPRESSION = auto()
3047        POST_INDEX = auto()
3048        UNSUPPORTED = auto()
3049
3050    @classmethod
3051    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3052        expressions = []
3053        for key, value in properties_dict.items():
3054            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3055            if property_cls:
3056                expressions.append(property_cls(this=convert(value)))
3057            else:
3058                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3059
3060        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:
3050    @classmethod
3051    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3052        expressions = []
3053        for key, value in properties_dict.items():
3054            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3055            if property_cls:
3056                expressions.append(property_cls(this=convert(value)))
3057            else:
3058                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3059
3060        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3040    class Location(AutoName):
3041        POST_CREATE = auto()
3042        POST_NAME = auto()
3043        POST_SCHEMA = auto()
3044        POST_WITH = auto()
3045        POST_ALIAS = auto()
3046        POST_EXPRESSION = auto()
3047        POST_INDEX = auto()
3048        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'>
Inherited Members
enum.Enum
name
value
class Qualify(Expression):
3063class Qualify(Expression):
3064    pass
key = 'qualify'
class InputOutputFormat(Expression):
3067class InputOutputFormat(Expression):
3068    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3072class Return(Expression):
3073    pass
key = 'return'
class Reference(Expression):
3076class Reference(Expression):
3077    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3080class Tuple(Expression):
3081    arg_types = {"expressions": False}
3082
3083    def isin(
3084        self,
3085        *expressions: t.Any,
3086        query: t.Optional[ExpOrStr] = None,
3087        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3088        copy: bool = True,
3089        **opts,
3090    ) -> In:
3091        return In(
3092            this=maybe_copy(self, copy),
3093            expressions=[convert(e, copy=copy) for e in expressions],
3094            query=maybe_parse(query, copy=copy, **opts) if query else None,
3095            unnest=(
3096                Unnest(
3097                    expressions=[
3098                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3099                        for e in ensure_list(unnest)
3100                    ]
3101                )
3102                if unnest
3103                else None
3104            ),
3105        )
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:
3083    def isin(
3084        self,
3085        *expressions: t.Any,
3086        query: t.Optional[ExpOrStr] = None,
3087        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3088        copy: bool = True,
3089        **opts,
3090    ) -> In:
3091        return In(
3092            this=maybe_copy(self, copy),
3093            expressions=[convert(e, copy=copy) for e in expressions],
3094            query=maybe_parse(query, copy=copy, **opts) if query else None,
3095            unnest=(
3096                Unnest(
3097                    expressions=[
3098                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3099                        for e in ensure_list(unnest)
3100                    ]
3101                )
3102                if unnest
3103                else None
3104            ),
3105        )
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):
3136class QueryOption(Expression):
3137    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3141class WithTableHint(Expression):
3142    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3146class IndexTableHint(Expression):
3147    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3151class HistoricalData(Expression):
3152    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3155class Table(Expression):
3156    arg_types = {
3157        "this": False,
3158        "alias": False,
3159        "db": False,
3160        "catalog": False,
3161        "laterals": False,
3162        "joins": False,
3163        "pivots": False,
3164        "hints": False,
3165        "system_time": False,
3166        "version": False,
3167        "format": False,
3168        "pattern": False,
3169        "ordinality": False,
3170        "when": False,
3171        "only": False,
3172        "partition": False,
3173        "changes": False,
3174        "rows_from": False,
3175        "sample": False,
3176    }
3177
3178    @property
3179    def name(self) -> str:
3180        if isinstance(self.this, Func):
3181            return ""
3182        return self.this.name
3183
3184    @property
3185    def db(self) -> str:
3186        return self.text("db")
3187
3188    @property
3189    def catalog(self) -> str:
3190        return self.text("catalog")
3191
3192    @property
3193    def selects(self) -> t.List[Expression]:
3194        return []
3195
3196    @property
3197    def named_selects(self) -> t.List[str]:
3198        return []
3199
3200    @property
3201    def parts(self) -> t.List[Expression]:
3202        """Return the parts of a table in order catalog, db, table."""
3203        parts: t.List[Expression] = []
3204
3205        for arg in ("catalog", "db", "this"):
3206            part = self.args.get(arg)
3207
3208            if isinstance(part, Dot):
3209                parts.extend(part.flatten())
3210            elif isinstance(part, Expression):
3211                parts.append(part)
3212
3213        return parts
3214
3215    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3216        parts = self.parts
3217        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3218        alias = self.args.get("alias")
3219        if alias:
3220            col = alias_(col, alias.this, copy=copy)
3221        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
3178    @property
3179    def name(self) -> str:
3180        if isinstance(self.this, Func):
3181            return ""
3182        return self.this.name
db: str
3184    @property
3185    def db(self) -> str:
3186        return self.text("db")
catalog: str
3188    @property
3189    def catalog(self) -> str:
3190        return self.text("catalog")
selects: List[Expression]
3192    @property
3193    def selects(self) -> t.List[Expression]:
3194        return []
named_selects: List[str]
3196    @property
3197    def named_selects(self) -> t.List[str]:
3198        return []
parts: List[Expression]
3200    @property
3201    def parts(self) -> t.List[Expression]:
3202        """Return the parts of a table in order catalog, db, table."""
3203        parts: t.List[Expression] = []
3204
3205        for arg in ("catalog", "db", "this"):
3206            part = self.args.get(arg)
3207
3208            if isinstance(part, Dot):
3209                parts.extend(part.flatten())
3210            elif isinstance(part, Expression):
3211                parts.append(part)
3212
3213        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3215    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3216        parts = self.parts
3217        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3218        alias = self.args.get("alias")
3219        if alias:
3220            col = alias_(col, alias.this, copy=copy)
3221        return col
key = 'table'
class SetOperation(Query):
3224class SetOperation(Query):
3225    arg_types = {
3226        "with": False,
3227        "this": True,
3228        "expression": True,
3229        "distinct": False,
3230        "by_name": False,
3231        **QUERY_MODIFIERS,
3232    }
3233
3234    def select(
3235        self: S,
3236        *expressions: t.Optional[ExpOrStr],
3237        append: bool = True,
3238        dialect: DialectType = None,
3239        copy: bool = True,
3240        **opts,
3241    ) -> S:
3242        this = maybe_copy(self, copy)
3243        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3244        this.expression.unnest().select(
3245            *expressions, append=append, dialect=dialect, copy=False, **opts
3246        )
3247        return this
3248
3249    @property
3250    def named_selects(self) -> t.List[str]:
3251        return self.this.unnest().named_selects
3252
3253    @property
3254    def is_star(self) -> bool:
3255        return self.this.is_star or self.expression.is_star
3256
3257    @property
3258    def selects(self) -> t.List[Expression]:
3259        return self.this.unnest().selects
3260
3261    @property
3262    def left(self) -> Query:
3263        return self.this
3264
3265    @property
3266    def right(self) -> Query:
3267        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:
3234    def select(
3235        self: S,
3236        *expressions: t.Optional[ExpOrStr],
3237        append: bool = True,
3238        dialect: DialectType = None,
3239        copy: bool = True,
3240        **opts,
3241    ) -> S:
3242        this = maybe_copy(self, copy)
3243        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3244        this.expression.unnest().select(
3245            *expressions, append=append, dialect=dialect, copy=False, **opts
3246        )
3247        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]
3249    @property
3250    def named_selects(self) -> t.List[str]:
3251        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3253    @property
3254    def is_star(self) -> bool:
3255        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3257    @property
3258    def selects(self) -> t.List[Expression]:
3259        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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:
3689    def select(
3690        self,
3691        *expressions: t.Optional[ExpOrStr],
3692        append: bool = True,
3693        dialect: DialectType = None,
3694        copy: bool = True,
3695        **opts,
3696    ) -> Select:
3697        return _apply_list_builder(
3698            *expressions,
3699            instance=self,
3700            arg="expressions",
3701            append=append,
3702            dialect=dialect,
3703            into=Expression,
3704            copy=copy,
3705            **opts,
3706        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
4079    @property
4080    def selects(self) -> t.List[Expression]:
4081        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
4102    def unwrap(self) -> Subquery:
4103        expression = self
4104        while expression.same_parent and expression.is_wrapper:
4105            expression = t.cast(Subquery, expression.parent)
4106        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:
4108    def select(
4109        self,
4110        *expressions: t.Optional[ExpOrStr],
4111        append: bool = True,
4112        dialect: DialectType = None,
4113        copy: bool = True,
4114        **opts,
4115    ) -> Subquery:
4116        this = maybe_copy(self, copy)
4117        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4118        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
4120    @property
4121    def is_wrapper(self) -> bool:
4122        """
4123        Whether this Subquery acts as a simple wrapper around another expression.
4124
4125        SELECT * FROM (((SELECT * FROM t)))
4126                      ^
4127                      This corresponds to a "wrapper" Subquery node
4128        """
4129        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
4131    @property
4132    def is_star(self) -> bool:
4133        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4135    @property
4136    def output_name(self) -> str:
4137        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):
4140class TableSample(Expression):
4141    arg_types = {
4142        "expressions": False,
4143        "method": False,
4144        "bucket_numerator": False,
4145        "bucket_denominator": False,
4146        "bucket_field": False,
4147        "percent": False,
4148        "rows": False,
4149        "size": False,
4150        "seed": False,
4151    }
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):
4154class Tag(Expression):
4155    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4156
4157    arg_types = {
4158        "this": False,
4159        "prefix": False,
4160        "postfix": False,
4161    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4166class Pivot(Expression):
4167    arg_types = {
4168        "this": False,
4169        "alias": False,
4170        "expressions": False,
4171        "field": False,
4172        "unpivot": False,
4173        "using": False,
4174        "group": False,
4175        "columns": False,
4176        "include_nulls": False,
4177        "default_on_null": False,
4178    }
4179
4180    @property
4181    def unpivot(self) -> bool:
4182        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
4180    @property
4181    def unpivot(self) -> bool:
4182        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
4185class Window(Condition):
4186    arg_types = {
4187        "this": True,
4188        "partition_by": False,
4189        "order": False,
4190        "spec": False,
4191        "alias": False,
4192        "over": False,
4193        "first": False,
4194    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4197class WindowSpec(Expression):
4198    arg_types = {
4199        "kind": False,
4200        "start": False,
4201        "start_side": False,
4202        "end": False,
4203        "end_side": False,
4204    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4207class PreWhere(Expression):
4208    pass
key = 'prewhere'
class Where(Expression):
4211class Where(Expression):
4212    pass
key = 'where'
class Star(Expression):
4215class Star(Expression):
4216    arg_types = {"except": False, "replace": False, "rename": False}
4217
4218    @property
4219    def name(self) -> str:
4220        return "*"
4221
4222    @property
4223    def output_name(self) -> str:
4224        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4218    @property
4219    def name(self) -> str:
4220        return "*"
output_name: str
4222    @property
4223    def output_name(self) -> str:
4224        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):
4227class Parameter(Condition):
4228    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4231class SessionParameter(Condition):
4232    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4235class Placeholder(Condition):
4236    arg_types = {"this": False, "kind": False}
4237
4238    @property
4239    def name(self) -> str:
4240        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4238    @property
4239    def name(self) -> str:
4240        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4243class Null(Condition):
4244    arg_types: t.Dict[str, t.Any] = {}
4245
4246    @property
4247    def name(self) -> str:
4248        return "NULL"
4249
4250    def to_py(self) -> Lit[None]:
4251        return None
arg_types: Dict[str, Any] = {}
name: str
4246    @property
4247    def name(self) -> str:
4248        return "NULL"
def to_py(self) -> Literal[None]:
4250    def to_py(self) -> Lit[None]:
4251        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4254class Boolean(Condition):
4255    def to_py(self) -> bool:
4256        return self.this
def to_py(self) -> bool:
4255    def to_py(self) -> bool:
4256        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
4706    @property
4707    def name(self) -> str:
4708        return self.expression.name
output_name: str
4710    @property
4711    def output_name(self) -> str:
4712        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:
4714    @classmethod
4715    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4716        """Build a Dot object with a sequence of expressions."""
4717        if len(expressions) < 2:
4718            raise ValueError("Dot requires >= 2 expressions.")
4719
4720        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]
4722    @property
4723    def parts(self) -> t.List[Expression]:
4724        """Return the parts of a table / column in order catalog, db, table."""
4725        this, *parts = self.flatten()
4726
4727        parts.reverse()
4728
4729        for arg in COLUMN_PARTS:
4730            part = this.args.get(arg)
4731
4732            if isinstance(part, Expression):
4733                parts.append(part)
4734
4735        parts.reverse()
4736        return parts

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

key = 'dot'
class DPipe(Binary):
4739class DPipe(Binary):
4740    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4743class EQ(Binary, Predicate):
4744    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4747class NullSafeEQ(Binary, Predicate):
4748    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4751class NullSafeNEQ(Binary, Predicate):
4752    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4756class PropertyEQ(Binary):
4757    pass
key = 'propertyeq'
class Distance(Binary):
4760class Distance(Binary):
4761    pass
key = 'distance'
class Escape(Binary):
4764class Escape(Binary):
4765    pass
key = 'escape'
class Glob(Binary, Predicate):
4768class Glob(Binary, Predicate):
4769    pass
key = 'glob'
class GT(Binary, Predicate):
4772class GT(Binary, Predicate):
4773    pass
key = 'gt'
class GTE(Binary, Predicate):
4776class GTE(Binary, Predicate):
4777    pass
key = 'gte'
class ILike(Binary, Predicate):
4780class ILike(Binary, Predicate):
4781    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4784class ILikeAny(Binary, Predicate):
4785    pass
key = 'ilikeany'
class IntDiv(Binary):
4788class IntDiv(Binary):
4789    pass
key = 'intdiv'
class Is(Binary, Predicate):
4792class Is(Binary, Predicate):
4793    pass
key = 'is'
class Kwarg(Binary):
4796class Kwarg(Binary):
4797    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4800class Like(Binary, Predicate):
4801    pass
key = 'like'
class LikeAny(Binary, Predicate):
4804class LikeAny(Binary, Predicate):
4805    pass
key = 'likeany'
class LT(Binary, Predicate):
4808class LT(Binary, Predicate):
4809    pass
key = 'lt'
class LTE(Binary, Predicate):
4812class LTE(Binary, Predicate):
4813    pass
key = 'lte'
class Mod(Binary):
4816class Mod(Binary):
4817    pass
key = 'mod'
class Mul(Binary):
4820class Mul(Binary):
4821    pass
key = 'mul'
class NEQ(Binary, Predicate):
4824class NEQ(Binary, Predicate):
4825    pass
key = 'neq'
class Operator(Binary):
4829class Operator(Binary):
4830    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4833class SimilarTo(Binary, Predicate):
4834    pass
key = 'similarto'
class Slice(Binary):
4837class Slice(Binary):
4838    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4841class Sub(Binary):
4842    pass
key = 'sub'
class Unary(Condition):
4847class Unary(Condition):
4848    pass
key = 'unary'
class BitwiseNot(Unary):
4851class BitwiseNot(Unary):
4852    pass
key = 'bitwisenot'
class Not(Unary):
4855class Not(Unary):
4856    pass
key = 'not'
class Paren(Unary):
4859class Paren(Unary):
4860    @property
4861    def output_name(self) -> str:
4862        return self.this.name
output_name: str
4860    @property
4861    def output_name(self) -> str:
4862        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):
4865class Neg(Unary):
4866    def to_py(self) -> int | Decimal:
4867        if self.is_number:
4868            return self.this.to_py() * -1
4869        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4866    def to_py(self) -> int | Decimal:
4867        if self.is_number:
4868            return self.this.to_py() * -1
4869        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4872class Alias(Expression):
4873    arg_types = {"this": True, "alias": False}
4874
4875    @property
4876    def output_name(self) -> str:
4877        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4875    @property
4876    def output_name(self) -> str:
4877        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):
4882class PivotAlias(Alias):
4883    pass
key = 'pivotalias'
class PivotAny(Expression):
4888class PivotAny(Expression):
4889    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4892class Aliases(Expression):
4893    arg_types = {"this": True, "expressions": True}
4894
4895    @property
4896    def aliases(self):
4897        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4895    @property
4896    def aliases(self):
4897        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4901class AtIndex(Expression):
4902    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4905class AtTimeZone(Expression):
4906    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4909class FromTimeZone(Expression):
4910    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4913class Between(Predicate):
4914    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4917class Bracket(Condition):
4918    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4919    arg_types = {
4920        "this": True,
4921        "expressions": True,
4922        "offset": False,
4923        "safe": False,
4924        "returns_list_for_maps": False,
4925    }
4926
4927    @property
4928    def output_name(self) -> str:
4929        if len(self.expressions) == 1:
4930            return self.expressions[0].output_name
4931
4932        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4927    @property
4928    def output_name(self) -> str:
4929        if len(self.expressions) == 1:
4930            return self.expressions[0].output_name
4931
4932        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):
4935class Distinct(Expression):
4936    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4939class In(Predicate):
4940    arg_types = {
4941        "this": True,
4942        "expressions": False,
4943        "query": False,
4944        "unnest": False,
4945        "field": False,
4946        "is_global": False,
4947    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4951class ForIn(Expression):
4952    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4955class TimeUnit(Expression):
4956    """Automatically converts unit arg into a var."""
4957
4958    arg_types = {"unit": False}
4959
4960    UNABBREVIATED_UNIT_NAME = {
4961        "D": "DAY",
4962        "H": "HOUR",
4963        "M": "MINUTE",
4964        "MS": "MILLISECOND",
4965        "NS": "NANOSECOND",
4966        "Q": "QUARTER",
4967        "S": "SECOND",
4968        "US": "MICROSECOND",
4969        "W": "WEEK",
4970        "Y": "YEAR",
4971    }
4972
4973    VAR_LIKE = (Column, Literal, Var)
4974
4975    def __init__(self, **args):
4976        unit = args.get("unit")
4977        if isinstance(unit, self.VAR_LIKE):
4978            args["unit"] = Var(
4979                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4980            )
4981        elif isinstance(unit, Week):
4982            unit.set("this", Var(this=unit.this.name.upper()))
4983
4984        super().__init__(**args)
4985
4986    @property
4987    def unit(self) -> t.Optional[Var | IntervalSpan]:
4988        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4975    def __init__(self, **args):
4976        unit = args.get("unit")
4977        if isinstance(unit, self.VAR_LIKE):
4978            args["unit"] = Var(
4979                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4980            )
4981        elif isinstance(unit, Week):
4982            unit.set("this", Var(this=unit.this.name.upper()))
4983
4984        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]
4986    @property
4987    def unit(self) -> t.Optional[Var | IntervalSpan]:
4988        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4991class IntervalOp(TimeUnit):
4992    arg_types = {"unit": False, "expression": True}
4993
4994    def interval(self):
4995        return Interval(
4996            this=self.expression.copy(),
4997            unit=self.unit.copy() if self.unit else None,
4998        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
4994    def interval(self):
4995        return Interval(
4996            this=self.expression.copy(),
4997            unit=self.unit.copy() if self.unit else None,
4998        )
key = 'intervalop'
class IntervalSpan(DataType):
5004class IntervalSpan(DataType):
5005    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5008class Interval(TimeUnit):
5009    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5012class IgnoreNulls(Expression):
5013    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5016class RespectNulls(Expression):
5017    pass
key = 'respectnulls'
class HavingMax(Expression):
5021class HavingMax(Expression):
5022    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5026class Func(Condition):
5027    """
5028    The base class for all function expressions.
5029
5030    Attributes:
5031        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5032            treated as a variable length argument and the argument's value will be stored as a list.
5033        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5034            function expression. These values are used to map this node to a name during parsing as
5035            well as to provide the function's name during SQL string generation. By default the SQL
5036            name is set to the expression's class name transformed to snake case.
5037    """
5038
5039    is_var_len_args = False
5040
5041    @classmethod
5042    def from_arg_list(cls, args):
5043        if cls.is_var_len_args:
5044            all_arg_keys = list(cls.arg_types)
5045            # If this function supports variable length argument treat the last argument as such.
5046            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5047            num_non_var = len(non_var_len_arg_keys)
5048
5049            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5050            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5051        else:
5052            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5053
5054        return cls(**args_dict)
5055
5056    @classmethod
5057    def sql_names(cls):
5058        if cls is Func:
5059            raise NotImplementedError(
5060                "SQL name is only supported by concrete function implementations"
5061            )
5062        if "_sql_names" not in cls.__dict__:
5063            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5064        return cls._sql_names
5065
5066    @classmethod
5067    def sql_name(cls):
5068        return cls.sql_names()[0]
5069
5070    @classmethod
5071    def default_parser_mappings(cls):
5072        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):
5041    @classmethod
5042    def from_arg_list(cls, args):
5043        if cls.is_var_len_args:
5044            all_arg_keys = list(cls.arg_types)
5045            # If this function supports variable length argument treat the last argument as such.
5046            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5047            num_non_var = len(non_var_len_arg_keys)
5048
5049            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5050            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5051        else:
5052            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5053
5054        return cls(**args_dict)
@classmethod
def sql_names(cls):
5056    @classmethod
5057    def sql_names(cls):
5058        if cls is Func:
5059            raise NotImplementedError(
5060                "SQL name is only supported by concrete function implementations"
5061            )
5062        if "_sql_names" not in cls.__dict__:
5063            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5064        return cls._sql_names
@classmethod
def sql_name(cls):
5066    @classmethod
5067    def sql_name(cls):
5068        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5070    @classmethod
5071    def default_parser_mappings(cls):
5072        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5075class AggFunc(Func):
5076    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5079class ParameterizedAgg(AggFunc):
5080    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5083class Abs(Func):
5084    pass
key = 'abs'
class ArgMax(AggFunc):
5087class ArgMax(AggFunc):
5088    arg_types = {"this": True, "expression": True, "count": False}
5089    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5092class ArgMin(AggFunc):
5093    arg_types = {"this": True, "expression": True, "count": False}
5094    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5097class ApproxTopK(AggFunc):
5098    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5101class Flatten(Func):
5102    pass
key = 'flatten'
class Transform(Func):
5106class Transform(Func):
5107    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5110class Anonymous(Func):
5111    arg_types = {"this": True, "expressions": False}
5112    is_var_len_args = True
5113
5114    @property
5115    def name(self) -> str:
5116        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
5114    @property
5115    def name(self) -> str:
5116        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5119class AnonymousAggFunc(AggFunc):
5120    arg_types = {"this": True, "expressions": False}
5121    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5125class CombinedAggFunc(AnonymousAggFunc):
5126    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5129class CombinedParameterizedAgg(ParameterizedAgg):
5130    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):
5135class Hll(AggFunc):
5136    arg_types = {"this": True, "expressions": False}
5137    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5140class ApproxDistinct(AggFunc):
5141    arg_types = {"this": True, "accuracy": False}
5142    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5145class Apply(Func):
5146    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5149class Array(Func):
5150    arg_types = {"expressions": False, "bracket_notation": False}
5151    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5155class ToArray(Func):
5156    pass
key = 'toarray'
class List(Func):
5160class List(Func):
5161    arg_types = {"expressions": False}
5162    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5166class Pad(Func):
5167    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):
5172class ToChar(Func):
5173    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5178class ToNumber(Func):
5179    arg_types = {
5180        "this": True,
5181        "format": False,
5182        "nlsparam": False,
5183        "precision": False,
5184        "scale": False,
5185    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Columns(Func):
5188class Columns(Func):
5189    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5193class Convert(Func):
5194    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5197class ConvertTimezone(Func):
5198    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):
5201class GenerateSeries(Func):
5202    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):
5208class ExplodingGenerateSeries(GenerateSeries):
5209    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5212class ArrayAgg(AggFunc):
5213    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5216class ArrayUniqueAgg(AggFunc):
5217    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5220class ArrayAll(Func):
5221    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5225class ArrayAny(Func):
5226    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5229class ArrayConcat(Func):
5230    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5231    arg_types = {"this": True, "expressions": False}
5232    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5235class ArrayConstructCompact(Func):
5236    arg_types = {"expressions": True}
5237    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5240class ArrayContains(Binary, Func):
5241    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5244class ArrayContainsAll(Binary, Func):
5245    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5248class ArrayFilter(Func):
5249    arg_types = {"this": True, "expression": True}
5250    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5253class ArrayToString(Func):
5254    arg_types = {"this": True, "expression": True, "null": False}
5255    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
5258class StringToArray(Func):
5259    arg_types = {"this": True, "expression": True, "null": False}
5260    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5263class ArrayOverlaps(Binary, Func):
5264    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5267class ArraySize(Func):
5268    arg_types = {"this": True, "expression": False}
5269    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5272class ArraySort(Func):
5273    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5276class ArraySum(Func):
5277    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5280class ArrayUnionAgg(AggFunc):
5281    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5284class Avg(AggFunc):
5285    pass
key = 'avg'
class AnyValue(AggFunc):
5288class AnyValue(AggFunc):
5289    pass
key = 'anyvalue'
class Lag(AggFunc):
5292class Lag(AggFunc):
5293    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5296class Lead(AggFunc):
5297    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5302class First(AggFunc):
5303    pass
key = 'first'
class Last(AggFunc):
5306class Last(AggFunc):
5307    pass
key = 'last'
class FirstValue(AggFunc):
5310class FirstValue(AggFunc):
5311    pass
key = 'firstvalue'
class LastValue(AggFunc):
5314class LastValue(AggFunc):
5315    pass
key = 'lastvalue'
class NthValue(AggFunc):
5318class NthValue(AggFunc):
5319    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5322class Case(Func):
5323    arg_types = {"this": False, "ifs": True, "default": False}
5324
5325    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5326        instance = maybe_copy(self, copy)
5327        instance.append(
5328            "ifs",
5329            If(
5330                this=maybe_parse(condition, copy=copy, **opts),
5331                true=maybe_parse(then, copy=copy, **opts),
5332            ),
5333        )
5334        return instance
5335
5336    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5337        instance = maybe_copy(self, copy)
5338        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5339        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:
5325    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5326        instance = maybe_copy(self, copy)
5327        instance.append(
5328            "ifs",
5329            If(
5330                this=maybe_parse(condition, copy=copy, **opts),
5331                true=maybe_parse(then, copy=copy, **opts),
5332            ),
5333        )
5334        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5336    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5337        instance = maybe_copy(self, copy)
5338        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5339        return instance
key = 'case'
class Cast(Func):
5342class Cast(Func):
5343    arg_types = {
5344        "this": True,
5345        "to": True,
5346        "format": False,
5347        "safe": False,
5348        "action": False,
5349    }
5350
5351    @property
5352    def name(self) -> str:
5353        return self.this.name
5354
5355    @property
5356    def to(self) -> DataType:
5357        return self.args["to"]
5358
5359    @property
5360    def output_name(self) -> str:
5361        return self.name
5362
5363    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5364        """
5365        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5366        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5367        array<int> != array<float>.
5368
5369        Args:
5370            dtypes: the data types to compare this Cast's DataType to.
5371
5372        Returns:
5373            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5374        """
5375        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5351    @property
5352    def name(self) -> str:
5353        return self.this.name
to: DataType
5355    @property
5356    def to(self) -> DataType:
5357        return self.args["to"]
output_name: str
5359    @property
5360    def output_name(self) -> str:
5361        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:
5363    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5364        """
5365        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5366        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5367        array<int> != array<float>.
5368
5369        Args:
5370            dtypes: the data types to compare this Cast's DataType to.
5371
5372        Returns:
5373            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5374        """
5375        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):
5378class TryCast(Cast):
5379    pass
key = 'trycast'
class Try(Func):
5382class Try(Func):
5383    pass
key = 'try'
class CastToStrType(Func):
5386class CastToStrType(Func):
5387    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5390class Collate(Binary, Func):
5391    pass
key = 'collate'
class Ceil(Func):
5394class Ceil(Func):
5395    arg_types = {"this": True, "decimals": False}
5396    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5399class Coalesce(Func):
5400    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5401    is_var_len_args = True
5402    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5405class Chr(Func):
5406    arg_types = {"expressions": True, "charset": False}
5407    is_var_len_args = True
5408    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5411class Concat(Func):
5412    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5413    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5416class ConcatWs(Concat):
5417    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5421class ConnectByRoot(Func):
5422    pass
key = 'connectbyroot'
class Count(AggFunc):
5425class Count(AggFunc):
5426    arg_types = {"this": False, "expressions": False, "big_int": False}
5427    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5430class CountIf(AggFunc):
5431    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5435class Cbrt(Func):
5436    pass
key = 'cbrt'
class CurrentDate(Func):
5439class CurrentDate(Func):
5440    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5443class CurrentDatetime(Func):
5444    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5447class CurrentTime(Func):
5448    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5451class CurrentTimestamp(Func):
5452    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5455class CurrentUser(Func):
5456    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5459class DateAdd(Func, IntervalOp):
5460    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5463class DateSub(Func, IntervalOp):
5464    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5467class DateDiff(Func, TimeUnit):
5468    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5469    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5472class DateTrunc(Func):
5473    arg_types = {"unit": True, "this": True, "zone": False}
5474
5475    def __init__(self, **args):
5476        unit = args.get("unit")
5477        if isinstance(unit, TimeUnit.VAR_LIKE):
5478            args["unit"] = Literal.string(
5479                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5480            )
5481        elif isinstance(unit, Week):
5482            unit.set("this", Literal.string(unit.this.name.upper()))
5483
5484        super().__init__(**args)
5485
5486    @property
5487    def unit(self) -> Expression:
5488        return self.args["unit"]
DateTrunc(**args)
5475    def __init__(self, **args):
5476        unit = args.get("unit")
5477        if isinstance(unit, TimeUnit.VAR_LIKE):
5478            args["unit"] = Literal.string(
5479                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5480            )
5481        elif isinstance(unit, Week):
5482            unit.set("this", Literal.string(unit.this.name.upper()))
5483
5484        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5486    @property
5487    def unit(self) -> Expression:
5488        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5493class Datetime(Func):
5494    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5497class DatetimeAdd(Func, IntervalOp):
5498    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5501class DatetimeSub(Func, IntervalOp):
5502    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5505class DatetimeDiff(Func, TimeUnit):
5506    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5509class DatetimeTrunc(Func, TimeUnit):
5510    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5513class DayOfWeek(Func):
5514    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5519class DayOfWeekIso(Func):
5520    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5523class DayOfMonth(Func):
5524    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5527class DayOfYear(Func):
5528    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5531class ToDays(Func):
5532    pass
key = 'todays'
class WeekOfYear(Func):
5535class WeekOfYear(Func):
5536    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5539class MonthsBetween(Func):
5540    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5543class LastDay(Func, TimeUnit):
5544    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5545    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5548class Extract(Func):
5549    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5552class Timestamp(Func):
5553    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5556class TimestampAdd(Func, TimeUnit):
5557    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5560class TimestampSub(Func, TimeUnit):
5561    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5564class TimestampDiff(Func, TimeUnit):
5565    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5566    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5569class TimestampTrunc(Func, TimeUnit):
5570    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5573class TimeAdd(Func, TimeUnit):
5574    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5577class TimeSub(Func, TimeUnit):
5578    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5581class TimeDiff(Func, TimeUnit):
5582    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5585class TimeTrunc(Func, TimeUnit):
5586    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5589class DateFromParts(Func):
5590    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5591    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5594class TimeFromParts(Func):
5595    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5596    arg_types = {
5597        "hour": True,
5598        "min": True,
5599        "sec": True,
5600        "nano": False,
5601        "fractions": False,
5602        "precision": False,
5603    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5606class DateStrToDate(Func):
5607    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5610class DateToDateStr(Func):
5611    pass
key = 'datetodatestr'
class DateToDi(Func):
5614class DateToDi(Func):
5615    pass
key = 'datetodi'
class Date(Func):
5619class Date(Func):
5620    arg_types = {"this": False, "zone": False, "expressions": False}
5621    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5624class Day(Func):
5625    pass
key = 'day'
class Decode(Func):
5628class Decode(Func):
5629    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5632class DiToDate(Func):
5633    pass
key = 'ditodate'
class Encode(Func):
5636class Encode(Func):
5637    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5640class Exp(Func):
5641    pass
key = 'exp'
class Explode(Func):
5645class Explode(Func):
5646    arg_types = {"this": True, "expressions": False}
5647    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5651class Inline(Func):
5652    pass
key = 'inline'
class ExplodeOuter(Explode):
5655class ExplodeOuter(Explode):
5656    pass
key = 'explodeouter'
class Posexplode(Explode):
5659class Posexplode(Explode):
5660    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5663class PosexplodeOuter(Posexplode, ExplodeOuter):
5664    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5667class Unnest(Func, UDTF):
5668    arg_types = {
5669        "expressions": True,
5670        "alias": False,
5671        "offset": False,
5672        "explode_array": False,
5673    }
5674
5675    @property
5676    def selects(self) -> t.List[Expression]:
5677        columns = super().selects
5678        offset = self.args.get("offset")
5679        if offset:
5680            columns = columns + [to_identifier("offset") if offset is True else offset]
5681        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5675    @property
5676    def selects(self) -> t.List[Expression]:
5677        columns = super().selects
5678        offset = self.args.get("offset")
5679        if offset:
5680            columns = columns + [to_identifier("offset") if offset is True else offset]
5681        return columns
key = 'unnest'
class Floor(Func):
5684class Floor(Func):
5685    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5688class FromBase64(Func):
5689    pass
key = 'frombase64'
class ToBase64(Func):
5692class ToBase64(Func):
5693    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5697class FromISO8601Timestamp(Func):
5698    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5701class GapFill(Func):
5702    arg_types = {
5703        "this": True,
5704        "ts_column": True,
5705        "bucket_width": True,
5706        "partitioning_columns": False,
5707        "value_columns": False,
5708        "origin": False,
5709        "ignore_nulls": False,
5710    }
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):
5714class GenerateDateArray(Func):
5715    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5719class GenerateTimestampArray(Func):
5720    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5723class Greatest(Func):
5724    arg_types = {"this": True, "expressions": False}
5725    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5728class GroupConcat(AggFunc):
5729    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5732class Hex(Func):
5733    pass
key = 'hex'
class LowerHex(Hex):
5736class LowerHex(Hex):
5737    pass
key = 'lowerhex'
class Xor(Connector, Func):
5740class Xor(Connector, Func):
5741    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5744class If(Func):
5745    arg_types = {"this": True, "true": True, "false": False}
5746    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5749class Nullif(Func):
5750    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5753class Initcap(Func):
5754    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5757class IsNan(Func):
5758    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5761class IsInf(Func):
5762    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5766class JSON(Expression):
5767    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5770class JSONPath(Expression):
5771    arg_types = {"expressions": True, "escape": False}
5772
5773    @property
5774    def output_name(self) -> str:
5775        last_segment = self.expressions[-1].this
5776        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5773    @property
5774    def output_name(self) -> str:
5775        last_segment = self.expressions[-1].this
5776        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):
5779class JSONPathPart(Expression):
5780    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5783class JSONPathFilter(JSONPathPart):
5784    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5787class JSONPathKey(JSONPathPart):
5788    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5791class JSONPathRecursive(JSONPathPart):
5792    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5795class JSONPathRoot(JSONPathPart):
5796    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5799class JSONPathScript(JSONPathPart):
5800    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5803class JSONPathSlice(JSONPathPart):
5804    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5807class JSONPathSelector(JSONPathPart):
5808    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5811class JSONPathSubscript(JSONPathPart):
5812    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5815class JSONPathUnion(JSONPathPart):
5816    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5819class JSONPathWildcard(JSONPathPart):
5820    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5823class FormatJson(Expression):
5824    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5827class JSONKeyValue(Expression):
5828    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5831class JSONObject(Func):
5832    arg_types = {
5833        "expressions": False,
5834        "null_handling": False,
5835        "unique_keys": False,
5836        "return_type": False,
5837        "encoding": False,
5838    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5841class JSONObjectAgg(AggFunc):
5842    arg_types = {
5843        "expressions": False,
5844        "null_handling": False,
5845        "unique_keys": False,
5846        "return_type": False,
5847        "encoding": False,
5848    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5852class JSONArray(Func):
5853    arg_types = {
5854        "expressions": True,
5855        "null_handling": False,
5856        "return_type": False,
5857        "strict": False,
5858    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5862class JSONArrayAgg(Func):
5863    arg_types = {
5864        "this": True,
5865        "order": False,
5866        "null_handling": False,
5867        "return_type": False,
5868        "strict": False,
5869    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5872class JSONExists(Func):
5873    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):
5878class JSONColumnDef(Expression):
5879    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):
5882class JSONSchema(Expression):
5883    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5887class JSONValue(Expression):
5888    arg_types = {
5889        "this": True,
5890        "path": True,
5891        "returning": False,
5892        "on_condition": False,
5893    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONTable(Func):
5897class JSONTable(Func):
5898    arg_types = {
5899        "this": True,
5900        "schema": True,
5901        "path": False,
5902        "error_handling": False,
5903        "empty_handling": False,
5904    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5908class ObjectInsert(Func):
5909    arg_types = {
5910        "this": True,
5911        "key": True,
5912        "value": True,
5913        "update_flag": False,
5914    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5917class OpenJSONColumnDef(Expression):
5918    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):
5921class OpenJSON(Func):
5922    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5925class JSONBContains(Binary, Func):
5926    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5929class JSONExtract(Binary, Func):
5930    arg_types = {
5931        "this": True,
5932        "expression": True,
5933        "only_json_types": False,
5934        "expressions": False,
5935        "variant_extract": False,
5936        "json_query": False,
5937        "option": False,
5938    }
5939    _sql_names = ["JSON_EXTRACT"]
5940    is_var_len_args = True
5941
5942    @property
5943    def output_name(self) -> str:
5944        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
5942    @property
5943    def output_name(self) -> str:
5944        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):
5947class JSONExtractScalar(Binary, Func):
5948    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5949    _sql_names = ["JSON_EXTRACT_SCALAR"]
5950    is_var_len_args = True
5951
5952    @property
5953    def output_name(self) -> str:
5954        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
5952    @property
5953    def output_name(self) -> str:
5954        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):
5957class JSONBExtract(Binary, Func):
5958    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5961class JSONBExtractScalar(Binary, Func):
5962    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5965class JSONFormat(Func):
5966    arg_types = {"this": False, "options": False}
5967    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5971class JSONArrayContains(Binary, Predicate, Func):
5972    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5975class ParseJSON(Func):
5976    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5977    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5978    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5979    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5982class Least(Func):
5983    arg_types = {"this": True, "expressions": False}
5984    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5987class Left(Func):
5988    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5995class Length(Func):
5996    arg_types = {"this": True, "binary": False}
5997    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
6000class Levenshtein(Func):
6001    arg_types = {
6002        "this": True,
6003        "expression": False,
6004        "ins_cost": False,
6005        "del_cost": False,
6006        "sub_cost": False,
6007    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
6010class Ln(Func):
6011    pass
key = 'ln'
class Log(Func):
6014class Log(Func):
6015    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6018class LogicalOr(AggFunc):
6019    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6022class LogicalAnd(AggFunc):
6023    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6026class Lower(Func):
6027    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6030class Map(Func):
6031    arg_types = {"keys": False, "values": False}
6032
6033    @property
6034    def keys(self) -> t.List[Expression]:
6035        keys = self.args.get("keys")
6036        return keys.expressions if keys else []
6037
6038    @property
6039    def values(self) -> t.List[Expression]:
6040        values = self.args.get("values")
6041        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6033    @property
6034    def keys(self) -> t.List[Expression]:
6035        keys = self.args.get("keys")
6036        return keys.expressions if keys else []
values: List[Expression]
6038    @property
6039    def values(self) -> t.List[Expression]:
6040        values = self.args.get("values")
6041        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6045class ToMap(Func):
6046    pass
key = 'tomap'
class MapFromEntries(Func):
6049class MapFromEntries(Func):
6050    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6054class ScopeResolution(Expression):
6055    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6058class Stream(Expression):
6059    pass
key = 'stream'
class StarMap(Func):
6062class StarMap(Func):
6063    pass
key = 'starmap'
class VarMap(Func):
6066class VarMap(Func):
6067    arg_types = {"keys": True, "values": True}
6068    is_var_len_args = True
6069
6070    @property
6071    def keys(self) -> t.List[Expression]:
6072        return self.args["keys"].expressions
6073
6074    @property
6075    def values(self) -> t.List[Expression]:
6076        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6070    @property
6071    def keys(self) -> t.List[Expression]:
6072        return self.args["keys"].expressions
values: List[Expression]
6074    @property
6075    def values(self) -> t.List[Expression]:
6076        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6080class MatchAgainst(Func):
6081    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6084class Max(AggFunc):
6085    arg_types = {"this": True, "expressions": False}
6086    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6089class MD5(Func):
6090    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6094class MD5Digest(Func):
6095    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
6098class Min(AggFunc):
6099    arg_types = {"this": True, "expressions": False}
6100    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6103class Month(Func):
6104    pass
key = 'month'
class AddMonths(Func):
6107class AddMonths(Func):
6108    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6111class Nvl2(Func):
6112    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6115class Normalize(Func):
6116    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6119class Overlay(Func):
6120    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):
6124class Predict(Func):
6125    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6128class Pow(Binary, Func):
6129    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6132class PercentileCont(AggFunc):
6133    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6136class PercentileDisc(AggFunc):
6137    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6140class Quantile(AggFunc):
6141    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6144class ApproxQuantile(Quantile):
6145    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):
6148class Quarter(Func):
6149    pass
key = 'quarter'
class Rand(Func):
6154class Rand(Func):
6155    _sql_names = ["RAND", "RANDOM"]
6156    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6159class Randn(Func):
6160    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6163class RangeN(Func):
6164    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6167class ReadCSV(Func):
6168    _sql_names = ["READ_CSV"]
6169    is_var_len_args = True
6170    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6173class Reduce(Func):
6174    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):
6177class RegexpExtract(Func):
6178    arg_types = {
6179        "this": True,
6180        "expression": True,
6181        "position": False,
6182        "occurrence": False,
6183        "parameters": False,
6184        "group": False,
6185    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
6188class RegexpReplace(Func):
6189    arg_types = {
6190        "this": True,
6191        "expression": True,
6192        "replacement": False,
6193        "position": False,
6194        "occurrence": False,
6195        "modifiers": False,
6196    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6199class RegexpLike(Binary, Func):
6200    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6203class RegexpILike(Binary, Func):
6204    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6209class RegexpSplit(Func):
6210    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6213class Repeat(Func):
6214    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6219class Round(Func):
6220    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6223class RowNumber(Func):
6224    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
6227class SafeDivide(Func):
6228    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6231class SHA(Func):
6232    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6235class SHA2(Func):
6236    _sql_names = ["SHA2"]
6237    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6240class Sign(Func):
6241    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6244class SortArray(Func):
6245    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6248class Split(Func):
6249    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
6254class Substring(Func):
6255    _sql_names = ["SUBSTRING", "SUBSTR"]
6256    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6259class StandardHash(Func):
6260    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6263class StartsWith(Func):
6264    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6265    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6268class StrPosition(Func):
6269    arg_types = {
6270        "this": True,
6271        "substr": True,
6272        "position": False,
6273        "instance": False,
6274    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6277class StrToDate(Func):
6278    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6281class StrToTime(Func):
6282    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):
6287class StrToUnix(Func):
6288    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6293class StrToMap(Func):
6294    arg_types = {
6295        "this": True,
6296        "pair_delim": False,
6297        "key_value_delim": False,
6298        "duplicate_resolution_callback": False,
6299    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6302class NumberToStr(Func):
6303    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6306class FromBase(Func):
6307    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6310class Struct(Func):
6311    arg_types = {"expressions": False}
6312    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6315class StructExtract(Func):
6316    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6321class Stuff(Func):
6322    _sql_names = ["STUFF", "INSERT"]
6323    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):
6326class Sum(AggFunc):
6327    pass
key = 'sum'
class Sqrt(Func):
6330class Sqrt(Func):
6331    pass
key = 'sqrt'
class Stddev(AggFunc):
6334class Stddev(AggFunc):
6335    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6338class StddevPop(AggFunc):
6339    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6342class StddevSamp(AggFunc):
6343    pass
key = 'stddevsamp'
class Time(Func):
6347class Time(Func):
6348    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6351class TimeToStr(Func):
6352    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):
6355class TimeToTimeStr(Func):
6356    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6359class TimeToUnix(Func):
6360    pass
key = 'timetounix'
class TimeStrToDate(Func):
6363class TimeStrToDate(Func):
6364    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6367class TimeStrToTime(Func):
6368    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6371class TimeStrToUnix(Func):
6372    pass
key = 'timestrtounix'
class Trim(Func):
6375class Trim(Func):
6376    arg_types = {
6377        "this": True,
6378        "expression": False,
6379        "position": False,
6380        "collation": False,
6381    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6384class TsOrDsAdd(Func, TimeUnit):
6385    # return_type is used to correctly cast the arguments of this expression when transpiling it
6386    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6387
6388    @property
6389    def return_type(self) -> DataType:
6390        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
6388    @property
6389    def return_type(self) -> DataType:
6390        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6393class TsOrDsDiff(Func, TimeUnit):
6394    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6397class TsOrDsToDateStr(Func):
6398    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6401class TsOrDsToDate(Func):
6402    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6405class TsOrDsToTime(Func):
6406    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6409class TsOrDsToTimestamp(Func):
6410    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6413class TsOrDiToDi(Func):
6414    pass
key = 'tsorditodi'
class Unhex(Func):
6417class Unhex(Func):
6418    pass
key = 'unhex'
class UnixDate(Func):
6422class UnixDate(Func):
6423    pass
key = 'unixdate'
class UnixToStr(Func):
6426class UnixToStr(Func):
6427    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6432class UnixToTime(Func):
6433    arg_types = {
6434        "this": True,
6435        "scale": False,
6436        "zone": False,
6437        "hours": False,
6438        "minutes": False,
6439        "format": False,
6440    }
6441
6442    SECONDS = Literal.number(0)
6443    DECIS = Literal.number(1)
6444    CENTIS = Literal.number(2)
6445    MILLIS = Literal.number(3)
6446    DECIMILLIS = Literal.number(4)
6447    CENTIMILLIS = Literal.number(5)
6448    MICROS = Literal.number(6)
6449    DECIMICROS = Literal.number(7)
6450    CENTIMICROS = Literal.number(8)
6451    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):
6454class UnixToTimeStr(Func):
6455    pass
key = 'unixtotimestr'
class Uuid(Func):
6458class Uuid(Func):
6459    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6460
6461    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6464class TimestampFromParts(Func):
6465    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6466    arg_types = {
6467        "year": True,
6468        "month": True,
6469        "day": True,
6470        "hour": True,
6471        "min": True,
6472        "sec": True,
6473        "nano": False,
6474        "zone": False,
6475        "milli": False,
6476    }
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):
6479class Upper(Func):
6480    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6483class Corr(Binary, AggFunc):
6484    pass
key = 'corr'
class Variance(AggFunc):
6487class Variance(AggFunc):
6488    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6491class VariancePop(AggFunc):
6492    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6495class CovarSamp(Binary, AggFunc):
6496    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6499class CovarPop(Binary, AggFunc):
6500    pass
key = 'covarpop'
class Week(Func):
6503class Week(Func):
6504    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6507class XMLTable(Func):
6508    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):
6511class Year(Func):
6512    pass
key = 'year'
class Use(Expression):
6515class Use(Expression):
6516    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6519class Merge(DML):
6520    arg_types = {
6521        "this": True,
6522        "using": True,
6523        "on": True,
6524        "expressions": True,
6525        "with": False,
6526        "returning": False,
6527    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6530class When(Func):
6531    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):
6536class NextValueFor(Func):
6537    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6542class Semicolon(Expression):
6543    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 '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 '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'>, '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_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:
6583def maybe_parse(
6584    sql_or_expression: ExpOrStr,
6585    *,
6586    into: t.Optional[IntoType] = None,
6587    dialect: DialectType = None,
6588    prefix: t.Optional[str] = None,
6589    copy: bool = False,
6590    **opts,
6591) -> Expression:
6592    """Gracefully handle a possible string or expression.
6593
6594    Example:
6595        >>> maybe_parse("1")
6596        Literal(this=1, is_string=False)
6597        >>> maybe_parse(to_identifier("x"))
6598        Identifier(this=x, quoted=False)
6599
6600    Args:
6601        sql_or_expression: the SQL code string or an expression
6602        into: the SQLGlot Expression to parse into
6603        dialect: the dialect used to parse the input expressions (in the case that an
6604            input expression is a SQL string).
6605        prefix: a string to prefix the sql with before it gets parsed
6606            (automatically includes a space)
6607        copy: whether to copy the expression.
6608        **opts: other options to use to parse the input expressions (again, in the case
6609            that an input expression is a SQL string).
6610
6611    Returns:
6612        Expression: the parsed or given expression.
6613    """
6614    if isinstance(sql_or_expression, Expression):
6615        if copy:
6616            return sql_or_expression.copy()
6617        return sql_or_expression
6618
6619    if sql_or_expression is None:
6620        raise ParseError("SQL cannot be None")
6621
6622    import sqlglot
6623
6624    sql = str(sql_or_expression)
6625    if prefix:
6626        sql = f"{prefix} {sql}"
6627
6628    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):
6639def maybe_copy(instance, copy=True):
6640    return instance.copy() if copy and instance else instance
def union( left: Union[str, Expression], right: 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:
6861def union(
6862    left: ExpOrStr,
6863    right: ExpOrStr,
6864    distinct: bool = True,
6865    dialect: DialectType = None,
6866    copy: bool = True,
6867    **opts,
6868) -> Union:
6869    """
6870    Initializes a syntax tree from one UNION expression.
6871
6872    Example:
6873        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6874        'SELECT * FROM foo UNION SELECT * FROM bla'
6875
6876    Args:
6877        left: the SQL code string corresponding to the left-hand side.
6878            If an `Expression` instance is passed, it will be used as-is.
6879        right: the SQL code string corresponding to the right-hand side.
6880            If an `Expression` instance is passed, it will be used as-is.
6881        distinct: set the DISTINCT flag if and only if this is true.
6882        dialect: the dialect used to parse the input expression.
6883        copy: whether to copy the expression.
6884        opts: other options to use to parse the input expressions.
6885
6886    Returns:
6887        The new Union instance.
6888    """
6889    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6890    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6891
6892    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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( left: Union[str, Expression], right: 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:
6895def intersect(
6896    left: ExpOrStr,
6897    right: ExpOrStr,
6898    distinct: bool = True,
6899    dialect: DialectType = None,
6900    copy: bool = True,
6901    **opts,
6902) -> Intersect:
6903    """
6904    Initializes a syntax tree from one INTERSECT expression.
6905
6906    Example:
6907        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6908        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6909
6910    Args:
6911        left: the SQL code string corresponding to the left-hand side.
6912            If an `Expression` instance is passed, it will be used as-is.
6913        right: the SQL code string corresponding to the right-hand side.
6914            If an `Expression` instance is passed, it will be used as-is.
6915        distinct: set the DISTINCT flag if and only if this is true.
6916        dialect: the dialect used to parse the input expression.
6917        copy: whether to copy the expression.
6918        opts: other options to use to parse the input expressions.
6919
6920    Returns:
6921        The new Intersect instance.
6922    """
6923    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6924    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6925
6926    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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_( left: Union[str, Expression], right: 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:
6929def except_(
6930    left: ExpOrStr,
6931    right: ExpOrStr,
6932    distinct: bool = True,
6933    dialect: DialectType = None,
6934    copy: bool = True,
6935    **opts,
6936) -> Except:
6937    """
6938    Initializes a syntax tree from one EXCEPT expression.
6939
6940    Example:
6941        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6942        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6943
6944    Args:
6945        left: the SQL code string corresponding to the left-hand side.
6946            If an `Expression` instance is passed, it will be used as-is.
6947        right: the SQL code string corresponding to the right-hand side.
6948            If an `Expression` instance is passed, it will be used as-is.
6949        distinct: set the DISTINCT flag if and only if this is true.
6950        dialect: the dialect used to parse the input expression.
6951        copy: whether to copy the expression.
6952        opts: other options to use to parse the input expressions.
6953
6954    Returns:
6955        The new Except instance.
6956    """
6957    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6958    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6959
6960    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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:
6963def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6964    """
6965    Initializes a syntax tree from one or multiple SELECT expressions.
6966
6967    Example:
6968        >>> select("col1", "col2").from_("tbl").sql()
6969        'SELECT col1, col2 FROM tbl'
6970
6971    Args:
6972        *expressions: the SQL code string to parse as the expressions of a
6973            SELECT statement. If an Expression instance is passed, this is used as-is.
6974        dialect: the dialect used to parse the input expressions (in the case that an
6975            input expression is a SQL string).
6976        **opts: other options to use to parse the input expressions (again, in the case
6977            that an input expression is a SQL string).
6978
6979    Returns:
6980        Select: the syntax tree for the SELECT statement.
6981    """
6982    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:
6985def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6986    """
6987    Initializes a syntax tree from a FROM expression.
6988
6989    Example:
6990        >>> from_("tbl").select("col1", "col2").sql()
6991        'SELECT col1, col2 FROM tbl'
6992
6993    Args:
6994        *expression: the SQL code string to parse as the FROM expressions of a
6995            SELECT statement. If an Expression instance is passed, this is used as-is.
6996        dialect: the dialect used to parse the input expression (in the case that the
6997            input expression is a SQL string).
6998        **opts: other options to use to parse the input expressions (again, in the case
6999            that the input expression is a SQL string).
7000
7001    Returns:
7002        Select: the syntax tree for the SELECT statement.
7003    """
7004    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:
7007def update(
7008    table: str | Table,
7009    properties: t.Optional[dict] = None,
7010    where: t.Optional[ExpOrStr] = None,
7011    from_: t.Optional[ExpOrStr] = None,
7012    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7013    dialect: DialectType = None,
7014    **opts,
7015) -> Update:
7016    """
7017    Creates an update statement.
7018
7019    Example:
7020        >>> 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()
7021        "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"
7022
7023    Args:
7024        properties: dictionary of properties to SET which are
7025            auto converted to sql objects eg None -> NULL
7026        where: sql conditional parsed into a WHERE statement
7027        from_: sql statement parsed into a FROM statement
7028        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7029        dialect: the dialect used to parse the input expressions.
7030        **opts: other options to use to parse the input expressions.
7031
7032    Returns:
7033        Update: the syntax tree for the UPDATE statement.
7034    """
7035    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7036    if properties:
7037        update_expr.set(
7038            "expressions",
7039            [
7040                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7041                for k, v in properties.items()
7042            ],
7043        )
7044    if from_:
7045        update_expr.set(
7046            "from",
7047            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7048        )
7049    if isinstance(where, Condition):
7050        where = Where(this=where)
7051    if where:
7052        update_expr.set(
7053            "where",
7054            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7055        )
7056    if with_:
7057        cte_list = [
7058            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7059            for alias, qry in with_.items()
7060        ]
7061        update_expr.set(
7062            "with",
7063            With(expressions=cte_list),
7064        )
7065    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:
7068def delete(
7069    table: ExpOrStr,
7070    where: t.Optional[ExpOrStr] = None,
7071    returning: t.Optional[ExpOrStr] = None,
7072    dialect: DialectType = None,
7073    **opts,
7074) -> Delete:
7075    """
7076    Builds a delete statement.
7077
7078    Example:
7079        >>> delete("my_table", where="id > 1").sql()
7080        'DELETE FROM my_table WHERE id > 1'
7081
7082    Args:
7083        where: sql conditional parsed into a WHERE statement
7084        returning: sql conditional parsed into a RETURNING statement
7085        dialect: the dialect used to parse the input expressions.
7086        **opts: other options to use to parse the input expressions.
7087
7088    Returns:
7089        Delete: the syntax tree for the DELETE statement.
7090    """
7091    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7092    if where:
7093        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7094    if returning:
7095        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7096    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:
7099def insert(
7100    expression: ExpOrStr,
7101    into: ExpOrStr,
7102    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7103    overwrite: t.Optional[bool] = None,
7104    returning: t.Optional[ExpOrStr] = None,
7105    dialect: DialectType = None,
7106    copy: bool = True,
7107    **opts,
7108) -> Insert:
7109    """
7110    Builds an INSERT statement.
7111
7112    Example:
7113        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7114        'INSERT INTO tbl VALUES (1, 2, 3)'
7115
7116    Args:
7117        expression: the sql string or expression of the INSERT statement
7118        into: the tbl to insert data to.
7119        columns: optionally the table's column names.
7120        overwrite: whether to INSERT OVERWRITE or not.
7121        returning: sql conditional parsed into a RETURNING statement
7122        dialect: the dialect used to parse the input expressions.
7123        copy: whether to copy the expression.
7124        **opts: other options to use to parse the input expressions.
7125
7126    Returns:
7127        Insert: the syntax tree for the INSERT statement.
7128    """
7129    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7130    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7131
7132    if columns:
7133        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7134
7135    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7136
7137    if returning:
7138        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7139
7140    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:
7143def merge(
7144    *when_exprs: ExpOrStr,
7145    into: ExpOrStr,
7146    using: ExpOrStr,
7147    on: ExpOrStr,
7148    returning: t.Optional[ExpOrStr] = None,
7149    dialect: DialectType = None,
7150    copy: bool = True,
7151    **opts,
7152) -> Merge:
7153    """
7154    Builds a MERGE statement.
7155
7156    Example:
7157        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7158        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7159        ...       into="my_table",
7160        ...       using="source_table",
7161        ...       on="my_table.id = source_table.id").sql()
7162        '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)'
7163
7164    Args:
7165        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7166        into: The target table to merge data into.
7167        using: The source table to merge data from.
7168        on: The join condition for the merge.
7169        returning: The columns to return from the merge.
7170        dialect: The dialect used to parse the input expressions.
7171        copy: Whether to copy the expression.
7172        **opts: Other options to use to parse the input expressions.
7173
7174    Returns:
7175        Merge: The syntax tree for the MERGE statement.
7176    """
7177    merge = Merge(
7178        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7179        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7180        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7181        expressions=[
7182            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
7183            for when_expr in when_exprs
7184        ],
7185    )
7186    if returning:
7187        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7188
7189    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:
7192def condition(
7193    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7194) -> Condition:
7195    """
7196    Initialize a logical condition expression.
7197
7198    Example:
7199        >>> condition("x=1").sql()
7200        'x = 1'
7201
7202        This is helpful for composing larger logical syntax trees:
7203        >>> where = condition("x=1")
7204        >>> where = where.and_("y=1")
7205        >>> Select().from_("tbl").select("*").where(where).sql()
7206        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7207
7208    Args:
7209        *expression: the SQL code string to parse.
7210            If an Expression instance is passed, this is used as-is.
7211        dialect: the dialect used to parse the input expression (in the case that the
7212            input expression is a SQL string).
7213        copy: Whether to copy `expression` (only applies to expressions).
7214        **opts: other options to use to parse the input expressions (again, in the case
7215            that the input expression is a SQL string).
7216
7217    Returns:
7218        The new Condition instance
7219    """
7220    return maybe_parse(
7221        expression,
7222        into=Condition,
7223        dialect=dialect,
7224        copy=copy,
7225        **opts,
7226    )

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:
7229def and_(
7230    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7231) -> Condition:
7232    """
7233    Combine multiple conditions with an AND logical operator.
7234
7235    Example:
7236        >>> and_("x=1", and_("y=1", "z=1")).sql()
7237        'x = 1 AND (y = 1 AND z = 1)'
7238
7239    Args:
7240        *expressions: the SQL code strings to parse.
7241            If an Expression instance is passed, this is used as-is.
7242        dialect: the dialect used to parse the input expression.
7243        copy: whether to copy `expressions` (only applies to Expressions).
7244        **opts: other options to use to parse the input expressions.
7245
7246    Returns:
7247        The new condition
7248    """
7249    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:
7252def or_(
7253    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7254) -> Condition:
7255    """
7256    Combine multiple conditions with an OR logical operator.
7257
7258    Example:
7259        >>> or_("x=1", or_("y=1", "z=1")).sql()
7260        'x = 1 OR (y = 1 OR z = 1)'
7261
7262    Args:
7263        *expressions: the SQL code strings to parse.
7264            If an Expression instance is passed, this is used as-is.
7265        dialect: the dialect used to parse the input expression.
7266        copy: whether to copy `expressions` (only applies to Expressions).
7267        **opts: other options to use to parse the input expressions.
7268
7269    Returns:
7270        The new condition
7271    """
7272    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:
7275def xor(
7276    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7277) -> Condition:
7278    """
7279    Combine multiple conditions with an XOR logical operator.
7280
7281    Example:
7282        >>> xor("x=1", xor("y=1", "z=1")).sql()
7283        'x = 1 XOR (y = 1 XOR z = 1)'
7284
7285    Args:
7286        *expressions: the SQL code strings to parse.
7287            If an Expression instance is passed, this is used as-is.
7288        dialect: the dialect used to parse the input expression.
7289        copy: whether to copy `expressions` (only applies to Expressions).
7290        **opts: other options to use to parse the input expressions.
7291
7292    Returns:
7293        The new condition
7294    """
7295    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:
7298def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7299    """
7300    Wrap a condition with a NOT operator.
7301
7302    Example:
7303        >>> not_("this_suit='black'").sql()
7304        "NOT this_suit = 'black'"
7305
7306    Args:
7307        expression: the SQL code string to parse.
7308            If an Expression instance is passed, this is used as-is.
7309        dialect: the dialect used to parse the input expression.
7310        copy: whether to copy the expression or not.
7311        **opts: other options to use to parse the input expressions.
7312
7313    Returns:
7314        The new condition.
7315    """
7316    this = condition(
7317        expression,
7318        dialect=dialect,
7319        copy=copy,
7320        **opts,
7321    )
7322    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:
7325def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7326    """
7327    Wrap an expression in parentheses.
7328
7329    Example:
7330        >>> paren("5 + 3").sql()
7331        '(5 + 3)'
7332
7333    Args:
7334        expression: the SQL code string to parse.
7335            If an Expression instance is passed, this is used as-is.
7336        copy: whether to copy the expression or not.
7337
7338    Returns:
7339        The wrapped expression.
7340    """
7341    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):
7357def to_identifier(name, quoted=None, copy=True):
7358    """Builds an identifier.
7359
7360    Args:
7361        name: The name to turn into an identifier.
7362        quoted: Whether to force quote the identifier.
7363        copy: Whether to copy name if it's an Identifier.
7364
7365    Returns:
7366        The identifier ast node.
7367    """
7368
7369    if name is None:
7370        return None
7371
7372    if isinstance(name, Identifier):
7373        identifier = maybe_copy(name, copy)
7374    elif isinstance(name, str):
7375        identifier = Identifier(
7376            this=name,
7377            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7378        )
7379    else:
7380        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7381    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:
7384def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7385    """
7386    Parses a given string into an identifier.
7387
7388    Args:
7389        name: The name to parse into an identifier.
7390        dialect: The dialect to parse against.
7391
7392    Returns:
7393        The identifier ast node.
7394    """
7395    try:
7396        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7397    except (ParseError, TokenError):
7398        expression = to_identifier(name)
7399
7400    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:
7406def to_interval(interval: str | Literal) -> Interval:
7407    """Builds an interval expression from a string like '1 day' or '5 months'."""
7408    if isinstance(interval, Literal):
7409        if not interval.is_string:
7410            raise ValueError("Invalid interval string.")
7411
7412        interval = interval.this
7413
7414    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
7415
7416    if not interval_parts:
7417        raise ValueError("Invalid interval string.")
7418
7419    return Interval(
7420        this=Literal.string(interval_parts.group(1)),
7421        unit=Var(this=interval_parts.group(2).upper()),
7422    )

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:
7425def to_table(
7426    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7427) -> Table:
7428    """
7429    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7430    If a table is passed in then that table is returned.
7431
7432    Args:
7433        sql_path: a `[catalog].[schema].[table]` string.
7434        dialect: the source dialect according to which the table name will be parsed.
7435        copy: Whether to copy a table if it is passed in.
7436        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7437
7438    Returns:
7439        A table expression.
7440    """
7441    if isinstance(sql_path, Table):
7442        return maybe_copy(sql_path, copy=copy)
7443
7444    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7445
7446    for k, v in kwargs.items():
7447        table.set(k, v)
7448
7449    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:
7452def to_column(
7453    sql_path: str | Column,
7454    quoted: t.Optional[bool] = None,
7455    dialect: DialectType = None,
7456    copy: bool = True,
7457    **kwargs,
7458) -> Column:
7459    """
7460    Create a column from a `[table].[column]` sql path. Table is optional.
7461    If a column is passed in then that column is returned.
7462
7463    Args:
7464        sql_path: a `[table].[column]` string.
7465        quoted: Whether or not to force quote identifiers.
7466        dialect: the source dialect according to which the column name will be parsed.
7467        copy: Whether to copy a column if it is passed in.
7468        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7469
7470    Returns:
7471        A column expression.
7472    """
7473    if isinstance(sql_path, Column):
7474        return maybe_copy(sql_path, copy=copy)
7475
7476    try:
7477        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7478    except ParseError:
7479        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7480
7481    for k, v in kwargs.items():
7482        col.set(k, v)
7483
7484    if quoted:
7485        for i in col.find_all(Identifier):
7486            i.set("quoted", True)
7487
7488    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):
7491def alias_(
7492    expression: ExpOrStr,
7493    alias: t.Optional[str | Identifier],
7494    table: bool | t.Sequence[str | Identifier] = False,
7495    quoted: t.Optional[bool] = None,
7496    dialect: DialectType = None,
7497    copy: bool = True,
7498    **opts,
7499):
7500    """Create an Alias expression.
7501
7502    Example:
7503        >>> alias_('foo', 'bar').sql()
7504        'foo AS bar'
7505
7506        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7507        '(SELECT 1, 2) AS bar(a, b)'
7508
7509    Args:
7510        expression: the SQL code strings to parse.
7511            If an Expression instance is passed, this is used as-is.
7512        alias: the alias name to use. If the name has
7513            special characters it is quoted.
7514        table: Whether to create a table alias, can also be a list of columns.
7515        quoted: whether to quote the alias
7516        dialect: the dialect used to parse the input expression.
7517        copy: Whether to copy the expression.
7518        **opts: other options to use to parse the input expressions.
7519
7520    Returns:
7521        Alias: the aliased expression
7522    """
7523    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7524    alias = to_identifier(alias, quoted=quoted)
7525
7526    if table:
7527        table_alias = TableAlias(this=alias)
7528        exp.set("alias", table_alias)
7529
7530        if not isinstance(table, bool):
7531            for column in table:
7532                table_alias.append("columns", to_identifier(column, quoted=quoted))
7533
7534        return exp
7535
7536    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7537    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7538    # for the complete Window expression.
7539    #
7540    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7541
7542    if "alias" in exp.arg_types and not isinstance(exp, Window):
7543        exp.set("alias", alias)
7544        return exp
7545    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:
7548def subquery(
7549    expression: ExpOrStr,
7550    alias: t.Optional[Identifier | str] = None,
7551    dialect: DialectType = None,
7552    **opts,
7553) -> Select:
7554    """
7555    Build a subquery expression that's selected from.
7556
7557    Example:
7558        >>> subquery('select x from tbl', 'bar').select('x').sql()
7559        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7560
7561    Args:
7562        expression: the SQL code strings to parse.
7563            If an Expression instance is passed, this is used as-is.
7564        alias: the alias name to use.
7565        dialect: the dialect used to parse the input expression.
7566        **opts: other options to use to parse the input expressions.
7567
7568    Returns:
7569        A new Select instance with the subquery expression included.
7570    """
7571
7572    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7573    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):
7604def column(
7605    col,
7606    table=None,
7607    db=None,
7608    catalog=None,
7609    *,
7610    fields=None,
7611    quoted=None,
7612    copy=True,
7613):
7614    """
7615    Build a Column.
7616
7617    Args:
7618        col: Column name.
7619        table: Table name.
7620        db: Database name.
7621        catalog: Catalog name.
7622        fields: Additional fields using dots.
7623        quoted: Whether to force quotes on the column's identifiers.
7624        copy: Whether to copy identifiers if passed in.
7625
7626    Returns:
7627        The new Column instance.
7628    """
7629    this = Column(
7630        this=to_identifier(col, quoted=quoted, copy=copy),
7631        table=to_identifier(table, quoted=quoted, copy=copy),
7632        db=to_identifier(db, quoted=quoted, copy=copy),
7633        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7634    )
7635
7636    if fields:
7637        this = Dot.build(
7638            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7639        )
7640    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:
7643def cast(
7644    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7645) -> Cast:
7646    """Cast an expression to a data type.
7647
7648    Example:
7649        >>> cast('x + 1', 'int').sql()
7650        'CAST(x + 1 AS INT)'
7651
7652    Args:
7653        expression: The expression to cast.
7654        to: The datatype to cast to.
7655        copy: Whether to copy the supplied expressions.
7656        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7657            - The expression to be cast is already a exp.Cast expression
7658            - The existing cast is to a type that is logically equivalent to new type
7659
7660            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7661            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7662            and instead just return the original expression `CAST(x as DATETIME)`.
7663
7664            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7665            mapping is applied in the target dialect generator.
7666
7667    Returns:
7668        The new Cast instance.
7669    """
7670    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7671    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7672
7673    # dont re-cast if the expression is already a cast to the correct type
7674    if isinstance(expr, Cast):
7675        from sqlglot.dialects.dialect import Dialect
7676
7677        target_dialect = Dialect.get_or_raise(dialect)
7678        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7679
7680        existing_cast_type: DataType.Type = expr.to.this
7681        new_cast_type: DataType.Type = data_type.this
7682        types_are_equivalent = type_mapping.get(
7683            existing_cast_type, existing_cast_type
7684        ) == type_mapping.get(new_cast_type, new_cast_type)
7685        if expr.is_type(data_type) or types_are_equivalent:
7686            return expr
7687
7688    expr = Cast(this=expr, to=data_type)
7689    expr.type = data_type
7690
7691    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:
7694def table_(
7695    table: Identifier | str,
7696    db: t.Optional[Identifier | str] = None,
7697    catalog: t.Optional[Identifier | str] = None,
7698    quoted: t.Optional[bool] = None,
7699    alias: t.Optional[Identifier | str] = None,
7700) -> Table:
7701    """Build a Table.
7702
7703    Args:
7704        table: Table name.
7705        db: Database name.
7706        catalog: Catalog name.
7707        quote: Whether to force quotes on the table's identifiers.
7708        alias: Table's alias.
7709
7710    Returns:
7711        The new Table instance.
7712    """
7713    return Table(
7714        this=to_identifier(table, quoted=quoted) if table else None,
7715        db=to_identifier(db, quoted=quoted) if db else None,
7716        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7717        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7718    )

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:
7721def values(
7722    values: t.Iterable[t.Tuple[t.Any, ...]],
7723    alias: t.Optional[str] = None,
7724    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7725) -> Values:
7726    """Build VALUES statement.
7727
7728    Example:
7729        >>> values([(1, '2')]).sql()
7730        "VALUES (1, '2')"
7731
7732    Args:
7733        values: values statements that will be converted to SQL
7734        alias: optional alias
7735        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7736         If either are provided then an alias is also required.
7737
7738    Returns:
7739        Values: the Values expression object
7740    """
7741    if columns and not alias:
7742        raise ValueError("Alias is required when providing columns")
7743
7744    return Values(
7745        expressions=[convert(tup) for tup in values],
7746        alias=(
7747            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7748            if columns
7749            else (TableAlias(this=to_identifier(alias)) if alias else None)
7750        ),
7751    )

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:
7754def var(name: t.Optional[ExpOrStr]) -> Var:
7755    """Build a SQL variable.
7756
7757    Example:
7758        >>> repr(var('x'))
7759        'Var(this=x)'
7760
7761        >>> repr(var(column('x', table='y')))
7762        'Var(this=x)'
7763
7764    Args:
7765        name: The name of the var or an expression who's name will become the var.
7766
7767    Returns:
7768        The new variable node.
7769    """
7770    if not name:
7771        raise ValueError("Cannot convert empty name into var.")
7772
7773    if isinstance(name, Expression):
7774        name = name.name
7775    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:
7778def rename_table(
7779    old_name: str | Table,
7780    new_name: str | Table,
7781    dialect: DialectType = None,
7782) -> Alter:
7783    """Build ALTER TABLE... RENAME... expression
7784
7785    Args:
7786        old_name: The old name of the table
7787        new_name: The new name of the table
7788        dialect: The dialect to parse the table.
7789
7790    Returns:
7791        Alter table expression
7792    """
7793    old_table = to_table(old_name, dialect=dialect)
7794    new_table = to_table(new_name, dialect=dialect)
7795    return Alter(
7796        this=old_table,
7797        kind="TABLE",
7798        actions=[
7799            RenameTable(this=new_table),
7800        ],
7801    )

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:
7804def rename_column(
7805    table_name: str | Table,
7806    old_column_name: str | Column,
7807    new_column_name: str | Column,
7808    exists: t.Optional[bool] = None,
7809    dialect: DialectType = None,
7810) -> Alter:
7811    """Build ALTER TABLE... RENAME COLUMN... expression
7812
7813    Args:
7814        table_name: Name of the table
7815        old_column: The old name of the column
7816        new_column: The new name of the column
7817        exists: Whether to add the `IF EXISTS` clause
7818        dialect: The dialect to parse the table/column.
7819
7820    Returns:
7821        Alter table expression
7822    """
7823    table = to_table(table_name, dialect=dialect)
7824    old_column = to_column(old_column_name, dialect=dialect)
7825    new_column = to_column(new_column_name, dialect=dialect)
7826    return Alter(
7827        this=table,
7828        kind="TABLE",
7829        actions=[
7830            RenameColumn(this=old_column, to=new_column, exists=exists),
7831        ],
7832    )

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

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:
7969def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7970    """Get the full name of a table as a string.
7971
7972    Args:
7973        table: Table expression node or string.
7974        dialect: The dialect to generate the table name for.
7975        identify: Determines when an identifier should be quoted. Possible values are:
7976            False (default): Never quote, except in cases where it's mandatory by the dialect.
7977            True: Always quote.
7978
7979    Examples:
7980        >>> from sqlglot import exp, parse_one
7981        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7982        'a.b.c'
7983
7984    Returns:
7985        The table name.
7986    """
7987
7988    table = maybe_parse(table, into=Table, dialect=dialect)
7989
7990    if not table:
7991        raise ValueError(f"Cannot parse {table}")
7992
7993    return ".".join(
7994        (
7995            part.sql(dialect=dialect, identify=True, copy=False)
7996            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7997            else part.name
7998        )
7999        for part in table.parts
8000    )

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:
8003def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8004    """Returns a case normalized table name without quotes.
8005
8006    Args:
8007        table: the table to normalize
8008        dialect: the dialect to use for normalization rules
8009        copy: whether to copy the expression.
8010
8011    Examples:
8012        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8013        'A-B.c'
8014    """
8015    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8016
8017    return ".".join(
8018        p.name
8019        for p in normalize_identifiers(
8020            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8021        ).parts
8022    )

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

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:
8252def tuple_(
8253    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8254) -> Tuple:
8255    """
8256    Returns an tuple.
8257
8258    Examples:
8259        >>> tuple_(1, 'x').sql()
8260        '(1, x)'
8261
8262    Args:
8263        expressions: the expressions to add to the tuple.
8264        copy: whether to copy the argument expressions.
8265        dialect: the source dialect.
8266        kwargs: the kwargs used to instantiate the function of interest.
8267
8268    Returns:
8269        A tuple expression.
8270    """
8271    return Tuple(
8272        expressions=[
8273            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8274            for expression in expressions
8275        ]
8276    )

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:
8279def true() -> Boolean:
8280    """
8281    Returns a true Boolean expression.
8282    """
8283    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8286def false() -> Boolean:
8287    """
8288    Returns a false Boolean expression.
8289    """
8290    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8293def null() -> Null:
8294    """
8295    Returns a Null expression.
8296    """
8297    return Null()

Returns a Null expression.

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