Edit on GitHub

Expressions

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

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


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

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • index: the index of an expression if it is inside of a list argument in its parent.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the sqlglot.expressions.DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
108    def __init__(self, **args: t.Any):
109        self.args: t.Dict[str, t.Any] = args
110        self.parent: t.Optional[Expression] = None
111        self.arg_key: t.Optional[str] = None
112        self.index: t.Optional[int] = None
113        self.comments: t.Optional[t.List[str]] = None
114        self._type: t.Optional[DataType] = None
115        self._meta: t.Optional[t.Dict[str, t.Any]] = None
116        self._hash: t.Optional[int] = None
117
118        for arg_key, value in self.args.items():
119            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
this: Any
167    @property
168    def this(self) -> t.Any:
169        """
170        Retrieves the argument with key "this".
171        """
172        return self.args.get("this")

Retrieves the argument with key "this".

expression: Any
174    @property
175    def expression(self) -> t.Any:
176        """
177        Retrieves the argument with key "expression".
178        """
179        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
181    @property
182    def expressions(self) -> t.List[t.Any]:
183        """
184        Retrieves the argument with key "expressions".
185        """
186        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
188    def text(self, key) -> str:
189        """
190        Returns a textual representation of the argument corresponding to "key". This can only be used
191        for args that are strings or leaf Expression instances, such as identifiers and literals.
192        """
193        field = self.args.get(key)
194        if isinstance(field, str):
195            return field
196        if isinstance(field, (Identifier, Literal, Var)):
197            return field.this
198        if isinstance(field, (Star, Null)):
199            return field.name
200        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
202    @property
203    def is_string(self) -> bool:
204        """
205        Checks whether a Literal expression is a string.
206        """
207        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
209    @property
210    def is_number(self) -> bool:
211        """
212        Checks whether a Literal expression is a number.
213        """
214        return (isinstance(self, Literal) and not self.args["is_string"]) or (
215            isinstance(self, Neg) and self.this.is_number
216        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
218    def to_py(self) -> t.Any:
219        """
220        Returns a Python object equivalent of the SQL node.
221        """
222        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
224    @property
225    def is_int(self) -> bool:
226        """
227        Checks whether an expression is an integer.
228        """
229        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
231    @property
232    def is_star(self) -> bool:
233        """Checks whether an expression is a star."""
234        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
236    @property
237    def alias(self) -> str:
238        """
239        Returns the alias of the expression, or an empty string if it's not aliased.
240        """
241        if isinstance(self.args.get("alias"), TableAlias):
242            return self.args["alias"].name
243        return self.text("alias")

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

alias_column_names: List[str]
245    @property
246    def alias_column_names(self) -> t.List[str]:
247        table_alias = self.args.get("alias")
248        if not table_alias:
249            return []
250        return [c.name for c in table_alias.args.get("columns") or []]
name: str
252    @property
253    def name(self) -> str:
254        return self.text("this")
alias_or_name: str
256    @property
257    def alias_or_name(self) -> str:
258        return self.alias or self.name
output_name: str
260    @property
261    def output_name(self) -> str:
262        """
263        Name of the output column if this expression is a selection.
264
265        If the Expression has no output name, an empty string is returned.
266
267        Example:
268            >>> from sqlglot import parse_one
269            >>> parse_one("SELECT a").expressions[0].output_name
270            'a'
271            >>> parse_one("SELECT b AS c").expressions[0].output_name
272            'c'
273            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
274            ''
275        """
276        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]
278    @property
279    def type(self) -> t.Optional[DataType]:
280        return self._type
def is_type(self, *dtypes) -> bool:
288    def is_type(self, *dtypes) -> bool:
289        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
291    def is_leaf(self) -> bool:
292        return not any(isinstance(v, (Expression, list)) and v for v in self.args.values())
meta: Dict[str, Any]
294    @property
295    def meta(self) -> t.Dict[str, t.Any]:
296        if self._meta is None:
297            self._meta = {}
298        return self._meta
def copy(self) -> typing_extensions.Self:
334    def copy(self) -> Self:
335        """
336        Returns a deep copy of the expression.
337        """
338        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
340    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
341        if self.comments is None:
342            self.comments = []
343
344        if comments:
345            for comment in comments:
346                _, *meta = comment.split(SQLGLOT_META)
347                if meta:
348                    for kv in "".join(meta).split(","):
349                        k, *v = kv.split("=")
350                        value = v[0].strip() if v else True
351                        self.meta[k.strip()] = to_bool(value)
352
353                if not prepend:
354                    self.comments.append(comment)
355
356            if prepend:
357                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
359    def pop_comments(self) -> t.List[str]:
360        comments = self.comments or []
361        self.comments = None
362        return comments
def append(self, arg_key: str, value: Any) -> None:
364    def append(self, arg_key: str, value: t.Any) -> None:
365        """
366        Appends value to arg_key if it's a list or sets it as a new list.
367
368        Args:
369            arg_key (str): name of the list expression arg
370            value (Any): value to append to the list
371        """
372        if type(self.args.get(arg_key)) is not list:
373            self.args[arg_key] = []
374        self._set_parent(arg_key, value)
375        values = self.args[arg_key]
376        if hasattr(value, "parent"):
377            value.index = len(values)
378        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:
380    def set(
381        self,
382        arg_key: str,
383        value: t.Any,
384        index: t.Optional[int] = None,
385        overwrite: bool = True,
386    ) -> None:
387        """
388        Sets arg_key to value.
389
390        Args:
391            arg_key: name of the expression arg.
392            value: value to set the arg to.
393            index: if the arg is a list, this specifies what position to add the value in it.
394            overwrite: assuming an index is given, this determines whether to overwrite the
395                list entry instead of only inserting a new value (i.e., like list.insert).
396        """
397        expression: t.Optional[Expression] = self
398
399        while expression and expression._hash is not None:
400            expression._hash = None
401            expression = expression.parent
402
403        if index is not None:
404            expressions = self.args.get(arg_key) or []
405
406            if seq_get(expressions, index) is None:
407                return
408            if value is None:
409                expressions.pop(index)
410                for v in expressions[index:]:
411                    v.index = v.index - 1
412                return
413
414            if isinstance(value, list):
415                expressions.pop(index)
416                expressions[index:index] = value
417            elif overwrite:
418                expressions[index] = value
419            else:
420                expressions.insert(index, value)
421
422            value = expressions
423        elif value is None:
424            self.args.pop(arg_key, None)
425            return
426
427        self.args[arg_key] = value
428        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
442    @property
443    def depth(self) -> int:
444        """
445        Returns the depth of this tree.
446        """
447        if self.parent:
448            return self.parent.depth + 1
449        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
451    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
452        """Yields the key and expression for all arguments, exploding list args."""
453        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
454            if type(vs) is list:
455                for v in reversed(vs) if reverse else vs:  # type: ignore
456                    if hasattr(v, "parent"):
457                        yield v
458            else:
459                if hasattr(vs, "parent"):
460                    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]:
462    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
463        """
464        Returns the first node in this tree which matches at least one of
465        the specified types.
466
467        Args:
468            expression_types: the expression type(s) to match.
469            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
470
471        Returns:
472            The node which matches the criteria or None if no such node was found.
473        """
474        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]:
476    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
477        """
478        Returns a generator object which visits all nodes in this tree and only
479        yields those that match at least one of the specified expression types.
480
481        Args:
482            expression_types: the expression type(s) to match.
483            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
484
485        Returns:
486            The generator object.
487        """
488        for expression in self.walk(bfs=bfs):
489            if isinstance(expression, expression_types):
490                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]:
492    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
493        """
494        Returns a nearest parent matching expression_types.
495
496        Args:
497            expression_types: the expression type(s) to match.
498
499        Returns:
500            The parent node.
501        """
502        ancestor = self.parent
503        while ancestor and not isinstance(ancestor, expression_types):
504            ancestor = ancestor.parent
505        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]
507    @property
508    def parent_select(self) -> t.Optional[Select]:
509        """
510        Returns the parent select statement.
511        """
512        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
514    @property
515    def same_parent(self) -> bool:
516        """Returns if the parent is the same class as itself."""
517        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
519    def root(self) -> Expression:
520        """
521        Returns the root expression of this tree.
522        """
523        expression = self
524        while expression.parent:
525            expression = expression.parent
526        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
528    def walk(
529        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
530    ) -> t.Iterator[Expression]:
531        """
532        Returns a generator object which visits all nodes in this tree.
533
534        Args:
535            bfs: if set to True the BFS traversal order will be applied,
536                otherwise the DFS traversal will be used instead.
537            prune: callable that returns True if the generator should stop traversing
538                this branch of the tree.
539
540        Returns:
541            the generator object.
542        """
543        if bfs:
544            yield from self.bfs(prune=prune)
545        else:
546            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]:
548    def dfs(
549        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
550    ) -> t.Iterator[Expression]:
551        """
552        Returns a generator object which visits all nodes in this tree in
553        the DFS (Depth-first) order.
554
555        Returns:
556            The generator object.
557        """
558        stack = [self]
559
560        while stack:
561            node = stack.pop()
562
563            yield node
564
565            if prune and prune(node):
566                continue
567
568            for v in node.iter_expressions(reverse=True):
569                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]:
571    def bfs(
572        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
573    ) -> t.Iterator[Expression]:
574        """
575        Returns a generator object which visits all nodes in this tree in
576        the BFS (Breadth-first) order.
577
578        Returns:
579            The generator object.
580        """
581        queue = deque([self])
582
583        while queue:
584            node = queue.popleft()
585
586            yield node
587
588            if prune and prune(node):
589                continue
590
591            for v in node.iter_expressions():
592                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):
594    def unnest(self):
595        """
596        Returns the first non parenthesis child or self.
597        """
598        expression = self
599        while type(expression) is Paren:
600            expression = expression.this
601        return expression

Returns the first non parenthesis child or self.

def unalias(self):
603    def unalias(self):
604        """
605        Returns the inner expression if this is an Alias.
606        """
607        if isinstance(self, Alias):
608            return self.this
609        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
611    def unnest_operands(self):
612        """
613        Returns unnested operands as a tuple.
614        """
615        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
617    def flatten(self, unnest=True):
618        """
619        Returns a generator which yields child nodes whose parents are the same class.
620
621        A AND B AND C -> [A, B, C]
622        """
623        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
624            if type(node) is not self.__class__:
625                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:
633    def to_s(self) -> str:
634        """
635        Same as __repr__, but includes additional information which can be useful
636        for debugging, like empty or missing args and the AST nodes' object IDs.
637        """
638        return _to_s(self, verbose=True)

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

def sql( self, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> str:
640    def sql(self, dialect: DialectType = None, **opts) -> str:
641        """
642        Returns SQL string representation of this tree.
643
644        Args:
645            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
646            opts: other `sqlglot.generator.Generator` options.
647
648        Returns:
649            The SQL string.
650        """
651        from sqlglot.dialects import Dialect
652
653        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:
655    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
656        """
657        Visits all tree nodes (excluding already transformed ones)
658        and applies the given transformation function to each node.
659
660        Args:
661            fun: a function which takes a node as an argument and returns a
662                new transformed node or the same node without modifications. If the function
663                returns None, then the corresponding node will be removed from the syntax tree.
664            copy: if set to True a new tree instance is constructed, otherwise the tree is
665                modified in place.
666
667        Returns:
668            The transformed tree.
669        """
670        root = None
671        new_node = None
672
673        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
674            parent, arg_key, index = node.parent, node.arg_key, node.index
675            new_node = fun(node, *args, **kwargs)
676
677            if not root:
678                root = new_node
679            elif parent and arg_key and new_node is not node:
680                parent.set(arg_key, new_node, index)
681
682        assert root
683        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):
691    def replace(self, expression):
692        """
693        Swap out this expression with a new expression.
694
695        For example::
696
697            >>> tree = Select().select("x").from_("tbl")
698            >>> tree.find(Column).replace(column("y"))
699            Column(
700              this=Identifier(this=y, quoted=False))
701            >>> tree.sql()
702            'SELECT y FROM tbl'
703
704        Args:
705            expression: new node
706
707        Returns:
708            The new expression or expressions.
709        """
710        parent = self.parent
711
712        if not parent or parent is expression:
713            return expression
714
715        key = self.arg_key
716        value = parent.args.get(key)
717
718        if type(expression) is list and isinstance(value, Expression):
719            # We are trying to replace an Expression with a list, so it's assumed that
720            # the intention was to really replace the parent of this expression.
721            value.parent.replace(expression)
722        else:
723            parent.set(key, expression, self.index)
724
725        if expression is not self:
726            self.parent = None
727            self.arg_key = None
728            self.index = None
729
730        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:
732    def pop(self: E) -> E:
733        """
734        Remove this expression from its AST.
735
736        Returns:
737            The popped expression.
738        """
739        self.replace(None)
740        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
742    def assert_is(self, type_: t.Type[E]) -> E:
743        """
744        Assert that this `Expression` is an instance of `type_`.
745
746        If it is NOT an instance of `type_`, this raises an assertion error.
747        Otherwise, this returns this expression.
748
749        Examples:
750            This is useful for type security in chained expressions:
751
752            >>> import sqlglot
753            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
754            'SELECT x, z FROM y'
755        """
756        if not isinstance(self, type_):
757            raise AssertionError(f"{self} is not {type_}.")
758        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]:
760    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
761        """
762        Checks if this expression is valid (e.g. all mandatory args are set).
763
764        Args:
765            args: a sequence of values that were used to instantiate a Func expression. This is used
766                to check that the provided arguments don't exceed the function argument limit.
767
768        Returns:
769            A list of error messages for all possible errors that were found.
770        """
771        errors: t.List[str] = []
772
773        for k in self.args:
774            if k not in self.arg_types:
775                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
776        for k, mandatory in self.arg_types.items():
777            v = self.args.get(k)
778            if mandatory and (v is None or (isinstance(v, list) and not v)):
779                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
780
781        if (
782            args
783            and isinstance(self, Func)
784            and len(args) > len(self.arg_types)
785            and not self.is_var_len_args
786        ):
787            errors.append(
788                f"The number of provided arguments ({len(args)}) is greater than "
789                f"the maximum number of supported arguments ({len(self.arg_types)})"
790            )
791
792        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):
794    def dump(self):
795        """
796        Dump this Expression to a JSON-serializable dict.
797        """
798        from sqlglot.serde import dump
799
800        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
802    @classmethod
803    def load(cls, obj):
804        """
805        Load a dict (as returned by `Expression.dump`) into an Expression instance.
806        """
807        from sqlglot.serde import load
808
809        return load(obj)

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

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

AND this condition with one or multiple expressions.

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

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
841    def or_(
842        self,
843        *expressions: t.Optional[ExpOrStr],
844        dialect: DialectType = None,
845        copy: bool = True,
846        wrap: bool = True,
847        **opts,
848    ) -> Condition:
849        """
850        OR this condition with one or multiple expressions.
851
852        Example:
853            >>> condition("x=1").or_("y=1").sql()
854            'x = 1 OR y = 1'
855
856        Args:
857            *expressions: the SQL code strings to parse.
858                If an `Expression` instance is passed, it will be used as-is.
859            dialect: the dialect used to parse the input expression.
860            copy: whether to copy the involved expressions (only applies to Expressions).
861            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
862                precedence issues, but can be turned off when the produced AST is too deep and
863                causes recursion-related issues.
864            opts: other options to use to parse the input expressions.
865
866        Returns:
867            The new Or condition.
868        """
869        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)

OR this condition with one or multiple expressions.

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

The new Or condition.

def not_(self, copy: bool = True):
871    def not_(self, copy: bool = True):
872        """
873        Wrap this condition with NOT.
874
875        Example:
876            >>> condition("x=1").not_().sql()
877            'NOT x = 1'
878
879        Args:
880            copy: whether to copy this object.
881
882        Returns:
883            The new Not instance.
884        """
885        return not_(self, copy=copy)

Wrap this condition with NOT.

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

The new Not instance.

def update_positions( self: ~E, other: Union[sqlglot.tokens.Token, Expression, NoneType] = None, **kwargs: Any) -> ~E:
887    def update_positions(
888        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
889    ) -> E:
890        """
891        Update this expression with positions from a token or other expression.
892
893        Args:
894            other: a token or expression to update this expression with.
895
896        Returns:
897            The updated expression.
898        """
899        if isinstance(other, Expression):
900            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
901        elif other is not None:
902            self.meta.update(
903                {
904                    "line": other.line,
905                    "col": other.col,
906                    "start": other.start,
907                    "end": other.end,
908                }
909            )
910        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
911        return self

Update this expression with positions from a token or other expression.

Arguments:
  • other: a token or expression to update this expression with.
Returns:

The updated expression.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
913    def as_(
914        self,
915        alias: str | Identifier,
916        quoted: t.Optional[bool] = None,
917        dialect: DialectType = None,
918        copy: bool = True,
919        **opts,
920    ) -> Alias:
921        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:
946    def isin(
947        self,
948        *expressions: t.Any,
949        query: t.Optional[ExpOrStr] = None,
950        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
951        copy: bool = True,
952        **opts,
953    ) -> In:
954        subquery = maybe_parse(query, copy=copy, **opts) if query else None
955        if subquery and not isinstance(subquery, Subquery):
956            subquery = subquery.subquery(copy=False)
957
958        return In(
959            this=maybe_copy(self, copy),
960            expressions=[convert(e, copy=copy) for e in expressions],
961            query=subquery,
962            unnest=(
963                Unnest(
964                    expressions=[
965                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
966                        for e in ensure_list(unnest)
967                    ]
968                )
969                if unnest
970                else None
971            ),
972        )
def between( self, low: Any, high: Any, copy: bool = True, symmetric: Optional[bool] = None, **opts) -> Between:
974    def between(
975        self,
976        low: t.Any,
977        high: t.Any,
978        copy: bool = True,
979        symmetric: t.Optional[bool] = None,
980        **opts,
981    ) -> Between:
982        between = Between(
983            this=maybe_copy(self, copy),
984            low=convert(low, copy=copy, **opts),
985            high=convert(high, copy=copy, **opts),
986        )
987        if symmetric is not None:
988            between.set("symmetric", symmetric)
989
990        return between
def is_( self, other: Union[str, Expression]) -> Is:
992    def is_(self, other: ExpOrStr) -> Is:
993        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
995    def like(self, other: ExpOrStr) -> Like:
996        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
998    def ilike(self, other: ExpOrStr) -> ILike:
999        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
1001    def eq(self, other: t.Any) -> EQ:
1002        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
1004    def neq(self, other: t.Any) -> NEQ:
1005        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
1007    def rlike(self, other: ExpOrStr) -> RegexpLike:
1008        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
1010    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
1011        div = self._binop(Div, other)
1012        div.args["typed"] = typed
1013        div.args["safe"] = safe
1014        return div
def asc(self, nulls_first: bool = True) -> Ordered:
1016    def asc(self, nulls_first: bool = True) -> Ordered:
1017        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
1019    def desc(self, nulls_first: bool = False) -> Ordered:
1020        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):
1103class Condition(Expression):
1104    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1141    def limit(
1142        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1143    ) -> Q:
1144        """
1145        Adds a LIMIT clause to this query.
1146
1147        Example:
1148            >>> select("1").union(select("1")).limit(1).sql()
1149            'SELECT 1 UNION SELECT 1 LIMIT 1'
1150
1151        Args:
1152            expression: the SQL code string to parse.
1153                This can also be an integer.
1154                If a `Limit` instance is passed, it will be used as-is.
1155                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1156            dialect: the dialect used to parse the input expression.
1157            copy: if `False`, modify this expression instance in-place.
1158            opts: other options to use to parse the input expressions.
1159
1160        Returns:
1161            A limited Select expression.
1162        """
1163        return _apply_builder(
1164            expression=expression,
1165            instance=self,
1166            arg="limit",
1167            into=Limit,
1168            prefix="LIMIT",
1169            dialect=dialect,
1170            copy=copy,
1171            into_arg="expression",
1172            **opts,
1173        )

Adds a LIMIT clause to this query.

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

A limited Select expression.

def offset( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1175    def offset(
1176        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1177    ) -> Q:
1178        """
1179        Set the OFFSET expression.
1180
1181        Example:
1182            >>> Select().from_("tbl").select("x").offset(10).sql()
1183            'SELECT x FROM tbl OFFSET 10'
1184
1185        Args:
1186            expression: the SQL code string to parse.
1187                This can also be an integer.
1188                If a `Offset` instance is passed, this is used as-is.
1189                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1190            dialect: the dialect used to parse the input expression.
1191            copy: if `False`, modify this expression instance in-place.
1192            opts: other options to use to parse the input expressions.
1193
1194        Returns:
1195            The modified Select expression.
1196        """
1197        return _apply_builder(
1198            expression=expression,
1199            instance=self,
1200            arg="offset",
1201            into=Offset,
1202            prefix="OFFSET",
1203            dialect=dialect,
1204            copy=copy,
1205            into_arg="expression",
1206            **opts,
1207        )

Set the OFFSET expression.

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

The modified Select expression.

def order_by( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1209    def order_by(
1210        self: Q,
1211        *expressions: t.Optional[ExpOrStr],
1212        append: bool = True,
1213        dialect: DialectType = None,
1214        copy: bool = True,
1215        **opts,
1216    ) -> Q:
1217        """
1218        Set the ORDER BY expression.
1219
1220        Example:
1221            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1222            'SELECT x FROM tbl ORDER BY x DESC'
1223
1224        Args:
1225            *expressions: the SQL code strings to parse.
1226                If a `Group` instance is passed, this is used as-is.
1227                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1228            append: if `True`, add to any existing expressions.
1229                Otherwise, this flattens all the `Order` expression into a single expression.
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 Select expression.
1236        """
1237        return _apply_child_list_builder(
1238            *expressions,
1239            instance=self,
1240            arg="order",
1241            append=append,
1242            copy=copy,
1243            prefix="ORDER BY",
1244            into=Order,
1245            dialect=dialect,
1246            **opts,
1247        )

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

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

selects: List[Expression]
1255    @property
1256    def selects(self) -> t.List[Expression]:
1257        """Returns the query's projections."""
1258        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

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

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1265    def select(
1266        self: Q,
1267        *expressions: t.Optional[ExpOrStr],
1268        append: bool = True,
1269        dialect: DialectType = None,
1270        copy: bool = True,
1271        **opts,
1272    ) -> Q:
1273        """
1274        Append to or set the SELECT expressions.
1275
1276        Example:
1277            >>> Select().select("x", "y").sql()
1278            'SELECT x, y'
1279
1280        Args:
1281            *expressions: the SQL code strings to parse.
1282                If an `Expression` instance is passed, it will be used as-is.
1283            append: if `True`, add to any existing expressions.
1284                Otherwise, this resets the expressions.
1285            dialect: the dialect used to parse the input expressions.
1286            copy: if `False`, modify this expression instance in-place.
1287            opts: other options to use to parse the input expressions.
1288
1289        Returns:
1290            The modified Query expression.
1291        """
1292        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

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

The modified Query expression.

def where( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1294    def where(
1295        self: Q,
1296        *expressions: t.Optional[ExpOrStr],
1297        append: bool = True,
1298        dialect: DialectType = None,
1299        copy: bool = True,
1300        **opts,
1301    ) -> Q:
1302        """
1303        Append to or set the WHERE expressions.
1304
1305        Examples:
1306            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1307            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1308
1309        Args:
1310            *expressions: the SQL code strings to parse.
1311                If an `Expression` instance is passed, it will be used as-is.
1312                Multiple expressions are combined with an AND operator.
1313            append: if `True`, AND the new expressions to any existing expression.
1314                Otherwise, this resets the expression.
1315            dialect: the dialect used to parse the input expressions.
1316            copy: if `False`, modify this expression instance in-place.
1317            opts: other options to use to parse the input expressions.
1318
1319        Returns:
1320            The modified expression.
1321        """
1322        return _apply_conjunction_builder(
1323            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1324            instance=self,
1325            arg="where",
1326            append=append,
1327            into=Where,
1328            dialect=dialect,
1329            copy=copy,
1330            **opts,
1331        )

Append to or set the WHERE expressions.

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

The modified expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: bool = False, **opts) -> ~Q:
1333    def with_(
1334        self: Q,
1335        alias: ExpOrStr,
1336        as_: ExpOrStr,
1337        recursive: t.Optional[bool] = None,
1338        materialized: t.Optional[bool] = None,
1339        append: bool = True,
1340        dialect: DialectType = None,
1341        copy: bool = True,
1342        scalar: bool = False,
1343        **opts,
1344    ) -> Q:
1345        """
1346        Append to or set the common table expressions.
1347
1348        Example:
1349            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1350            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1351
1352        Args:
1353            alias: the SQL code string to parse as the table name.
1354                If an `Expression` instance is passed, this is used as-is.
1355            as_: the SQL code string to parse as the table expression.
1356                If an `Expression` instance is passed, it will be used as-is.
1357            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1358            materialized: set the MATERIALIZED part of the expression.
1359            append: if `True`, add to any existing expressions.
1360                Otherwise, this resets the expressions.
1361            dialect: the dialect used to parse the input expression.
1362            copy: if `False`, modify this expression instance in-place.
1363            scalar: if `True`, this is a scalar common table expression.
1364            opts: other options to use to parse the input expressions.
1365
1366        Returns:
1367            The modified expression.
1368        """
1369        return _apply_cte_builder(
1370            self,
1371            alias,
1372            as_,
1373            recursive=recursive,
1374            materialized=materialized,
1375            append=append,
1376            dialect=dialect,
1377            copy=copy,
1378            scalar=scalar,
1379            **opts,
1380        )

Append to or set the common table expressions.

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

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Union:
1382    def union(
1383        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1384    ) -> Union:
1385        """
1386        Builds a UNION expression.
1387
1388        Example:
1389            >>> import sqlglot
1390            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1391            'SELECT * FROM foo UNION SELECT * FROM bla'
1392
1393        Args:
1394            expressions: the SQL code strings.
1395                If `Expression` instances are passed, they will be used as-is.
1396            distinct: set the DISTINCT flag if and only if this is true.
1397            dialect: the dialect used to parse the input expression.
1398            opts: other options to use to parse the input expressions.
1399
1400        Returns:
1401            The new Union expression.
1402        """
1403        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

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

The new Union expression.

def intersect( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Intersect:
1405    def intersect(
1406        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1407    ) -> Intersect:
1408        """
1409        Builds an INTERSECT expression.
1410
1411        Example:
1412            >>> import sqlglot
1413            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1414            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1415
1416        Args:
1417            expressions: the SQL code strings.
1418                If `Expression` instances are passed, they will be used as-is.
1419            distinct: set the DISTINCT flag if and only if this is true.
1420            dialect: the dialect used to parse the input expression.
1421            opts: other options to use to parse the input expressions.
1422
1423        Returns:
1424            The new Intersect expression.
1425        """
1426        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

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

The new Intersect expression.

def except_( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Except:
1428    def except_(
1429        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1430    ) -> Except:
1431        """
1432        Builds an EXCEPT expression.
1433
1434        Example:
1435            >>> import sqlglot
1436            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1437            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1438
1439        Args:
1440            expressions: the SQL code strings.
1441                If `Expression` instance are passed, they will be used as-is.
1442            distinct: set the DISTINCT flag if and only if this is true.
1443            dialect: the dialect used to parse the input expression.
1444            opts: other options to use to parse the input expressions.
1445
1446        Returns:
1447            The new Except expression.
1448        """
1449        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

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

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1452class UDTF(DerivedTable):
1453    @property
1454    def selects(self) -> t.List[Expression]:
1455        alias = self.args.get("alias")
1456        return alias.columns if alias else []
selects: List[Expression]
1453    @property
1454    def selects(self) -> t.List[Expression]:
1455        alias = self.args.get("alias")
1456        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1459class Cache(Expression):
1460    arg_types = {
1461        "this": True,
1462        "lazy": False,
1463        "options": False,
1464        "expression": False,
1465    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1468class Uncache(Expression):
1469    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1472class Refresh(Expression):
1473    pass
key = 'refresh'
class DDL(Expression):
1476class DDL(Expression):
1477    @property
1478    def ctes(self) -> t.List[CTE]:
1479        """Returns a list of all the CTEs attached to this statement."""
1480        with_ = self.args.get("with")
1481        return with_.expressions if with_ else []
1482
1483    @property
1484    def selects(self) -> t.List[Expression]:
1485        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1486        return self.expression.selects if isinstance(self.expression, Query) else []
1487
1488    @property
1489    def named_selects(self) -> t.List[str]:
1490        """
1491        If this statement contains a query (e.g. a CTAS), this returns the output
1492        names of the query's projections.
1493        """
1494        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1477    @property
1478    def ctes(self) -> t.List[CTE]:
1479        """Returns a list of all the CTEs attached to this statement."""
1480        with_ = self.args.get("with")
1481        return with_.expressions if with_ else []

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

selects: List[Expression]
1483    @property
1484    def selects(self) -> t.List[Expression]:
1485        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1486        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]
1488    @property
1489    def named_selects(self) -> t.List[str]:
1490        """
1491        If this statement contains a query (e.g. a CTAS), this returns the output
1492        names of the query's projections.
1493        """
1494        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 LockingStatement(Expression):
1498class LockingStatement(Expression):
1499    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'lockingstatement'
class DML(Expression):
1502class DML(Expression):
1503    def returning(
1504        self,
1505        expression: ExpOrStr,
1506        dialect: DialectType = None,
1507        copy: bool = True,
1508        **opts,
1509    ) -> "Self":
1510        """
1511        Set the RETURNING expression. Not supported by all dialects.
1512
1513        Example:
1514            >>> delete("tbl").returning("*", dialect="postgres").sql()
1515            'DELETE FROM tbl RETURNING *'
1516
1517        Args:
1518            expression: the SQL code strings to parse.
1519                If an `Expression` instance is passed, it will be used as-is.
1520            dialect: the dialect used to parse the input expressions.
1521            copy: if `False`, modify this expression instance in-place.
1522            opts: other options to use to parse the input expressions.
1523
1524        Returns:
1525            Delete: the modified expression.
1526        """
1527        return _apply_builder(
1528            expression=expression,
1529            instance=self,
1530            arg="returning",
1531            prefix="RETURNING",
1532            dialect=dialect,
1533            copy=copy,
1534            into=Returning,
1535            **opts,
1536        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1503    def returning(
1504        self,
1505        expression: ExpOrStr,
1506        dialect: DialectType = None,
1507        copy: bool = True,
1508        **opts,
1509    ) -> "Self":
1510        """
1511        Set the RETURNING expression. Not supported by all dialects.
1512
1513        Example:
1514            >>> delete("tbl").returning("*", dialect="postgres").sql()
1515            'DELETE FROM tbl RETURNING *'
1516
1517        Args:
1518            expression: the SQL code strings to parse.
1519                If an `Expression` instance is passed, it will be used as-is.
1520            dialect: the dialect used to parse the input expressions.
1521            copy: if `False`, modify this expression instance in-place.
1522            opts: other options to use to parse the input expressions.
1523
1524        Returns:
1525            Delete: the modified expression.
1526        """
1527        return _apply_builder(
1528            expression=expression,
1529            instance=self,
1530            arg="returning",
1531            prefix="RETURNING",
1532            dialect=dialect,
1533            copy=copy,
1534            into=Returning,
1535            **opts,
1536        )

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):
1539class Create(DDL):
1540    arg_types = {
1541        "with": False,
1542        "this": True,
1543        "kind": True,
1544        "expression": False,
1545        "exists": False,
1546        "properties": False,
1547        "replace": False,
1548        "refresh": False,
1549        "unique": False,
1550        "indexes": False,
1551        "no_schema_binding": False,
1552        "begin": False,
1553        "end": False,
1554        "clone": False,
1555        "concurrently": False,
1556        "clustered": False,
1557    }
1558
1559    @property
1560    def kind(self) -> t.Optional[str]:
1561        kind = self.args.get("kind")
1562        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]
1559    @property
1560    def kind(self) -> t.Optional[str]:
1561        kind = self.args.get("kind")
1562        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1565class SequenceProperties(Expression):
1566    arg_types = {
1567        "increment": False,
1568        "minvalue": False,
1569        "maxvalue": False,
1570        "cache": False,
1571        "start": False,
1572        "owned": False,
1573        "options": False,
1574    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1577class TruncateTable(Expression):
1578    arg_types = {
1579        "expressions": True,
1580        "is_database": False,
1581        "exists": False,
1582        "only": False,
1583        "cluster": False,
1584        "identity": False,
1585        "option": False,
1586        "partition": False,
1587    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1593class Clone(Expression):
1594    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1597class Describe(Expression):
1598    arg_types = {
1599        "this": True,
1600        "style": False,
1601        "kind": False,
1602        "expressions": False,
1603        "partition": False,
1604        "format": False,
1605    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1609class Attach(Expression):
1610    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1614class Detach(Expression):
1615    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Install(Expression):
1619class Install(Expression):
1620    arg_types = {"this": True, "from": False, "force": False}
arg_types = {'this': True, 'from': False, 'force': False}
key = 'install'
class Summarize(Expression):
1624class Summarize(Expression):
1625    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1628class Kill(Expression):
1629    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1632class Pragma(Expression):
1633    pass
key = 'pragma'
class Declare(Expression):
1636class Declare(Expression):
1637    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1640class DeclareItem(Expression):
1641    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
class Set(Expression):
1644class Set(Expression):
1645    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1648class Heredoc(Expression):
1649    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1652class SetItem(Expression):
1653    arg_types = {
1654        "this": False,
1655        "expressions": False,
1656        "kind": False,
1657        "collate": False,  # MySQL SET NAMES statement
1658        "global": False,
1659    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class QueryBand(Expression):
1662class QueryBand(Expression):
1663    arg_types = {"this": True, "scope": False, "update": False}
arg_types = {'this': True, 'scope': False, 'update': False}
key = 'queryband'
class Show(Expression):
1666class Show(Expression):
1667    arg_types = {
1668        "this": True,
1669        "history": False,
1670        "terse": False,
1671        "target": False,
1672        "offset": False,
1673        "starts_with": False,
1674        "limit": False,
1675        "from": False,
1676        "like": False,
1677        "where": False,
1678        "db": False,
1679        "scope": False,
1680        "scope_kind": False,
1681        "full": False,
1682        "mutex": False,
1683        "query": False,
1684        "channel": False,
1685        "global": False,
1686        "log": False,
1687        "position": False,
1688        "types": False,
1689        "privileges": False,
1690        "for_table": False,
1691        "for_group": False,
1692        "for_user": False,
1693        "for_role": False,
1694        "into_outfile": False,
1695        "json": False,
1696    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False, 'privileges': False, 'for_table': False, 'for_group': False, 'for_user': False, 'for_role': False, 'into_outfile': False, 'json': False}
key = 'show'
class UserDefinedFunction(Expression):
1699class UserDefinedFunction(Expression):
1700    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1703class CharacterSet(Expression):
1704    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1707class RecursiveWithSearch(Expression):
1708    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key = 'recursivewithsearch'
class With(Expression):
1711class With(Expression):
1712    arg_types = {"expressions": True, "recursive": False, "search": False}
1713
1714    @property
1715    def recursive(self) -> bool:
1716        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1714    @property
1715    def recursive(self) -> bool:
1716        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1719class WithinGroup(Expression):
1720    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1725class CTE(DerivedTable):
1726    arg_types = {
1727        "this": True,
1728        "alias": True,
1729        "scalar": False,
1730        "materialized": False,
1731    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1734class ProjectionDef(Expression):
1735    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1738class TableAlias(Expression):
1739    arg_types = {"this": False, "columns": False}
1740
1741    @property
1742    def columns(self):
1743        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1741    @property
1742    def columns(self):
1743        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1746class BitString(Condition):
1747    pass
key = 'bitstring'
class HexString(Condition):
1750class HexString(Condition):
1751    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1754class ByteString(Condition):
1755    pass
key = 'bytestring'
class RawString(Condition):
1758class RawString(Condition):
1759    pass
key = 'rawstring'
class UnicodeString(Condition):
1762class UnicodeString(Condition):
1763    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1766class Column(Condition):
1767    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1768
1769    @property
1770    def table(self) -> str:
1771        return self.text("table")
1772
1773    @property
1774    def db(self) -> str:
1775        return self.text("db")
1776
1777    @property
1778    def catalog(self) -> str:
1779        return self.text("catalog")
1780
1781    @property
1782    def output_name(self) -> str:
1783        return self.name
1784
1785    @property
1786    def parts(self) -> t.List[Identifier]:
1787        """Return the parts of a column in order catalog, db, table, name."""
1788        return [
1789            t.cast(Identifier, self.args[part])
1790            for part in ("catalog", "db", "table", "this")
1791            if self.args.get(part)
1792        ]
1793
1794    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1795        """Converts the column into a dot expression."""
1796        parts = self.parts
1797        parent = self.parent
1798
1799        if include_dots:
1800            while isinstance(parent, Dot):
1801                parts.append(parent.expression)
1802                parent = parent.parent
1803
1804        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
1769    @property
1770    def table(self) -> str:
1771        return self.text("table")
db: str
1773    @property
1774    def db(self) -> str:
1775        return self.text("db")
catalog: str
1777    @property
1778    def catalog(self) -> str:
1779        return self.text("catalog")
output_name: str
1781    @property
1782    def output_name(self) -> str:
1783        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]
1785    @property
1786    def parts(self) -> t.List[Identifier]:
1787        """Return the parts of a column in order catalog, db, table, name."""
1788        return [
1789            t.cast(Identifier, self.args[part])
1790            for part in ("catalog", "db", "table", "this")
1791            if self.args.get(part)
1792        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1794    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1795        """Converts the column into a dot expression."""
1796        parts = self.parts
1797        parent = self.parent
1798
1799        if include_dots:
1800            while isinstance(parent, Dot):
1801                parts.append(parent.expression)
1802                parent = parent.parent
1803
1804        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1807class ColumnPosition(Expression):
1808    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1811class ColumnDef(Expression):
1812    arg_types = {
1813        "this": True,
1814        "kind": False,
1815        "constraints": False,
1816        "exists": False,
1817        "position": False,
1818        "default": False,
1819        "output": False,
1820    }
1821
1822    @property
1823    def constraints(self) -> t.List[ColumnConstraint]:
1824        return self.args.get("constraints") or []
1825
1826    @property
1827    def kind(self) -> t.Optional[DataType]:
1828        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1822    @property
1823    def constraints(self) -> t.List[ColumnConstraint]:
1824        return self.args.get("constraints") or []
kind: Optional[DataType]
1826    @property
1827    def kind(self) -> t.Optional[DataType]:
1828        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1831class AlterColumn(Expression):
1832    arg_types = {
1833        "this": True,
1834        "dtype": False,
1835        "collate": False,
1836        "using": False,
1837        "default": False,
1838        "drop": False,
1839        "comment": False,
1840        "allow_null": False,
1841        "visible": False,
1842        "rename_to": False,
1843    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False, 'rename_to': False}
key = 'altercolumn'
class AlterIndex(Expression):
1847class AlterIndex(Expression):
1848    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1852class AlterDistStyle(Expression):
1853    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1856class AlterSortKey(Expression):
1857    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1860class AlterSet(Expression):
1861    arg_types = {
1862        "expressions": False,
1863        "option": False,
1864        "tablespace": False,
1865        "access_method": False,
1866        "file_format": False,
1867        "copy_options": False,
1868        "tag": False,
1869        "location": False,
1870        "serde": False,
1871    }
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):
1874class RenameColumn(Expression):
1875    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1878class AlterRename(Expression):
1879    pass
key = 'alterrename'
class SwapTable(Expression):
1882class SwapTable(Expression):
1883    pass
key = 'swaptable'
class Comment(Expression):
1886class Comment(Expression):
1887    arg_types = {
1888        "this": True,
1889        "kind": True,
1890        "expression": True,
1891        "exists": False,
1892        "materialized": False,
1893    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1896class Comprehension(Expression):
1897    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):
1901class MergeTreeTTLAction(Expression):
1902    arg_types = {
1903        "this": True,
1904        "delete": False,
1905        "recompress": False,
1906        "to_disk": False,
1907        "to_volume": False,
1908    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1912class MergeTreeTTL(Expression):
1913    arg_types = {
1914        "expressions": True,
1915        "where": False,
1916        "group": False,
1917        "aggregates": False,
1918    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1922class IndexConstraintOption(Expression):
1923    arg_types = {
1924        "key_block_size": False,
1925        "using": False,
1926        "parser": False,
1927        "comment": False,
1928        "visible": False,
1929        "engine_attr": False,
1930        "secondary_engine_attr": False,
1931    }
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):
1934class ColumnConstraint(Expression):
1935    arg_types = {"this": False, "kind": True}
1936
1937    @property
1938    def kind(self) -> ColumnConstraintKind:
1939        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1937    @property
1938    def kind(self) -> ColumnConstraintKind:
1939        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1942class ColumnConstraintKind(Expression):
1943    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1946class AutoIncrementColumnConstraint(ColumnConstraintKind):
1947    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1950class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1951    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1954class CaseSpecificColumnConstraint(ColumnConstraintKind):
1955    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1958class CharacterSetColumnConstraint(ColumnConstraintKind):
1959    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1962class CheckColumnConstraint(ColumnConstraintKind):
1963    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1966class ClusteredColumnConstraint(ColumnConstraintKind):
1967    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1970class CollateColumnConstraint(ColumnConstraintKind):
1971    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1974class CommentColumnConstraint(ColumnConstraintKind):
1975    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1978class CompressColumnConstraint(ColumnConstraintKind):
1979    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1982class DateFormatColumnConstraint(ColumnConstraintKind):
1983    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1986class DefaultColumnConstraint(ColumnConstraintKind):
1987    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1990class EncodeColumnConstraint(ColumnConstraintKind):
1991    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1995class ExcludeColumnConstraint(ColumnConstraintKind):
1996    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1999class EphemeralColumnConstraint(ColumnConstraintKind):
2000    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
2003class WithOperator(Expression):
2004    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
2007class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
2008    # this: True -> ALWAYS, this: False -> BY DEFAULT
2009    arg_types = {
2010        "this": False,
2011        "expression": False,
2012        "on_null": False,
2013        "start": False,
2014        "increment": False,
2015        "minvalue": False,
2016        "maxvalue": False,
2017        "cycle": False,
2018        "order": False,
2019    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False, 'order': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
2022class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
2023    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
2028class IndexColumnConstraint(ColumnConstraintKind):
2029    arg_types = {
2030        "this": False,
2031        "expressions": False,
2032        "kind": False,
2033        "index_type": False,
2034        "options": False,
2035        "expression": False,  # Clickhouse
2036        "granularity": False,
2037    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
2040class InlineLengthColumnConstraint(ColumnConstraintKind):
2041    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
2044class NonClusteredColumnConstraint(ColumnConstraintKind):
2045    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
2048class NotForReplicationColumnConstraint(ColumnConstraintKind):
2049    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2053class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2054    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
2057class NotNullColumnConstraint(ColumnConstraintKind):
2058    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
2062class OnUpdateColumnConstraint(ColumnConstraintKind):
2063    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2066class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2067    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2070class TitleColumnConstraint(ColumnConstraintKind):
2071    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2074class UniqueColumnConstraint(ColumnConstraintKind):
2075    arg_types = {
2076        "this": False,
2077        "index_type": False,
2078        "on_conflict": False,
2079        "nulls": False,
2080        "options": False,
2081    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2084class UppercaseColumnConstraint(ColumnConstraintKind):
2085    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2089class WatermarkColumnConstraint(Expression):
2090    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2093class PathColumnConstraint(ColumnConstraintKind):
2094    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2098class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2099    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2104class ComputedColumnConstraint(ColumnConstraintKind):
2105    arg_types = {"this": True, "persisted": False, "not_null": False, "data_type": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False, 'data_type': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2108class Constraint(Expression):
2109    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2112class Delete(DML):
2113    arg_types = {
2114        "with": False,
2115        "this": False,
2116        "using": False,
2117        "where": False,
2118        "returning": False,
2119        "limit": False,
2120        "tables": False,  # Multiple-Table Syntax (MySQL)
2121        "cluster": False,  # Clickhouse
2122    }
2123
2124    def delete(
2125        self,
2126        table: ExpOrStr,
2127        dialect: DialectType = None,
2128        copy: bool = True,
2129        **opts,
2130    ) -> Delete:
2131        """
2132        Create a DELETE expression or replace the table on an existing DELETE expression.
2133
2134        Example:
2135            >>> delete("tbl").sql()
2136            'DELETE FROM tbl'
2137
2138        Args:
2139            table: the table from which to delete.
2140            dialect: the dialect used to parse the input expression.
2141            copy: if `False`, modify this expression instance in-place.
2142            opts: other options to use to parse the input expressions.
2143
2144        Returns:
2145            Delete: the modified expression.
2146        """
2147        return _apply_builder(
2148            expression=table,
2149            instance=self,
2150            arg="this",
2151            dialect=dialect,
2152            into=Table,
2153            copy=copy,
2154            **opts,
2155        )
2156
2157    def where(
2158        self,
2159        *expressions: t.Optional[ExpOrStr],
2160        append: bool = True,
2161        dialect: DialectType = None,
2162        copy: bool = True,
2163        **opts,
2164    ) -> Delete:
2165        """
2166        Append to or set the WHERE expressions.
2167
2168        Example:
2169            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2170            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2171
2172        Args:
2173            *expressions: the SQL code strings to parse.
2174                If an `Expression` instance is passed, it will be used as-is.
2175                Multiple expressions are combined with an AND operator.
2176            append: if `True`, AND the new expressions to any existing expression.
2177                Otherwise, this resets the expression.
2178            dialect: the dialect used to parse the input expressions.
2179            copy: if `False`, modify this expression instance in-place.
2180            opts: other options to use to parse the input expressions.
2181
2182        Returns:
2183            Delete: the modified expression.
2184        """
2185        return _apply_conjunction_builder(
2186            *expressions,
2187            instance=self,
2188            arg="where",
2189            append=append,
2190            into=Where,
2191            dialect=dialect,
2192            copy=copy,
2193            **opts,
2194        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2124    def delete(
2125        self,
2126        table: ExpOrStr,
2127        dialect: DialectType = None,
2128        copy: bool = True,
2129        **opts,
2130    ) -> Delete:
2131        """
2132        Create a DELETE expression or replace the table on an existing DELETE expression.
2133
2134        Example:
2135            >>> delete("tbl").sql()
2136            'DELETE FROM tbl'
2137
2138        Args:
2139            table: the table from which to delete.
2140            dialect: the dialect used to parse the input expression.
2141            copy: if `False`, modify this expression instance in-place.
2142            opts: other options to use to parse the input expressions.
2143
2144        Returns:
2145            Delete: the modified expression.
2146        """
2147        return _apply_builder(
2148            expression=table,
2149            instance=self,
2150            arg="this",
2151            dialect=dialect,
2152            into=Table,
2153            copy=copy,
2154            **opts,
2155        )

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

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

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2157    def where(
2158        self,
2159        *expressions: t.Optional[ExpOrStr],
2160        append: bool = True,
2161        dialect: DialectType = None,
2162        copy: bool = True,
2163        **opts,
2164    ) -> Delete:
2165        """
2166        Append to or set the WHERE expressions.
2167
2168        Example:
2169            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2170            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2171
2172        Args:
2173            *expressions: the SQL code strings to parse.
2174                If an `Expression` instance is passed, it will be used as-is.
2175                Multiple expressions are combined with an AND operator.
2176            append: if `True`, AND the new expressions to any existing expression.
2177                Otherwise, this resets the expression.
2178            dialect: the dialect used to parse the input expressions.
2179            copy: if `False`, modify this expression instance in-place.
2180            opts: other options to use to parse the input expressions.
2181
2182        Returns:
2183            Delete: the modified expression.
2184        """
2185        return _apply_conjunction_builder(
2186            *expressions,
2187            instance=self,
2188            arg="where",
2189            append=append,
2190            into=Where,
2191            dialect=dialect,
2192            copy=copy,
2193            **opts,
2194        )

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):
2197class Drop(Expression):
2198    arg_types = {
2199        "this": False,
2200        "kind": False,
2201        "expressions": False,
2202        "exists": False,
2203        "temporary": False,
2204        "materialized": False,
2205        "cascade": False,
2206        "constraints": False,
2207        "purge": False,
2208        "cluster": False,
2209        "concurrently": False,
2210    }
2211
2212    @property
2213    def kind(self) -> t.Optional[str]:
2214        kind = self.args.get("kind")
2215        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]
2212    @property
2213    def kind(self) -> t.Optional[str]:
2214        kind = self.args.get("kind")
2215        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2219class Export(Expression):
2220    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2223class Filter(Expression):
2224    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2227class Check(Expression):
2228    pass
key = 'check'
class Changes(Expression):
2231class Changes(Expression):
2232    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2236class Connect(Expression):
2237    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2240class CopyParameter(Expression):
2241    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2244class Copy(DML):
2245    arg_types = {
2246        "this": True,
2247        "kind": True,
2248        "files": False,
2249        "credentials": False,
2250        "format": False,
2251        "params": False,
2252    }
arg_types = {'this': True, 'kind': True, 'files': False, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2255class Credentials(Expression):
2256    arg_types = {
2257        "credentials": False,
2258        "encryption": False,
2259        "storage": False,
2260        "iam_role": False,
2261        "region": False,
2262    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2265class Prior(Expression):
2266    pass
key = 'prior'
class Directory(Expression):
2269class Directory(Expression):
2270    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class DirectoryStage(Expression):
2274class DirectoryStage(Expression):
2275    pass
key = 'directorystage'
class ForeignKey(Expression):
2278class ForeignKey(Expression):
2279    arg_types = {
2280        "expressions": False,
2281        "reference": False,
2282        "delete": False,
2283        "update": False,
2284        "options": False,
2285    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2288class ColumnPrefix(Expression):
2289    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2292class PrimaryKey(Expression):
2293    arg_types = {"expressions": True, "options": False, "include": False}
arg_types = {'expressions': True, 'options': False, 'include': False}
key = 'primarykey'
class Into(Expression):
2298class Into(Expression):
2299    arg_types = {
2300        "this": False,
2301        "temporary": False,
2302        "unlogged": False,
2303        "bulk_collect": False,
2304        "expressions": False,
2305    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2308class From(Expression):
2309    @property
2310    def name(self) -> str:
2311        return self.this.name
2312
2313    @property
2314    def alias_or_name(self) -> str:
2315        return self.this.alias_or_name
name: str
2309    @property
2310    def name(self) -> str:
2311        return self.this.name
alias_or_name: str
2313    @property
2314    def alias_or_name(self) -> str:
2315        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2318class Having(Expression):
2319    pass
key = 'having'
class Hint(Expression):
2322class Hint(Expression):
2323    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2326class JoinHint(Expression):
2327    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2330class Identifier(Expression):
2331    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2332
2333    @property
2334    def quoted(self) -> bool:
2335        return bool(self.args.get("quoted"))
2336
2337    @property
2338    def output_name(self) -> str:
2339        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2333    @property
2334    def quoted(self) -> bool:
2335        return bool(self.args.get("quoted"))
output_name: str
2337    @property
2338    def output_name(self) -> str:
2339        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):
2343class Opclass(Expression):
2344    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2347class Index(Expression):
2348    arg_types = {
2349        "this": False,
2350        "table": False,
2351        "unique": False,
2352        "primary": False,
2353        "amp": False,  # teradata
2354        "params": False,
2355    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2358class IndexParameters(Expression):
2359    arg_types = {
2360        "using": False,
2361        "include": False,
2362        "columns": False,
2363        "with_storage": False,
2364        "partition_by": False,
2365        "tablespace": False,
2366        "where": False,
2367        "on": False,
2368    }
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):
2371class Insert(DDL, DML):
2372    arg_types = {
2373        "hint": False,
2374        "with": False,
2375        "is_function": False,
2376        "this": False,
2377        "expression": False,
2378        "conflict": False,
2379        "returning": False,
2380        "overwrite": False,
2381        "exists": False,
2382        "alternative": False,
2383        "where": False,
2384        "ignore": False,
2385        "by_name": False,
2386        "stored": False,
2387        "partition": False,
2388        "settings": False,
2389        "source": False,
2390    }
2391
2392    def with_(
2393        self,
2394        alias: ExpOrStr,
2395        as_: ExpOrStr,
2396        recursive: t.Optional[bool] = None,
2397        materialized: t.Optional[bool] = None,
2398        append: bool = True,
2399        dialect: DialectType = None,
2400        copy: bool = True,
2401        **opts,
2402    ) -> Insert:
2403        """
2404        Append to or set the common table expressions.
2405
2406        Example:
2407            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2408            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2409
2410        Args:
2411            alias: the SQL code string to parse as the table name.
2412                If an `Expression` instance is passed, this is used as-is.
2413            as_: the SQL code string to parse as the table expression.
2414                If an `Expression` instance is passed, it will be used as-is.
2415            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2416            materialized: set the MATERIALIZED part of the expression.
2417            append: if `True`, add to any existing expressions.
2418                Otherwise, this resets the expressions.
2419            dialect: the dialect used to parse the input expression.
2420            copy: if `False`, modify this expression instance in-place.
2421            opts: other options to use to parse the input expressions.
2422
2423        Returns:
2424            The modified expression.
2425        """
2426        return _apply_cte_builder(
2427            self,
2428            alias,
2429            as_,
2430            recursive=recursive,
2431            materialized=materialized,
2432            append=append,
2433            dialect=dialect,
2434            copy=copy,
2435            **opts,
2436        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2392    def with_(
2393        self,
2394        alias: ExpOrStr,
2395        as_: ExpOrStr,
2396        recursive: t.Optional[bool] = None,
2397        materialized: t.Optional[bool] = None,
2398        append: bool = True,
2399        dialect: DialectType = None,
2400        copy: bool = True,
2401        **opts,
2402    ) -> Insert:
2403        """
2404        Append to or set the common table expressions.
2405
2406        Example:
2407            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2408            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2409
2410        Args:
2411            alias: the SQL code string to parse as the table name.
2412                If an `Expression` instance is passed, this is used as-is.
2413            as_: the SQL code string to parse as the table expression.
2414                If an `Expression` instance is passed, it will be used as-is.
2415            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2416            materialized: set the MATERIALIZED part of the expression.
2417            append: if `True`, add to any existing expressions.
2418                Otherwise, this resets the expressions.
2419            dialect: the dialect used to parse the input expression.
2420            copy: if `False`, modify this expression instance in-place.
2421            opts: other options to use to parse the input expressions.
2422
2423        Returns:
2424            The modified expression.
2425        """
2426        return _apply_cte_builder(
2427            self,
2428            alias,
2429            as_,
2430            recursive=recursive,
2431            materialized=materialized,
2432            append=append,
2433            dialect=dialect,
2434            copy=copy,
2435            **opts,
2436        )

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):
2439class ConditionalInsert(Expression):
2440    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2443class MultitableInserts(Expression):
2444    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2447class OnConflict(Expression):
2448    arg_types = {
2449        "duplicate": False,
2450        "expressions": False,
2451        "action": False,
2452        "conflict_keys": False,
2453        "constraint": False,
2454        "where": False,
2455    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2458class OnCondition(Expression):
2459    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2462class Returning(Expression):
2463    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2467class Introducer(Expression):
2468    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2472class National(Expression):
2473    pass
key = 'national'
class LoadData(Expression):
2476class LoadData(Expression):
2477    arg_types = {
2478        "this": True,
2479        "local": False,
2480        "overwrite": False,
2481        "inpath": True,
2482        "partition": False,
2483        "input_format": False,
2484        "serde": False,
2485    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2488class Partition(Expression):
2489    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2492class PartitionRange(Expression):
2493    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
class PartitionId(Expression):
2497class PartitionId(Expression):
2498    pass
key = 'partitionid'
class Fetch(Expression):
2501class Fetch(Expression):
2502    arg_types = {
2503        "direction": False,
2504        "count": False,
2505        "limit_options": False,
2506    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2509class Grant(Expression):
2510    arg_types = {
2511        "privileges": True,
2512        "kind": False,
2513        "securable": True,
2514        "principals": True,
2515        "grant_option": False,
2516    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Revoke(Expression):
2519class Revoke(Expression):
2520    arg_types = {**Grant.arg_types, "cascade": False}
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False, 'cascade': False}
key = 'revoke'
class Group(Expression):
2523class Group(Expression):
2524    arg_types = {
2525        "expressions": False,
2526        "grouping_sets": False,
2527        "cube": False,
2528        "rollup": False,
2529        "totals": False,
2530        "all": False,
2531    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2534class Cube(Expression):
2535    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2538class Rollup(Expression):
2539    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2542class GroupingSets(Expression):
2543    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2546class Lambda(Expression):
2547    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2550class Limit(Expression):
2551    arg_types = {
2552        "this": False,
2553        "expression": True,
2554        "offset": False,
2555        "limit_options": False,
2556        "expressions": False,
2557    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2560class LimitOptions(Expression):
2561    arg_types = {
2562        "percent": False,
2563        "rows": False,
2564        "with_ties": False,
2565    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2568class Literal(Condition):
2569    arg_types = {"this": True, "is_string": True}
2570
2571    @classmethod
2572    def number(cls, number) -> Literal:
2573        return cls(this=str(number), is_string=False)
2574
2575    @classmethod
2576    def string(cls, string) -> Literal:
2577        return cls(this=str(string), is_string=True)
2578
2579    @property
2580    def output_name(self) -> str:
2581        return self.name
2582
2583    def to_py(self) -> int | str | Decimal:
2584        if self.is_number:
2585            try:
2586                return int(self.this)
2587            except ValueError:
2588                return Decimal(self.this)
2589        return self.this
arg_types = {'this': True, 'is_string': True}
@classmethod
def number(cls, number) -> Literal:
2571    @classmethod
2572    def number(cls, number) -> Literal:
2573        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2575    @classmethod
2576    def string(cls, string) -> Literal:
2577        return cls(this=str(string), is_string=True)
output_name: str
2579    @property
2580    def output_name(self) -> str:
2581        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:
2583    def to_py(self) -> int | str | Decimal:
2584        if self.is_number:
2585            try:
2586                return int(self.this)
2587            except ValueError:
2588                return Decimal(self.this)
2589        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2592class Join(Expression):
2593    arg_types = {
2594        "this": True,
2595        "on": False,
2596        "side": False,
2597        "kind": False,
2598        "using": False,
2599        "method": False,
2600        "global": False,
2601        "hint": False,
2602        "match_condition": False,  # Snowflake
2603        "expressions": False,
2604        "pivots": False,
2605    }
2606
2607    @property
2608    def method(self) -> str:
2609        return self.text("method").upper()
2610
2611    @property
2612    def kind(self) -> str:
2613        return self.text("kind").upper()
2614
2615    @property
2616    def side(self) -> str:
2617        return self.text("side").upper()
2618
2619    @property
2620    def hint(self) -> str:
2621        return self.text("hint").upper()
2622
2623    @property
2624    def alias_or_name(self) -> str:
2625        return self.this.alias_or_name
2626
2627    @property
2628    def is_semi_or_anti_join(self) -> bool:
2629        return self.kind in ("SEMI", "ANTI")
2630
2631    def on(
2632        self,
2633        *expressions: t.Optional[ExpOrStr],
2634        append: bool = True,
2635        dialect: DialectType = None,
2636        copy: bool = True,
2637        **opts,
2638    ) -> Join:
2639        """
2640        Append to or set the ON expressions.
2641
2642        Example:
2643            >>> import sqlglot
2644            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2645            'JOIN x ON y = 1'
2646
2647        Args:
2648            *expressions: the SQL code strings to parse.
2649                If an `Expression` instance is passed, it will be used as-is.
2650                Multiple expressions are combined with an AND operator.
2651            append: if `True`, AND the new expressions to any existing expression.
2652                Otherwise, this resets the expression.
2653            dialect: the dialect used to parse the input expressions.
2654            copy: if `False`, modify this expression instance in-place.
2655            opts: other options to use to parse the input expressions.
2656
2657        Returns:
2658            The modified Join expression.
2659        """
2660        join = _apply_conjunction_builder(
2661            *expressions,
2662            instance=self,
2663            arg="on",
2664            append=append,
2665            dialect=dialect,
2666            copy=copy,
2667            **opts,
2668        )
2669
2670        if join.kind == "CROSS":
2671            join.set("kind", None)
2672
2673        return join
2674
2675    def using(
2676        self,
2677        *expressions: t.Optional[ExpOrStr],
2678        append: bool = True,
2679        dialect: DialectType = None,
2680        copy: bool = True,
2681        **opts,
2682    ) -> Join:
2683        """
2684        Append to or set the USING expressions.
2685
2686        Example:
2687            >>> import sqlglot
2688            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2689            'JOIN x USING (foo, bla)'
2690
2691        Args:
2692            *expressions: the SQL code strings to parse.
2693                If an `Expression` instance is passed, it will be used as-is.
2694            append: if `True`, concatenate the new expressions to the existing "using" list.
2695                Otherwise, this resets the expression.
2696            dialect: the dialect used to parse the input expressions.
2697            copy: if `False`, modify this expression instance in-place.
2698            opts: other options to use to parse the input expressions.
2699
2700        Returns:
2701            The modified Join expression.
2702        """
2703        join = _apply_list_builder(
2704            *expressions,
2705            instance=self,
2706            arg="using",
2707            append=append,
2708            dialect=dialect,
2709            copy=copy,
2710            **opts,
2711        )
2712
2713        if join.kind == "CROSS":
2714            join.set("kind", None)
2715
2716        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False, 'pivots': False}
method: str
2607    @property
2608    def method(self) -> str:
2609        return self.text("method").upper()
kind: str
2611    @property
2612    def kind(self) -> str:
2613        return self.text("kind").upper()
side: str
2615    @property
2616    def side(self) -> str:
2617        return self.text("side").upper()
hint: str
2619    @property
2620    def hint(self) -> str:
2621        return self.text("hint").upper()
alias_or_name: str
2623    @property
2624    def alias_or_name(self) -> str:
2625        return self.this.alias_or_name
is_semi_or_anti_join: bool
2627    @property
2628    def is_semi_or_anti_join(self) -> bool:
2629        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2631    def on(
2632        self,
2633        *expressions: t.Optional[ExpOrStr],
2634        append: bool = True,
2635        dialect: DialectType = None,
2636        copy: bool = True,
2637        **opts,
2638    ) -> Join:
2639        """
2640        Append to or set the ON expressions.
2641
2642        Example:
2643            >>> import sqlglot
2644            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2645            'JOIN x ON y = 1'
2646
2647        Args:
2648            *expressions: the SQL code strings to parse.
2649                If an `Expression` instance is passed, it will be used as-is.
2650                Multiple expressions are combined with an AND operator.
2651            append: if `True`, AND the new expressions to any existing expression.
2652                Otherwise, this resets the expression.
2653            dialect: the dialect used to parse the input expressions.
2654            copy: if `False`, modify this expression instance in-place.
2655            opts: other options to use to parse the input expressions.
2656
2657        Returns:
2658            The modified Join expression.
2659        """
2660        join = _apply_conjunction_builder(
2661            *expressions,
2662            instance=self,
2663            arg="on",
2664            append=append,
2665            dialect=dialect,
2666            copy=copy,
2667            **opts,
2668        )
2669
2670        if join.kind == "CROSS":
2671            join.set("kind", None)
2672
2673        return join

Append to or set the ON expressions.

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

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2675    def using(
2676        self,
2677        *expressions: t.Optional[ExpOrStr],
2678        append: bool = True,
2679        dialect: DialectType = None,
2680        copy: bool = True,
2681        **opts,
2682    ) -> Join:
2683        """
2684        Append to or set the USING expressions.
2685
2686        Example:
2687            >>> import sqlglot
2688            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2689            'JOIN x USING (foo, bla)'
2690
2691        Args:
2692            *expressions: the SQL code strings to parse.
2693                If an `Expression` instance is passed, it will be used as-is.
2694            append: if `True`, concatenate the new expressions to the existing "using" list.
2695                Otherwise, this resets the expression.
2696            dialect: the dialect used to parse the input expressions.
2697            copy: if `False`, modify this expression instance in-place.
2698            opts: other options to use to parse the input expressions.
2699
2700        Returns:
2701            The modified Join expression.
2702        """
2703        join = _apply_list_builder(
2704            *expressions,
2705            instance=self,
2706            arg="using",
2707            append=append,
2708            dialect=dialect,
2709            copy=copy,
2710            **opts,
2711        )
2712
2713        if join.kind == "CROSS":
2714            join.set("kind", None)
2715
2716        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):
2719class Lateral(UDTF):
2720    arg_types = {
2721        "this": True,
2722        "view": False,
2723        "outer": False,
2724        "alias": False,
2725        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2726        "ordinality": False,
2727    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2732class TableFromRows(UDTF):
2733    arg_types = {
2734        "this": True,
2735        "alias": False,
2736        "joins": False,
2737        "pivots": False,
2738        "sample": False,
2739    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2742class MatchRecognizeMeasure(Expression):
2743    arg_types = {
2744        "this": True,
2745        "window_frame": False,
2746    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2749class MatchRecognize(Expression):
2750    arg_types = {
2751        "partition_by": False,
2752        "order": False,
2753        "measures": False,
2754        "rows": False,
2755        "after": False,
2756        "pattern": False,
2757        "define": False,
2758        "alias": False,
2759    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2764class Final(Expression):
2765    pass
key = 'final'
class Offset(Expression):
2768class Offset(Expression):
2769    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2772class Order(Expression):
2773    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2777class WithFill(Expression):
2778    arg_types = {
2779        "from": False,
2780        "to": False,
2781        "step": False,
2782        "interpolate": False,
2783    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2788class Cluster(Order):
2789    pass
key = 'cluster'
class Distribute(Order):
2792class Distribute(Order):
2793    pass
key = 'distribute'
class Sort(Order):
2796class Sort(Order):
2797    pass
key = 'sort'
class Ordered(Expression):
2800class Ordered(Expression):
2801    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2802
2803    @property
2804    def name(self) -> str:
2805        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2803    @property
2804    def name(self) -> str:
2805        return self.this.name
key = 'ordered'
class Property(Expression):
2808class Property(Expression):
2809    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2812class GrantPrivilege(Expression):
2813    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2816class GrantPrincipal(Expression):
2817    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2820class AllowedValuesProperty(Expression):
2821    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2824class AlgorithmProperty(Property):
2825    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2828class AutoIncrementProperty(Property):
2829    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2833class AutoRefreshProperty(Property):
2834    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2837class BackupProperty(Property):
2838    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BuildProperty(Property):
2842class BuildProperty(Property):
2843    arg_types = {"this": True}
arg_types = {'this': True}
key = 'buildproperty'
class BlockCompressionProperty(Property):
2846class BlockCompressionProperty(Property):
2847    arg_types = {
2848        "autotemp": False,
2849        "always": False,
2850        "default": False,
2851        "manual": False,
2852        "never": False,
2853    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2856class CharacterSetProperty(Property):
2857    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2860class ChecksumProperty(Property):
2861    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2864class CollateProperty(Property):
2865    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2868class CopyGrantsProperty(Property):
2869    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2872class DataBlocksizeProperty(Property):
2873    arg_types = {
2874        "size": False,
2875        "units": False,
2876        "minimum": False,
2877        "maximum": False,
2878        "default": False,
2879    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2882class DataDeletionProperty(Property):
2883    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):
2886class DefinerProperty(Property):
2887    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2890class DistKeyProperty(Property):
2891    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2896class DistributedByProperty(Property):
2897    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):
2900class DistStyleProperty(Property):
2901    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2904class DuplicateKeyProperty(Property):
2905    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2908class EngineProperty(Property):
2909    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2912class HeapProperty(Property):
2913    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2916class ToTableProperty(Property):
2917    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2920class ExecuteAsProperty(Property):
2921    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2924class ExternalProperty(Property):
2925    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2928class FallbackProperty(Property):
2929    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2933class FileFormatProperty(Property):
2934    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2937class CredentialsProperty(Property):
2938    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2941class FreespaceProperty(Property):
2942    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2945class GlobalProperty(Property):
2946    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2949class IcebergProperty(Property):
2950    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2953class InheritsProperty(Property):
2954    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2957class InputModelProperty(Property):
2958    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2961class OutputModelProperty(Property):
2962    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2965class IsolatedLoadingProperty(Property):
2966    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2969class JournalProperty(Property):
2970    arg_types = {
2971        "no": False,
2972        "dual": False,
2973        "before": False,
2974        "local": False,
2975        "after": False,
2976    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2979class LanguageProperty(Property):
2980    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2983class EnviromentProperty(Property):
2984    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2988class ClusteredByProperty(Property):
2989    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2992class DictProperty(Property):
2993    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2996class DictSubProperty(Property):
2997    pass
key = 'dictsubproperty'
class DictRange(Property):
3000class DictRange(Property):
3001    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
3004class DynamicProperty(Property):
3005    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
3010class OnCluster(Property):
3011    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
3015class EmptyProperty(Property):
3016    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
3019class LikeProperty(Property):
3020    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
3023class LocationProperty(Property):
3024    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
3027class LockProperty(Property):
3028    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
3031class LockingProperty(Property):
3032    arg_types = {
3033        "this": False,
3034        "kind": True,
3035        "for_or_in": False,
3036        "lock_type": True,
3037        "override": False,
3038    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
3041class LogProperty(Property):
3042    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
3045class MaterializedProperty(Property):
3046    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
3049class MergeBlockRatioProperty(Property):
3050    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):
3053class NoPrimaryIndexProperty(Property):
3054    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
3057class OnProperty(Property):
3058    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
3061class OnCommitProperty(Property):
3062    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3065class PartitionedByProperty(Property):
3066    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3069class PartitionedByBucket(Property):
3070    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3073class PartitionByTruncate(Property):
3074    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3078class PartitionByRangeProperty(Property):
3079    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3083class PartitionByRangePropertyDynamic(Expression):
3084    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class PartitionByListProperty(Property):
3088class PartitionByListProperty(Property):
3089    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbylistproperty'
class PartitionList(Expression):
3093class PartitionList(Expression):
3094    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'partitionlist'
class RefreshTriggerProperty(Property):
3098class RefreshTriggerProperty(Property):
3099    arg_types = {
3100        "method": True,
3101        "kind": False,
3102        "every": False,
3103        "unit": False,
3104        "starts": False,
3105    }
arg_types = {'method': True, 'kind': False, 'every': False, 'unit': False, 'starts': False}
key = 'refreshtriggerproperty'
class UniqueKeyProperty(Property):
3109class UniqueKeyProperty(Property):
3110    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3114class PartitionBoundSpec(Expression):
3115    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3116    arg_types = {
3117        "this": False,
3118        "expression": False,
3119        "from_expressions": False,
3120        "to_expressions": False,
3121    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3124class PartitionedOfProperty(Property):
3125    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3126    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3129class StreamingTableProperty(Property):
3130    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3133class RemoteWithConnectionModelProperty(Property):
3134    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3137class ReturnsProperty(Property):
3138    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):
3141class StrictProperty(Property):
3142    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3145class RowFormatProperty(Property):
3146    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3149class RowFormatDelimitedProperty(Property):
3150    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3151    arg_types = {
3152        "fields": False,
3153        "escaped": False,
3154        "collection_items": False,
3155        "map_keys": False,
3156        "lines": False,
3157        "null": False,
3158        "serde": False,
3159    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3162class RowFormatSerdeProperty(Property):
3163    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3167class QueryTransform(Expression):
3168    arg_types = {
3169        "expressions": True,
3170        "command_script": True,
3171        "schema": False,
3172        "row_format_before": False,
3173        "record_writer": False,
3174        "row_format_after": False,
3175        "record_reader": False,
3176    }
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):
3179class SampleProperty(Property):
3180    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3184class SecurityProperty(Property):
3185    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3188class SchemaCommentProperty(Property):
3189    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3192class SemanticView(Expression):
3193    arg_types = {"this": True, "metrics": False, "dimensions": False, "where": False}
arg_types = {'this': True, 'metrics': False, 'dimensions': False, 'where': False}
key = 'semanticview'
class SerdeProperties(Property):
3196class SerdeProperties(Property):
3197    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3200class SetProperty(Property):
3201    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3204class SharingProperty(Property):
3205    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3208class SetConfigProperty(Property):
3209    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3212class SettingsProperty(Property):
3213    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3216class SortKeyProperty(Property):
3217    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3220class SqlReadWriteProperty(Property):
3221    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3224class SqlSecurityProperty(Property):
3225    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3228class StabilityProperty(Property):
3229    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3232class StorageHandlerProperty(Property):
3233    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3236class TemporaryProperty(Property):
3237    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3240class SecureProperty(Property):
3241    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3245class Tags(ColumnConstraintKind, Property):
3246    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3249class TransformModelProperty(Property):
3250    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3253class TransientProperty(Property):
3254    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3257class UnloggedProperty(Property):
3258    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3262class UsingTemplateProperty(Property):
3263    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3267class ViewAttributeProperty(Property):
3268    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3271class VolatileProperty(Property):
3272    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3275class WithDataProperty(Property):
3276    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3279class WithJournalTableProperty(Property):
3280    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3283class WithSchemaBindingProperty(Property):
3284    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3287class WithSystemVersioningProperty(Property):
3288    arg_types = {
3289        "on": False,
3290        "this": False,
3291        "data_consistency": False,
3292        "retention_period": False,
3293        "with": True,
3294    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3297class WithProcedureOptions(Property):
3298    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3301class EncodeProperty(Property):
3302    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3305class IncludeProperty(Property):
3306    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3309class ForceProperty(Property):
3310    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3313class Properties(Expression):
3314    arg_types = {"expressions": True}
3315
3316    NAME_TO_PROPERTY = {
3317        "ALGORITHM": AlgorithmProperty,
3318        "AUTO_INCREMENT": AutoIncrementProperty,
3319        "CHARACTER SET": CharacterSetProperty,
3320        "CLUSTERED_BY": ClusteredByProperty,
3321        "COLLATE": CollateProperty,
3322        "COMMENT": SchemaCommentProperty,
3323        "CREDENTIALS": CredentialsProperty,
3324        "DEFINER": DefinerProperty,
3325        "DISTKEY": DistKeyProperty,
3326        "DISTRIBUTED_BY": DistributedByProperty,
3327        "DISTSTYLE": DistStyleProperty,
3328        "ENGINE": EngineProperty,
3329        "EXECUTE AS": ExecuteAsProperty,
3330        "FORMAT": FileFormatProperty,
3331        "LANGUAGE": LanguageProperty,
3332        "LOCATION": LocationProperty,
3333        "LOCK": LockProperty,
3334        "PARTITIONED_BY": PartitionedByProperty,
3335        "RETURNS": ReturnsProperty,
3336        "ROW_FORMAT": RowFormatProperty,
3337        "SORTKEY": SortKeyProperty,
3338        "ENCODE": EncodeProperty,
3339        "INCLUDE": IncludeProperty,
3340    }
3341
3342    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3343
3344    # CREATE property locations
3345    # Form: schema specified
3346    #   create [POST_CREATE]
3347    #     table a [POST_NAME]
3348    #     (b int) [POST_SCHEMA]
3349    #     with ([POST_WITH])
3350    #     index (b) [POST_INDEX]
3351    #
3352    # Form: alias selection
3353    #   create [POST_CREATE]
3354    #     table a [POST_NAME]
3355    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3356    #     index (c) [POST_INDEX]
3357    class Location(AutoName):
3358        POST_CREATE = auto()
3359        POST_NAME = auto()
3360        POST_SCHEMA = auto()
3361        POST_WITH = auto()
3362        POST_ALIAS = auto()
3363        POST_EXPRESSION = auto()
3364        POST_INDEX = auto()
3365        UNSUPPORTED = auto()
3366
3367    @classmethod
3368    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3369        expressions = []
3370        for key, value in properties_dict.items():
3371            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3372            if property_cls:
3373                expressions.append(property_cls(this=convert(value)))
3374            else:
3375                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3376
3377        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'CREDENTIALS': <class 'CredentialsProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>, 'ENCODE': <class 'EncodeProperty'>, 'INCLUDE': <class 'IncludeProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'CredentialsProperty'>: 'CREDENTIALS', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistributedByProperty'>: 'DISTRIBUTED_BY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY', <class 'EncodeProperty'>: 'ENCODE', <class 'IncludeProperty'>: 'INCLUDE'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3367    @classmethod
3368    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3369        expressions = []
3370        for key, value in properties_dict.items():
3371            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3372            if property_cls:
3373                expressions.append(property_cls(this=convert(value)))
3374            else:
3375                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3376
3377        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3357    class Location(AutoName):
3358        POST_CREATE = auto()
3359        POST_NAME = auto()
3360        POST_SCHEMA = auto()
3361        POST_WITH = auto()
3362        POST_ALIAS = auto()
3363        POST_EXPRESSION = auto()
3364        POST_INDEX = auto()
3365        UNSUPPORTED = auto()

An enumeration.

POST_CREATE = <Location.POST_CREATE: 'POST_CREATE'>
POST_NAME = <Location.POST_NAME: 'POST_NAME'>
POST_SCHEMA = <Location.POST_SCHEMA: 'POST_SCHEMA'>
POST_WITH = <Location.POST_WITH: 'POST_WITH'>
POST_ALIAS = <Location.POST_ALIAS: 'POST_ALIAS'>
POST_EXPRESSION = <Location.POST_EXPRESSION: 'POST_EXPRESSION'>
POST_INDEX = <Location.POST_INDEX: 'POST_INDEX'>
UNSUPPORTED = <Location.UNSUPPORTED: 'UNSUPPORTED'>
class Qualify(Expression):
3380class Qualify(Expression):
3381    pass
key = 'qualify'
class InputOutputFormat(Expression):
3384class InputOutputFormat(Expression):
3385    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3389class Return(Expression):
3390    pass
key = 'return'
class Reference(Expression):
3393class Reference(Expression):
3394    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3397class Tuple(Expression):
3398    arg_types = {"expressions": False}
3399
3400    def isin(
3401        self,
3402        *expressions: t.Any,
3403        query: t.Optional[ExpOrStr] = None,
3404        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3405        copy: bool = True,
3406        **opts,
3407    ) -> In:
3408        return In(
3409            this=maybe_copy(self, copy),
3410            expressions=[convert(e, copy=copy) for e in expressions],
3411            query=maybe_parse(query, copy=copy, **opts) if query else None,
3412            unnest=(
3413                Unnest(
3414                    expressions=[
3415                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3416                        for e in ensure_list(unnest)
3417                    ]
3418                )
3419                if unnest
3420                else None
3421            ),
3422        )
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:
3400    def isin(
3401        self,
3402        *expressions: t.Any,
3403        query: t.Optional[ExpOrStr] = None,
3404        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3405        copy: bool = True,
3406        **opts,
3407    ) -> In:
3408        return In(
3409            this=maybe_copy(self, copy),
3410            expressions=[convert(e, copy=copy) for e in expressions],
3411            query=maybe_parse(query, copy=copy, **opts) if query else None,
3412            unnest=(
3413                Unnest(
3414                    expressions=[
3415                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3416                        for e in ensure_list(unnest)
3417                    ]
3418                )
3419                if unnest
3420                else None
3421            ),
3422        )
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):
3453class QueryOption(Expression):
3454    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3458class WithTableHint(Expression):
3459    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3463class IndexTableHint(Expression):
3464    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3468class HistoricalData(Expression):
3469    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3473class Put(Expression):
3474    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3478class Get(Expression):
3479    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3482class Table(Expression):
3483    arg_types = {
3484        "this": False,
3485        "alias": False,
3486        "db": False,
3487        "catalog": False,
3488        "laterals": False,
3489        "joins": False,
3490        "pivots": False,
3491        "hints": False,
3492        "system_time": False,
3493        "version": False,
3494        "format": False,
3495        "pattern": False,
3496        "ordinality": False,
3497        "when": False,
3498        "only": False,
3499        "partition": False,
3500        "changes": False,
3501        "rows_from": False,
3502        "sample": False,
3503    }
3504
3505    @property
3506    def name(self) -> str:
3507        if not self.this or isinstance(self.this, Func):
3508            return ""
3509        return self.this.name
3510
3511    @property
3512    def db(self) -> str:
3513        return self.text("db")
3514
3515    @property
3516    def catalog(self) -> str:
3517        return self.text("catalog")
3518
3519    @property
3520    def selects(self) -> t.List[Expression]:
3521        return []
3522
3523    @property
3524    def named_selects(self) -> t.List[str]:
3525        return []
3526
3527    @property
3528    def parts(self) -> t.List[Expression]:
3529        """Return the parts of a table in order catalog, db, table."""
3530        parts: t.List[Expression] = []
3531
3532        for arg in ("catalog", "db", "this"):
3533            part = self.args.get(arg)
3534
3535            if isinstance(part, Dot):
3536                parts.extend(part.flatten())
3537            elif isinstance(part, Expression):
3538                parts.append(part)
3539
3540        return parts
3541
3542    def to_column(self, copy: bool = True) -> Expression:
3543        parts = self.parts
3544        last_part = parts[-1]
3545
3546        if isinstance(last_part, Identifier):
3547            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3548        else:
3549            # This branch will be reached if a function or array is wrapped in a `Table`
3550            col = last_part
3551
3552        alias = self.args.get("alias")
3553        if alias:
3554            col = alias_(col, alias.this, copy=copy)
3555
3556        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
3505    @property
3506    def name(self) -> str:
3507        if not self.this or isinstance(self.this, Func):
3508            return ""
3509        return self.this.name
db: str
3511    @property
3512    def db(self) -> str:
3513        return self.text("db")
catalog: str
3515    @property
3516    def catalog(self) -> str:
3517        return self.text("catalog")
selects: List[Expression]
3519    @property
3520    def selects(self) -> t.List[Expression]:
3521        return []
named_selects: List[str]
3523    @property
3524    def named_selects(self) -> t.List[str]:
3525        return []
parts: List[Expression]
3527    @property
3528    def parts(self) -> t.List[Expression]:
3529        """Return the parts of a table in order catalog, db, table."""
3530        parts: t.List[Expression] = []
3531
3532        for arg in ("catalog", "db", "this"):
3533            part = self.args.get(arg)
3534
3535            if isinstance(part, Dot):
3536                parts.extend(part.flatten())
3537            elif isinstance(part, Expression):
3538                parts.append(part)
3539
3540        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3542    def to_column(self, copy: bool = True) -> Expression:
3543        parts = self.parts
3544        last_part = parts[-1]
3545
3546        if isinstance(last_part, Identifier):
3547            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3548        else:
3549            # This branch will be reached if a function or array is wrapped in a `Table`
3550            col = last_part
3551
3552        alias = self.args.get("alias")
3553        if alias:
3554            col = alias_(col, alias.this, copy=copy)
3555
3556        return col
key = 'table'
class SetOperation(Query):
3559class SetOperation(Query):
3560    arg_types = {
3561        "with": False,
3562        "this": True,
3563        "expression": True,
3564        "distinct": False,
3565        "by_name": False,
3566        "side": False,
3567        "kind": False,
3568        "on": False,
3569        **QUERY_MODIFIERS,
3570    }
3571
3572    def select(
3573        self: S,
3574        *expressions: t.Optional[ExpOrStr],
3575        append: bool = True,
3576        dialect: DialectType = None,
3577        copy: bool = True,
3578        **opts,
3579    ) -> S:
3580        this = maybe_copy(self, copy)
3581        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3582        this.expression.unnest().select(
3583            *expressions, append=append, dialect=dialect, copy=False, **opts
3584        )
3585        return this
3586
3587    @property
3588    def named_selects(self) -> t.List[str]:
3589        return self.this.unnest().named_selects
3590
3591    @property
3592    def is_star(self) -> bool:
3593        return self.this.is_star or self.expression.is_star
3594
3595    @property
3596    def selects(self) -> t.List[Expression]:
3597        return self.this.unnest().selects
3598
3599    @property
3600    def left(self) -> Query:
3601        return self.this
3602
3603    @property
3604    def right(self) -> Query:
3605        return self.expression
3606
3607    @property
3608    def kind(self) -> str:
3609        return self.text("kind").upper()
3610
3611    @property
3612    def side(self) -> str:
3613        return self.text("side").upper()
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3572    def select(
3573        self: S,
3574        *expressions: t.Optional[ExpOrStr],
3575        append: bool = True,
3576        dialect: DialectType = None,
3577        copy: bool = True,
3578        **opts,
3579    ) -> S:
3580        this = maybe_copy(self, copy)
3581        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3582        this.expression.unnest().select(
3583            *expressions, append=append, dialect=dialect, copy=False, **opts
3584        )
3585        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]
3587    @property
3588    def named_selects(self) -> t.List[str]:
3589        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3591    @property
3592    def is_star(self) -> bool:
3593        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3595    @property
3596    def selects(self) -> t.List[Expression]:
3597        return self.this.unnest().selects

Returns the query's projections.

left: Query
3599    @property
3600    def left(self) -> Query:
3601        return self.this
right: Query
3603    @property
3604    def right(self) -> Query:
3605        return self.expression
kind: str
3607    @property
3608    def kind(self) -> str:
3609        return self.text("kind").upper()
side: str
3611    @property
3612    def side(self) -> str:
3613        return self.text("side").upper()
key = 'setoperation'
class Union(SetOperation):
3616class Union(SetOperation):
3617    pass
key = 'union'
class Except(SetOperation):
3620class Except(SetOperation):
3621    pass
key = 'except'
class Intersect(SetOperation):
3624class Intersect(SetOperation):
3625    pass
key = 'intersect'
class Update(DML):
3628class Update(DML):
3629    arg_types = {
3630        "with": False,
3631        "this": False,
3632        "expressions": True,
3633        "from": False,
3634        "where": False,
3635        "returning": False,
3636        "order": False,
3637        "limit": False,
3638        "options": False,
3639    }
3640
3641    def table(
3642        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3643    ) -> Update:
3644        """
3645        Set the table to update.
3646
3647        Example:
3648            >>> Update().table("my_table").set_("x = 1").sql()
3649            'UPDATE my_table SET x = 1'
3650
3651        Args:
3652            expression : the SQL code strings to parse.
3653                If a `Table` instance is passed, this is used as-is.
3654                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3655            dialect: the dialect used to parse the input expression.
3656            copy: if `False`, modify this expression instance in-place.
3657            opts: other options to use to parse the input expressions.
3658
3659        Returns:
3660            The modified Update expression.
3661        """
3662        return _apply_builder(
3663            expression=expression,
3664            instance=self,
3665            arg="this",
3666            into=Table,
3667            prefix=None,
3668            dialect=dialect,
3669            copy=copy,
3670            **opts,
3671        )
3672
3673    def set_(
3674        self,
3675        *expressions: ExpOrStr,
3676        append: bool = True,
3677        dialect: DialectType = None,
3678        copy: bool = True,
3679        **opts,
3680    ) -> Update:
3681        """
3682        Append to or set the SET expressions.
3683
3684        Example:
3685            >>> Update().table("my_table").set_("x = 1").sql()
3686            'UPDATE my_table SET x = 1'
3687
3688        Args:
3689            *expressions: the SQL code strings to parse.
3690                If `Expression` instance(s) are passed, they will be used as-is.
3691                Multiple expressions are combined with a comma.
3692            append: if `True`, add the new expressions to any existing SET expressions.
3693                Otherwise, this resets the expressions.
3694            dialect: the dialect used to parse the input expressions.
3695            copy: if `False`, modify this expression instance in-place.
3696            opts: other options to use to parse the input expressions.
3697        """
3698        return _apply_list_builder(
3699            *expressions,
3700            instance=self,
3701            arg="expressions",
3702            append=append,
3703            into=Expression,
3704            prefix=None,
3705            dialect=dialect,
3706            copy=copy,
3707            **opts,
3708        )
3709
3710    def where(
3711        self,
3712        *expressions: t.Optional[ExpOrStr],
3713        append: bool = True,
3714        dialect: DialectType = None,
3715        copy: bool = True,
3716        **opts,
3717    ) -> Select:
3718        """
3719        Append to or set the WHERE expressions.
3720
3721        Example:
3722            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3723            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3724
3725        Args:
3726            *expressions: the SQL code strings to parse.
3727                If an `Expression` instance is passed, it will be used as-is.
3728                Multiple expressions are combined with an AND operator.
3729            append: if `True`, AND the new expressions to any existing expression.
3730                Otherwise, this resets the expression.
3731            dialect: the dialect used to parse the input expressions.
3732            copy: if `False`, modify this expression instance in-place.
3733            opts: other options to use to parse the input expressions.
3734
3735        Returns:
3736            Select: the modified expression.
3737        """
3738        return _apply_conjunction_builder(
3739            *expressions,
3740            instance=self,
3741            arg="where",
3742            append=append,
3743            into=Where,
3744            dialect=dialect,
3745            copy=copy,
3746            **opts,
3747        )
3748
3749    def from_(
3750        self,
3751        expression: t.Optional[ExpOrStr] = None,
3752        dialect: DialectType = None,
3753        copy: bool = True,
3754        **opts,
3755    ) -> Update:
3756        """
3757        Set the FROM expression.
3758
3759        Example:
3760            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3761            'UPDATE my_table SET x = 1 FROM baz'
3762
3763        Args:
3764            expression : the SQL code strings to parse.
3765                If a `From` instance is passed, this is used as-is.
3766                If another `Expression` instance is passed, it will be wrapped in a `From`.
3767                If nothing is passed in then a from is not applied to the expression
3768            dialect: the dialect used to parse the input expression.
3769            copy: if `False`, modify this expression instance in-place.
3770            opts: other options to use to parse the input expressions.
3771
3772        Returns:
3773            The modified Update expression.
3774        """
3775        if not expression:
3776            return maybe_copy(self, copy)
3777
3778        return _apply_builder(
3779            expression=expression,
3780            instance=self,
3781            arg="from",
3782            into=From,
3783            prefix="FROM",
3784            dialect=dialect,
3785            copy=copy,
3786            **opts,
3787        )
3788
3789    def with_(
3790        self,
3791        alias: ExpOrStr,
3792        as_: ExpOrStr,
3793        recursive: t.Optional[bool] = None,
3794        materialized: t.Optional[bool] = None,
3795        append: bool = True,
3796        dialect: DialectType = None,
3797        copy: bool = True,
3798        **opts,
3799    ) -> Update:
3800        """
3801        Append to or set the common table expressions.
3802
3803        Example:
3804            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3805            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3806
3807        Args:
3808            alias: the SQL code string to parse as the table name.
3809                If an `Expression` instance is passed, this is used as-is.
3810            as_: the SQL code string to parse as the table expression.
3811                If an `Expression` instance is passed, it will be used as-is.
3812            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3813            materialized: set the MATERIALIZED part of the expression.
3814            append: if `True`, add to any existing expressions.
3815                Otherwise, this resets the expressions.
3816            dialect: the dialect used to parse the input expression.
3817            copy: if `False`, modify this expression instance in-place.
3818            opts: other options to use to parse the input expressions.
3819
3820        Returns:
3821            The modified expression.
3822        """
3823        return _apply_cte_builder(
3824            self,
3825            alias,
3826            as_,
3827            recursive=recursive,
3828            materialized=materialized,
3829            append=append,
3830            dialect=dialect,
3831            copy=copy,
3832            **opts,
3833        )
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False, 'options': False}
def table( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3641    def table(
3642        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3643    ) -> Update:
3644        """
3645        Set the table to update.
3646
3647        Example:
3648            >>> Update().table("my_table").set_("x = 1").sql()
3649            'UPDATE my_table SET x = 1'
3650
3651        Args:
3652            expression : the SQL code strings to parse.
3653                If a `Table` instance is passed, this is used as-is.
3654                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3655            dialect: the dialect used to parse the input expression.
3656            copy: if `False`, modify this expression instance in-place.
3657            opts: other options to use to parse the input expressions.
3658
3659        Returns:
3660            The modified Update expression.
3661        """
3662        return _apply_builder(
3663            expression=expression,
3664            instance=self,
3665            arg="this",
3666            into=Table,
3667            prefix=None,
3668            dialect=dialect,
3669            copy=copy,
3670            **opts,
3671        )

Set the table to update.

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

The modified Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3673    def set_(
3674        self,
3675        *expressions: ExpOrStr,
3676        append: bool = True,
3677        dialect: DialectType = None,
3678        copy: bool = True,
3679        **opts,
3680    ) -> Update:
3681        """
3682        Append to or set the SET expressions.
3683
3684        Example:
3685            >>> Update().table("my_table").set_("x = 1").sql()
3686            'UPDATE my_table SET x = 1'
3687
3688        Args:
3689            *expressions: the SQL code strings to parse.
3690                If `Expression` instance(s) are passed, they will be used as-is.
3691                Multiple expressions are combined with a comma.
3692            append: if `True`, add the new expressions to any existing SET expressions.
3693                Otherwise, this resets the expressions.
3694            dialect: the dialect used to parse the input expressions.
3695            copy: if `False`, modify this expression instance in-place.
3696            opts: other options to use to parse the input expressions.
3697        """
3698        return _apply_list_builder(
3699            *expressions,
3700            instance=self,
3701            arg="expressions",
3702            append=append,
3703            into=Expression,
3704            prefix=None,
3705            dialect=dialect,
3706            copy=copy,
3707            **opts,
3708        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3710    def where(
3711        self,
3712        *expressions: t.Optional[ExpOrStr],
3713        append: bool = True,
3714        dialect: DialectType = None,
3715        copy: bool = True,
3716        **opts,
3717    ) -> Select:
3718        """
3719        Append to or set the WHERE expressions.
3720
3721        Example:
3722            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3723            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3724
3725        Args:
3726            *expressions: the SQL code strings to parse.
3727                If an `Expression` instance is passed, it will be used as-is.
3728                Multiple expressions are combined with an AND operator.
3729            append: if `True`, AND the new expressions to any existing expression.
3730                Otherwise, this resets the expression.
3731            dialect: the dialect used to parse the input expressions.
3732            copy: if `False`, modify this expression instance in-place.
3733            opts: other options to use to parse the input expressions.
3734
3735        Returns:
3736            Select: the modified expression.
3737        """
3738        return _apply_conjunction_builder(
3739            *expressions,
3740            instance=self,
3741            arg="where",
3742            append=append,
3743            into=Where,
3744            dialect=dialect,
3745            copy=copy,
3746            **opts,
3747        )

Append to or set the WHERE expressions.

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

Select: the modified expression.

def from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3749    def from_(
3750        self,
3751        expression: t.Optional[ExpOrStr] = None,
3752        dialect: DialectType = None,
3753        copy: bool = True,
3754        **opts,
3755    ) -> Update:
3756        """
3757        Set the FROM expression.
3758
3759        Example:
3760            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3761            'UPDATE my_table SET x = 1 FROM baz'
3762
3763        Args:
3764            expression : the SQL code strings to parse.
3765                If a `From` instance is passed, this is used as-is.
3766                If another `Expression` instance is passed, it will be wrapped in a `From`.
3767                If nothing is passed in then a from is not applied to the expression
3768            dialect: the dialect used to parse the input expression.
3769            copy: if `False`, modify this expression instance in-place.
3770            opts: other options to use to parse the input expressions.
3771
3772        Returns:
3773            The modified Update expression.
3774        """
3775        if not expression:
3776            return maybe_copy(self, copy)
3777
3778        return _apply_builder(
3779            expression=expression,
3780            instance=self,
3781            arg="from",
3782            into=From,
3783            prefix="FROM",
3784            dialect=dialect,
3785            copy=copy,
3786            **opts,
3787        )

Set the FROM expression.

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

The modified Update expression.

def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3789    def with_(
3790        self,
3791        alias: ExpOrStr,
3792        as_: ExpOrStr,
3793        recursive: t.Optional[bool] = None,
3794        materialized: t.Optional[bool] = None,
3795        append: bool = True,
3796        dialect: DialectType = None,
3797        copy: bool = True,
3798        **opts,
3799    ) -> Update:
3800        """
3801        Append to or set the common table expressions.
3802
3803        Example:
3804            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3805            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3806
3807        Args:
3808            alias: the SQL code string to parse as the table name.
3809                If an `Expression` instance is passed, this is used as-is.
3810            as_: the SQL code string to parse as the table expression.
3811                If an `Expression` instance is passed, it will be used as-is.
3812            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3813            materialized: set the MATERIALIZED part of the expression.
3814            append: if `True`, add to any existing expressions.
3815                Otherwise, this resets the expressions.
3816            dialect: the dialect used to parse the input expression.
3817            copy: if `False`, modify this expression instance in-place.
3818            opts: other options to use to parse the input expressions.
3819
3820        Returns:
3821            The modified expression.
3822        """
3823        return _apply_cte_builder(
3824            self,
3825            alias,
3826            as_,
3827            recursive=recursive,
3828            materialized=materialized,
3829            append=append,
3830            dialect=dialect,
3831            copy=copy,
3832            **opts,
3833        )

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):
3836class Values(UDTF):
3837    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3840class Var(Expression):
3841    pass
key = 'var'
class Version(Expression):
3844class Version(Expression):
3845    """
3846    Time travel, iceberg, bigquery etc
3847    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3848    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3849    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3850    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3851    this is either TIMESTAMP or VERSION
3852    kind is ("AS OF", "BETWEEN")
3853    """
3854
3855    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3858class Schema(Expression):
3859    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3864class Lock(Expression):
3865    arg_types = {"update": True, "expressions": False, "wait": False, "key": False}
arg_types = {'update': True, 'expressions': False, 'wait': False, 'key': False}
key = 'lock'
class Select(Query):
3868class Select(Query):
3869    arg_types = {
3870        "with": False,
3871        "kind": False,
3872        "expressions": False,
3873        "hint": False,
3874        "distinct": False,
3875        "into": False,
3876        "from": False,
3877        "operation_modifiers": False,
3878        **QUERY_MODIFIERS,
3879    }
3880
3881    def from_(
3882        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3883    ) -> Select:
3884        """
3885        Set the FROM expression.
3886
3887        Example:
3888            >>> Select().from_("tbl").select("x").sql()
3889            'SELECT x FROM tbl'
3890
3891        Args:
3892            expression : the SQL code strings to parse.
3893                If a `From` instance is passed, this is used as-is.
3894                If another `Expression` instance is passed, it will be wrapped in a `From`.
3895            dialect: the dialect used to parse the input expression.
3896            copy: if `False`, modify this expression instance in-place.
3897            opts: other options to use to parse the input expressions.
3898
3899        Returns:
3900            The modified Select expression.
3901        """
3902        return _apply_builder(
3903            expression=expression,
3904            instance=self,
3905            arg="from",
3906            into=From,
3907            prefix="FROM",
3908            dialect=dialect,
3909            copy=copy,
3910            **opts,
3911        )
3912
3913    def group_by(
3914        self,
3915        *expressions: t.Optional[ExpOrStr],
3916        append: bool = True,
3917        dialect: DialectType = None,
3918        copy: bool = True,
3919        **opts,
3920    ) -> Select:
3921        """
3922        Set the GROUP BY expression.
3923
3924        Example:
3925            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3926            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3927
3928        Args:
3929            *expressions: the SQL code strings to parse.
3930                If a `Group` instance is passed, this is used as-is.
3931                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3932                If nothing is passed in then a group by is not applied to the expression
3933            append: if `True`, add to any existing expressions.
3934                Otherwise, this flattens all the `Group` expression into a single expression.
3935            dialect: the dialect used to parse the input expression.
3936            copy: if `False`, modify this expression instance in-place.
3937            opts: other options to use to parse the input expressions.
3938
3939        Returns:
3940            The modified Select expression.
3941        """
3942        if not expressions:
3943            return self if not copy else self.copy()
3944
3945        return _apply_child_list_builder(
3946            *expressions,
3947            instance=self,
3948            arg="group",
3949            append=append,
3950            copy=copy,
3951            prefix="GROUP BY",
3952            into=Group,
3953            dialect=dialect,
3954            **opts,
3955        )
3956
3957    def sort_by(
3958        self,
3959        *expressions: t.Optional[ExpOrStr],
3960        append: bool = True,
3961        dialect: DialectType = None,
3962        copy: bool = True,
3963        **opts,
3964    ) -> Select:
3965        """
3966        Set the SORT BY expression.
3967
3968        Example:
3969            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3970            'SELECT x FROM tbl SORT BY x DESC'
3971
3972        Args:
3973            *expressions: the SQL code strings to parse.
3974                If a `Group` instance is passed, this is used as-is.
3975                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3976            append: if `True`, add to any existing expressions.
3977                Otherwise, this flattens all the `Order` expression into a single expression.
3978            dialect: the dialect used to parse the input expression.
3979            copy: if `False`, modify this expression instance in-place.
3980            opts: other options to use to parse the input expressions.
3981
3982        Returns:
3983            The modified Select expression.
3984        """
3985        return _apply_child_list_builder(
3986            *expressions,
3987            instance=self,
3988            arg="sort",
3989            append=append,
3990            copy=copy,
3991            prefix="SORT BY",
3992            into=Sort,
3993            dialect=dialect,
3994            **opts,
3995        )
3996
3997    def cluster_by(
3998        self,
3999        *expressions: t.Optional[ExpOrStr],
4000        append: bool = True,
4001        dialect: DialectType = None,
4002        copy: bool = True,
4003        **opts,
4004    ) -> Select:
4005        """
4006        Set the CLUSTER BY expression.
4007
4008        Example:
4009            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
4010            'SELECT x FROM tbl CLUSTER BY x DESC'
4011
4012        Args:
4013            *expressions: the SQL code strings to parse.
4014                If a `Group` instance is passed, this is used as-is.
4015                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
4016            append: if `True`, add to any existing expressions.
4017                Otherwise, this flattens all the `Order` expression into a single expression.
4018            dialect: the dialect used to parse the input expression.
4019            copy: if `False`, modify this expression instance in-place.
4020            opts: other options to use to parse the input expressions.
4021
4022        Returns:
4023            The modified Select expression.
4024        """
4025        return _apply_child_list_builder(
4026            *expressions,
4027            instance=self,
4028            arg="cluster",
4029            append=append,
4030            copy=copy,
4031            prefix="CLUSTER BY",
4032            into=Cluster,
4033            dialect=dialect,
4034            **opts,
4035        )
4036
4037    def select(
4038        self,
4039        *expressions: t.Optional[ExpOrStr],
4040        append: bool = True,
4041        dialect: DialectType = None,
4042        copy: bool = True,
4043        **opts,
4044    ) -> Select:
4045        return _apply_list_builder(
4046            *expressions,
4047            instance=self,
4048            arg="expressions",
4049            append=append,
4050            dialect=dialect,
4051            into=Expression,
4052            copy=copy,
4053            **opts,
4054        )
4055
4056    def lateral(
4057        self,
4058        *expressions: t.Optional[ExpOrStr],
4059        append: bool = True,
4060        dialect: DialectType = None,
4061        copy: bool = True,
4062        **opts,
4063    ) -> Select:
4064        """
4065        Append to or set the LATERAL expressions.
4066
4067        Example:
4068            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
4069            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
4070
4071        Args:
4072            *expressions: the SQL code strings to parse.
4073                If an `Expression` instance is passed, it will be used as-is.
4074            append: if `True`, add to any existing expressions.
4075                Otherwise, this resets the expressions.
4076            dialect: the dialect used to parse the input expressions.
4077            copy: if `False`, modify this expression instance in-place.
4078            opts: other options to use to parse the input expressions.
4079
4080        Returns:
4081            The modified Select expression.
4082        """
4083        return _apply_list_builder(
4084            *expressions,
4085            instance=self,
4086            arg="laterals",
4087            append=append,
4088            into=Lateral,
4089            prefix="LATERAL VIEW",
4090            dialect=dialect,
4091            copy=copy,
4092            **opts,
4093        )
4094
4095    def join(
4096        self,
4097        expression: ExpOrStr,
4098        on: t.Optional[ExpOrStr] = None,
4099        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4100        append: bool = True,
4101        join_type: t.Optional[str] = None,
4102        join_alias: t.Optional[Identifier | str] = None,
4103        dialect: DialectType = None,
4104        copy: bool = True,
4105        **opts,
4106    ) -> Select:
4107        """
4108        Append to or set the JOIN expressions.
4109
4110        Example:
4111            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4112            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4113
4114            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4115            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4116
4117            Use `join_type` to change the type of join:
4118
4119            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4120            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4121
4122        Args:
4123            expression: the SQL code string to parse.
4124                If an `Expression` instance is passed, it will be used as-is.
4125            on: optionally specify the join "on" criteria as a SQL string.
4126                If an `Expression` instance is passed, it will be used as-is.
4127            using: optionally specify the join "using" criteria as a SQL string.
4128                If an `Expression` instance is passed, it will be used as-is.
4129            append: if `True`, add to any existing expressions.
4130                Otherwise, this resets the expressions.
4131            join_type: if set, alter the parsed join type.
4132            join_alias: an optional alias for the joined source.
4133            dialect: the dialect used to parse the input expressions.
4134            copy: if `False`, modify this expression instance in-place.
4135            opts: other options to use to parse the input expressions.
4136
4137        Returns:
4138            Select: the modified expression.
4139        """
4140        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4141
4142        try:
4143            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4144        except ParseError:
4145            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4146
4147        join = expression if isinstance(expression, Join) else Join(this=expression)
4148
4149        if isinstance(join.this, Select):
4150            join.this.replace(join.this.subquery())
4151
4152        if join_type:
4153            method: t.Optional[Token]
4154            side: t.Optional[Token]
4155            kind: t.Optional[Token]
4156
4157            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4158
4159            if method:
4160                join.set("method", method.text)
4161            if side:
4162                join.set("side", side.text)
4163            if kind:
4164                join.set("kind", kind.text)
4165
4166        if on:
4167            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4168            join.set("on", on)
4169
4170        if using:
4171            join = _apply_list_builder(
4172                *ensure_list(using),
4173                instance=join,
4174                arg="using",
4175                append=append,
4176                copy=copy,
4177                into=Identifier,
4178                **opts,
4179            )
4180
4181        if join_alias:
4182            join.set("this", alias_(join.this, join_alias, table=True))
4183
4184        return _apply_list_builder(
4185            join,
4186            instance=self,
4187            arg="joins",
4188            append=append,
4189            copy=copy,
4190            **opts,
4191        )
4192
4193    def having(
4194        self,
4195        *expressions: t.Optional[ExpOrStr],
4196        append: bool = True,
4197        dialect: DialectType = None,
4198        copy: bool = True,
4199        **opts,
4200    ) -> Select:
4201        """
4202        Append to or set the HAVING expressions.
4203
4204        Example:
4205            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4206            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4207
4208        Args:
4209            *expressions: the SQL code strings to parse.
4210                If an `Expression` instance is passed, it will be used as-is.
4211                Multiple expressions are combined with an AND operator.
4212            append: if `True`, AND the new expressions to any existing expression.
4213                Otherwise, this resets the expression.
4214            dialect: the dialect used to parse the input expressions.
4215            copy: if `False`, modify this expression instance in-place.
4216            opts: other options to use to parse the input expressions.
4217
4218        Returns:
4219            The modified Select expression.
4220        """
4221        return _apply_conjunction_builder(
4222            *expressions,
4223            instance=self,
4224            arg="having",
4225            append=append,
4226            into=Having,
4227            dialect=dialect,
4228            copy=copy,
4229            **opts,
4230        )
4231
4232    def window(
4233        self,
4234        *expressions: t.Optional[ExpOrStr],
4235        append: bool = True,
4236        dialect: DialectType = None,
4237        copy: bool = True,
4238        **opts,
4239    ) -> Select:
4240        return _apply_list_builder(
4241            *expressions,
4242            instance=self,
4243            arg="windows",
4244            append=append,
4245            into=Window,
4246            dialect=dialect,
4247            copy=copy,
4248            **opts,
4249        )
4250
4251    def qualify(
4252        self,
4253        *expressions: t.Optional[ExpOrStr],
4254        append: bool = True,
4255        dialect: DialectType = None,
4256        copy: bool = True,
4257        **opts,
4258    ) -> Select:
4259        return _apply_conjunction_builder(
4260            *expressions,
4261            instance=self,
4262            arg="qualify",
4263            append=append,
4264            into=Qualify,
4265            dialect=dialect,
4266            copy=copy,
4267            **opts,
4268        )
4269
4270    def distinct(
4271        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4272    ) -> Select:
4273        """
4274        Set the OFFSET expression.
4275
4276        Example:
4277            >>> Select().from_("tbl").select("x").distinct().sql()
4278            'SELECT DISTINCT x FROM tbl'
4279
4280        Args:
4281            ons: the expressions to distinct on
4282            distinct: whether the Select should be distinct
4283            copy: if `False`, modify this expression instance in-place.
4284
4285        Returns:
4286            Select: the modified expression.
4287        """
4288        instance = maybe_copy(self, copy)
4289        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4290        instance.set("distinct", Distinct(on=on) if distinct else None)
4291        return instance
4292
4293    def ctas(
4294        self,
4295        table: ExpOrStr,
4296        properties: t.Optional[t.Dict] = None,
4297        dialect: DialectType = None,
4298        copy: bool = True,
4299        **opts,
4300    ) -> Create:
4301        """
4302        Convert this expression to a CREATE TABLE AS statement.
4303
4304        Example:
4305            >>> Select().select("*").from_("tbl").ctas("x").sql()
4306            'CREATE TABLE x AS SELECT * FROM tbl'
4307
4308        Args:
4309            table: the SQL code string to parse as the table name.
4310                If another `Expression` instance is passed, it will be used as-is.
4311            properties: an optional mapping of table properties
4312            dialect: the dialect used to parse the input table.
4313            copy: if `False`, modify this expression instance in-place.
4314            opts: other options to use to parse the input table.
4315
4316        Returns:
4317            The new Create expression.
4318        """
4319        instance = maybe_copy(self, copy)
4320        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4321
4322        properties_expression = None
4323        if properties:
4324            properties_expression = Properties.from_dict(properties)
4325
4326        return Create(
4327            this=table_expression,
4328            kind="TABLE",
4329            expression=instance,
4330            properties=properties_expression,
4331        )
4332
4333    def lock(self, update: bool = True, copy: bool = True) -> Select:
4334        """
4335        Set the locking read mode for this expression.
4336
4337        Examples:
4338            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4339            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4340
4341            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4342            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4343
4344        Args:
4345            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4346            copy: if `False`, modify this expression instance in-place.
4347
4348        Returns:
4349            The modified expression.
4350        """
4351        inst = maybe_copy(self, copy)
4352        inst.set("locks", [Lock(update=update)])
4353
4354        return inst
4355
4356    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4357        """
4358        Set hints for this expression.
4359
4360        Examples:
4361            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4362            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4363
4364        Args:
4365            hints: The SQL code strings to parse as the hints.
4366                If an `Expression` instance is passed, it will be used as-is.
4367            dialect: The dialect used to parse the hints.
4368            copy: If `False`, modify this expression instance in-place.
4369
4370        Returns:
4371            The modified expression.
4372        """
4373        inst = maybe_copy(self, copy)
4374        inst.set(
4375            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4376        )
4377
4378        return inst
4379
4380    @property
4381    def named_selects(self) -> t.List[str]:
4382        selects = []
4383
4384        for e in self.expressions:
4385            if e.alias_or_name:
4386                selects.append(e.output_name)
4387            elif isinstance(e, Aliases):
4388                selects.extend([a.name for a in e.aliases])
4389        return selects
4390
4391    @property
4392    def is_star(self) -> bool:
4393        return any(expression.is_star for expression in self.expressions)
4394
4395    @property
4396    def selects(self) -> t.List[Expression]:
4397        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': False, 'operation_modifiers': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def from_( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3881    def from_(
3882        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3883    ) -> Select:
3884        """
3885        Set the FROM expression.
3886
3887        Example:
3888            >>> Select().from_("tbl").select("x").sql()
3889            'SELECT x FROM tbl'
3890
3891        Args:
3892            expression : the SQL code strings to parse.
3893                If a `From` instance is passed, this is used as-is.
3894                If another `Expression` instance is passed, it will be wrapped in a `From`.
3895            dialect: the dialect used to parse the input expression.
3896            copy: if `False`, modify this expression instance in-place.
3897            opts: other options to use to parse the input expressions.
3898
3899        Returns:
3900            The modified Select expression.
3901        """
3902        return _apply_builder(
3903            expression=expression,
3904            instance=self,
3905            arg="from",
3906            into=From,
3907            prefix="FROM",
3908            dialect=dialect,
3909            copy=copy,
3910            **opts,
3911        )

Set the FROM expression.

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

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3913    def group_by(
3914        self,
3915        *expressions: t.Optional[ExpOrStr],
3916        append: bool = True,
3917        dialect: DialectType = None,
3918        copy: bool = True,
3919        **opts,
3920    ) -> Select:
3921        """
3922        Set the GROUP BY expression.
3923
3924        Example:
3925            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3926            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3927
3928        Args:
3929            *expressions: the SQL code strings to parse.
3930                If a `Group` instance is passed, this is used as-is.
3931                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3932                If nothing is passed in then a group by is not applied to the expression
3933            append: if `True`, add to any existing expressions.
3934                Otherwise, this flattens all the `Group` expression into a single expression.
3935            dialect: the dialect used to parse the input expression.
3936            copy: if `False`, modify this expression instance in-place.
3937            opts: other options to use to parse the input expressions.
3938
3939        Returns:
3940            The modified Select expression.
3941        """
3942        if not expressions:
3943            return self if not copy else self.copy()
3944
3945        return _apply_child_list_builder(
3946            *expressions,
3947            instance=self,
3948            arg="group",
3949            append=append,
3950            copy=copy,
3951            prefix="GROUP BY",
3952            into=Group,
3953            dialect=dialect,
3954            **opts,
3955        )

Set the GROUP BY expression.

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

The modified Select expression.

def sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3957    def sort_by(
3958        self,
3959        *expressions: t.Optional[ExpOrStr],
3960        append: bool = True,
3961        dialect: DialectType = None,
3962        copy: bool = True,
3963        **opts,
3964    ) -> Select:
3965        """
3966        Set the SORT BY expression.
3967
3968        Example:
3969            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3970            'SELECT x FROM tbl SORT BY x DESC'
3971
3972        Args:
3973            *expressions: the SQL code strings to parse.
3974                If a `Group` instance is passed, this is used as-is.
3975                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3976            append: if `True`, add to any existing expressions.
3977                Otherwise, this flattens all the `Order` expression into a single expression.
3978            dialect: the dialect used to parse the input expression.
3979            copy: if `False`, modify this expression instance in-place.
3980            opts: other options to use to parse the input expressions.
3981
3982        Returns:
3983            The modified Select expression.
3984        """
3985        return _apply_child_list_builder(
3986            *expressions,
3987            instance=self,
3988            arg="sort",
3989            append=append,
3990            copy=copy,
3991            prefix="SORT BY",
3992            into=Sort,
3993            dialect=dialect,
3994            **opts,
3995        )

Set the SORT BY expression.

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

The modified Select expression.

def cluster_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3997    def cluster_by(
3998        self,
3999        *expressions: t.Optional[ExpOrStr],
4000        append: bool = True,
4001        dialect: DialectType = None,
4002        copy: bool = True,
4003        **opts,
4004    ) -> Select:
4005        """
4006        Set the CLUSTER BY expression.
4007
4008        Example:
4009            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
4010            'SELECT x FROM tbl CLUSTER BY x DESC'
4011
4012        Args:
4013            *expressions: the SQL code strings to parse.
4014                If a `Group` instance is passed, this is used as-is.
4015                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
4016            append: if `True`, add to any existing expressions.
4017                Otherwise, this flattens all the `Order` expression into a single expression.
4018            dialect: the dialect used to parse the input expression.
4019            copy: if `False`, modify this expression instance in-place.
4020            opts: other options to use to parse the input expressions.
4021
4022        Returns:
4023            The modified Select expression.
4024        """
4025        return _apply_child_list_builder(
4026            *expressions,
4027            instance=self,
4028            arg="cluster",
4029            append=append,
4030            copy=copy,
4031            prefix="CLUSTER BY",
4032            into=Cluster,
4033            dialect=dialect,
4034            **opts,
4035        )

Set the CLUSTER BY expression.

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

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4037    def select(
4038        self,
4039        *expressions: t.Optional[ExpOrStr],
4040        append: bool = True,
4041        dialect: DialectType = None,
4042        copy: bool = True,
4043        **opts,
4044    ) -> Select:
4045        return _apply_list_builder(
4046            *expressions,
4047            instance=self,
4048            arg="expressions",
4049            append=append,
4050            dialect=dialect,
4051            into=Expression,
4052            copy=copy,
4053            **opts,
4054        )

Append to or set the SELECT expressions.

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

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4056    def lateral(
4057        self,
4058        *expressions: t.Optional[ExpOrStr],
4059        append: bool = True,
4060        dialect: DialectType = None,
4061        copy: bool = True,
4062        **opts,
4063    ) -> Select:
4064        """
4065        Append to or set the LATERAL expressions.
4066
4067        Example:
4068            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
4069            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
4070
4071        Args:
4072            *expressions: the SQL code strings to parse.
4073                If an `Expression` instance is passed, it will be used as-is.
4074            append: if `True`, add to any existing expressions.
4075                Otherwise, this resets the expressions.
4076            dialect: the dialect used to parse the input expressions.
4077            copy: if `False`, modify this expression instance in-place.
4078            opts: other options to use to parse the input expressions.
4079
4080        Returns:
4081            The modified Select expression.
4082        """
4083        return _apply_list_builder(
4084            *expressions,
4085            instance=self,
4086            arg="laterals",
4087            append=append,
4088            into=Lateral,
4089            prefix="LATERAL VIEW",
4090            dialect=dialect,
4091            copy=copy,
4092            **opts,
4093        )

Append to or set the LATERAL expressions.

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

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4095    def join(
4096        self,
4097        expression: ExpOrStr,
4098        on: t.Optional[ExpOrStr] = None,
4099        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4100        append: bool = True,
4101        join_type: t.Optional[str] = None,
4102        join_alias: t.Optional[Identifier | str] = None,
4103        dialect: DialectType = None,
4104        copy: bool = True,
4105        **opts,
4106    ) -> Select:
4107        """
4108        Append to or set the JOIN expressions.
4109
4110        Example:
4111            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4112            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4113
4114            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4115            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4116
4117            Use `join_type` to change the type of join:
4118
4119            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4120            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4121
4122        Args:
4123            expression: the SQL code string to parse.
4124                If an `Expression` instance is passed, it will be used as-is.
4125            on: optionally specify the join "on" criteria as a SQL string.
4126                If an `Expression` instance is passed, it will be used as-is.
4127            using: optionally specify the join "using" criteria as a SQL string.
4128                If an `Expression` instance is passed, it will be used as-is.
4129            append: if `True`, add to any existing expressions.
4130                Otherwise, this resets the expressions.
4131            join_type: if set, alter the parsed join type.
4132            join_alias: an optional alias for the joined source.
4133            dialect: the dialect used to parse the input expressions.
4134            copy: if `False`, modify this expression instance in-place.
4135            opts: other options to use to parse the input expressions.
4136
4137        Returns:
4138            Select: the modified expression.
4139        """
4140        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4141
4142        try:
4143            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4144        except ParseError:
4145            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4146
4147        join = expression if isinstance(expression, Join) else Join(this=expression)
4148
4149        if isinstance(join.this, Select):
4150            join.this.replace(join.this.subquery())
4151
4152        if join_type:
4153            method: t.Optional[Token]
4154            side: t.Optional[Token]
4155            kind: t.Optional[Token]
4156
4157            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4158
4159            if method:
4160                join.set("method", method.text)
4161            if side:
4162                join.set("side", side.text)
4163            if kind:
4164                join.set("kind", kind.text)
4165
4166        if on:
4167            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4168            join.set("on", on)
4169
4170        if using:
4171            join = _apply_list_builder(
4172                *ensure_list(using),
4173                instance=join,
4174                arg="using",
4175                append=append,
4176                copy=copy,
4177                into=Identifier,
4178                **opts,
4179            )
4180
4181        if join_alias:
4182            join.set("this", alias_(join.this, join_alias, table=True))
4183
4184        return _apply_list_builder(
4185            join,
4186            instance=self,
4187            arg="joins",
4188            append=append,
4189            copy=copy,
4190            **opts,
4191        )

Append to or set the JOIN expressions.

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

Use join_type to change the type of join:

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

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4193    def having(
4194        self,
4195        *expressions: t.Optional[ExpOrStr],
4196        append: bool = True,
4197        dialect: DialectType = None,
4198        copy: bool = True,
4199        **opts,
4200    ) -> Select:
4201        """
4202        Append to or set the HAVING expressions.
4203
4204        Example:
4205            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4206            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4207
4208        Args:
4209            *expressions: the SQL code strings to parse.
4210                If an `Expression` instance is passed, it will be used as-is.
4211                Multiple expressions are combined with an AND operator.
4212            append: if `True`, AND the new expressions to any existing expression.
4213                Otherwise, this resets the expression.
4214            dialect: the dialect used to parse the input expressions.
4215            copy: if `False`, modify this expression instance in-place.
4216            opts: other options to use to parse the input expressions.
4217
4218        Returns:
4219            The modified Select expression.
4220        """
4221        return _apply_conjunction_builder(
4222            *expressions,
4223            instance=self,
4224            arg="having",
4225            append=append,
4226            into=Having,
4227            dialect=dialect,
4228            copy=copy,
4229            **opts,
4230        )

Append to or set the HAVING expressions.

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

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4232    def window(
4233        self,
4234        *expressions: t.Optional[ExpOrStr],
4235        append: bool = True,
4236        dialect: DialectType = None,
4237        copy: bool = True,
4238        **opts,
4239    ) -> Select:
4240        return _apply_list_builder(
4241            *expressions,
4242            instance=self,
4243            arg="windows",
4244            append=append,
4245            into=Window,
4246            dialect=dialect,
4247            copy=copy,
4248            **opts,
4249        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4251    def qualify(
4252        self,
4253        *expressions: t.Optional[ExpOrStr],
4254        append: bool = True,
4255        dialect: DialectType = None,
4256        copy: bool = True,
4257        **opts,
4258    ) -> Select:
4259        return _apply_conjunction_builder(
4260            *expressions,
4261            instance=self,
4262            arg="qualify",
4263            append=append,
4264            into=Qualify,
4265            dialect=dialect,
4266            copy=copy,
4267            **opts,
4268        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4270    def distinct(
4271        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4272    ) -> Select:
4273        """
4274        Set the OFFSET expression.
4275
4276        Example:
4277            >>> Select().from_("tbl").select("x").distinct().sql()
4278            'SELECT DISTINCT x FROM tbl'
4279
4280        Args:
4281            ons: the expressions to distinct on
4282            distinct: whether the Select should be distinct
4283            copy: if `False`, modify this expression instance in-place.
4284
4285        Returns:
4286            Select: the modified expression.
4287        """
4288        instance = maybe_copy(self, copy)
4289        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4290        instance.set("distinct", Distinct(on=on) if distinct else None)
4291        return instance

Set the OFFSET expression.

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

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4293    def ctas(
4294        self,
4295        table: ExpOrStr,
4296        properties: t.Optional[t.Dict] = None,
4297        dialect: DialectType = None,
4298        copy: bool = True,
4299        **opts,
4300    ) -> Create:
4301        """
4302        Convert this expression to a CREATE TABLE AS statement.
4303
4304        Example:
4305            >>> Select().select("*").from_("tbl").ctas("x").sql()
4306            'CREATE TABLE x AS SELECT * FROM tbl'
4307
4308        Args:
4309            table: the SQL code string to parse as the table name.
4310                If another `Expression` instance is passed, it will be used as-is.
4311            properties: an optional mapping of table properties
4312            dialect: the dialect used to parse the input table.
4313            copy: if `False`, modify this expression instance in-place.
4314            opts: other options to use to parse the input table.
4315
4316        Returns:
4317            The new Create expression.
4318        """
4319        instance = maybe_copy(self, copy)
4320        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4321
4322        properties_expression = None
4323        if properties:
4324            properties_expression = Properties.from_dict(properties)
4325
4326        return Create(
4327            this=table_expression,
4328            kind="TABLE",
4329            expression=instance,
4330            properties=properties_expression,
4331        )

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:
4333    def lock(self, update: bool = True, copy: bool = True) -> Select:
4334        """
4335        Set the locking read mode for this expression.
4336
4337        Examples:
4338            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4339            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4340
4341            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4342            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4343
4344        Args:
4345            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4346            copy: if `False`, modify this expression instance in-place.
4347
4348        Returns:
4349            The modified expression.
4350        """
4351        inst = maybe_copy(self, copy)
4352        inst.set("locks", [Lock(update=update)])
4353
4354        return inst

Set the locking read mode for this expression.

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

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Select:
4356    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4357        """
4358        Set hints for this expression.
4359
4360        Examples:
4361            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4362            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4363
4364        Args:
4365            hints: The SQL code strings to parse as the hints.
4366                If an `Expression` instance is passed, it will be used as-is.
4367            dialect: The dialect used to parse the hints.
4368            copy: If `False`, modify this expression instance in-place.
4369
4370        Returns:
4371            The modified expression.
4372        """
4373        inst = maybe_copy(self, copy)
4374        inst.set(
4375            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4376        )
4377
4378        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]
4380    @property
4381    def named_selects(self) -> t.List[str]:
4382        selects = []
4383
4384        for e in self.expressions:
4385            if e.alias_or_name:
4386                selects.append(e.output_name)
4387            elif isinstance(e, Aliases):
4388                selects.extend([a.name for a in e.aliases])
4389        return selects

Returns the output names of the query's projections.

is_star: bool
4391    @property
4392    def is_star(self) -> bool:
4393        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4395    @property
4396    def selects(self) -> t.List[Expression]:
4397        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4403class Subquery(DerivedTable, Query):
4404    arg_types = {
4405        "this": True,
4406        "alias": False,
4407        "with": False,
4408        **QUERY_MODIFIERS,
4409    }
4410
4411    def unnest(self):
4412        """Returns the first non subquery."""
4413        expression = self
4414        while isinstance(expression, Subquery):
4415            expression = expression.this
4416        return expression
4417
4418    def unwrap(self) -> Subquery:
4419        expression = self
4420        while expression.same_parent and expression.is_wrapper:
4421            expression = t.cast(Subquery, expression.parent)
4422        return expression
4423
4424    def select(
4425        self,
4426        *expressions: t.Optional[ExpOrStr],
4427        append: bool = True,
4428        dialect: DialectType = None,
4429        copy: bool = True,
4430        **opts,
4431    ) -> Subquery:
4432        this = maybe_copy(self, copy)
4433        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4434        return this
4435
4436    @property
4437    def is_wrapper(self) -> bool:
4438        """
4439        Whether this Subquery acts as a simple wrapper around another expression.
4440
4441        SELECT * FROM (((SELECT * FROM t)))
4442                      ^
4443                      This corresponds to a "wrapper" Subquery node
4444        """
4445        return all(v is None for k, v in self.args.items() if k != "this")
4446
4447    @property
4448    def is_star(self) -> bool:
4449        return self.this.is_star
4450
4451    @property
4452    def output_name(self) -> str:
4453        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):
4411    def unnest(self):
4412        """Returns the first non subquery."""
4413        expression = self
4414        while isinstance(expression, Subquery):
4415            expression = expression.this
4416        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4418    def unwrap(self) -> Subquery:
4419        expression = self
4420        while expression.same_parent and expression.is_wrapper:
4421            expression = t.cast(Subquery, expression.parent)
4422        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4424    def select(
4425        self,
4426        *expressions: t.Optional[ExpOrStr],
4427        append: bool = True,
4428        dialect: DialectType = None,
4429        copy: bool = True,
4430        **opts,
4431    ) -> Subquery:
4432        this = maybe_copy(self, copy)
4433        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4434        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
4436    @property
4437    def is_wrapper(self) -> bool:
4438        """
4439        Whether this Subquery acts as a simple wrapper around another expression.
4440
4441        SELECT * FROM (((SELECT * FROM t)))
4442                      ^
4443                      This corresponds to a "wrapper" Subquery node
4444        """
4445        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
4447    @property
4448    def is_star(self) -> bool:
4449        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4451    @property
4452    def output_name(self) -> str:
4453        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):
4456class TableSample(Expression):
4457    arg_types = {
4458        "expressions": False,
4459        "method": False,
4460        "bucket_numerator": False,
4461        "bucket_denominator": False,
4462        "bucket_field": False,
4463        "percent": False,
4464        "rows": False,
4465        "size": False,
4466        "seed": False,
4467    }
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):
4470class Tag(Expression):
4471    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4472
4473    arg_types = {
4474        "this": False,
4475        "prefix": False,
4476        "postfix": False,
4477    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4482class Pivot(Expression):
4483    arg_types = {
4484        "this": False,
4485        "alias": False,
4486        "expressions": False,
4487        "fields": False,
4488        "unpivot": False,
4489        "using": False,
4490        "group": False,
4491        "columns": False,
4492        "include_nulls": False,
4493        "default_on_null": False,
4494        "into": False,
4495    }
4496
4497    @property
4498    def unpivot(self) -> bool:
4499        return bool(self.args.get("unpivot"))
4500
4501    @property
4502    def fields(self) -> t.List[Expression]:
4503        return self.args.get("fields", [])
arg_types = {'this': False, 'alias': False, 'expressions': False, 'fields': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4497    @property
4498    def unpivot(self) -> bool:
4499        return bool(self.args.get("unpivot"))
fields: List[Expression]
4501    @property
4502    def fields(self) -> t.List[Expression]:
4503        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4508class UnpivotColumns(Expression):
4509    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4512class Window(Condition):
4513    arg_types = {
4514        "this": True,
4515        "partition_by": False,
4516        "order": False,
4517        "spec": False,
4518        "alias": False,
4519        "over": False,
4520        "first": False,
4521    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4524class WindowSpec(Expression):
4525    arg_types = {
4526        "kind": False,
4527        "start": False,
4528        "start_side": False,
4529        "end": False,
4530        "end_side": False,
4531        "exclude": False,
4532    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4535class PreWhere(Expression):
4536    pass
key = 'prewhere'
class Where(Expression):
4539class Where(Expression):
4540    pass
key = 'where'
class Star(Expression):
4543class Star(Expression):
4544    arg_types = {"except": False, "replace": False, "rename": False}
4545
4546    @property
4547    def name(self) -> str:
4548        return "*"
4549
4550    @property
4551    def output_name(self) -> str:
4552        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4546    @property
4547    def name(self) -> str:
4548        return "*"
output_name: str
4550    @property
4551    def output_name(self) -> str:
4552        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):
4555class Parameter(Condition):
4556    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4559class SessionParameter(Condition):
4560    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4565class Placeholder(Condition):
4566    arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
4567
4568    @property
4569    def name(self) -> str:
4570        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False, 'jdbc': False}
name: str
4568    @property
4569    def name(self) -> str:
4570        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4573class Null(Condition):
4574    arg_types: t.Dict[str, t.Any] = {}
4575
4576    @property
4577    def name(self) -> str:
4578        return "NULL"
4579
4580    def to_py(self) -> Lit[None]:
4581        return None
arg_types: Dict[str, Any] = {}
name: str
4576    @property
4577    def name(self) -> str:
4578        return "NULL"
def to_py(self) -> Literal[None]:
4580    def to_py(self) -> Lit[None]:
4581        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4584class Boolean(Condition):
4585    def to_py(self) -> bool:
4586        return self.this
def to_py(self) -> bool:
4585    def to_py(self) -> bool:
4586        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4589class DataTypeParam(Expression):
4590    arg_types = {"this": True, "expression": False}
4591
4592    @property
4593    def name(self) -> str:
4594        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4592    @property
4593    def name(self) -> str:
4594        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4599class DataType(Expression):
4600    arg_types = {
4601        "this": True,
4602        "expressions": False,
4603        "nested": False,
4604        "values": False,
4605        "prefix": False,
4606        "kind": False,
4607        "nullable": False,
4608    }
4609
4610    class Type(AutoName):
4611        ARRAY = auto()
4612        AGGREGATEFUNCTION = auto()
4613        SIMPLEAGGREGATEFUNCTION = auto()
4614        BIGDECIMAL = auto()
4615        BIGINT = auto()
4616        BIGSERIAL = auto()
4617        BINARY = auto()
4618        BIT = auto()
4619        BLOB = auto()
4620        BOOLEAN = auto()
4621        BPCHAR = auto()
4622        CHAR = auto()
4623        DATE = auto()
4624        DATE32 = auto()
4625        DATEMULTIRANGE = auto()
4626        DATERANGE = auto()
4627        DATETIME = auto()
4628        DATETIME2 = auto()
4629        DATETIME64 = auto()
4630        DECIMAL = auto()
4631        DECIMAL32 = auto()
4632        DECIMAL64 = auto()
4633        DECIMAL128 = auto()
4634        DECIMAL256 = auto()
4635        DOUBLE = auto()
4636        DYNAMIC = auto()
4637        ENUM = auto()
4638        ENUM8 = auto()
4639        ENUM16 = auto()
4640        FIXEDSTRING = auto()
4641        FLOAT = auto()
4642        GEOGRAPHY = auto()
4643        GEOGRAPHYPOINT = auto()
4644        GEOMETRY = auto()
4645        POINT = auto()
4646        RING = auto()
4647        LINESTRING = auto()
4648        MULTILINESTRING = auto()
4649        POLYGON = auto()
4650        MULTIPOLYGON = auto()
4651        HLLSKETCH = auto()
4652        HSTORE = auto()
4653        IMAGE = auto()
4654        INET = auto()
4655        INT = auto()
4656        INT128 = auto()
4657        INT256 = auto()
4658        INT4MULTIRANGE = auto()
4659        INT4RANGE = auto()
4660        INT8MULTIRANGE = auto()
4661        INT8RANGE = auto()
4662        INTERVAL = auto()
4663        IPADDRESS = auto()
4664        IPPREFIX = auto()
4665        IPV4 = auto()
4666        IPV6 = auto()
4667        JSON = auto()
4668        JSONB = auto()
4669        LIST = auto()
4670        LONGBLOB = auto()
4671        LONGTEXT = auto()
4672        LOWCARDINALITY = auto()
4673        MAP = auto()
4674        MEDIUMBLOB = auto()
4675        MEDIUMINT = auto()
4676        MEDIUMTEXT = auto()
4677        MONEY = auto()
4678        NAME = auto()
4679        NCHAR = auto()
4680        NESTED = auto()
4681        NOTHING = auto()
4682        NULL = auto()
4683        NUMMULTIRANGE = auto()
4684        NUMRANGE = auto()
4685        NVARCHAR = auto()
4686        OBJECT = auto()
4687        RANGE = auto()
4688        ROWVERSION = auto()
4689        SERIAL = auto()
4690        SET = auto()
4691        SMALLDATETIME = auto()
4692        SMALLINT = auto()
4693        SMALLMONEY = auto()
4694        SMALLSERIAL = auto()
4695        STRUCT = auto()
4696        SUPER = auto()
4697        TEXT = auto()
4698        TINYBLOB = auto()
4699        TINYTEXT = auto()
4700        TIME = auto()
4701        TIMETZ = auto()
4702        TIMESTAMP = auto()
4703        TIMESTAMPNTZ = auto()
4704        TIMESTAMPLTZ = auto()
4705        TIMESTAMPTZ = auto()
4706        TIMESTAMP_S = auto()
4707        TIMESTAMP_MS = auto()
4708        TIMESTAMP_NS = auto()
4709        TINYINT = auto()
4710        TSMULTIRANGE = auto()
4711        TSRANGE = auto()
4712        TSTZMULTIRANGE = auto()
4713        TSTZRANGE = auto()
4714        UBIGINT = auto()
4715        UINT = auto()
4716        UINT128 = auto()
4717        UINT256 = auto()
4718        UMEDIUMINT = auto()
4719        UDECIMAL = auto()
4720        UDOUBLE = auto()
4721        UNION = auto()
4722        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4723        USERDEFINED = "USER-DEFINED"
4724        USMALLINT = auto()
4725        UTINYINT = auto()
4726        UUID = auto()
4727        VARBINARY = auto()
4728        VARCHAR = auto()
4729        VARIANT = auto()
4730        VECTOR = auto()
4731        XML = auto()
4732        YEAR = auto()
4733        TDIGEST = auto()
4734
4735    STRUCT_TYPES = {
4736        Type.NESTED,
4737        Type.OBJECT,
4738        Type.STRUCT,
4739        Type.UNION,
4740    }
4741
4742    ARRAY_TYPES = {
4743        Type.ARRAY,
4744        Type.LIST,
4745    }
4746
4747    NESTED_TYPES = {
4748        *STRUCT_TYPES,
4749        *ARRAY_TYPES,
4750        Type.MAP,
4751    }
4752
4753    TEXT_TYPES = {
4754        Type.CHAR,
4755        Type.NCHAR,
4756        Type.NVARCHAR,
4757        Type.TEXT,
4758        Type.VARCHAR,
4759        Type.NAME,
4760    }
4761
4762    SIGNED_INTEGER_TYPES = {
4763        Type.BIGINT,
4764        Type.INT,
4765        Type.INT128,
4766        Type.INT256,
4767        Type.MEDIUMINT,
4768        Type.SMALLINT,
4769        Type.TINYINT,
4770    }
4771
4772    UNSIGNED_INTEGER_TYPES = {
4773        Type.UBIGINT,
4774        Type.UINT,
4775        Type.UINT128,
4776        Type.UINT256,
4777        Type.UMEDIUMINT,
4778        Type.USMALLINT,
4779        Type.UTINYINT,
4780    }
4781
4782    INTEGER_TYPES = {
4783        *SIGNED_INTEGER_TYPES,
4784        *UNSIGNED_INTEGER_TYPES,
4785        Type.BIT,
4786    }
4787
4788    FLOAT_TYPES = {
4789        Type.DOUBLE,
4790        Type.FLOAT,
4791    }
4792
4793    REAL_TYPES = {
4794        *FLOAT_TYPES,
4795        Type.BIGDECIMAL,
4796        Type.DECIMAL,
4797        Type.DECIMAL32,
4798        Type.DECIMAL64,
4799        Type.DECIMAL128,
4800        Type.DECIMAL256,
4801        Type.MONEY,
4802        Type.SMALLMONEY,
4803        Type.UDECIMAL,
4804        Type.UDOUBLE,
4805    }
4806
4807    NUMERIC_TYPES = {
4808        *INTEGER_TYPES,
4809        *REAL_TYPES,
4810    }
4811
4812    TEMPORAL_TYPES = {
4813        Type.DATE,
4814        Type.DATE32,
4815        Type.DATETIME,
4816        Type.DATETIME2,
4817        Type.DATETIME64,
4818        Type.SMALLDATETIME,
4819        Type.TIME,
4820        Type.TIMESTAMP,
4821        Type.TIMESTAMPNTZ,
4822        Type.TIMESTAMPLTZ,
4823        Type.TIMESTAMPTZ,
4824        Type.TIMESTAMP_MS,
4825        Type.TIMESTAMP_NS,
4826        Type.TIMESTAMP_S,
4827        Type.TIMETZ,
4828    }
4829
4830    @classmethod
4831    def build(
4832        cls,
4833        dtype: DATA_TYPE,
4834        dialect: DialectType = None,
4835        udt: bool = False,
4836        copy: bool = True,
4837        **kwargs,
4838    ) -> DataType:
4839        """
4840        Constructs a DataType object.
4841
4842        Args:
4843            dtype: the data type of interest.
4844            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4845            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4846                DataType, thus creating a user-defined type.
4847            copy: whether to copy the data type.
4848            kwargs: additional arguments to pass in the constructor of DataType.
4849
4850        Returns:
4851            The constructed DataType object.
4852        """
4853        from sqlglot import parse_one
4854
4855        if isinstance(dtype, str):
4856            if dtype.upper() == "UNKNOWN":
4857                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4858
4859            try:
4860                data_type_exp = parse_one(
4861                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4862                )
4863            except ParseError:
4864                if udt:
4865                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4866                raise
4867        elif isinstance(dtype, (Identifier, Dot)) and udt:
4868            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4869        elif isinstance(dtype, DataType.Type):
4870            data_type_exp = DataType(this=dtype)
4871        elif isinstance(dtype, DataType):
4872            return maybe_copy(dtype, copy)
4873        else:
4874            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4875
4876        return DataType(**{**data_type_exp.args, **kwargs})
4877
4878    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4879        """
4880        Checks whether this DataType matches one of the provided data types. Nested types or precision
4881        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4882
4883        Args:
4884            dtypes: the data types to compare this DataType to.
4885            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4886                If false, it means that NULLABLE<INT> is equivalent to INT.
4887
4888        Returns:
4889            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4890        """
4891        self_is_nullable = self.args.get("nullable")
4892        for dtype in dtypes:
4893            other_type = DataType.build(dtype, copy=False, udt=True)
4894            other_is_nullable = other_type.args.get("nullable")
4895            if (
4896                other_type.expressions
4897                or (check_nullable and (self_is_nullable or other_is_nullable))
4898                or self.this == DataType.Type.USERDEFINED
4899                or other_type.this == DataType.Type.USERDEFINED
4900            ):
4901                matches = self == other_type
4902            else:
4903                matches = self.this == other_type.this
4904
4905            if matches:
4906                return True
4907        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.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>}
ARRAY_TYPES = {<Type.LIST: 'LIST'>, <Type.ARRAY: 'ARRAY'>}
NESTED_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>, <Type.MAP: 'MAP'>, <Type.LIST: 'LIST'>, <Type.OBJECT: 'OBJECT'>, <Type.ARRAY: 'ARRAY'>}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>}
SIGNED_INTEGER_TYPES = {<Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT256: 'UINT256'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT128: 'INT128'>, <Type.UINT256: 'UINT256'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.MONEY: 'MONEY'>}
NUMERIC_TYPES = {<Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT256: 'INT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.INT: 'INT'>, <Type.FLOAT: 'FLOAT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.BIGINT: 'BIGINT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.UBIGINT: 'UBIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.UINT256: 'UINT256'>, <Type.MONEY: 'MONEY'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME2: 'DATETIME2'>}
@classmethod
def build( cls, dtype: Union[str, Identifier, Dot, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4830    @classmethod
4831    def build(
4832        cls,
4833        dtype: DATA_TYPE,
4834        dialect: DialectType = None,
4835        udt: bool = False,
4836        copy: bool = True,
4837        **kwargs,
4838    ) -> DataType:
4839        """
4840        Constructs a DataType object.
4841
4842        Args:
4843            dtype: the data type of interest.
4844            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4845            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4846                DataType, thus creating a user-defined type.
4847            copy: whether to copy the data type.
4848            kwargs: additional arguments to pass in the constructor of DataType.
4849
4850        Returns:
4851            The constructed DataType object.
4852        """
4853        from sqlglot import parse_one
4854
4855        if isinstance(dtype, str):
4856            if dtype.upper() == "UNKNOWN":
4857                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4858
4859            try:
4860                data_type_exp = parse_one(
4861                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4862                )
4863            except ParseError:
4864                if udt:
4865                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4866                raise
4867        elif isinstance(dtype, (Identifier, Dot)) and udt:
4868            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4869        elif isinstance(dtype, DataType.Type):
4870            data_type_exp = DataType(this=dtype)
4871        elif isinstance(dtype, DataType):
4872            return maybe_copy(dtype, copy)
4873        else:
4874            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4875
4876        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

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

The constructed DataType object.

def is_type( self, *dtypes: Union[str, Identifier, Dot, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4878    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4879        """
4880        Checks whether this DataType matches one of the provided data types. Nested types or precision
4881        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4882
4883        Args:
4884            dtypes: the data types to compare this DataType to.
4885            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4886                If false, it means that NULLABLE<INT> is equivalent to INT.
4887
4888        Returns:
4889            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4890        """
4891        self_is_nullable = self.args.get("nullable")
4892        for dtype in dtypes:
4893            other_type = DataType.build(dtype, copy=False, udt=True)
4894            other_is_nullable = other_type.args.get("nullable")
4895            if (
4896                other_type.expressions
4897                or (check_nullable and (self_is_nullable or other_is_nullable))
4898                or self.this == DataType.Type.USERDEFINED
4899                or other_type.this == DataType.Type.USERDEFINED
4900            ):
4901                matches = self == other_type
4902            else:
4903                matches = self.this == other_type.this
4904
4905            if matches:
4906                return True
4907        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):
4610    class Type(AutoName):
4611        ARRAY = auto()
4612        AGGREGATEFUNCTION = auto()
4613        SIMPLEAGGREGATEFUNCTION = auto()
4614        BIGDECIMAL = auto()
4615        BIGINT = auto()
4616        BIGSERIAL = auto()
4617        BINARY = auto()
4618        BIT = auto()
4619        BLOB = auto()
4620        BOOLEAN = auto()
4621        BPCHAR = auto()
4622        CHAR = auto()
4623        DATE = auto()
4624        DATE32 = auto()
4625        DATEMULTIRANGE = auto()
4626        DATERANGE = auto()
4627        DATETIME = auto()
4628        DATETIME2 = auto()
4629        DATETIME64 = auto()
4630        DECIMAL = auto()
4631        DECIMAL32 = auto()
4632        DECIMAL64 = auto()
4633        DECIMAL128 = auto()
4634        DECIMAL256 = auto()
4635        DOUBLE = auto()
4636        DYNAMIC = auto()
4637        ENUM = auto()
4638        ENUM8 = auto()
4639        ENUM16 = auto()
4640        FIXEDSTRING = auto()
4641        FLOAT = auto()
4642        GEOGRAPHY = auto()
4643        GEOGRAPHYPOINT = auto()
4644        GEOMETRY = auto()
4645        POINT = auto()
4646        RING = auto()
4647        LINESTRING = auto()
4648        MULTILINESTRING = auto()
4649        POLYGON = auto()
4650        MULTIPOLYGON = auto()
4651        HLLSKETCH = auto()
4652        HSTORE = auto()
4653        IMAGE = auto()
4654        INET = auto()
4655        INT = auto()
4656        INT128 = auto()
4657        INT256 = auto()
4658        INT4MULTIRANGE = auto()
4659        INT4RANGE = auto()
4660        INT8MULTIRANGE = auto()
4661        INT8RANGE = auto()
4662        INTERVAL = auto()
4663        IPADDRESS = auto()
4664        IPPREFIX = auto()
4665        IPV4 = auto()
4666        IPV6 = auto()
4667        JSON = auto()
4668        JSONB = auto()
4669        LIST = auto()
4670        LONGBLOB = auto()
4671        LONGTEXT = auto()
4672        LOWCARDINALITY = auto()
4673        MAP = auto()
4674        MEDIUMBLOB = auto()
4675        MEDIUMINT = auto()
4676        MEDIUMTEXT = auto()
4677        MONEY = auto()
4678        NAME = auto()
4679        NCHAR = auto()
4680        NESTED = auto()
4681        NOTHING = auto()
4682        NULL = auto()
4683        NUMMULTIRANGE = auto()
4684        NUMRANGE = auto()
4685        NVARCHAR = auto()
4686        OBJECT = auto()
4687        RANGE = auto()
4688        ROWVERSION = auto()
4689        SERIAL = auto()
4690        SET = auto()
4691        SMALLDATETIME = auto()
4692        SMALLINT = auto()
4693        SMALLMONEY = auto()
4694        SMALLSERIAL = auto()
4695        STRUCT = auto()
4696        SUPER = auto()
4697        TEXT = auto()
4698        TINYBLOB = auto()
4699        TINYTEXT = auto()
4700        TIME = auto()
4701        TIMETZ = auto()
4702        TIMESTAMP = auto()
4703        TIMESTAMPNTZ = auto()
4704        TIMESTAMPLTZ = auto()
4705        TIMESTAMPTZ = auto()
4706        TIMESTAMP_S = auto()
4707        TIMESTAMP_MS = auto()
4708        TIMESTAMP_NS = auto()
4709        TINYINT = auto()
4710        TSMULTIRANGE = auto()
4711        TSRANGE = auto()
4712        TSTZMULTIRANGE = auto()
4713        TSTZRANGE = auto()
4714        UBIGINT = auto()
4715        UINT = auto()
4716        UINT128 = auto()
4717        UINT256 = auto()
4718        UMEDIUMINT = auto()
4719        UDECIMAL = auto()
4720        UDOUBLE = auto()
4721        UNION = auto()
4722        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4723        USERDEFINED = "USER-DEFINED"
4724        USMALLINT = auto()
4725        UTINYINT = auto()
4726        UUID = auto()
4727        VARBINARY = auto()
4728        VARCHAR = auto()
4729        VARIANT = auto()
4730        VECTOR = auto()
4731        XML = auto()
4732        YEAR = auto()
4733        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BLOB = <Type.BLOB: 'BLOB'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME2 = <Type.DATETIME2: 'DATETIME2'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
DYNAMIC = <Type.DYNAMIC: 'DYNAMIC'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOGRAPHYPOINT = <Type.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NOTHING = <Type.NOTHING: 'NOTHING'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
class PseudoType(DataType):
4911class PseudoType(DataType):
4912    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4916class ObjectIdentifier(DataType):
4917    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4921class SubqueryPredicate(Predicate):
4922    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4925class All(SubqueryPredicate):
4926    pass
key = 'all'
class Any(SubqueryPredicate):
4929class Any(SubqueryPredicate):
4930    pass
key = 'any'
class Command(Expression):
4935class Command(Expression):
4936    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4939class Transaction(Expression):
4940    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4943class Commit(Expression):
4944    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4947class Rollback(Expression):
4948    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4951class Alter(Expression):
4952    arg_types = {
4953        "this": False,
4954        "kind": True,
4955        "actions": True,
4956        "exists": False,
4957        "only": False,
4958        "options": False,
4959        "cluster": False,
4960        "not_valid": False,
4961        "check": False,
4962        "cascade": False,
4963    }
4964
4965    @property
4966    def kind(self) -> t.Optional[str]:
4967        kind = self.args.get("kind")
4968        return kind and kind.upper()
4969
4970    @property
4971    def actions(self) -> t.List[Expression]:
4972        return self.args.get("actions") or []
arg_types = {'this': False, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False, 'check': False, 'cascade': False}
kind: Optional[str]
4965    @property
4966    def kind(self) -> t.Optional[str]:
4967        kind = self.args.get("kind")
4968        return kind and kind.upper()
actions: List[Expression]
4970    @property
4971    def actions(self) -> t.List[Expression]:
4972        return self.args.get("actions") or []
key = 'alter'
class AlterSession(Expression):
4975class AlterSession(Expression):
4976    arg_types = {"expressions": True, "unset": False}
arg_types = {'expressions': True, 'unset': False}
key = 'altersession'
class Analyze(Expression):
4979class Analyze(Expression):
4980    arg_types = {
4981        "kind": False,
4982        "this": False,
4983        "options": False,
4984        "mode": False,
4985        "partition": False,
4986        "expression": False,
4987        "properties": False,
4988    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4991class AnalyzeStatistics(Expression):
4992    arg_types = {
4993        "kind": True,
4994        "option": False,
4995        "this": False,
4996        "expressions": False,
4997    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
5000class AnalyzeHistogram(Expression):
5001    arg_types = {
5002        "this": True,
5003        "expressions": True,
5004        "expression": False,
5005        "update_options": False,
5006    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
5009class AnalyzeSample(Expression):
5010    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
5013class AnalyzeListChainedRows(Expression):
5014    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
5017class AnalyzeDelete(Expression):
5018    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
5021class AnalyzeWith(Expression):
5022    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
5025class AnalyzeValidate(Expression):
5026    arg_types = {
5027        "kind": True,
5028        "this": False,
5029        "expression": False,
5030    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
5033class AnalyzeColumns(Expression):
5034    pass
key = 'analyzecolumns'
class UsingData(Expression):
5037class UsingData(Expression):
5038    pass
key = 'usingdata'
class AddConstraint(Expression):
5041class AddConstraint(Expression):
5042    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AddPartition(Expression):
5045class AddPartition(Expression):
5046    arg_types = {"this": True, "exists": False, "location": False}
arg_types = {'this': True, 'exists': False, 'location': False}
key = 'addpartition'
class AttachOption(Expression):
5049class AttachOption(Expression):
5050    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
5053class DropPartition(Expression):
5054    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
5058class ReplacePartition(Expression):
5059    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
5063class Binary(Condition):
5064    arg_types = {"this": True, "expression": True}
5065
5066    @property
5067    def left(self) -> Expression:
5068        return self.this
5069
5070    @property
5071    def right(self) -> Expression:
5072        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
5066    @property
5067    def left(self) -> Expression:
5068        return self.this
right: Expression
5070    @property
5071    def right(self) -> Expression:
5072        return self.expression
key = 'binary'
class Add(Binary):
5075class Add(Binary):
5076    pass
key = 'add'
class Connector(Binary):
5079class Connector(Binary):
5080    pass
key = 'connector'
class BitwiseAnd(Binary):
5083class BitwiseAnd(Binary):
5084    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
5087class BitwiseLeftShift(Binary):
5088    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
5091class BitwiseOr(Binary):
5092    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
5095class BitwiseRightShift(Binary):
5096    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
5099class BitwiseXor(Binary):
5100    pass
key = 'bitwisexor'
class Div(Binary):
5103class Div(Binary):
5104    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):
5107class Overlaps(Binary):
5108    pass
key = 'overlaps'
class Dot(Binary):
5111class Dot(Binary):
5112    @property
5113    def is_star(self) -> bool:
5114        return self.expression.is_star
5115
5116    @property
5117    def name(self) -> str:
5118        return self.expression.name
5119
5120    @property
5121    def output_name(self) -> str:
5122        return self.name
5123
5124    @classmethod
5125    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5126        """Build a Dot object with a sequence of expressions."""
5127        if len(expressions) < 2:
5128            raise ValueError("Dot requires >= 2 expressions.")
5129
5130        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5131
5132    @property
5133    def parts(self) -> t.List[Expression]:
5134        """Return the parts of a table / column in order catalog, db, table."""
5135        this, *parts = self.flatten()
5136
5137        parts.reverse()
5138
5139        for arg in COLUMN_PARTS:
5140            part = this.args.get(arg)
5141
5142            if isinstance(part, Expression):
5143                parts.append(part)
5144
5145        parts.reverse()
5146        return parts
is_star: bool
5112    @property
5113    def is_star(self) -> bool:
5114        return self.expression.is_star

Checks whether an expression is a star.

name: str
5116    @property
5117    def name(self) -> str:
5118        return self.expression.name
output_name: str
5120    @property
5121    def output_name(self) -> str:
5122        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:
5124    @classmethod
5125    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5126        """Build a Dot object with a sequence of expressions."""
5127        if len(expressions) < 2:
5128            raise ValueError("Dot requires >= 2 expressions.")
5129
5130        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]
5132    @property
5133    def parts(self) -> t.List[Expression]:
5134        """Return the parts of a table / column in order catalog, db, table."""
5135        this, *parts = self.flatten()
5136
5137        parts.reverse()
5138
5139        for arg in COLUMN_PARTS:
5140            part = this.args.get(arg)
5141
5142            if isinstance(part, Expression):
5143                parts.append(part)
5144
5145        parts.reverse()
5146        return parts

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

key = 'dot'
DATA_TYPE = typing.Union[str, Identifier, Dot, DataType, DataType.Type]
class DPipe(Binary):
5152class DPipe(Binary):
5153    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5156class EQ(Binary, Predicate):
5157    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5160class NullSafeEQ(Binary, Predicate):
5161    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5164class NullSafeNEQ(Binary, Predicate):
5165    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5169class PropertyEQ(Binary):
5170    pass
key = 'propertyeq'
class Distance(Binary):
5173class Distance(Binary):
5174    pass
key = 'distance'
class Escape(Binary):
5177class Escape(Binary):
5178    pass
key = 'escape'
class Glob(Binary, Predicate):
5181class Glob(Binary, Predicate):
5182    pass
key = 'glob'
class GT(Binary, Predicate):
5185class GT(Binary, Predicate):
5186    pass
key = 'gt'
class GTE(Binary, Predicate):
5189class GTE(Binary, Predicate):
5190    pass
key = 'gte'
class ILike(Binary, Predicate):
5193class ILike(Binary, Predicate):
5194    pass
key = 'ilike'
class IntDiv(Binary):
5197class IntDiv(Binary):
5198    pass
key = 'intdiv'
class Is(Binary, Predicate):
5201class Is(Binary, Predicate):
5202    pass
key = 'is'
class Kwarg(Binary):
5205class Kwarg(Binary):
5206    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5209class Like(Binary, Predicate):
5210    pass
key = 'like'
class LT(Binary, Predicate):
5213class LT(Binary, Predicate):
5214    pass
key = 'lt'
class LTE(Binary, Predicate):
5217class LTE(Binary, Predicate):
5218    pass
key = 'lte'
class Mod(Binary):
5221class Mod(Binary):
5222    pass
key = 'mod'
class Mul(Binary):
5225class Mul(Binary):
5226    pass
key = 'mul'
class NEQ(Binary, Predicate):
5229class NEQ(Binary, Predicate):
5230    pass
key = 'neq'
class Operator(Binary):
5234class Operator(Binary):
5235    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5238class SimilarTo(Binary, Predicate):
5239    pass
key = 'similarto'
class Slice(Binary):
5242class Slice(Binary):
5243    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5246class Sub(Binary):
5247    pass
key = 'sub'
class Unary(Condition):
5252class Unary(Condition):
5253    pass
key = 'unary'
class BitwiseNot(Unary):
5256class BitwiseNot(Unary):
5257    pass
key = 'bitwisenot'
class Not(Unary):
5260class Not(Unary):
5261    pass
key = 'not'
class Paren(Unary):
5264class Paren(Unary):
5265    @property
5266    def output_name(self) -> str:
5267        return self.this.name
output_name: str
5265    @property
5266    def output_name(self) -> str:
5267        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):
5270class Neg(Unary):
5271    def to_py(self) -> int | Decimal:
5272        if self.is_number:
5273            return self.this.to_py() * -1
5274        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5271    def to_py(self) -> int | Decimal:
5272        if self.is_number:
5273            return self.this.to_py() * -1
5274        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5277class Alias(Expression):
5278    arg_types = {"this": True, "alias": False}
5279
5280    @property
5281    def output_name(self) -> str:
5282        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5280    @property
5281    def output_name(self) -> str:
5282        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):
5287class PivotAlias(Alias):
5288    pass
key = 'pivotalias'
class PivotAny(Expression):
5293class PivotAny(Expression):
5294    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5297class Aliases(Expression):
5298    arg_types = {"this": True, "expressions": True}
5299
5300    @property
5301    def aliases(self):
5302        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5300    @property
5301    def aliases(self):
5302        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5306class AtIndex(Expression):
5307    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5310class AtTimeZone(Expression):
5311    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5314class FromTimeZone(Expression):
5315    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class FormatPhrase(Expression):
5318class FormatPhrase(Expression):
5319    """Format override for a column in Teradata.
5320    Can be expanded to additional dialects as needed
5321
5322    https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT
5323    """
5324
5325    arg_types = {"this": True, "format": True}

Format override for a column in Teradata. Can be expanded to additional dialects as needed

https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT

arg_types = {'this': True, 'format': True}
key = 'formatphrase'
class Between(Predicate):
5328class Between(Predicate):
5329    arg_types = {"this": True, "low": True, "high": True, "symmetric": False}
arg_types = {'this': True, 'low': True, 'high': True, 'symmetric': False}
key = 'between'
class Bracket(Condition):
5332class Bracket(Condition):
5333    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5334    arg_types = {
5335        "this": True,
5336        "expressions": True,
5337        "offset": False,
5338        "safe": False,
5339        "returns_list_for_maps": False,
5340    }
5341
5342    @property
5343    def output_name(self) -> str:
5344        if len(self.expressions) == 1:
5345            return self.expressions[0].output_name
5346
5347        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5342    @property
5343    def output_name(self) -> str:
5344        if len(self.expressions) == 1:
5345            return self.expressions[0].output_name
5346
5347        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):
5350class Distinct(Expression):
5351    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5354class In(Predicate):
5355    arg_types = {
5356        "this": True,
5357        "expressions": False,
5358        "query": False,
5359        "unnest": False,
5360        "field": False,
5361        "is_global": False,
5362    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5366class ForIn(Expression):
5367    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5370class TimeUnit(Expression):
5371    """Automatically converts unit arg into a var."""
5372
5373    arg_types = {"unit": False}
5374
5375    UNABBREVIATED_UNIT_NAME = {
5376        "D": "DAY",
5377        "H": "HOUR",
5378        "M": "MINUTE",
5379        "MS": "MILLISECOND",
5380        "NS": "NANOSECOND",
5381        "Q": "QUARTER",
5382        "S": "SECOND",
5383        "US": "MICROSECOND",
5384        "W": "WEEK",
5385        "Y": "YEAR",
5386    }
5387
5388    VAR_LIKE = (Column, Literal, Var)
5389
5390    def __init__(self, **args):
5391        unit = args.get("unit")
5392        if type(unit) in self.VAR_LIKE and not (isinstance(unit, Column) and len(unit.parts) != 1):
5393            args["unit"] = Var(
5394                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5395            )
5396        elif isinstance(unit, Week):
5397            unit.set("this", Var(this=unit.this.name.upper()))
5398
5399        super().__init__(**args)
5400
5401    @property
5402    def unit(self) -> t.Optional[Var | IntervalSpan]:
5403        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5390    def __init__(self, **args):
5391        unit = args.get("unit")
5392        if type(unit) in self.VAR_LIKE and not (isinstance(unit, Column) and len(unit.parts) != 1):
5393            args["unit"] = Var(
5394                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5395            )
5396        elif isinstance(unit, Week):
5397            unit.set("this", Var(this=unit.this.name.upper()))
5398
5399        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]
5401    @property
5402    def unit(self) -> t.Optional[Var | IntervalSpan]:
5403        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5406class IntervalOp(TimeUnit):
5407    arg_types = {"unit": False, "expression": True}
5408
5409    def interval(self):
5410        return Interval(
5411            this=self.expression.copy(),
5412            unit=self.unit.copy() if self.unit else None,
5413        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5409    def interval(self):
5410        return Interval(
5411            this=self.expression.copy(),
5412            unit=self.unit.copy() if self.unit else None,
5413        )
key = 'intervalop'
class IntervalSpan(DataType):
5419class IntervalSpan(DataType):
5420    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5423class Interval(TimeUnit):
5424    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5427class IgnoreNulls(Expression):
5428    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5431class RespectNulls(Expression):
5432    pass
key = 'respectnulls'
class HavingMax(Expression):
5436class HavingMax(Expression):
5437    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5441class Func(Condition):
5442    """
5443    The base class for all function expressions.
5444
5445    Attributes:
5446        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5447            treated as a variable length argument and the argument's value will be stored as a list.
5448        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5449            function expression. These values are used to map this node to a name during parsing as
5450            well as to provide the function's name during SQL string generation. By default the SQL
5451            name is set to the expression's class name transformed to snake case.
5452    """
5453
5454    is_var_len_args = False
5455
5456    @classmethod
5457    def from_arg_list(cls, args):
5458        if cls.is_var_len_args:
5459            all_arg_keys = list(cls.arg_types)
5460            # If this function supports variable length argument treat the last argument as such.
5461            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5462            num_non_var = len(non_var_len_arg_keys)
5463
5464            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5465            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5466        else:
5467            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5468
5469        return cls(**args_dict)
5470
5471    @classmethod
5472    def sql_names(cls):
5473        if cls is Func:
5474            raise NotImplementedError(
5475                "SQL name is only supported by concrete function implementations"
5476            )
5477        if "_sql_names" not in cls.__dict__:
5478            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5479        return cls._sql_names
5480
5481    @classmethod
5482    def sql_name(cls):
5483        sql_names = cls.sql_names()
5484        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5485        return sql_names[0]
5486
5487    @classmethod
5488    def default_parser_mappings(cls):
5489        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):
5456    @classmethod
5457    def from_arg_list(cls, args):
5458        if cls.is_var_len_args:
5459            all_arg_keys = list(cls.arg_types)
5460            # If this function supports variable length argument treat the last argument as such.
5461            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5462            num_non_var = len(non_var_len_arg_keys)
5463
5464            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5465            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5466        else:
5467            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5468
5469        return cls(**args_dict)
@classmethod
def sql_names(cls):
5471    @classmethod
5472    def sql_names(cls):
5473        if cls is Func:
5474            raise NotImplementedError(
5475                "SQL name is only supported by concrete function implementations"
5476            )
5477        if "_sql_names" not in cls.__dict__:
5478            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5479        return cls._sql_names
@classmethod
def sql_name(cls):
5481    @classmethod
5482    def sql_name(cls):
5483        sql_names = cls.sql_names()
5484        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5485        return sql_names[0]
@classmethod
def default_parser_mappings(cls):
5487    @classmethod
5488    def default_parser_mappings(cls):
5489        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5492class Typeof(Func):
5493    pass
key = 'typeof'
class Acos(Func):
5496class Acos(Func):
5497    pass
key = 'acos'
class Acosh(Func):
5500class Acosh(Func):
5501    pass
key = 'acosh'
class Asin(Func):
5504class Asin(Func):
5505    pass
key = 'asin'
class Asinh(Func):
5508class Asinh(Func):
5509    pass
key = 'asinh'
class Atan(Func):
5512class Atan(Func):
5513    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'atan'
class Atanh(Func):
5516class Atanh(Func):
5517    pass
key = 'atanh'
class Atan2(Func):
5520class Atan2(Func):
5521    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atan2'
class Cot(Func):
5524class Cot(Func):
5525    pass
key = 'cot'
class Coth(Func):
5528class Coth(Func):
5529    pass
key = 'coth'
class Cos(Func):
5532class Cos(Func):
5533    pass
key = 'cos'
class Csc(Func):
5536class Csc(Func):
5537    pass
key = 'csc'
class Csch(Func):
5540class Csch(Func):
5541    pass
key = 'csch'
class Sec(Func):
5544class Sec(Func):
5545    pass
key = 'sec'
class Sech(Func):
5548class Sech(Func):
5549    pass
key = 'sech'
class Sin(Func):
5552class Sin(Func):
5553    pass
key = 'sin'
class Sinh(Func):
5556class Sinh(Func):
5557    pass
key = 'sinh'
class Tan(Func):
5560class Tan(Func):
5561    pass
key = 'tan'
class Degrees(Func):
5564class Degrees(Func):
5565    pass
key = 'degrees'
class Cosh(Func):
5568class Cosh(Func):
5569    pass
key = 'cosh'
class CosineDistance(Func):
5572class CosineDistance(Func):
5573    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'cosinedistance'
class EuclideanDistance(Func):
5576class EuclideanDistance(Func):
5577    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'euclideandistance'
class JarowinklerSimilarity(Func):
5580class JarowinklerSimilarity(Func):
5581    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jarowinklersimilarity'
class AggFunc(Func):
5584class AggFunc(Func):
5585    pass
key = 'aggfunc'
class BitwiseAndAgg(AggFunc):
5588class BitwiseAndAgg(AggFunc):
5589    pass
key = 'bitwiseandagg'
class BitwiseOrAgg(AggFunc):
5592class BitwiseOrAgg(AggFunc):
5593    pass
key = 'bitwiseoragg'
class BitwiseXorAgg(AggFunc):
5596class BitwiseXorAgg(AggFunc):
5597    pass
key = 'bitwisexoragg'
class BitwiseCountAgg(AggFunc):
5600class BitwiseCountAgg(AggFunc):
5601    pass
key = 'bitwisecountagg'
class ByteLength(Func):
5604class ByteLength(Func):
5605    pass
key = 'bytelength'
class JSONBool(Func):
5609class JSONBool(Func):
5610    pass
key = 'jsonbool'
class ArrayRemove(Func):
5613class ArrayRemove(Func):
5614    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5617class ParameterizedAgg(AggFunc):
5618    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5621class Abs(Func):
5622    pass
key = 'abs'
class ArgMax(AggFunc):
5625class ArgMax(AggFunc):
5626    arg_types = {"this": True, "expression": True, "count": False}
5627    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5630class ArgMin(AggFunc):
5631    arg_types = {"this": True, "expression": True, "count": False}
5632    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5635class ApproxTopK(AggFunc):
5636    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class ApproxTopSum(AggFunc):
5639class ApproxTopSum(AggFunc):
5640    arg_types = {"this": True, "expression": True, "count": True}
arg_types = {'this': True, 'expression': True, 'count': True}
key = 'approxtopsum'
class ApproxQuantiles(AggFunc):
5643class ApproxQuantiles(AggFunc):
5644    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'approxquantiles'
class FarmFingerprint(Func):
5647class FarmFingerprint(Func):
5648    arg_types = {"expressions": True}
5649    is_var_len_args = True
5650    _sql_names = ["FARM_FINGERPRINT", "FARMFINGERPRINT64"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'farmfingerprint'
class Flatten(Func):
5653class Flatten(Func):
5654    pass
key = 'flatten'
class Float64(Func):
5657class Float64(Func):
5658    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'float64'
class Transform(Func):
5662class Transform(Func):
5663    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Translate(Func):
5666class Translate(Func):
5667    arg_types = {"this": True, "from": True, "to": True}
arg_types = {'this': True, 'from': True, 'to': True}
key = 'translate'
class Grouping(AggFunc):
5670class Grouping(AggFunc):
5671    arg_types = {"expressions": True}
5672    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'grouping'
class Anonymous(Func):
5675class Anonymous(Func):
5676    arg_types = {"this": True, "expressions": False}
5677    is_var_len_args = True
5678
5679    @property
5680    def name(self) -> str:
5681        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
5679    @property
5680    def name(self) -> str:
5681        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5684class AnonymousAggFunc(AggFunc):
5685    arg_types = {"this": True, "expressions": False}
5686    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5690class CombinedAggFunc(AnonymousAggFunc):
5691    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5694class CombinedParameterizedAgg(ParameterizedAgg):
5695    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5700class Hll(AggFunc):
5701    arg_types = {"this": True, "expressions": False}
5702    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5705class ApproxDistinct(AggFunc):
5706    arg_types = {"this": True, "accuracy": False}
5707    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5710class Apply(Func):
5711    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5714class Array(Func):
5715    arg_types = {"expressions": False, "bracket_notation": False}
5716    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5719class Ascii(Func):
5720    pass
key = 'ascii'
class ToArray(Func):
5724class ToArray(Func):
5725    pass
key = 'toarray'
class List(Func):
5729class List(Func):
5730    arg_types = {"expressions": False}
5731    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5735class Pad(Func):
5736    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):
5741class ToChar(Func):
5742    arg_types = {
5743        "this": True,
5744        "format": False,
5745        "nlsparam": False,
5746        "is_numeric": False,
5747    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'is_numeric': False}
key = 'tochar'
class ToCodePoints(Func):
5750class ToCodePoints(Func):
5751    pass
key = 'tocodepoints'
class ToNumber(Func):
5756class ToNumber(Func):
5757    arg_types = {
5758        "this": True,
5759        "format": False,
5760        "nlsparam": False,
5761        "precision": False,
5762        "scale": False,
5763    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5767class ToDouble(Func):
5768    arg_types = {
5769        "this": True,
5770        "format": False,
5771    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class CodePointsToBytes(Func):
5774class CodePointsToBytes(Func):
5775    pass
key = 'codepointstobytes'
class Columns(Func):
5778class Columns(Func):
5779    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5783class Convert(Func):
5784    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5788class ConvertToCharset(Func):
5789    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5792class ConvertTimezone(Func):
5793    arg_types = {
5794        "source_tz": False,
5795        "target_tz": True,
5796        "timestamp": True,
5797        "options": False,
5798    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class CodePointsToString(Func):
5801class CodePointsToString(Func):
5802    pass
key = 'codepointstostring'
class GenerateSeries(Func):
5805class GenerateSeries(Func):
5806    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):
5812class ExplodingGenerateSeries(GenerateSeries):
5813    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5816class ArrayAgg(AggFunc):
5817    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5820class ArrayUniqueAgg(AggFunc):
5821    pass
key = 'arrayuniqueagg'
class AIAgg(AggFunc):
5824class AIAgg(AggFunc):
5825    arg_types = {"this": True, "expression": True}
5826    _sql_names = ["AI_AGG"]
arg_types = {'this': True, 'expression': True}
key = 'aiagg'
class AISummarizeAgg(AggFunc):
5829class AISummarizeAgg(AggFunc):
5830    _sql_names = ["AI_SUMMARIZE_AGG"]
key = 'aisummarizeagg'
class AIClassify(Func):
5833class AIClassify(Func):
5834    arg_types = {"this": True, "categories": True, "config": False}
5835    _sql_names = ["AI_CLASSIFY"]
arg_types = {'this': True, 'categories': True, 'config': False}
key = 'aiclassify'
class ArrayAll(Func):
5838class ArrayAll(Func):
5839    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5843class ArrayAny(Func):
5844    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5847class ArrayConcat(Func):
5848    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5849    arg_types = {"this": True, "expressions": False}
5850    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5853class ArrayConcatAgg(AggFunc):
5854    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5857class ArrayConstructCompact(Func):
5858    arg_types = {"expressions": True}
5859    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5862class ArrayContains(Binary, Func):
5863    arg_types = {"this": True, "expression": True, "ensure_variant": False}
5864    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
arg_types = {'this': True, 'expression': True, 'ensure_variant': False}
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5867class ArrayContainsAll(Binary, Func):
5868    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5871class ArrayFilter(Func):
5872    arg_types = {"this": True, "expression": True}
5873    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5876class ArrayFirst(Func):
5877    pass
key = 'arrayfirst'
class ArrayLast(Func):
5880class ArrayLast(Func):
5881    pass
key = 'arraylast'
class ArrayReverse(Func):
5884class ArrayReverse(Func):
5885    pass
key = 'arrayreverse'
class ArraySlice(Func):
5888class ArraySlice(Func):
5889    arg_types = {"this": True, "start": True, "end": False, "step": False}
arg_types = {'this': True, 'start': True, 'end': False, 'step': False}
key = 'arrayslice'
class ArrayToString(Func):
5892class ArrayToString(Func):
5893    arg_types = {"this": True, "expression": True, "null": False}
5894    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5897class ArrayIntersect(Func):
5898    arg_types = {"expressions": True}
5899    is_var_len_args = True
5900    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5903class StPoint(Func):
5904    arg_types = {"this": True, "expression": True, "null": False}
5905    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5908class StDistance(Func):
5909    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5913class String(Func):
5914    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5917class StringToArray(Func):
5918    arg_types = {"this": True, "expression": False, "null": False}
5919    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
arg_types = {'this': True, 'expression': False, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5922class ArrayOverlaps(Binary, Func):
5923    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5926class ArraySize(Func):
5927    arg_types = {"this": True, "expression": False}
5928    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5931class ArraySort(Func):
5932    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5935class ArraySum(Func):
5936    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5939class ArrayUnionAgg(AggFunc):
5940    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5943class Avg(AggFunc):
5944    pass
key = 'avg'
class AnyValue(AggFunc):
5947class AnyValue(AggFunc):
5948    pass
key = 'anyvalue'
class Lag(AggFunc):
5951class Lag(AggFunc):
5952    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5955class Lead(AggFunc):
5956    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5961class First(AggFunc):
5962    pass
key = 'first'
class Last(AggFunc):
5965class Last(AggFunc):
5966    pass
key = 'last'
class FirstValue(AggFunc):
5969class FirstValue(AggFunc):
5970    pass
key = 'firstvalue'
class LastValue(AggFunc):
5973class LastValue(AggFunc):
5974    pass
key = 'lastvalue'
class NthValue(AggFunc):
5977class NthValue(AggFunc):
5978    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5981class Case(Func):
5982    arg_types = {"this": False, "ifs": True, "default": False}
5983
5984    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5985        instance = maybe_copy(self, copy)
5986        instance.append(
5987            "ifs",
5988            If(
5989                this=maybe_parse(condition, copy=copy, **opts),
5990                true=maybe_parse(then, copy=copy, **opts),
5991            ),
5992        )
5993        return instance
5994
5995    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5996        instance = maybe_copy(self, copy)
5997        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5998        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:
5984    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5985        instance = maybe_copy(self, copy)
5986        instance.append(
5987            "ifs",
5988            If(
5989                this=maybe_parse(condition, copy=copy, **opts),
5990                true=maybe_parse(then, copy=copy, **opts),
5991            ),
5992        )
5993        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5995    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5996        instance = maybe_copy(self, copy)
5997        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5998        return instance
key = 'case'
class Cast(Func):
6001class Cast(Func):
6002    arg_types = {
6003        "this": True,
6004        "to": True,
6005        "format": False,
6006        "safe": False,
6007        "action": False,
6008        "default": False,
6009    }
6010
6011    @property
6012    def name(self) -> str:
6013        return self.this.name
6014
6015    @property
6016    def to(self) -> DataType:
6017        return self.args["to"]
6018
6019    @property
6020    def output_name(self) -> str:
6021        return self.name
6022
6023    def is_type(self, *dtypes: DATA_TYPE) -> bool:
6024        """
6025        Checks whether this Cast's DataType matches one of the provided data types. Nested types
6026        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
6027        array<int> != array<float>.
6028
6029        Args:
6030            dtypes: the data types to compare this Cast's DataType to.
6031
6032        Returns:
6033            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
6034        """
6035        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
6011    @property
6012    def name(self) -> str:
6013        return self.this.name
to: DataType
6015    @property
6016    def to(self) -> DataType:
6017        return self.args["to"]
output_name: str
6019    @property
6020    def output_name(self) -> str:
6021        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, Identifier, Dot, DataType, DataType.Type]) -> bool:
6023    def is_type(self, *dtypes: DATA_TYPE) -> bool:
6024        """
6025        Checks whether this Cast's DataType matches one of the provided data types. Nested types
6026        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
6027        array<int> != array<float>.
6028
6029        Args:
6030            dtypes: the data types to compare this Cast's DataType to.
6031
6032        Returns:
6033            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
6034        """
6035        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):
6038class TryCast(Cast):
6039    arg_types = {**Cast.arg_types, "requires_string": False}
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False, 'requires_string': False}
key = 'trycast'
class JSONCast(Cast):
6043class JSONCast(Cast):
6044    pass
key = 'jsoncast'
class JustifyDays(Func):
6047class JustifyDays(Func):
6048    pass
key = 'justifydays'
class JustifyHours(Func):
6051class JustifyHours(Func):
6052    pass
key = 'justifyhours'
class JustifyInterval(Func):
6055class JustifyInterval(Func):
6056    pass
key = 'justifyinterval'
class Try(Func):
6059class Try(Func):
6060    pass
key = 'try'
class CastToStrType(Func):
6063class CastToStrType(Func):
6064    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
6068class TranslateCharacters(Expression):
6069    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
6072class Collate(Binary, Func):
6073    pass
key = 'collate'
class Collation(Func):
6076class Collation(Func):
6077    pass
key = 'collation'
class Ceil(Func):
6080class Ceil(Func):
6081    arg_types = {"this": True, "decimals": False, "to": False}
6082    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
6085class Coalesce(Func):
6086    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
6087    is_var_len_args = True
6088    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False, 'is_null': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
6091class Chr(Func):
6092    arg_types = {"expressions": True, "charset": False}
6093    is_var_len_args = True
6094    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
6097class Concat(Func):
6098    arg_types = {"expressions": True, "safe": False, "coalesce": False}
6099    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
6102class ConcatWs(Concat):
6103    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
6107class Contains(Func):
6108    arg_types = {"this": True, "expression": True, "json_scope": False}
arg_types = {'this': True, 'expression': True, 'json_scope': False}
key = 'contains'
class ConnectByRoot(Func):
6112class ConnectByRoot(Func):
6113    pass
key = 'connectbyroot'
class Count(AggFunc):
6116class Count(AggFunc):
6117    arg_types = {"this": False, "expressions": False, "big_int": False}
6118    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
6121class CountIf(AggFunc):
6122    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
6126class Cbrt(Func):
6127    pass
key = 'cbrt'
class CurrentDate(Func):
6130class CurrentDate(Func):
6131    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
6134class CurrentDatetime(Func):
6135    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
6138class CurrentTime(Func):
6139    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
6142class CurrentTimestamp(Func):
6143    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
6146class CurrentTimestampLTZ(Func):
6147    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
6150class CurrentSchema(Func):
6151    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
6154class CurrentUser(Func):
6155    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class UtcDate(Func):
6158class UtcDate(Func):
6159    arg_types = {}
arg_types = {}
key = 'utcdate'
class UtcTime(Func):
6162class UtcTime(Func):
6163    arg_types = {"this": False}
arg_types = {'this': False}
key = 'utctime'
class UtcTimestamp(Func):
6166class UtcTimestamp(Func):
6167    arg_types = {"this": False}
arg_types = {'this': False}
key = 'utctimestamp'
class DateAdd(Func, IntervalOp):
6170class DateAdd(Func, IntervalOp):
6171    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
6174class DateBin(Func, IntervalOp):
6175    arg_types = {"this": True, "expression": True, "unit": False, "zone": False, "origin": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False, 'origin': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
6178class DateSub(Func, IntervalOp):
6179    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
6182class DateDiff(Func, TimeUnit):
6183    _sql_names = ["DATEDIFF", "DATE_DIFF"]
6184    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datediff'
class DateTrunc(Func):
6187class DateTrunc(Func):
6188    arg_types = {"unit": True, "this": True, "zone": False}
6189
6190    def __init__(self, **args):
6191        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6192        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6193        unabbreviate = args.pop("unabbreviate", True)
6194
6195        unit = args.get("unit")
6196        if isinstance(unit, TimeUnit.VAR_LIKE) and not (
6197            isinstance(unit, Column) and len(unit.parts) != 1
6198        ):
6199            unit_name = unit.name.upper()
6200            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6201                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6202
6203            args["unit"] = Literal.string(unit_name)
6204
6205        super().__init__(**args)
6206
6207    @property
6208    def unit(self) -> Expression:
6209        return self.args["unit"]
DateTrunc(**args)
6190    def __init__(self, **args):
6191        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6192        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6193        unabbreviate = args.pop("unabbreviate", True)
6194
6195        unit = args.get("unit")
6196        if isinstance(unit, TimeUnit.VAR_LIKE) and not (
6197            isinstance(unit, Column) and len(unit.parts) != 1
6198        ):
6199            unit_name = unit.name.upper()
6200            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6201                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6202
6203            args["unit"] = Literal.string(unit_name)
6204
6205        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
6207    @property
6208    def unit(self) -> Expression:
6209        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
6214class Datetime(Func):
6215    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
6218class DatetimeAdd(Func, IntervalOp):
6219    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
6222class DatetimeSub(Func, IntervalOp):
6223    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
6226class DatetimeDiff(Func, TimeUnit):
6227    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
6230class DatetimeTrunc(Func, TimeUnit):
6231    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DateFromUnixDate(Func):
6234class DateFromUnixDate(Func):
6235    pass
key = 'datefromunixdate'
class DayOfWeek(Func):
6238class DayOfWeek(Func):
6239    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
6244class DayOfWeekIso(Func):
6245    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
6248class DayOfMonth(Func):
6249    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
6252class DayOfYear(Func):
6253    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
6256class ToDays(Func):
6257    pass
key = 'todays'
class WeekOfYear(Func):
6260class WeekOfYear(Func):
6261    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
6264class MonthsBetween(Func):
6265    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
6268class MakeInterval(Func):
6269    arg_types = {
6270        "year": False,
6271        "month": False,
6272        "day": False,
6273        "hour": False,
6274        "minute": False,
6275        "second": False,
6276    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
6279class LastDay(Func, TimeUnit):
6280    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
6281    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class LaxBool(Func):
6284class LaxBool(Func):
6285    pass
key = 'laxbool'
class LaxFloat64(Func):
6288class LaxFloat64(Func):
6289    pass
key = 'laxfloat64'
class LaxInt64(Func):
6292class LaxInt64(Func):
6293    pass
key = 'laxint64'
class LaxString(Func):
6296class LaxString(Func):
6297    pass
key = 'laxstring'
class Extract(Func):
6300class Extract(Func):
6301    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6304class Exists(Func, SubqueryPredicate):
6305    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6308class Timestamp(Func):
6309    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6312class TimestampAdd(Func, TimeUnit):
6313    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6316class TimestampSub(Func, TimeUnit):
6317    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6320class TimestampDiff(Func, TimeUnit):
6321    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6322    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6325class TimestampTrunc(Func, TimeUnit):
6326    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6329class TimeAdd(Func, TimeUnit):
6330    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6333class TimeSub(Func, TimeUnit):
6334    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6337class TimeDiff(Func, TimeUnit):
6338    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6341class TimeTrunc(Func, TimeUnit):
6342    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6345class DateFromParts(Func):
6346    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6347    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6350class TimeFromParts(Func):
6351    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6352    arg_types = {
6353        "hour": True,
6354        "min": True,
6355        "sec": True,
6356        "nano": False,
6357        "fractions": False,
6358        "precision": False,
6359    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6362class DateStrToDate(Func):
6363    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6366class DateToDateStr(Func):
6367    pass
key = 'datetodatestr'
class DateToDi(Func):
6370class DateToDi(Func):
6371    pass
key = 'datetodi'
class Date(Func):
6375class Date(Func):
6376    arg_types = {"this": False, "zone": False, "expressions": False}
6377    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6380class Day(Func):
6381    pass
key = 'day'
class Decode(Func):
6384class Decode(Func):
6385    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6388class DecodeCase(Func):
6389    arg_types = {"expressions": True}
6390    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DenseRank(AggFunc):
6393class DenseRank(AggFunc):
6394    arg_types = {"expressions": False}
6395    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'denserank'
class DiToDate(Func):
6398class DiToDate(Func):
6399    pass
key = 'ditodate'
class Encode(Func):
6402class Encode(Func):
6403    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6406class Exp(Func):
6407    pass
key = 'exp'
class Factorial(Func):
6410class Factorial(Func):
6411    pass
key = 'factorial'
class Explode(Func, UDTF):
6415class Explode(Func, UDTF):
6416    arg_types = {"this": True, "expressions": False}
6417    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6421class Inline(Func):
6422    pass
key = 'inline'
class ExplodeOuter(Explode):
6425class ExplodeOuter(Explode):
6426    pass
key = 'explodeouter'
class Posexplode(Explode):
6429class Posexplode(Explode):
6430    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6433class PosexplodeOuter(Posexplode, ExplodeOuter):
6434    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6437class PositionalColumn(Expression):
6438    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6441class Unnest(Func, UDTF):
6442    arg_types = {
6443        "expressions": True,
6444        "alias": False,
6445        "offset": False,
6446        "explode_array": False,
6447    }
6448
6449    @property
6450    def selects(self) -> t.List[Expression]:
6451        columns = super().selects
6452        offset = self.args.get("offset")
6453        if offset:
6454            columns = columns + [to_identifier("offset") if offset is True else offset]
6455        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6449    @property
6450    def selects(self) -> t.List[Expression]:
6451        columns = super().selects
6452        offset = self.args.get("offset")
6453        if offset:
6454            columns = columns + [to_identifier("offset") if offset is True else offset]
6455        return columns
key = 'unnest'
class Floor(Func):
6458class Floor(Func):
6459    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase32(Func):
6462class FromBase32(Func):
6463    pass
key = 'frombase32'
class FromBase64(Func):
6466class FromBase64(Func):
6467    pass
key = 'frombase64'
class ToBase32(Func):
6470class ToBase32(Func):
6471    pass
key = 'tobase32'
class ToBase64(Func):
6474class ToBase64(Func):
6475    pass
key = 'tobase64'
class Base64DecodeBinary(Func):
6479class Base64DecodeBinary(Func):
6480    arg_types = {"this": True, "alphabet": False}
arg_types = {'this': True, 'alphabet': False}
key = 'base64decodebinary'
class Base64DecodeString(Func):
6484class Base64DecodeString(Func):
6485    arg_types = {"this": True, "alphabet": False}
arg_types = {'this': True, 'alphabet': False}
key = 'base64decodestring'
class Base64Encode(Func):
6489class Base64Encode(Func):
6490    arg_types = {"this": True, "max_line_length": False, "alphabet": False}
arg_types = {'this': True, 'max_line_length': False, 'alphabet': False}
key = 'base64encode'
class TryBase64DecodeBinary(Func):
6494class TryBase64DecodeBinary(Func):
6495    arg_types = {"this": True, "alphabet": False}
arg_types = {'this': True, 'alphabet': False}
key = 'trybase64decodebinary'
class TryBase64DecodeString(Func):
6499class TryBase64DecodeString(Func):
6500    arg_types = {"this": True, "alphabet": False}
arg_types = {'this': True, 'alphabet': False}
key = 'trybase64decodestring'
class TryHexDecodeBinary(Func):
6504class TryHexDecodeBinary(Func):
6505    pass
key = 'tryhexdecodebinary'
class TryHexDecodeString(Func):
6509class TryHexDecodeString(Func):
6510    pass
key = 'tryhexdecodestring'
class FromISO8601Timestamp(Func):
6514class FromISO8601Timestamp(Func):
6515    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6518class GapFill(Func):
6519    arg_types = {
6520        "this": True,
6521        "ts_column": True,
6522        "bucket_width": True,
6523        "partitioning_columns": False,
6524        "value_columns": False,
6525        "origin": False,
6526        "ignore_nulls": False,
6527    }
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):
6531class GenerateDateArray(Func):
6532    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6536class GenerateTimestampArray(Func):
6537    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class GetExtract(Func):
6541class GetExtract(Func):
6542    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'getextract'
class Greatest(Func):
6545class Greatest(Func):
6546    arg_types = {"this": True, "expressions": False}
6547    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6552class OverflowTruncateBehavior(Expression):
6553    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6556class GroupConcat(AggFunc):
6557    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6560class Hex(Func):
6561    pass
key = 'hex'
class HexDecodeString(Func):
6565class HexDecodeString(Func):
6566    pass
key = 'hexdecodestring'
class HexEncode(Func):
6570class HexEncode(Func):
6571    arg_types = {"this": True, "case": False}
arg_types = {'this': True, 'case': False}
key = 'hexencode'
class Compress(Func):
6576class Compress(Func):
6577    arg_types = {"this": True, "method": False}
arg_types = {'this': True, 'method': False}
key = 'compress'
class DecompressBinary(Func):
6581class DecompressBinary(Func):
6582    arg_types = {"this": True, "method": True}
arg_types = {'this': True, 'method': True}
key = 'decompressbinary'
class DecompressString(Func):
6586class DecompressString(Func):
6587    arg_types = {"this": True, "method": True}
arg_types = {'this': True, 'method': True}
key = 'decompressstring'
class LowerHex(Hex):
6590class LowerHex(Hex):
6591    pass
key = 'lowerhex'
class And(Connector, Func):
6594class And(Connector, Func):
6595    pass
key = 'and'
class Or(Connector, Func):
6598class Or(Connector, Func):
6599    pass
key = 'or'
class Xor(Connector, Func):
6602class Xor(Connector, Func):
6603    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6606class If(Func):
6607    arg_types = {"this": True, "true": True, "false": False}
6608    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6611class Nullif(Func):
6612    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6615class Initcap(Func):
6616    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6619class IsAscii(Func):
6620    pass
key = 'isascii'
class IsNan(Func):
6623class IsNan(Func):
6624    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6628class Int64(Func):
6629    pass
key = 'int64'
class IsInf(Func):
6632class IsInf(Func):
6633    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6637class JSON(Expression):
6638    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6641class JSONPath(Expression):
6642    arg_types = {"expressions": True, "escape": False}
6643
6644    @property
6645    def output_name(self) -> str:
6646        last_segment = self.expressions[-1].this
6647        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6644    @property
6645    def output_name(self) -> str:
6646        last_segment = self.expressions[-1].this
6647        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):
6650class JSONPathPart(Expression):
6651    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6654class JSONPathFilter(JSONPathPart):
6655    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6658class JSONPathKey(JSONPathPart):
6659    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6662class JSONPathRecursive(JSONPathPart):
6663    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6666class JSONPathRoot(JSONPathPart):
6667    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6670class JSONPathScript(JSONPathPart):
6671    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6674class JSONPathSlice(JSONPathPart):
6675    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6678class JSONPathSelector(JSONPathPart):
6679    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6682class JSONPathSubscript(JSONPathPart):
6683    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6686class JSONPathUnion(JSONPathPart):
6687    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6690class JSONPathWildcard(JSONPathPart):
6691    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6694class FormatJson(Expression):
6695    pass
key = 'formatjson'
class Format(Func):
6698class Format(Func):
6699    arg_types = {"this": True, "expressions": True}
6700    is_var_len_args = True
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'format'
class JSONKeyValue(Expression):
6703class JSONKeyValue(Expression):
6704    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONKeysAtDepth(Func):
6708class JSONKeysAtDepth(Func):
6709    arg_types = {"this": True, "expression": False, "mode": False}
arg_types = {'this': True, 'expression': False, 'mode': False}
key = 'jsonkeysatdepth'
class JSONObject(Func):
6712class JSONObject(Func):
6713    arg_types = {
6714        "expressions": False,
6715        "null_handling": False,
6716        "unique_keys": False,
6717        "return_type": False,
6718        "encoding": False,
6719    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6722class JSONObjectAgg(AggFunc):
6723    arg_types = {
6724        "expressions": False,
6725        "null_handling": False,
6726        "unique_keys": False,
6727        "return_type": False,
6728        "encoding": False,
6729    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6733class JSONBObjectAgg(AggFunc):
6734    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6738class JSONArray(Func):
6739    arg_types = {
6740        "expressions": False,
6741        "null_handling": False,
6742        "return_type": False,
6743        "strict": False,
6744    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6748class JSONArrayAgg(Func):
6749    arg_types = {
6750        "this": True,
6751        "order": False,
6752        "null_handling": False,
6753        "return_type": False,
6754        "strict": False,
6755    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6758class JSONExists(Func):
6759    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):
6764class JSONColumnDef(Expression):
6765    arg_types = {
6766        "this": False,
6767        "kind": False,
6768        "path": False,
6769        "nested_schema": False,
6770        "ordinality": False,
6771    }
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False, 'ordinality': False}
key = 'jsoncolumndef'
class JSONSchema(Expression):
6774class JSONSchema(Expression):
6775    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONSet(Func):
6778class JSONSet(Func):
6779    arg_types = {"this": True, "expressions": True}
6780    is_var_len_args = True
6781    _sql_names = ["JSON_SET"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonset'
class JSONStripNulls(Func):
6785class JSONStripNulls(Func):
6786    arg_types = {
6787        "this": True,
6788        "expression": False,
6789        "include_arrays": False,
6790        "remove_empty": False,
6791    }
6792    _sql_names = ["JSON_STRIP_NULLS"]
arg_types = {'this': True, 'expression': False, 'include_arrays': False, 'remove_empty': False}
key = 'jsonstripnulls'
class JSONValue(Expression):
6796class JSONValue(Expression):
6797    arg_types = {
6798        "this": True,
6799        "path": True,
6800        "returning": False,
6801        "on_condition": False,
6802    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6805class JSONValueArray(Func):
6806    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONRemove(Func):
6809class JSONRemove(Func):
6810    arg_types = {"this": True, "expressions": True}
6811    is_var_len_args = True
6812    _sql_names = ["JSON_REMOVE"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonremove'
class JSONTable(Func):
6816class JSONTable(Func):
6817    arg_types = {
6818        "this": True,
6819        "schema": True,
6820        "path": False,
6821        "error_handling": False,
6822        "empty_handling": False,
6823    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6828class JSONType(Func):
6829    arg_types = {"this": True, "expression": False}
6830    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6834class ObjectInsert(Func):
6835    arg_types = {
6836        "this": True,
6837        "key": True,
6838        "value": True,
6839        "update_flag": False,
6840    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6843class OpenJSONColumnDef(Expression):
6844    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):
6847class OpenJSON(Func):
6848    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6851class JSONBContains(Binary, Func):
6852    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBContainsAnyTopKeys(Binary, Func):
6856class JSONBContainsAnyTopKeys(Binary, Func):
6857    pass
key = 'jsonbcontainsanytopkeys'
class JSONBContainsAllTopKeys(Binary, Func):
6861class JSONBContainsAllTopKeys(Binary, Func):
6862    pass
key = 'jsonbcontainsalltopkeys'
class JSONBExists(Func):
6865class JSONBExists(Func):
6866    arg_types = {"this": True, "path": True}
6867    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONBDeleteAtPath(Binary, Func):
6871class JSONBDeleteAtPath(Binary, Func):
6872    pass
key = 'jsonbdeleteatpath'
class JSONExtract(Binary, Func):
6875class JSONExtract(Binary, Func):
6876    arg_types = {
6877        "this": True,
6878        "expression": True,
6879        "only_json_types": False,
6880        "expressions": False,
6881        "variant_extract": False,
6882        "json_query": False,
6883        "option": False,
6884        "quote": False,
6885        "on_condition": False,
6886        "requires_json": False,
6887    }
6888    _sql_names = ["JSON_EXTRACT"]
6889    is_var_len_args = True
6890
6891    @property
6892    def output_name(self) -> str:
6893        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False, 'json_query': False, 'option': False, 'quote': False, 'on_condition': False, 'requires_json': False}
is_var_len_args = True
output_name: str
6891    @property
6892    def output_name(self) -> str:
6893        return self.expression.output_name if not self.expressions else ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextract'
class JSONExtractQuote(Expression):
6897class JSONExtractQuote(Expression):
6898    arg_types = {
6899        "option": True,
6900        "scalar": False,
6901    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6904class JSONExtractArray(Func):
6905    arg_types = {"this": True, "expression": False}
6906    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6909class JSONExtractScalar(Binary, Func):
6910    arg_types = {
6911        "this": True,
6912        "expression": True,
6913        "only_json_types": False,
6914        "expressions": False,
6915        "json_type": False,
6916    }
6917    _sql_names = ["JSON_EXTRACT_SCALAR"]
6918    is_var_len_args = True
6919
6920    @property
6921    def output_name(self) -> str:
6922        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'json_type': False}
is_var_len_args = True
output_name: str
6920    @property
6921    def output_name(self) -> str:
6922        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):
6925class JSONBExtract(Binary, Func):
6926    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6929class JSONBExtractScalar(Binary, Func):
6930    arg_types = {"this": True, "expression": True, "json_type": False}
6931    _sql_names = ["JSONB_EXTRACT_SCALAR"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonbextractscalar'
class JSONFormat(Func):
6934class JSONFormat(Func):
6935    arg_types = {"this": False, "options": False, "is_json": False, "to_json": False}
6936    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False, 'to_json': False}
key = 'jsonformat'
class JSONArrayAppend(Func):
6939class JSONArrayAppend(Func):
6940    arg_types = {"this": True, "expressions": True}
6941    is_var_len_args = True
6942    _sql_names = ["JSON_ARRAY_APPEND"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayappend'
class JSONArrayContains(Binary, Predicate, Func):
6946class JSONArrayContains(Binary, Predicate, Func):
6947    arg_types = {"this": True, "expression": True, "json_type": False}
6948    _sql_names = ["JSON_ARRAY_CONTAINS"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonarraycontains'
class JSONArrayInsert(Func):
6951class JSONArrayInsert(Func):
6952    arg_types = {"this": True, "expressions": True}
6953    is_var_len_args = True
6954    _sql_names = ["JSON_ARRAY_INSERT"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayinsert'
class ParseBignumeric(Func):
6957class ParseBignumeric(Func):
6958    pass
key = 'parsebignumeric'
class ParseNumeric(Func):
6961class ParseNumeric(Func):
6962    pass
key = 'parsenumeric'
class ParseJSON(Func):
6965class ParseJSON(Func):
6966    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6967    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6968    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6969    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class ParseUrl(Func):
6974class ParseUrl(Func):
6975    arg_types = {"this": True, "part_to_extract": False, "key": False, "permissive": False}
arg_types = {'this': True, 'part_to_extract': False, 'key': False, 'permissive': False}
key = 'parseurl'
class ParseIp(Func):
6978class ParseIp(Func):
6979    arg_types = {"this": True, "type": True, "permissive": False}
arg_types = {'this': True, 'type': True, 'permissive': False}
key = 'parseip'
class ParseTime(Func):
6982class ParseTime(Func):
6983    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'parsetime'
class ParseDatetime(Func):
6986class ParseDatetime(Func):
6987    arg_types = {"this": True, "format": False, "zone": False}
arg_types = {'this': True, 'format': False, 'zone': False}
key = 'parsedatetime'
class Least(Func):
6990class Least(Func):
6991    arg_types = {"this": True, "expressions": False}
6992    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6995class Left(Func):
6996    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Reverse(Func):
7003class Reverse(Func):
7004    pass
key = 'reverse'
class Length(Func):
7007class Length(Func):
7008    arg_types = {"this": True, "binary": False, "encoding": False}
7009    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class RtrimmedLength(Func):
7012class RtrimmedLength(Func):
7013    pass
key = 'rtrimmedlength'
class BitLength(Func):
7016class BitLength(Func):
7017    pass
key = 'bitlength'
class Levenshtein(Func):
7020class Levenshtein(Func):
7021    arg_types = {
7022        "this": True,
7023        "expression": False,
7024        "ins_cost": False,
7025        "del_cost": False,
7026        "sub_cost": False,
7027        "max_dist": False,
7028    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
7031class Ln(Func):
7032    pass
key = 'ln'
class Log(Func):
7035class Log(Func):
7036    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
7039class LogicalOr(AggFunc):
7040    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
7043class LogicalAnd(AggFunc):
7044    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
7047class Lower(Func):
7048    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
7051class Map(Func):
7052    arg_types = {"keys": False, "values": False}
7053
7054    @property
7055    def keys(self) -> t.List[Expression]:
7056        keys = self.args.get("keys")
7057        return keys.expressions if keys else []
7058
7059    @property
7060    def values(self) -> t.List[Expression]:
7061        values = self.args.get("values")
7062        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
7054    @property
7055    def keys(self) -> t.List[Expression]:
7056        keys = self.args.get("keys")
7057        return keys.expressions if keys else []
values: List[Expression]
7059    @property
7060    def values(self) -> t.List[Expression]:
7061        values = self.args.get("values")
7062        return values.expressions if values else []
key = 'map'
class ToMap(Func):
7066class ToMap(Func):
7067    pass
key = 'tomap'
class MapFromEntries(Func):
7070class MapFromEntries(Func):
7071    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
7075class ScopeResolution(Expression):
7076    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
7079class Stream(Expression):
7080    pass
key = 'stream'
class StarMap(Func):
7083class StarMap(Func):
7084    pass
key = 'starmap'
class VarMap(Func):
7087class VarMap(Func):
7088    arg_types = {"keys": True, "values": True}
7089    is_var_len_args = True
7090
7091    @property
7092    def keys(self) -> t.List[Expression]:
7093        return self.args["keys"].expressions
7094
7095    @property
7096    def values(self) -> t.List[Expression]:
7097        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
7091    @property
7092    def keys(self) -> t.List[Expression]:
7093        return self.args["keys"].expressions
values: List[Expression]
7095    @property
7096    def values(self) -> t.List[Expression]:
7097        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
7101class MatchAgainst(Func):
7102    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
7105class Max(AggFunc):
7106    arg_types = {"this": True, "expressions": False}
7107    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
7110class MD5(Func):
7111    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
7115class MD5Digest(Func):
7116    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class MD5NumberLower64(Func):
7120class MD5NumberLower64(Func):
7121    pass
key = 'md5numberlower64'
class MD5NumberUpper64(Func):
7125class MD5NumberUpper64(Func):
7126    pass
key = 'md5numberupper64'
class Median(AggFunc):
7129class Median(AggFunc):
7130    pass
key = 'median'
class Min(AggFunc):
7133class Min(AggFunc):
7134    arg_types = {"this": True, "expressions": False}
7135    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
7138class Month(Func):
7139    pass
key = 'month'
class AddMonths(Func):
7142class AddMonths(Func):
7143    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
7146class Nvl2(Func):
7147    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Ntile(AggFunc):
7150class Ntile(AggFunc):
7151    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ntile'
class Normalize(Func):
7154class Normalize(Func):
7155    arg_types = {"this": True, "form": False, "is_casefold": False}
arg_types = {'this': True, 'form': False, 'is_casefold': False}
key = 'normalize'
class Overlay(Func):
7158class Overlay(Func):
7159    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):
7163class Predict(Func):
7164    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class MLTranslate(Func):
7168class MLTranslate(Func):
7169    arg_types = {"this": True, "expression": True, "params_struct": True}
arg_types = {'this': True, 'expression': True, 'params_struct': True}
key = 'mltranslate'
class FeaturesAtTime(Func):
7173class FeaturesAtTime(Func):
7174    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
arg_types = {'this': True, 'time': False, 'num_rows': False, 'ignore_feature_nulls': False}
key = 'featuresattime'
class GenerateEmbedding(Func):
7178class GenerateEmbedding(Func):
7179    arg_types = {"this": True, "expression": True, "params_struct": False, "is_text": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False, 'is_text': False}
key = 'generateembedding'
class MLForecast(Func):
7182class MLForecast(Func):
7183    arg_types = {"this": True, "expression": False, "params_struct": False}
arg_types = {'this': True, 'expression': False, 'params_struct': False}
key = 'mlforecast'
class ModelAttribute(Expression):
7188class ModelAttribute(Expression):
7189    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'modelattribute'
class VectorSearch(Func):
7193class VectorSearch(Func):
7194    arg_types = {
7195        "this": True,
7196        "column_to_search": True,
7197        "query_table": True,
7198        "query_column_to_search": False,
7199        "top_k": False,
7200        "distance_type": False,
7201        "options": False,
7202    }
arg_types = {'this': True, 'column_to_search': True, 'query_table': True, 'query_column_to_search': False, 'top_k': False, 'distance_type': False, 'options': False}
key = 'vectorsearch'
class Pow(Binary, Func):
7205class Pow(Binary, Func):
7206    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
7209class PercentileCont(AggFunc):
7210    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
7213class PercentileDisc(AggFunc):
7214    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class PercentRank(AggFunc):
7217class PercentRank(AggFunc):
7218    arg_types = {"expressions": False}
7219    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'percentrank'
class Quantile(AggFunc):
7222class Quantile(AggFunc):
7223    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
7226class ApproxQuantile(Quantile):
7227    arg_types = {
7228        "this": True,
7229        "quantile": True,
7230        "accuracy": False,
7231        "weight": False,
7232        "error_tolerance": False,
7233    }
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False, 'error_tolerance': False}
key = 'approxquantile'
class Quarter(Func):
7236class Quarter(Func):
7237    pass
key = 'quarter'
class Rand(Func):
7242class Rand(Func):
7243    _sql_names = ["RAND", "RANDOM"]
7244    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
7247class Randn(Func):
7248    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
7251class RangeN(Func):
7252    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class RangeBucket(Func):
7255class RangeBucket(Func):
7256    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'rangebucket'
class Rank(AggFunc):
7259class Rank(AggFunc):
7260    arg_types = {"expressions": False}
7261    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'rank'
class ReadCSV(Func):
7264class ReadCSV(Func):
7265    _sql_names = ["READ_CSV"]
7266    is_var_len_args = True
7267    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
7270class Reduce(Func):
7271    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):
7274class RegexpExtract(Func):
7275    arg_types = {
7276        "this": True,
7277        "expression": True,
7278        "position": False,
7279        "occurrence": False,
7280        "parameters": False,
7281        "group": False,
7282    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
7285class RegexpExtractAll(Func):
7286    arg_types = {
7287        "this": True,
7288        "expression": True,
7289        "position": False,
7290        "occurrence": False,
7291        "parameters": False,
7292        "group": False,
7293    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
7296class RegexpReplace(Func):
7297    arg_types = {
7298        "this": True,
7299        "expression": True,
7300        "replacement": False,
7301        "position": False,
7302        "occurrence": False,
7303        "modifiers": False,
7304    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
7307class RegexpLike(Binary, Func):
7308    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
7311class RegexpILike(Binary, Func):
7312    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpFullMatch(Binary, Func):
7315class RegexpFullMatch(Binary, Func):
7316    arg_types = {"this": True, "expression": True, "options": False}
arg_types = {'this': True, 'expression': True, 'options': False}
key = 'regexpfullmatch'
class RegexpInstr(Func):
7319class RegexpInstr(Func):
7320    arg_types = {
7321        "this": True,
7322        "expression": True,
7323        "position": False,
7324        "occurrence": False,
7325        "option": False,
7326        "parameters": False,
7327        "group": False,
7328    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'option': False, 'parameters': False, 'group': False}
key = 'regexpinstr'
class RegexpSplit(Func):
7333class RegexpSplit(Func):
7334    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class RegexpCount(Func):
7337class RegexpCount(Func):
7338    arg_types = {
7339        "this": True,
7340        "expression": True,
7341        "position": False,
7342        "parameters": False,
7343    }
arg_types = {'this': True, 'expression': True, 'position': False, 'parameters': False}
key = 'regexpcount'
class Repeat(Func):
7346class Repeat(Func):
7347    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
7351class Replace(Func):
7352    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
7357class Round(Func):
7358    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
7361class RowNumber(Func):
7362    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeAdd(Func):
7365class SafeAdd(Func):
7366    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safeadd'
class SafeDivide(Func):
7369class SafeDivide(Func):
7370    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SafeMultiply(Func):
7373class SafeMultiply(Func):
7374    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safemultiply'
class SafeNegate(Func):
7377class SafeNegate(Func):
7378    pass
key = 'safenegate'
class SafeSubtract(Func):
7381class SafeSubtract(Func):
7382    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safesubtract'
class SafeConvertBytesToString(Func):
7385class SafeConvertBytesToString(Func):
7386    pass
key = 'safeconvertbytestostring'
class SHA(Func):
7389class SHA(Func):
7390    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
7393class SHA2(Func):
7394    _sql_names = ["SHA2"]
7395    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SHA1Digest(Func):
7399class SHA1Digest(Func):
7400    pass
key = 'sha1digest'
class SHA2Digest(Func):
7404class SHA2Digest(Func):
7405    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2digest'
class Sign(Func):
7408class Sign(Func):
7409    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
7412class SortArray(Func):
7413    arg_types = {"this": True, "asc": False, "nulls_first": False}
arg_types = {'this': True, 'asc': False, 'nulls_first': False}
key = 'sortarray'
class Soundex(Func):
7416class Soundex(Func):
7417    pass
key = 'soundex'
class SoundexP123(Func):
7421class SoundexP123(Func):
7422    pass
key = 'soundexp123'
class Split(Func):
7425class Split(Func):
7426    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
7432class SplitPart(Func):
7433    arg_types = {"this": True, "delimiter": False, "part_index": False}
arg_types = {'this': True, 'delimiter': False, 'part_index': False}
key = 'splitpart'
class Substring(Func):
7438class Substring(Func):
7439    _sql_names = ["SUBSTRING", "SUBSTR"]
7440    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
7443class SubstringIndex(Func):
7444    """
7445    SUBSTRING_INDEX(str, delim, count)
7446
7447    *count* > 0  → left slice before the *count*-th delimiter
7448    *count* < 0  → right slice after the |count|-th delimiter
7449    """
7450
7451    arg_types = {"this": True, "delimiter": True, "count": True}

SUBSTRING_INDEX(str, delim, count)

count > 0 → left slice before the count-th delimiter count < 0 → right slice after the |count|-th delimiter

arg_types = {'this': True, 'delimiter': True, 'count': True}
key = 'substringindex'
class StandardHash(Func):
7454class StandardHash(Func):
7455    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
7458class StartsWith(Func):
7459    _sql_names = ["STARTS_WITH", "STARTSWITH"]
7460    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
7463class EndsWith(Func):
7464    _sql_names = ["ENDS_WITH", "ENDSWITH"]
7465    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
7468class StrPosition(Func):
7469    arg_types = {
7470        "this": True,
7471        "substr": True,
7472        "position": False,
7473        "occurrence": False,
7474    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
7490class StrToDate(Func):
7491    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
7494class StrToTime(Func):
7495    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):
7500class StrToUnix(Func):
7501    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
7506class StrToMap(Func):
7507    arg_types = {
7508        "this": True,
7509        "pair_delim": False,
7510        "key_value_delim": False,
7511        "duplicate_resolution_callback": False,
7512    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
7515class NumberToStr(Func):
7516    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
7519class FromBase(Func):
7520    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
7523class Space(Func):
7524    """
7525    SPACE(n) → string consisting of n blank characters
7526    """
7527
7528    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
7531class Struct(Func):
7532    arg_types = {"expressions": False}
7533    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
7536class StructExtract(Func):
7537    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
7542class Stuff(Func):
7543    _sql_names = ["STUFF", "INSERT"]
7544    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):
7547class Sum(AggFunc):
7548    pass
key = 'sum'
class Sqrt(Func):
7551class Sqrt(Func):
7552    pass
key = 'sqrt'
class Stddev(AggFunc):
7555class Stddev(AggFunc):
7556    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
7559class StddevPop(AggFunc):
7560    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
7563class StddevSamp(AggFunc):
7564    pass
key = 'stddevsamp'
class Time(Func):
7568class Time(Func):
7569    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
7572class TimeToStr(Func):
7573    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):
7576class TimeToTimeStr(Func):
7577    pass
key = 'timetotimestr'
class TimeToUnix(Func):
7580class TimeToUnix(Func):
7581    pass
key = 'timetounix'
class TimeStrToDate(Func):
7584class TimeStrToDate(Func):
7585    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
7588class TimeStrToTime(Func):
7589    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
7592class TimeStrToUnix(Func):
7593    pass
key = 'timestrtounix'
class Trim(Func):
7596class Trim(Func):
7597    arg_types = {
7598        "this": True,
7599        "expression": False,
7600        "position": False,
7601        "collation": False,
7602    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
7605class TsOrDsAdd(Func, TimeUnit):
7606    # return_type is used to correctly cast the arguments of this expression when transpiling it
7607    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
7608
7609    @property
7610    def return_type(self) -> DataType:
7611        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
7609    @property
7610    def return_type(self) -> DataType:
7611        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
7614class TsOrDsDiff(Func, TimeUnit):
7615    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
7618class TsOrDsToDateStr(Func):
7619    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
7622class TsOrDsToDate(Func):
7623    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
7626class TsOrDsToDatetime(Func):
7627    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
7630class TsOrDsToTime(Func):
7631    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
7634class TsOrDsToTimestamp(Func):
7635    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
7638class TsOrDiToDi(Func):
7639    pass
key = 'tsorditodi'
class Unhex(Func):
7642class Unhex(Func):
7643    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7646class Unicode(Func):
7647    pass
key = 'unicode'
class UnixDate(Func):
7651class UnixDate(Func):
7652    pass
key = 'unixdate'
class UnixToStr(Func):
7655class UnixToStr(Func):
7656    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7661class UnixToTime(Func):
7662    arg_types = {
7663        "this": True,
7664        "scale": False,
7665        "zone": False,
7666        "hours": False,
7667        "minutes": False,
7668        "format": False,
7669    }
7670
7671    SECONDS = Literal.number(0)
7672    DECIS = Literal.number(1)
7673    CENTIS = Literal.number(2)
7674    MILLIS = Literal.number(3)
7675    DECIMILLIS = Literal.number(4)
7676    CENTIMILLIS = Literal.number(5)
7677    MICROS = Literal.number(6)
7678    DECIMICROS = Literal.number(7)
7679    CENTIMICROS = Literal.number(8)
7680    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):
7683class UnixToTimeStr(Func):
7684    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7687class UnixSeconds(Func):
7688    pass
key = 'unixseconds'
class UnixMicros(Func):
7691class UnixMicros(Func):
7692    pass
key = 'unixmicros'
class UnixMillis(Func):
7695class UnixMillis(Func):
7696    pass
key = 'unixmillis'
class Uuid(Func):
7699class Uuid(Func):
7700    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7701
7702    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7705class TimestampFromParts(Func):
7706    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7707    arg_types = {
7708        "year": True,
7709        "month": True,
7710        "day": True,
7711        "hour": True,
7712        "min": True,
7713        "sec": True,
7714        "nano": False,
7715        "zone": False,
7716        "milli": False,
7717    }
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):
7720class Upper(Func):
7721    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7724class Corr(Binary, AggFunc):
7725    pass
key = 'corr'
class CumeDist(AggFunc):
7729class CumeDist(AggFunc):
7730    arg_types = {"expressions": False}
7731    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'cumedist'
class Variance(AggFunc):
7734class Variance(AggFunc):
7735    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7738class VariancePop(AggFunc):
7739    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7742class CovarSamp(Binary, AggFunc):
7743    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7746class CovarPop(Binary, AggFunc):
7747    pass
key = 'covarpop'
class Week(Func):
7750class Week(Func):
7751    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class WeekStart(Expression):
7754class WeekStart(Expression):
7755    pass
key = 'weekstart'
class XMLElement(Func):
7758class XMLElement(Func):
7759    _sql_names = ["XMLELEMENT"]
7760    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7763class XMLTable(Func):
7764    arg_types = {
7765        "this": True,
7766        "namespaces": False,
7767        "passing": False,
7768        "columns": False,
7769        "by_ref": False,
7770    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7773class XMLNamespace(Expression):
7774    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7778class XMLKeyValueOption(Expression):
7779    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7782class Year(Func):
7783    pass
key = 'year'
class Use(Expression):
7786class Use(Expression):
7787    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7790class Merge(DML):
7791    arg_types = {
7792        "this": True,
7793        "using": True,
7794        "on": True,
7795        "whens": True,
7796        "with": False,
7797        "returning": False,
7798    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7801class When(Expression):
7802    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class Whens(Expression):
7805class Whens(Expression):
7806    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7807
7808    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7813class NextValueFor(Func):
7814    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7819class Semicolon(Expression):
7820    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7825class TableColumn(Expression):
7826    pass
key = 'tablecolumn'
ALL_FUNCTIONS = [<class 'AIAgg'>, <class 'AIClassify'>, <class 'AISummarizeAgg'>, <class 'Abs'>, <class 'Acos'>, <class 'Acosh'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxQuantiles'>, <class 'ApproxTopK'>, <class 'ApproxTopSum'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConcatAgg'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayFirst'>, <class 'ArrayIntersect'>, <class 'ArrayLast'>, <class 'ArrayOverlaps'>, <class 'ArrayRemove'>, <class 'ArrayReverse'>, <class 'ArraySize'>, <class 'ArraySlice'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Ascii'>, <class 'Asin'>, <class 'Asinh'>, <class 'Atan'>, <class 'Atan2'>, <class 'Atanh'>, <class 'Avg'>, <class 'Base64DecodeBinary'>, <class 'Base64DecodeString'>, <class 'Base64Encode'>, <class 'BitLength'>, <class 'BitwiseAndAgg'>, <class 'BitwiseCountAgg'>, <class 'BitwiseOrAgg'>, <class 'BitwiseXorAgg'>, <class 'ByteLength'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'CodePointsToBytes'>, <class 'CodePointsToString'>, <class 'Collate'>, <class 'Collation'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Compress'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'Cos'>, <class 'Cosh'>, <class 'CosineDistance'>, <class 'Cot'>, <class 'Coth'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'Csc'>, <class 'Csch'>, <class 'CumeDist'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentTimestampLTZ'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateFromUnixDate'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DecodeCase'>, <class 'DecompressBinary'>, <class 'DecompressString'>, <class 'Degrees'>, <class 'DenseRank'>, <class 'DiToDate'>, <class 'Encode'>, <class 'EndsWith'>, <class 'EuclideanDistance'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'Factorial'>, <class 'FarmFingerprint'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Float64'>, <class 'Floor'>, <class 'Format'>, <class 'FromBase'>, <class 'FromBase32'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateEmbedding'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'GetExtract'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Grouping'>, <class 'Hex'>, <class 'HexDecodeString'>, <class 'HexEncode'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayAppend'>, <class 'JSONArrayContains'>, <class 'JSONArrayInsert'>, <class 'JSONBContains'>, <class 'JSONBContainsAllTopKeys'>, <class 'JSONBContainsAnyTopKeys'>, <class 'JSONBDeleteAtPath'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONBool'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONKeysAtDepth'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONRemove'>, <class 'JSONSet'>, <class 'JSONStripNulls'>, <class 'JSONTable'>, <class 'JSONType'>, <class 'JSONValueArray'>, <class 'JarowinklerSimilarity'>, <class 'JustifyDays'>, <class 'JustifyHours'>, <class 'JustifyInterval'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'LaxBool'>, <class 'LaxFloat64'>, <class 'LaxInt64'>, <class 'LaxString'>, <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 'MD5NumberLower64'>, <class 'MD5NumberUpper64'>, <class 'MLForecast'>, <class 'MLTranslate'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Ntile'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseBignumeric'>, <class 'ParseDatetime'>, <class 'ParseIp'>, <class 'ParseJSON'>, <class 'ParseNumeric'>, <class 'ParseTime'>, <class 'ParseUrl'>, <class 'PercentRank'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeBucket'>, <class 'RangeN'>, <class 'Rank'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpCount'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpFullMatch'>, <class 'RegexpILike'>, <class 'RegexpInstr'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Replace'>, <class 'Reverse'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'RtrimmedLength'>, <class 'SHA'>, <class 'SHA1Digest'>, <class 'SHA2'>, <class 'SHA2Digest'>, <class 'SafeAdd'>, <class 'SafeConvertBytesToString'>, <class 'SafeDivide'>, <class 'SafeMultiply'>, <class 'SafeNegate'>, <class 'SafeSubtract'>, <class 'Search'>, <class 'Sec'>, <class 'Sech'>, <class 'Sign'>, <class 'Sin'>, <class 'Sinh'>, <class 'SortArray'>, <class 'Soundex'>, <class 'SoundexP123'>, <class 'Space'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StDistance'>, <class 'StPoint'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'SubstringIndex'>, <class 'Sum'>, <class 'Tan'>, <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 'ToBase32'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToCodePoints'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Translate'>, <class 'Trim'>, <class 'Try'>, <class 'TryBase64DecodeBinary'>, <class 'TryBase64DecodeString'>, <class 'TryCast'>, <class 'TryHexDecodeBinary'>, <class 'TryHexDecodeString'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Typeof'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixMicros'>, <class 'UnixMillis'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'UtcDate'>, <class 'UtcTime'>, <class 'UtcTimestamp'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'VectorSearch'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'AI_AGG': <class 'AIAgg'>, 'AI_CLASSIFY': <class 'AIClassify'>, 'AI_SUMMARIZE_AGG': <class 'AISummarizeAgg'>, 'ABS': <class 'Abs'>, 'ACOS': <class 'Acos'>, 'ACOSH': <class 'Acosh'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_QUANTILES': <class 'ApproxQuantiles'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'APPROX_TOP_SUM': <class 'ApproxTopSum'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONCAT_AGG': <class 'ArrayConcatAgg'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_FIRST': <class 'ArrayFirst'>, 'ARRAY_INTERSECT': <class 'ArrayIntersect'>, 'ARRAY_INTERSECTION': <class 'ArrayIntersect'>, 'ARRAY_LAST': <class 'ArrayLast'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_REMOVE': <class 'ArrayRemove'>, 'ARRAY_REVERSE': <class 'ArrayReverse'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SLICE': <class 'ArraySlice'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'ASCII': <class 'Ascii'>, 'ASIN': <class 'Asin'>, 'ASINH': <class 'Asinh'>, 'ATAN': <class 'Atan'>, 'ATAN2': <class 'Atan2'>, 'ATANH': <class 'Atanh'>, 'AVG': <class 'Avg'>, 'BASE64_DECODE_BINARY': <class 'Base64DecodeBinary'>, 'BASE64_DECODE_STRING': <class 'Base64DecodeString'>, 'BASE64_ENCODE': <class 'Base64Encode'>, 'BIT_LENGTH': <class 'BitLength'>, 'BITWISE_AND_AGG': <class 'BitwiseAndAgg'>, 'BITWISE_COUNT_AGG': <class 'BitwiseCountAgg'>, 'BITWISE_OR_AGG': <class 'BitwiseOrAgg'>, 'BITWISE_XOR_AGG': <class 'BitwiseXorAgg'>, 'BYTE_LENGTH': <class 'ByteLength'>, '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'>, 'CODE_POINTS_TO_BYTES': <class 'CodePointsToBytes'>, 'CODE_POINTS_TO_STRING': <class 'CodePointsToString'>, 'COLLATE': <class 'Collate'>, 'COLLATION': <class 'Collation'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'COMPRESS': <class 'Compress'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CONVERT_TO_CHARSET': <class 'ConvertToCharset'>, 'CORR': <class 'Corr'>, 'COS': <class 'Cos'>, 'COSH': <class 'Cosh'>, 'COSINE_DISTANCE': <class 'CosineDistance'>, 'COT': <class 'Cot'>, 'COTH': <class 'Coth'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CSC': <class 'Csc'>, 'CSCH': <class 'Csch'>, 'CUME_DIST': <class 'CumeDist'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_TIMESTAMP_L_T_Z': <class 'CurrentTimestampLTZ'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_FROM_UNIX_DATE': <class 'DateFromUnixDate'>, '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'>, 'DECODE_CASE': <class 'DecodeCase'>, 'DECOMPRESS_BINARY': <class 'DecompressBinary'>, 'DECOMPRESS_STRING': <class 'DecompressString'>, 'DEGREES': <class 'Degrees'>, 'DENSE_RANK': <class 'DenseRank'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'ENDS_WITH': <class 'EndsWith'>, 'ENDSWITH': <class 'EndsWith'>, 'EUCLIDEAN_DISTANCE': <class 'EuclideanDistance'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FACTORIAL': <class 'Factorial'>, 'FARM_FINGERPRINT': <class 'FarmFingerprint'>, 'FARMFINGERPRINT64': <class 'FarmFingerprint'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOAT64': <class 'Float64'>, 'FLOOR': <class 'Floor'>, 'FORMAT': <class 'Format'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE32': <class 'FromBase32'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_EMBEDDING': <class 'GenerateEmbedding'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GET_EXTRACT': <class 'GetExtract'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'GROUPING': <class 'Grouping'>, 'HEX': <class 'Hex'>, 'HEX_DECODE_STRING': <class 'HexDecodeString'>, 'HEX_ENCODE': <class 'HexEncode'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_ASCII': <class 'IsAscii'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_APPEND': <class 'JSONArrayAppend'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSON_ARRAY_INSERT': <class 'JSONArrayInsert'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'J_S_O_N_B_CONTAINS_ALL_TOP_KEYS': <class 'JSONBContainsAllTopKeys'>, 'J_S_O_N_B_CONTAINS_ANY_TOP_KEYS': <class 'JSONBContainsAnyTopKeys'>, 'J_S_O_N_B_DELETE_AT_PATH': <class 'JSONBDeleteAtPath'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_BOOL': <class 'JSONBool'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_KEYS_AT_DEPTH': <class 'JSONKeysAtDepth'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'JSON_REMOVE': <class 'JSONRemove'>, 'JSON_SET': <class 'JSONSet'>, 'JSON_STRIP_NULLS': <class 'JSONStripNulls'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'JSON_TYPE': <class 'JSONType'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'JAROWINKLER_SIMILARITY': <class 'JarowinklerSimilarity'>, 'JUSTIFY_DAYS': <class 'JustifyDays'>, 'JUSTIFY_HOURS': <class 'JustifyHours'>, 'JUSTIFY_INTERVAL': <class 'JustifyInterval'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LAX_BOOL': <class 'LaxBool'>, 'LAX_FLOAT64': <class 'LaxFloat64'>, 'LAX_INT64': <class 'LaxInt64'>, 'LAX_STRING': <class 'LaxString'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'CHAR_LENGTH': <class 'Length'>, 'CHARACTER_LENGTH': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'M_D5_NUMBER_LOWER64': <class 'MD5NumberLower64'>, 'M_D5_NUMBER_UPPER64': <class 'MD5NumberUpper64'>, 'M_L_FORECAST': <class 'MLForecast'>, 'M_L_TRANSLATE': <class 'MLTranslate'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NTILE': <class 'Ntile'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OR': <class 'Or'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_BIGNUMERIC': <class 'ParseBignumeric'>, 'PARSE_DATETIME': <class 'ParseDatetime'>, 'PARSE_IP': <class 'ParseIp'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PARSE_NUMERIC': <class 'ParseNumeric'>, 'PARSE_TIME': <class 'ParseTime'>, 'PARSE_URL': <class 'ParseUrl'>, 'PERCENT_RANK': <class 'PercentRank'>, '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_BUCKET': <class 'RangeBucket'>, 'RANGE_N': <class 'RangeN'>, 'RANK': <class 'Rank'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_COUNT': <class 'RegexpCount'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_FULL_MATCH': <class 'RegexpFullMatch'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_INSTR': <class 'RegexpInstr'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'REPLACE': <class 'Replace'>, 'REVERSE': <class 'Reverse'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'RTRIMMED_LENGTH': <class 'RtrimmedLength'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'S_H_A1_DIGEST': <class 'SHA1Digest'>, 'SHA2': <class 'SHA2'>, 'S_H_A2_DIGEST': <class 'SHA2Digest'>, 'SAFE_ADD': <class 'SafeAdd'>, 'SAFE_CONVERT_BYTES_TO_STRING': <class 'SafeConvertBytesToString'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SAFE_MULTIPLY': <class 'SafeMultiply'>, 'SAFE_NEGATE': <class 'SafeNegate'>, 'SAFE_SUBTRACT': <class 'SafeSubtract'>, 'SEARCH': <class 'Search'>, 'SEC': <class 'Sec'>, 'SECH': <class 'Sech'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SIN': <class 'Sin'>, 'SINH': <class 'Sinh'>, 'SORT_ARRAY': <class 'SortArray'>, 'SOUNDEX': <class 'Soundex'>, 'SOUNDEX_P123': <class 'SoundexP123'>, 'SPACE': <class 'Space'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'ST_DISTANCE': <class 'StDistance'>, 'ST_POINT': <class 'StPoint'>, 'ST_MAKEPOINT': <class 'StPoint'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRTOK_TO_ARRAY': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUBSTRING_INDEX': <class 'SubstringIndex'>, 'SUM': <class 'Sum'>, 'TAN': <class 'Tan'>, '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_BASE32': <class 'ToBase32'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_CODE_POINTS': <class 'ToCodePoints'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRANSLATE': <class 'Translate'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_BASE64_DECODE_BINARY': <class 'TryBase64DecodeBinary'>, 'TRY_BASE64_DECODE_STRING': <class 'TryBase64DecodeString'>, 'TRY_CAST': <class 'TryCast'>, 'TRY_HEX_DECODE_BINARY': <class 'TryHexDecodeBinary'>, 'TRY_HEX_DECODE_STRING': <class 'TryHexDecodeString'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'TYPEOF': <class 'Typeof'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_MICROS': <class 'UnixMicros'>, 'UNIX_MILLIS': <class 'UnixMillis'>, 'UNIX_SECONDS': <class 'UnixSeconds'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'UTC_DATE': <class 'UtcDate'>, 'UTC_TIME': <class 'UtcTime'>, 'UTC_TIMESTAMP': <class 'UtcTimestamp'>, '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'>, 'VECTOR_SEARCH': <class 'VectorSearch'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'XMLELEMENT': <class 'XMLElement'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
7862def maybe_parse(
7863    sql_or_expression: ExpOrStr,
7864    *,
7865    into: t.Optional[IntoType] = None,
7866    dialect: DialectType = None,
7867    prefix: t.Optional[str] = None,
7868    copy: bool = False,
7869    **opts,
7870) -> Expression:
7871    """Gracefully handle a possible string or expression.
7872
7873    Example:
7874        >>> maybe_parse("1")
7875        Literal(this=1, is_string=False)
7876        >>> maybe_parse(to_identifier("x"))
7877        Identifier(this=x, quoted=False)
7878
7879    Args:
7880        sql_or_expression: the SQL code string or an expression
7881        into: the SQLGlot Expression to parse into
7882        dialect: the dialect used to parse the input expressions (in the case that an
7883            input expression is a SQL string).
7884        prefix: a string to prefix the sql with before it gets parsed
7885            (automatically includes a space)
7886        copy: whether to copy the expression.
7887        **opts: other options to use to parse the input expressions (again, in the case
7888            that an input expression is a SQL string).
7889
7890    Returns:
7891        Expression: the parsed or given expression.
7892    """
7893    if isinstance(sql_or_expression, Expression):
7894        if copy:
7895            return sql_or_expression.copy()
7896        return sql_or_expression
7897
7898    if sql_or_expression is None:
7899        raise ParseError("SQL cannot be None")
7900
7901    import sqlglot
7902
7903    sql = str(sql_or_expression)
7904    if prefix:
7905        sql = f"{prefix} {sql}"
7906
7907    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):
7918def maybe_copy(instance, copy=True):
7919    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
8174def union(
8175    *expressions: ExpOrStr,
8176    distinct: bool = True,
8177    dialect: DialectType = None,
8178    copy: bool = True,
8179    **opts,
8180) -> Union:
8181    """
8182    Initializes a syntax tree for the `UNION` operation.
8183
8184    Example:
8185        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
8186        'SELECT * FROM foo UNION SELECT * FROM bla'
8187
8188    Args:
8189        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
8190            If `Expression` instances are passed, they will be used as-is.
8191        distinct: set the DISTINCT flag if and only if this is true.
8192        dialect: the dialect used to parse the input expression.
8193        copy: whether to copy the expression.
8194        opts: other options to use to parse the input expressions.
8195
8196    Returns:
8197        The new Union instance.
8198    """
8199    assert len(expressions) >= 2, "At least two expressions are required by `union`."
8200    return _apply_set_operation(
8201        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
8202    )

Initializes a syntax tree for the UNION operation.

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

The new Union instance.

def intersect( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
8205def intersect(
8206    *expressions: ExpOrStr,
8207    distinct: bool = True,
8208    dialect: DialectType = None,
8209    copy: bool = True,
8210    **opts,
8211) -> Intersect:
8212    """
8213    Initializes a syntax tree for the `INTERSECT` operation.
8214
8215    Example:
8216        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
8217        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
8218
8219    Args:
8220        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
8221            If `Expression` instances are passed, they will be used as-is.
8222        distinct: set the DISTINCT flag if and only if this is true.
8223        dialect: the dialect used to parse the input expression.
8224        copy: whether to copy the expression.
8225        opts: other options to use to parse the input expressions.
8226
8227    Returns:
8228        The new Intersect instance.
8229    """
8230    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
8231    return _apply_set_operation(
8232        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
8233    )

Initializes a syntax tree for the INTERSECT operation.

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

The new Intersect instance.

def except_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
8236def except_(
8237    *expressions: ExpOrStr,
8238    distinct: bool = True,
8239    dialect: DialectType = None,
8240    copy: bool = True,
8241    **opts,
8242) -> Except:
8243    """
8244    Initializes a syntax tree for the `EXCEPT` operation.
8245
8246    Example:
8247        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
8248        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
8249
8250    Args:
8251        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
8252            If `Expression` instances are passed, they will be used as-is.
8253        distinct: set the DISTINCT flag if and only if this is true.
8254        dialect: the dialect used to parse the input expression.
8255        copy: whether to copy the expression.
8256        opts: other options to use to parse the input expressions.
8257
8258    Returns:
8259        The new Except instance.
8260    """
8261    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
8262    return _apply_set_operation(
8263        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
8264    )

Initializes a syntax tree for the EXCEPT operation.

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

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8267def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
8268    """
8269    Initializes a syntax tree from one or multiple SELECT expressions.
8270
8271    Example:
8272        >>> select("col1", "col2").from_("tbl").sql()
8273        'SELECT col1, col2 FROM tbl'
8274
8275    Args:
8276        *expressions: the SQL code string to parse as the expressions of a
8277            SELECT statement. If an Expression instance is passed, this is used as-is.
8278        dialect: the dialect used to parse the input expressions (in the case that an
8279            input expression is a SQL string).
8280        **opts: other options to use to parse the input expressions (again, in the case
8281            that an input expression is a SQL string).
8282
8283    Returns:
8284        Select: the syntax tree for the SELECT statement.
8285    """
8286    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

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

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8289def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
8290    """
8291    Initializes a syntax tree from a FROM expression.
8292
8293    Example:
8294        >>> from_("tbl").select("col1", "col2").sql()
8295        'SELECT col1, col2 FROM tbl'
8296
8297    Args:
8298        *expression: the SQL code string to parse as the FROM expressions of a
8299            SELECT statement. If an Expression instance is passed, this is used as-is.
8300        dialect: the dialect used to parse the input expression (in the case that the
8301            input expression is a SQL string).
8302        **opts: other options to use to parse the input expressions (again, in the case
8303            that the input expression is a SQL string).
8304
8305    Returns:
8306        Select: the syntax tree for the SELECT statement.
8307    """
8308    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

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

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Update:
8311def update(
8312    table: str | Table,
8313    properties: t.Optional[dict] = None,
8314    where: t.Optional[ExpOrStr] = None,
8315    from_: t.Optional[ExpOrStr] = None,
8316    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
8317    dialect: DialectType = None,
8318    **opts,
8319) -> Update:
8320    """
8321    Creates an update statement.
8322
8323    Example:
8324        >>> 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()
8325        "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"
8326
8327    Args:
8328        properties: dictionary of properties to SET which are
8329            auto converted to sql objects eg None -> NULL
8330        where: sql conditional parsed into a WHERE statement
8331        from_: sql statement parsed into a FROM statement
8332        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
8333        dialect: the dialect used to parse the input expressions.
8334        **opts: other options to use to parse the input expressions.
8335
8336    Returns:
8337        Update: the syntax tree for the UPDATE statement.
8338    """
8339    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
8340    if properties:
8341        update_expr.set(
8342            "expressions",
8343            [
8344                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
8345                for k, v in properties.items()
8346            ],
8347        )
8348    if from_:
8349        update_expr.set(
8350            "from",
8351            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
8352        )
8353    if isinstance(where, Condition):
8354        where = Where(this=where)
8355    if where:
8356        update_expr.set(
8357            "where",
8358            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
8359        )
8360    if with_:
8361        cte_list = [
8362            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
8363            for alias, qry in with_.items()
8364        ]
8365        update_expr.set(
8366            "with",
8367            With(expressions=cte_list),
8368        )
8369    return update_expr

Creates an update statement.

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

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Delete:
8372def delete(
8373    table: ExpOrStr,
8374    where: t.Optional[ExpOrStr] = None,
8375    returning: t.Optional[ExpOrStr] = None,
8376    dialect: DialectType = None,
8377    **opts,
8378) -> Delete:
8379    """
8380    Builds a delete statement.
8381
8382    Example:
8383        >>> delete("my_table", where="id > 1").sql()
8384        'DELETE FROM my_table WHERE id > 1'
8385
8386    Args:
8387        where: sql conditional parsed into a WHERE statement
8388        returning: sql conditional parsed into a RETURNING statement
8389        dialect: the dialect used to parse the input expressions.
8390        **opts: other options to use to parse the input expressions.
8391
8392    Returns:
8393        Delete: the syntax tree for the DELETE statement.
8394    """
8395    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
8396    if where:
8397        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
8398    if returning:
8399        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
8400    return delete_expr

Builds a delete statement.

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

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
8403def insert(
8404    expression: ExpOrStr,
8405    into: ExpOrStr,
8406    columns: t.Optional[t.Sequence[str | Identifier]] = None,
8407    overwrite: t.Optional[bool] = None,
8408    returning: t.Optional[ExpOrStr] = None,
8409    dialect: DialectType = None,
8410    copy: bool = True,
8411    **opts,
8412) -> Insert:
8413    """
8414    Builds an INSERT statement.
8415
8416    Example:
8417        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
8418        'INSERT INTO tbl VALUES (1, 2, 3)'
8419
8420    Args:
8421        expression: the sql string or expression of the INSERT statement
8422        into: the tbl to insert data to.
8423        columns: optionally the table's column names.
8424        overwrite: whether to INSERT OVERWRITE or not.
8425        returning: sql conditional parsed into a RETURNING statement
8426        dialect: the dialect used to parse the input expressions.
8427        copy: whether to copy the expression.
8428        **opts: other options to use to parse the input expressions.
8429
8430    Returns:
8431        Insert: the syntax tree for the INSERT statement.
8432    """
8433    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8434    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
8435
8436    if columns:
8437        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
8438
8439    insert = Insert(this=this, expression=expr, overwrite=overwrite)
8440
8441    if returning:
8442        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
8443
8444    return insert

Builds an INSERT statement.

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

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
8447def merge(
8448    *when_exprs: ExpOrStr,
8449    into: ExpOrStr,
8450    using: ExpOrStr,
8451    on: ExpOrStr,
8452    returning: t.Optional[ExpOrStr] = None,
8453    dialect: DialectType = None,
8454    copy: bool = True,
8455    **opts,
8456) -> Merge:
8457    """
8458    Builds a MERGE statement.
8459
8460    Example:
8461        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
8462        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
8463        ...       into="my_table",
8464        ...       using="source_table",
8465        ...       on="my_table.id = source_table.id").sql()
8466        '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)'
8467
8468    Args:
8469        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
8470        into: The target table to merge data into.
8471        using: The source table to merge data from.
8472        on: The join condition for the merge.
8473        returning: The columns to return from the merge.
8474        dialect: The dialect used to parse the input expressions.
8475        copy: Whether to copy the expression.
8476        **opts: Other options to use to parse the input expressions.
8477
8478    Returns:
8479        Merge: The syntax tree for the MERGE statement.
8480    """
8481    expressions: t.List[Expression] = []
8482    for when_expr in when_exprs:
8483        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
8484        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
8485
8486    merge = Merge(
8487        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
8488        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
8489        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
8490        whens=Whens(expressions=expressions),
8491    )
8492    if returning:
8493        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
8494
8495    if isinstance(using_clause := merge.args.get("using"), Alias):
8496        using_clause.replace(alias_(using_clause.this, using_clause.args["alias"], table=True))
8497
8498    return merge

Builds a MERGE statement.

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

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
8501def condition(
8502    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
8503) -> Condition:
8504    """
8505    Initialize a logical condition expression.
8506
8507    Example:
8508        >>> condition("x=1").sql()
8509        'x = 1'
8510
8511        This is helpful for composing larger logical syntax trees:
8512        >>> where = condition("x=1")
8513        >>> where = where.and_("y=1")
8514        >>> Select().from_("tbl").select("*").where(where).sql()
8515        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
8516
8517    Args:
8518        *expression: the SQL code string to parse.
8519            If an Expression instance is passed, this is used as-is.
8520        dialect: the dialect used to parse the input expression (in the case that the
8521            input expression is a SQL string).
8522        copy: Whether to copy `expression` (only applies to expressions).
8523        **opts: other options to use to parse the input expressions (again, in the case
8524            that the input expression is a SQL string).
8525
8526    Returns:
8527        The new Condition instance
8528    """
8529    return maybe_parse(
8530        expression,
8531        into=Condition,
8532        dialect=dialect,
8533        copy=copy,
8534        **opts,
8535    )

Initialize a logical condition expression.

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

This is helpful for composing larger logical syntax trees:

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

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
8538def and_(
8539    *expressions: t.Optional[ExpOrStr],
8540    dialect: DialectType = None,
8541    copy: bool = True,
8542    wrap: bool = True,
8543    **opts,
8544) -> Condition:
8545    """
8546    Combine multiple conditions with an AND logical operator.
8547
8548    Example:
8549        >>> and_("x=1", and_("y=1", "z=1")).sql()
8550        'x = 1 AND (y = 1 AND z = 1)'
8551
8552    Args:
8553        *expressions: the SQL code strings to parse.
8554            If an Expression instance is passed, this is used as-is.
8555        dialect: the dialect used to parse the input expression.
8556        copy: whether to copy `expressions` (only applies to Expressions).
8557        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8558            precedence issues, but can be turned off when the produced AST is too deep and
8559            causes recursion-related issues.
8560        **opts: other options to use to parse the input expressions.
8561
8562    Returns:
8563        The new condition
8564    """
8565    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an AND logical operator.

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

The new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
8568def or_(
8569    *expressions: t.Optional[ExpOrStr],
8570    dialect: DialectType = None,
8571    copy: bool = True,
8572    wrap: bool = True,
8573    **opts,
8574) -> Condition:
8575    """
8576    Combine multiple conditions with an OR logical operator.
8577
8578    Example:
8579        >>> or_("x=1", or_("y=1", "z=1")).sql()
8580        'x = 1 OR (y = 1 OR z = 1)'
8581
8582    Args:
8583        *expressions: the SQL code strings to parse.
8584            If an Expression instance is passed, this is used as-is.
8585        dialect: the dialect used to parse the input expression.
8586        copy: whether to copy `expressions` (only applies to Expressions).
8587        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8588            precedence issues, but can be turned off when the produced AST is too deep and
8589            causes recursion-related issues.
8590        **opts: other options to use to parse the input expressions.
8591
8592    Returns:
8593        The new condition
8594    """
8595    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an OR logical operator.

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

The new condition

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
8598def xor(
8599    *expressions: t.Optional[ExpOrStr],
8600    dialect: DialectType = None,
8601    copy: bool = True,
8602    wrap: bool = True,
8603    **opts,
8604) -> Condition:
8605    """
8606    Combine multiple conditions with an XOR logical operator.
8607
8608    Example:
8609        >>> xor("x=1", xor("y=1", "z=1")).sql()
8610        'x = 1 XOR (y = 1 XOR z = 1)'
8611
8612    Args:
8613        *expressions: the SQL code strings to parse.
8614            If an Expression instance is passed, this is used as-is.
8615        dialect: the dialect used to parse the input expression.
8616        copy: whether to copy `expressions` (only applies to Expressions).
8617        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8618            precedence issues, but can be turned off when the produced AST is too deep and
8619            causes recursion-related issues.
8620        **opts: other options to use to parse the input expressions.
8621
8622    Returns:
8623        The new condition
8624    """
8625    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an XOR logical operator.

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

The new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
8628def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
8629    """
8630    Wrap a condition with a NOT operator.
8631
8632    Example:
8633        >>> not_("this_suit='black'").sql()
8634        "NOT this_suit = 'black'"
8635
8636    Args:
8637        expression: the SQL code string to parse.
8638            If an Expression instance is passed, this is used as-is.
8639        dialect: the dialect used to parse the input expression.
8640        copy: whether to copy the expression or not.
8641        **opts: other options to use to parse the input expressions.
8642
8643    Returns:
8644        The new condition.
8645    """
8646    this = condition(
8647        expression,
8648        dialect=dialect,
8649        copy=copy,
8650        **opts,
8651    )
8652    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:
8655def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
8656    """
8657    Wrap an expression in parentheses.
8658
8659    Example:
8660        >>> paren("5 + 3").sql()
8661        '(5 + 3)'
8662
8663    Args:
8664        expression: the SQL code string to parse.
8665            If an Expression instance is passed, this is used as-is.
8666        copy: whether to copy the expression or not.
8667
8668    Returns:
8669        The wrapped expression.
8670    """
8671    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):
8687def to_identifier(name, quoted=None, copy=True):
8688    """Builds an identifier.
8689
8690    Args:
8691        name: The name to turn into an identifier.
8692        quoted: Whether to force quote the identifier.
8693        copy: Whether to copy name if it's an Identifier.
8694
8695    Returns:
8696        The identifier ast node.
8697    """
8698
8699    if name is None:
8700        return None
8701
8702    if isinstance(name, Identifier):
8703        identifier = maybe_copy(name, copy)
8704    elif isinstance(name, str):
8705        identifier = Identifier(
8706            this=name,
8707            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8708        )
8709    else:
8710        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8711    return identifier

Builds an identifier.

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

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Identifier:
8714def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8715    """
8716    Parses a given string into an identifier.
8717
8718    Args:
8719        name: The name to parse into an identifier.
8720        dialect: The dialect to parse against.
8721
8722    Returns:
8723        The identifier ast node.
8724    """
8725    try:
8726        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8727    except (ParseError, TokenError):
8728        expression = to_identifier(name)
8729
8730    return expression

Parses a given string into an identifier.

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

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*(-?[0-9]+(?:\\.[0-9]+)?)\\s*([a-zA-Z]+)\\s*')
INTERVAL_DAY_TIME_RE = re.compile('\\s*-?\\s*\\d+(?:\\.\\d+)?\\s+(?:-?(?:\\d+:)?\\d+:\\d+(?:\\.\\d+)?|-?(?:\\d+:){1,2}|:)\\s*')
def to_interval( interval: str | Literal) -> Interval:
8749def to_interval(interval: str | Literal) -> Interval:
8750    """Builds an interval expression from a string like '1 day' or '5 months'."""
8751    if isinstance(interval, Literal):
8752        if not interval.is_string:
8753            raise ValueError("Invalid interval string.")
8754
8755        interval = interval.this
8756
8757    interval = maybe_parse(f"INTERVAL {interval}")
8758    assert isinstance(interval, Interval)
8759    return interval

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

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
8762def to_table(
8763    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8764) -> Table:
8765    """
8766    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8767    If a table is passed in then that table is returned.
8768
8769    Args:
8770        sql_path: a `[catalog].[schema].[table]` string.
8771        dialect: the source dialect according to which the table name will be parsed.
8772        copy: Whether to copy a table if it is passed in.
8773        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8774
8775    Returns:
8776        A table expression.
8777    """
8778    if isinstance(sql_path, Table):
8779        return maybe_copy(sql_path, copy=copy)
8780
8781    try:
8782        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8783    except ParseError:
8784        catalog, db, this = split_num_words(sql_path, ".", 3)
8785
8786        if not this:
8787            raise
8788
8789        table = table_(this, db=db, catalog=catalog)
8790
8791    for k, v in kwargs.items():
8792        table.set(k, v)
8793
8794    return table

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

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

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
8797def to_column(
8798    sql_path: str | Column,
8799    quoted: t.Optional[bool] = None,
8800    dialect: DialectType = None,
8801    copy: bool = True,
8802    **kwargs,
8803) -> Column:
8804    """
8805    Create a column from a `[table].[column]` sql path. Table is optional.
8806    If a column is passed in then that column is returned.
8807
8808    Args:
8809        sql_path: a `[table].[column]` string.
8810        quoted: Whether or not to force quote identifiers.
8811        dialect: the source dialect according to which the column name will be parsed.
8812        copy: Whether to copy a column if it is passed in.
8813        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8814
8815    Returns:
8816        A column expression.
8817    """
8818    if isinstance(sql_path, Column):
8819        return maybe_copy(sql_path, copy=copy)
8820
8821    try:
8822        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8823    except ParseError:
8824        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8825
8826    for k, v in kwargs.items():
8827        col.set(k, v)
8828
8829    if quoted:
8830        for i in col.find_all(Identifier):
8831            i.set("quoted", True)
8832
8833    return col

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

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

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts):
8836def alias_(
8837    expression: ExpOrStr,
8838    alias: t.Optional[str | Identifier],
8839    table: bool | t.Sequence[str | Identifier] = False,
8840    quoted: t.Optional[bool] = None,
8841    dialect: DialectType = None,
8842    copy: bool = True,
8843    **opts,
8844):
8845    """Create an Alias expression.
8846
8847    Example:
8848        >>> alias_('foo', 'bar').sql()
8849        'foo AS bar'
8850
8851        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8852        '(SELECT 1, 2) AS bar(a, b)'
8853
8854    Args:
8855        expression: the SQL code strings to parse.
8856            If an Expression instance is passed, this is used as-is.
8857        alias: the alias name to use. If the name has
8858            special characters it is quoted.
8859        table: Whether to create a table alias, can also be a list of columns.
8860        quoted: whether to quote the alias
8861        dialect: the dialect used to parse the input expression.
8862        copy: Whether to copy the expression.
8863        **opts: other options to use to parse the input expressions.
8864
8865    Returns:
8866        Alias: the aliased expression
8867    """
8868    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8869    alias = to_identifier(alias, quoted=quoted)
8870
8871    if table:
8872        table_alias = TableAlias(this=alias)
8873        exp.set("alias", table_alias)
8874
8875        if not isinstance(table, bool):
8876            for column in table:
8877                table_alias.append("columns", to_identifier(column, quoted=quoted))
8878
8879        return exp
8880
8881    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8882    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8883    # for the complete Window expression.
8884    #
8885    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8886
8887    if "alias" in exp.arg_types and not isinstance(exp, Window):
8888        exp.set("alias", alias)
8889        return exp
8890    return Alias(this=exp, alias=alias)

Create an Alias expression.

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

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8893def subquery(
8894    expression: ExpOrStr,
8895    alias: t.Optional[Identifier | str] = None,
8896    dialect: DialectType = None,
8897    **opts,
8898) -> Select:
8899    """
8900    Build a subquery expression that's selected from.
8901
8902    Example:
8903        >>> subquery('select x from tbl', 'bar').select('x').sql()
8904        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8905
8906    Args:
8907        expression: the SQL code strings to parse.
8908            If an Expression instance is passed, this is used as-is.
8909        alias: the alias name to use.
8910        dialect: the dialect used to parse the input expression.
8911        **opts: other options to use to parse the input expressions.
8912
8913    Returns:
8914        A new Select instance with the subquery expression included.
8915    """
8916
8917    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8918    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):
8949def column(
8950    col,
8951    table=None,
8952    db=None,
8953    catalog=None,
8954    *,
8955    fields=None,
8956    quoted=None,
8957    copy=True,
8958):
8959    """
8960    Build a Column.
8961
8962    Args:
8963        col: Column name.
8964        table: Table name.
8965        db: Database name.
8966        catalog: Catalog name.
8967        fields: Additional fields using dots.
8968        quoted: Whether to force quotes on the column's identifiers.
8969        copy: Whether to copy identifiers if passed in.
8970
8971    Returns:
8972        The new Column instance.
8973    """
8974    if not isinstance(col, Star):
8975        col = to_identifier(col, quoted=quoted, copy=copy)
8976
8977    this = Column(
8978        this=col,
8979        table=to_identifier(table, quoted=quoted, copy=copy),
8980        db=to_identifier(db, quoted=quoted, copy=copy),
8981        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8982    )
8983
8984    if fields:
8985        this = Dot.build(
8986            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8987        )
8988    return this

Build a Column.

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

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, Identifier, Dot, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8991def cast(
8992    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8993) -> Cast:
8994    """Cast an expression to a data type.
8995
8996    Example:
8997        >>> cast('x + 1', 'int').sql()
8998        'CAST(x + 1 AS INT)'
8999
9000    Args:
9001        expression: The expression to cast.
9002        to: The datatype to cast to.
9003        copy: Whether to copy the supplied expressions.
9004        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
9005            - The expression to be cast is already a exp.Cast expression
9006            - The existing cast is to a type that is logically equivalent to new type
9007
9008            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
9009            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
9010            and instead just return the original expression `CAST(x as DATETIME)`.
9011
9012            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
9013            mapping is applied in the target dialect generator.
9014
9015    Returns:
9016        The new Cast instance.
9017    """
9018    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
9019    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
9020
9021    # dont re-cast if the expression is already a cast to the correct type
9022    if isinstance(expr, Cast):
9023        from sqlglot.dialects.dialect import Dialect
9024
9025        target_dialect = Dialect.get_or_raise(dialect)
9026        type_mapping = target_dialect.generator_class.TYPE_MAPPING
9027
9028        existing_cast_type: DataType.Type = expr.to.this
9029        new_cast_type: DataType.Type = data_type.this
9030        types_are_equivalent = type_mapping.get(
9031            existing_cast_type, existing_cast_type.value
9032        ) == type_mapping.get(new_cast_type, new_cast_type.value)
9033
9034        if expr.is_type(data_type) or types_are_equivalent:
9035            return expr
9036
9037    expr = Cast(this=expr, to=data_type)
9038    expr.type = data_type
9039
9040    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:
9043def table_(
9044    table: Identifier | str,
9045    db: t.Optional[Identifier | str] = None,
9046    catalog: t.Optional[Identifier | str] = None,
9047    quoted: t.Optional[bool] = None,
9048    alias: t.Optional[Identifier | str] = None,
9049) -> Table:
9050    """Build a Table.
9051
9052    Args:
9053        table: Table name.
9054        db: Database name.
9055        catalog: Catalog name.
9056        quote: Whether to force quotes on the table's identifiers.
9057        alias: Table's alias.
9058
9059    Returns:
9060        The new Table instance.
9061    """
9062    return Table(
9063        this=to_identifier(table, quoted=quoted) if table else None,
9064        db=to_identifier(db, quoted=quoted) if db else None,
9065        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
9066        alias=TableAlias(this=to_identifier(alias)) if alias else None,
9067    )

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:
9070def values(
9071    values: t.Iterable[t.Tuple[t.Any, ...]],
9072    alias: t.Optional[str] = None,
9073    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
9074) -> Values:
9075    """Build VALUES statement.
9076
9077    Example:
9078        >>> values([(1, '2')]).sql()
9079        "VALUES (1, '2')"
9080
9081    Args:
9082        values: values statements that will be converted to SQL
9083        alias: optional alias
9084        columns: Optional list of ordered column names or ordered dictionary of column names to types.
9085         If either are provided then an alias is also required.
9086
9087    Returns:
9088        Values: the Values expression object
9089    """
9090    if columns and not alias:
9091        raise ValueError("Alias is required when providing columns")
9092
9093    return Values(
9094        expressions=[convert(tup) for tup in values],
9095        alias=(
9096            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
9097            if columns
9098            else (TableAlias(this=to_identifier(alias)) if alias else None)
9099        ),
9100    )

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:
9103def var(name: t.Optional[ExpOrStr]) -> Var:
9104    """Build a SQL variable.
9105
9106    Example:
9107        >>> repr(var('x'))
9108        'Var(this=x)'
9109
9110        >>> repr(var(column('x', table='y')))
9111        'Var(this=x)'
9112
9113    Args:
9114        name: The name of the var or an expression who's name will become the var.
9115
9116    Returns:
9117        The new variable node.
9118    """
9119    if not name:
9120        raise ValueError("Cannot convert empty name into var.")
9121
9122    if isinstance(name, Expression):
9123        name = name.name
9124    return Var(this=name)

Build a SQL variable.

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

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
9127def rename_table(
9128    old_name: str | Table,
9129    new_name: str | Table,
9130    dialect: DialectType = None,
9131) -> Alter:
9132    """Build ALTER TABLE... RENAME... expression
9133
9134    Args:
9135        old_name: The old name of the table
9136        new_name: The new name of the table
9137        dialect: The dialect to parse the table.
9138
9139    Returns:
9140        Alter table expression
9141    """
9142    old_table = to_table(old_name, dialect=dialect)
9143    new_table = to_table(new_name, dialect=dialect)
9144    return Alter(
9145        this=old_table,
9146        kind="TABLE",
9147        actions=[
9148            AlterRename(this=new_table),
9149        ],
9150    )

Build ALTER TABLE... RENAME... expression

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

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
9153def rename_column(
9154    table_name: str | Table,
9155    old_column_name: str | Column,
9156    new_column_name: str | Column,
9157    exists: t.Optional[bool] = None,
9158    dialect: DialectType = None,
9159) -> Alter:
9160    """Build ALTER TABLE... RENAME COLUMN... expression
9161
9162    Args:
9163        table_name: Name of the table
9164        old_column: The old name of the column
9165        new_column: The new name of the column
9166        exists: Whether to add the `IF EXISTS` clause
9167        dialect: The dialect to parse the table/column.
9168
9169    Returns:
9170        Alter table expression
9171    """
9172    table = to_table(table_name, dialect=dialect)
9173    old_column = to_column(old_column_name, dialect=dialect)
9174    new_column = to_column(new_column_name, dialect=dialect)
9175    return Alter(
9176        this=table,
9177        kind="TABLE",
9178        actions=[
9179            RenameColumn(this=old_column, to=new_column, exists=exists),
9180        ],
9181    )

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:
9184def convert(value: t.Any, copy: bool = False) -> Expression:
9185    """Convert a python value into an expression object.
9186
9187    Raises an error if a conversion is not possible.
9188
9189    Args:
9190        value: A python object.
9191        copy: Whether to copy `value` (only applies to Expressions and collections).
9192
9193    Returns:
9194        The equivalent expression object.
9195    """
9196    if isinstance(value, Expression):
9197        return maybe_copy(value, copy)
9198    if isinstance(value, str):
9199        return Literal.string(value)
9200    if isinstance(value, bool):
9201        return Boolean(this=value)
9202    if value is None or (isinstance(value, float) and math.isnan(value)):
9203        return null()
9204    if isinstance(value, numbers.Number):
9205        return Literal.number(value)
9206    if isinstance(value, bytes):
9207        return HexString(this=value.hex())
9208    if isinstance(value, datetime.datetime):
9209        datetime_literal = Literal.string(value.isoformat(sep=" "))
9210
9211        tz = None
9212        if value.tzinfo:
9213            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
9214            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
9215            tz = Literal.string(str(value.tzinfo))
9216
9217        return TimeStrToTime(this=datetime_literal, zone=tz)
9218    if isinstance(value, datetime.date):
9219        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
9220        return DateStrToDate(this=date_literal)
9221    if isinstance(value, datetime.time):
9222        time_literal = Literal.string(value.isoformat())
9223        return TsOrDsToTime(this=time_literal)
9224    if isinstance(value, tuple):
9225        if hasattr(value, "_fields"):
9226            return Struct(
9227                expressions=[
9228                    PropertyEQ(
9229                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
9230                    )
9231                    for k in value._fields
9232                ]
9233            )
9234        return Tuple(expressions=[convert(v, copy=copy) for v in value])
9235    if isinstance(value, list):
9236        return Array(expressions=[convert(v, copy=copy) for v in value])
9237    if isinstance(value, dict):
9238        return Map(
9239            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
9240            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
9241        )
9242    if hasattr(value, "__dict__"):
9243        return Struct(
9244            expressions=[
9245                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
9246                for k, v in value.__dict__.items()
9247            ]
9248        )
9249    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:
9252def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
9253    """
9254    Replace children of an expression with the result of a lambda fun(child) -> exp.
9255    """
9256    for k, v in tuple(expression.args.items()):
9257        is_list_arg = type(v) is list
9258
9259        child_nodes = v if is_list_arg else [v]
9260        new_child_nodes = []
9261
9262        for cn in child_nodes:
9263            if isinstance(cn, Expression):
9264                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
9265                    new_child_nodes.append(child_node)
9266            else:
9267                new_child_nodes.append(cn)
9268
9269        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:
9272def replace_tree(
9273    expression: Expression,
9274    fun: t.Callable,
9275    prune: t.Optional[t.Callable[[Expression], bool]] = None,
9276) -> Expression:
9277    """
9278    Replace an entire tree with the result of function calls on each node.
9279
9280    This will be traversed in reverse dfs, so leaves first.
9281    If new nodes are created as a result of function calls, they will also be traversed.
9282    """
9283    stack = list(expression.dfs(prune=prune))
9284
9285    while stack:
9286        node = stack.pop()
9287        new_node = fun(node)
9288
9289        if new_node is not node:
9290            node.replace(new_node)
9291
9292            if isinstance(new_node, Expression):
9293                stack.append(new_node)
9294
9295    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]:
9298def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
9299    """
9300    Return all table names referenced through columns in an expression.
9301
9302    Example:
9303        >>> import sqlglot
9304        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
9305        ['a', 'c']
9306
9307    Args:
9308        expression: expression to find table names.
9309        exclude: a table name to exclude
9310
9311    Returns:
9312        A list of unique names.
9313    """
9314    return {
9315        table
9316        for table in (column.table for column in expression.find_all(Column))
9317        if table and table != exclude
9318    }

Return all table names referenced through columns in an expression.

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

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, identify: bool = False) -> str:
9321def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
9322    """Get the full name of a table as a string.
9323
9324    Args:
9325        table: Table expression node or string.
9326        dialect: The dialect to generate the table name for.
9327        identify: Determines when an identifier should be quoted. Possible values are:
9328            False (default): Never quote, except in cases where it's mandatory by the dialect.
9329            True: Always quote.
9330
9331    Examples:
9332        >>> from sqlglot import exp, parse_one
9333        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
9334        'a.b.c'
9335
9336    Returns:
9337        The table name.
9338    """
9339
9340    table = maybe_parse(table, into=Table, dialect=dialect)
9341
9342    if not table:
9343        raise ValueError(f"Cannot parse {table}")
9344
9345    return ".".join(
9346        (
9347            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
9348            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
9349            else part.name
9350        )
9351        for part in table.parts
9352    )

Get the full name of a table as a string.

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

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> str:
9355def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
9356    """Returns a case normalized table name without quotes.
9357
9358    Args:
9359        table: the table to normalize
9360        dialect: the dialect to use for normalization rules
9361        copy: whether to copy the expression.
9362
9363    Examples:
9364        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
9365        'A-B.c'
9366    """
9367    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
9368
9369    return ".".join(
9370        p.name
9371        for p in normalize_identifiers(
9372            to_table(table, dialect=dialect, copy=copy), dialect=dialect
9373        ).parts
9374    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> ~E:
9377def replace_tables(
9378    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
9379) -> E:
9380    """Replace all tables in expression according to the mapping.
9381
9382    Args:
9383        expression: expression node to be transformed and replaced.
9384        mapping: mapping of table names.
9385        dialect: the dialect of the mapping table
9386        copy: whether to copy the expression.
9387
9388    Examples:
9389        >>> from sqlglot import exp, parse_one
9390        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
9391        'SELECT * FROM c /* a.b */'
9392
9393    Returns:
9394        The mapped expression.
9395    """
9396
9397    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
9398
9399    def _replace_tables(node: Expression) -> Expression:
9400        if isinstance(node, Table) and node.meta.get("replace") is not False:
9401            original = normalize_table_name(node, dialect=dialect)
9402            new_name = mapping.get(original)
9403
9404            if new_name:
9405                table = to_table(
9406                    new_name,
9407                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
9408                    dialect=dialect,
9409                )
9410                table.add_comments([original])
9411                return table
9412        return node
9413
9414    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:
9417def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
9418    """Replace placeholders in an expression.
9419
9420    Args:
9421        expression: expression node to be transformed and replaced.
9422        args: positional names that will substitute unnamed placeholders in the given order.
9423        kwargs: keyword arguments that will substitute named placeholders.
9424
9425    Examples:
9426        >>> from sqlglot import exp, parse_one
9427        >>> replace_placeholders(
9428        ...     parse_one("select * from :tbl where ? = ?"),
9429        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
9430        ... ).sql()
9431        "SELECT * FROM foo WHERE str_col = 'b'"
9432
9433    Returns:
9434        The mapped expression.
9435    """
9436
9437    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
9438        if isinstance(node, Placeholder):
9439            if node.this:
9440                new_name = kwargs.get(node.this)
9441                if new_name is not None:
9442                    return convert(new_name)
9443            else:
9444                try:
9445                    return convert(next(args))
9446                except StopIteration:
9447                    pass
9448        return node
9449
9450    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

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

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Union[Query, Callable[[], Query]]], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Expression:
9453def expand(
9454    expression: Expression,
9455    sources: t.Dict[str, Query | t.Callable[[], Query]],
9456    dialect: DialectType = None,
9457    copy: bool = True,
9458) -> Expression:
9459    """Transforms an expression by expanding all referenced sources into subqueries.
9460
9461    Examples:
9462        >>> from sqlglot import parse_one
9463        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
9464        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
9465
9466        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
9467        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
9468
9469    Args:
9470        expression: The expression to expand.
9471        sources: A dict of name to query or a callable that provides a query on demand.
9472        dialect: The dialect of the sources dict or the callable.
9473        copy: Whether to copy the expression during transformation. Defaults to True.
9474
9475    Returns:
9476        The transformed expression.
9477    """
9478    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
9479
9480    def _expand(node: Expression):
9481        if isinstance(node, Table):
9482            name = normalize_table_name(node, dialect=dialect)
9483            source = normalized_sources.get(name)
9484
9485            if source:
9486                # Create a subquery with the same alias (or table name if no alias)
9487                parsed_source = source() if callable(source) else source
9488                subquery = parsed_source.subquery(node.alias or name)
9489                subquery.comments = [f"source: {name}"]
9490
9491                # Continue expanding within the subquery
9492                return subquery.transform(_expand, copy=False)
9493
9494        return node
9495
9496    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

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

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Func:
9499def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
9500    """
9501    Returns a Func expression.
9502
9503    Examples:
9504        >>> func("abs", 5).sql()
9505        'ABS(5)'
9506
9507        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
9508        'CAST(5 AS DOUBLE)'
9509
9510    Args:
9511        name: the name of the function to build.
9512        args: the args used to instantiate the function of interest.
9513        copy: whether to copy the argument expressions.
9514        dialect: the source dialect.
9515        kwargs: the kwargs used to instantiate the function of interest.
9516
9517    Note:
9518        The arguments `args` and `kwargs` are mutually exclusive.
9519
9520    Returns:
9521        An instance of the function of interest, or an anonymous function, if `name` doesn't
9522        correspond to an existing `sqlglot.expressions.Func` class.
9523    """
9524    if args and kwargs:
9525        raise ValueError("Can't use both args and kwargs to instantiate a function.")
9526
9527    from sqlglot.dialects.dialect import Dialect
9528
9529    dialect = Dialect.get_or_raise(dialect)
9530
9531    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
9532    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
9533
9534    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
9535    if constructor:
9536        if converted:
9537            if "dialect" in constructor.__code__.co_varnames:
9538                function = constructor(converted, dialect=dialect)
9539            else:
9540                function = constructor(converted)
9541        elif constructor.__name__ == "from_arg_list":
9542            function = constructor.__self__(**kwargs)  # type: ignore
9543        else:
9544            constructor = FUNCTION_BY_NAME.get(name.upper())
9545            if constructor:
9546                function = constructor(**kwargs)
9547            else:
9548                raise ValueError(
9549                    f"Unable to convert '{name}' into a Func. Either manually construct "
9550                    "the Func expression of interest or parse the function call."
9551                )
9552    else:
9553        kwargs = kwargs or {"expressions": converted}
9554        function = Anonymous(this=name, **kwargs)
9555
9556    for error_message in function.error_messages(converted):
9557        raise ValueError(error_message)
9558
9559    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:
9562def case(
9563    expression: t.Optional[ExpOrStr] = None,
9564    **opts,
9565) -> Case:
9566    """
9567    Initialize a CASE statement.
9568
9569    Example:
9570        case().when("a = 1", "foo").else_("bar")
9571
9572    Args:
9573        expression: Optionally, the input expression (not all dialects support this)
9574        **opts: Extra keyword arguments for parsing `expression`
9575    """
9576    if expression is not None:
9577        this = maybe_parse(expression, **opts)
9578    else:
9579        this = None
9580    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

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

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Array:
9583def array(
9584    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9585) -> Array:
9586    """
9587    Returns an array.
9588
9589    Examples:
9590        >>> array(1, 'x').sql()
9591        'ARRAY(1, x)'
9592
9593    Args:
9594        expressions: the expressions to add to the array.
9595        copy: whether to copy the argument expressions.
9596        dialect: the source dialect.
9597        kwargs: the kwargs used to instantiate the function of interest.
9598
9599    Returns:
9600        An array expression.
9601    """
9602    return Array(
9603        expressions=[
9604            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9605            for expression in expressions
9606        ]
9607    )

Returns an array.

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

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Tuple:
9610def tuple_(
9611    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9612) -> Tuple:
9613    """
9614    Returns an tuple.
9615
9616    Examples:
9617        >>> tuple_(1, 'x').sql()
9618        '(1, x)'
9619
9620    Args:
9621        expressions: the expressions to add to the tuple.
9622        copy: whether to copy the argument expressions.
9623        dialect: the source dialect.
9624        kwargs: the kwargs used to instantiate the function of interest.
9625
9626    Returns:
9627        A tuple expression.
9628    """
9629    return Tuple(
9630        expressions=[
9631            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9632            for expression in expressions
9633        ]
9634    )

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:
9637def true() -> Boolean:
9638    """
9639    Returns a true Boolean expression.
9640    """
9641    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
9644def false() -> Boolean:
9645    """
9646    Returns a false Boolean expression.
9647    """
9648    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
9651def null() -> Null:
9652    """
9653    Returns a Null expression.
9654    """
9655    return Null()

Returns a Null expression.

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