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

Retrieves the argument with key "this".

expression: Any
145    @property
146    def expression(self) -> t.Any:
147        """
148        Retrieves the argument with key "expression".
149        """
150        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
152    @property
153    def expressions(self) -> t.List[t.Any]:
154        """
155        Retrieves the argument with key "expressions".
156        """
157        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
159    def text(self, key) -> str:
160        """
161        Returns a textual representation of the argument corresponding to "key". This can only be used
162        for args that are strings or leaf Expression instances, such as identifiers and literals.
163        """
164        field = self.args.get(key)
165        if isinstance(field, str):
166            return field
167        if isinstance(field, (Identifier, Literal, Var)):
168            return field.this
169        if isinstance(field, (Star, Null)):
170            return field.name
171        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
173    @property
174    def is_string(self) -> bool:
175        """
176        Checks whether a Literal expression is a string.
177        """
178        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
180    @property
181    def is_number(self) -> bool:
182        """
183        Checks whether a Literal expression is a number.
184        """
185        return (isinstance(self, Literal) and not self.args["is_string"]) or (
186            isinstance(self, Neg) and self.this.is_number
187        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
189    def to_py(self) -> t.Any:
190        """
191        Returns a Python object equivalent of the SQL node.
192        """
193        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
195    @property
196    def is_int(self) -> bool:
197        """
198        Checks whether an expression is an integer.
199        """
200        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
202    @property
203    def is_star(self) -> bool:
204        """Checks whether an expression is a star."""
205        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
207    @property
208    def alias(self) -> str:
209        """
210        Returns the alias of the expression, or an empty string if it's not aliased.
211        """
212        if isinstance(self.args.get("alias"), TableAlias):
213            return self.args["alias"].name
214        return self.text("alias")

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

alias_column_names: List[str]
216    @property
217    def alias_column_names(self) -> t.List[str]:
218        table_alias = self.args.get("alias")
219        if not table_alias:
220            return []
221        return [c.name for c in table_alias.args.get("columns") or []]
name: str
223    @property
224    def name(self) -> str:
225        return self.text("this")
alias_or_name: str
227    @property
228    def alias_or_name(self) -> str:
229        return self.alias or self.name
output_name: str
231    @property
232    def output_name(self) -> str:
233        """
234        Name of the output column if this expression is a selection.
235
236        If the Expression has no output name, an empty string is returned.
237
238        Example:
239            >>> from sqlglot import parse_one
240            >>> parse_one("SELECT a").expressions[0].output_name
241            'a'
242            >>> parse_one("SELECT b AS c").expressions[0].output_name
243            'c'
244            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
245            ''
246        """
247        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]
249    @property
250    def type(self) -> t.Optional[DataType]:
251        return self._type
def is_type(self, *dtypes) -> bool:
259    def is_type(self, *dtypes) -> bool:
260        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
262    def is_leaf(self) -> bool:
263        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
265    @property
266    def meta(self) -> t.Dict[str, t.Any]:
267        if self._meta is None:
268            self._meta = {}
269        return self._meta
def copy(self) -> typing_extensions.Self:
305    def copy(self) -> Self:
306        """
307        Returns a deep copy of the expression.
308        """
309        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
311    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
312        if self.comments is None:
313            self.comments = []
314
315        if comments:
316            for comment in comments:
317                _, *meta = comment.split(SQLGLOT_META)
318                if meta:
319                    for kv in "".join(meta).split(","):
320                        k, *v = kv.split("=")
321                        value = v[0].strip() if v else True
322                        self.meta[k.strip()] = to_bool(value)
323
324                if not prepend:
325                    self.comments.append(comment)
326
327            if prepend:
328                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
330    def pop_comments(self) -> t.List[str]:
331        comments = self.comments or []
332        self.comments = None
333        return comments
def append(self, arg_key: str, value: Any) -> None:
335    def append(self, arg_key: str, value: t.Any) -> None:
336        """
337        Appends value to arg_key if it's a list or sets it as a new list.
338
339        Args:
340            arg_key (str): name of the list expression arg
341            value (Any): value to append to the list
342        """
343        if type(self.args.get(arg_key)) is not list:
344            self.args[arg_key] = []
345        self._set_parent(arg_key, value)
346        values = self.args[arg_key]
347        if hasattr(value, "parent"):
348            value.index = len(values)
349        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:
351    def set(
352        self,
353        arg_key: str,
354        value: t.Any,
355        index: t.Optional[int] = None,
356        overwrite: bool = True,
357    ) -> None:
358        """
359        Sets arg_key to value.
360
361        Args:
362            arg_key: name of the expression arg.
363            value: value to set the arg to.
364            index: if the arg is a list, this specifies what position to add the value in it.
365            overwrite: assuming an index is given, this determines whether to overwrite the
366                list entry instead of only inserting a new value (i.e., like list.insert).
367        """
368        if index is not None:
369            expressions = self.args.get(arg_key) or []
370
371            if seq_get(expressions, index) is None:
372                return
373            if value is None:
374                expressions.pop(index)
375                for v in expressions[index:]:
376                    v.index = v.index - 1
377                return
378
379            if isinstance(value, list):
380                expressions.pop(index)
381                expressions[index:index] = value
382            elif overwrite:
383                expressions[index] = value
384            else:
385                expressions.insert(index, value)
386
387            value = expressions
388        elif value is None:
389            self.args.pop(arg_key, None)
390            return
391
392        self.args[arg_key] = value
393        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
407    @property
408    def depth(self) -> int:
409        """
410        Returns the depth of this tree.
411        """
412        if self.parent:
413            return self.parent.depth + 1
414        return 0

Returns the depth of this tree.

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

Returns the parent select statement.

same_parent: bool
479    @property
480    def same_parent(self) -> bool:
481        """Returns if the parent is the same class as itself."""
482        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
484    def root(self) -> Expression:
485        """
486        Returns the root expression of this tree.
487        """
488        expression = self
489        while expression.parent:
490            expression = expression.parent
491        return expression

Returns the root expression of this tree.

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

Returns the first non parenthesis child or self.

def unalias(self):
568    def unalias(self):
569        """
570        Returns the inner expression if this is an Alias.
571        """
572        if isinstance(self, Alias):
573            return self.this
574        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
576    def unnest_operands(self):
577        """
578        Returns unnested operands as a tuple.
579        """
580        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
767    @classmethod
768    def load(cls, obj):
769        """
770        Load a dict (as returned by `Expression.dump`) into an Expression instance.
771        """
772        from sqlglot.serde import load
773
774        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:
776    def and_(
777        self,
778        *expressions: t.Optional[ExpOrStr],
779        dialect: DialectType = None,
780        copy: bool = True,
781        wrap: bool = True,
782        **opts,
783    ) -> Condition:
784        """
785        AND this condition with one or multiple expressions.
786
787        Example:
788            >>> condition("x=1").and_("y=1").sql()
789            'x = 1 AND y = 1'
790
791        Args:
792            *expressions: the SQL code strings to parse.
793                If an `Expression` instance is passed, it will be used as-is.
794            dialect: the dialect used to parse the input expression.
795            copy: whether to copy the involved expressions (only applies to Expressions).
796            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
797                precedence issues, but can be turned off when the produced AST is too deep and
798                causes recursion-related issues.
799            opts: other options to use to parse the input expressions.
800
801        Returns:
802            The new And condition.
803        """
804        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:
806    def or_(
807        self,
808        *expressions: t.Optional[ExpOrStr],
809        dialect: DialectType = None,
810        copy: bool = True,
811        wrap: bool = True,
812        **opts,
813    ) -> Condition:
814        """
815        OR this condition with one or multiple expressions.
816
817        Example:
818            >>> condition("x=1").or_("y=1").sql()
819            'x = 1 OR y = 1'
820
821        Args:
822            *expressions: the SQL code strings to parse.
823                If an `Expression` instance is passed, it will be used as-is.
824            dialect: the dialect used to parse the input expression.
825            copy: whether to copy the involved expressions (only applies to Expressions).
826            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
827                precedence issues, but can be turned off when the produced AST is too deep and
828                causes recursion-related issues.
829            opts: other options to use to parse the input expressions.
830
831        Returns:
832            The new Or condition.
833        """
834        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):
836    def not_(self, copy: bool = True):
837        """
838        Wrap this condition with NOT.
839
840        Example:
841            >>> condition("x=1").not_().sql()
842            'NOT x = 1'
843
844        Args:
845            copy: whether to copy this object.
846
847        Returns:
848            The new Not instance.
849        """
850        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:
852    def update_positions(
853        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
854    ) -> E:
855        """
856        Update this expression with positions from a token or other expression.
857
858        Args:
859            other: a token or expression to update this expression with.
860
861        Returns:
862            The updated expression.
863        """
864        if isinstance(other, Expression):
865            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
866        elif other is not None:
867            self.meta.update(
868                {
869                    "line": other.line,
870                    "col": other.col,
871                    "start": other.start,
872                    "end": other.end,
873                }
874            )
875        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
876        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:
878    def as_(
879        self,
880        alias: str | Identifier,
881        quoted: t.Optional[bool] = None,
882        dialect: DialectType = None,
883        copy: bool = True,
884        **opts,
885    ) -> Alias:
886        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:
911    def isin(
912        self,
913        *expressions: t.Any,
914        query: t.Optional[ExpOrStr] = None,
915        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
916        copy: bool = True,
917        **opts,
918    ) -> In:
919        subquery = maybe_parse(query, copy=copy, **opts) if query else None
920        if subquery and not isinstance(subquery, Subquery):
921            subquery = subquery.subquery(copy=False)
922
923        return In(
924            this=maybe_copy(self, copy),
925            expressions=[convert(e, copy=copy) for e in expressions],
926            query=subquery,
927            unnest=(
928                Unnest(
929                    expressions=[
930                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
931                        for e in ensure_list(unnest)
932                    ]
933                )
934                if unnest
935                else None
936            ),
937        )
def between( self, low: Any, high: Any, copy: bool = True, symmetric: Optional[bool] = None, **opts) -> Between:
939    def between(
940        self,
941        low: t.Any,
942        high: t.Any,
943        copy: bool = True,
944        symmetric: t.Optional[bool] = None,
945        **opts,
946    ) -> Between:
947        between = Between(
948            this=maybe_copy(self, copy),
949            low=convert(low, copy=copy, **opts),
950            high=convert(high, copy=copy, **opts),
951        )
952        if symmetric is not None:
953            between.set("symmetric", symmetric)
954
955        return between
def is_( self, other: Union[str, Expression]) -> Is:
957    def is_(self, other: ExpOrStr) -> Is:
958        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
960    def like(self, other: ExpOrStr) -> Like:
961        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
963    def ilike(self, other: ExpOrStr) -> ILike:
964        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
966    def eq(self, other: t.Any) -> EQ:
967        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
969    def neq(self, other: t.Any) -> NEQ:
970        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
972    def rlike(self, other: ExpOrStr) -> RegexpLike:
973        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
975    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
976        div = self._binop(Div, other)
977        div.args["typed"] = typed
978        div.args["safe"] = safe
979        return div
def asc(self, nulls_first: bool = True) -> Ordered:
981    def asc(self, nulls_first: bool = True) -> Ordered:
982        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
984    def desc(self, nulls_first: bool = False) -> Ordered:
985        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):
1068class Condition(Expression):
1069    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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:
1140    def offset(
1141        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1142    ) -> Q:
1143        """
1144        Set the OFFSET expression.
1145
1146        Example:
1147            >>> Select().from_("tbl").select("x").offset(10).sql()
1148            'SELECT x FROM tbl OFFSET 10'
1149
1150        Args:
1151            expression: the SQL code string to parse.
1152                This can also be an integer.
1153                If a `Offset` instance is passed, this is used as-is.
1154                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
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            The modified Select expression.
1161        """
1162        return _apply_builder(
1163            expression=expression,
1164            instance=self,
1165            arg="offset",
1166            into=Offset,
1167            prefix="OFFSET",
1168            dialect=dialect,
1169            copy=copy,
1170            into_arg="expression",
1171            **opts,
1172        )

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:
1174    def order_by(
1175        self: Q,
1176        *expressions: t.Optional[ExpOrStr],
1177        append: bool = True,
1178        dialect: DialectType = None,
1179        copy: bool = True,
1180        **opts,
1181    ) -> Q:
1182        """
1183        Set the ORDER BY expression.
1184
1185        Example:
1186            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1187            'SELECT x FROM tbl ORDER BY x DESC'
1188
1189        Args:
1190            *expressions: the SQL code strings to parse.
1191                If a `Group` instance is passed, this is used as-is.
1192                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1193            append: if `True`, add to any existing expressions.
1194                Otherwise, this flattens all the `Order` expression into a single expression.
1195            dialect: the dialect used to parse the input expression.
1196            copy: if `False`, modify this expression instance in-place.
1197            opts: other options to use to parse the input expressions.
1198
1199        Returns:
1200            The modified Select expression.
1201        """
1202        return _apply_child_list_builder(
1203            *expressions,
1204            instance=self,
1205            arg="order",
1206            append=append,
1207            copy=copy,
1208            prefix="ORDER BY",
1209            into=Order,
1210            dialect=dialect,
1211            **opts,
1212        )

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

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

selects: List[Expression]
1220    @property
1221    def selects(self) -> t.List[Expression]:
1222        """Returns the query's projections."""
1223        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1225    @property
1226    def named_selects(self) -> t.List[str]:
1227        """Returns the output names of the query's projections."""
1228        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:
1230    def select(
1231        self: Q,
1232        *expressions: t.Optional[ExpOrStr],
1233        append: bool = True,
1234        dialect: DialectType = None,
1235        copy: bool = True,
1236        **opts,
1237    ) -> Q:
1238        """
1239        Append to or set the SELECT expressions.
1240
1241        Example:
1242            >>> Select().select("x", "y").sql()
1243            'SELECT x, y'
1244
1245        Args:
1246            *expressions: the SQL code strings to parse.
1247                If an `Expression` instance is passed, it will be used as-is.
1248            append: if `True`, add to any existing expressions.
1249                Otherwise, this resets the expressions.
1250            dialect: the dialect used to parse the input expressions.
1251            copy: if `False`, modify this expression instance in-place.
1252            opts: other options to use to parse the input expressions.
1253
1254        Returns:
1255            The modified Query expression.
1256        """
1257        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:
1259    def where(
1260        self: Q,
1261        *expressions: t.Optional[ExpOrStr],
1262        append: bool = True,
1263        dialect: DialectType = None,
1264        copy: bool = True,
1265        **opts,
1266    ) -> Q:
1267        """
1268        Append to or set the WHERE expressions.
1269
1270        Examples:
1271            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1272            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1273
1274        Args:
1275            *expressions: the SQL code strings to parse.
1276                If an `Expression` instance is passed, it will be used as-is.
1277                Multiple expressions are combined with an AND operator.
1278            append: if `True`, AND the new expressions to any existing expression.
1279                Otherwise, this resets the expression.
1280            dialect: the dialect used to parse the input expressions.
1281            copy: if `False`, modify this expression instance in-place.
1282            opts: other options to use to parse the input expressions.
1283
1284        Returns:
1285            The modified expression.
1286        """
1287        return _apply_conjunction_builder(
1288            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1289            instance=self,
1290            arg="where",
1291            append=append,
1292            into=Where,
1293            dialect=dialect,
1294            copy=copy,
1295            **opts,
1296        )

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:
1298    def with_(
1299        self: Q,
1300        alias: ExpOrStr,
1301        as_: ExpOrStr,
1302        recursive: t.Optional[bool] = None,
1303        materialized: t.Optional[bool] = None,
1304        append: bool = True,
1305        dialect: DialectType = None,
1306        copy: bool = True,
1307        scalar: bool = False,
1308        **opts,
1309    ) -> Q:
1310        """
1311        Append to or set the common table expressions.
1312
1313        Example:
1314            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1315            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1316
1317        Args:
1318            alias: the SQL code string to parse as the table name.
1319                If an `Expression` instance is passed, this is used as-is.
1320            as_: the SQL code string to parse as the table expression.
1321                If an `Expression` instance is passed, it will be used as-is.
1322            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1323            materialized: set the MATERIALIZED part of the expression.
1324            append: if `True`, add to any existing expressions.
1325                Otherwise, this resets the expressions.
1326            dialect: the dialect used to parse the input expression.
1327            copy: if `False`, modify this expression instance in-place.
1328            scalar: if `True`, this is a scalar common table expression.
1329            opts: other options to use to parse the input expressions.
1330
1331        Returns:
1332            The modified expression.
1333        """
1334        return _apply_cte_builder(
1335            self,
1336            alias,
1337            as_,
1338            recursive=recursive,
1339            materialized=materialized,
1340            append=append,
1341            dialect=dialect,
1342            copy=copy,
1343            scalar=scalar,
1344            **opts,
1345        )

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:
1347    def union(
1348        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1349    ) -> Union:
1350        """
1351        Builds a UNION expression.
1352
1353        Example:
1354            >>> import sqlglot
1355            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1356            'SELECT * FROM foo UNION SELECT * FROM bla'
1357
1358        Args:
1359            expressions: the SQL code strings.
1360                If `Expression` instances are passed, they will be used as-is.
1361            distinct: set the DISTINCT flag if and only if this is true.
1362            dialect: the dialect used to parse the input expression.
1363            opts: other options to use to parse the input expressions.
1364
1365        Returns:
1366            The new Union expression.
1367        """
1368        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:
1370    def intersect(
1371        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1372    ) -> Intersect:
1373        """
1374        Builds an INTERSECT expression.
1375
1376        Example:
1377            >>> import sqlglot
1378            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1379            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1380
1381        Args:
1382            expressions: the SQL code strings.
1383                If `Expression` instances are passed, they will be used as-is.
1384            distinct: set the DISTINCT flag if and only if this is true.
1385            dialect: the dialect used to parse the input expression.
1386            opts: other options to use to parse the input expressions.
1387
1388        Returns:
1389            The new Intersect expression.
1390        """
1391        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:
1393    def except_(
1394        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1395    ) -> Except:
1396        """
1397        Builds an EXCEPT expression.
1398
1399        Example:
1400            >>> import sqlglot
1401            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1402            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1403
1404        Args:
1405            expressions: the SQL code strings.
1406                If `Expression` instance are passed, they will be used as-is.
1407            distinct: set the DISTINCT flag if and only if this is true.
1408            dialect: the dialect used to parse the input expression.
1409            opts: other options to use to parse the input expressions.
1410
1411        Returns:
1412            The new Except expression.
1413        """
1414        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):
1417class UDTF(DerivedTable):
1418    @property
1419    def selects(self) -> t.List[Expression]:
1420        alias = self.args.get("alias")
1421        return alias.columns if alias else []
selects: List[Expression]
1418    @property
1419    def selects(self) -> t.List[Expression]:
1420        alias = self.args.get("alias")
1421        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1424class Cache(Expression):
1425    arg_types = {
1426        "this": True,
1427        "lazy": False,
1428        "options": False,
1429        "expression": False,
1430    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1433class Uncache(Expression):
1434    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1437class Refresh(Expression):
1438    pass
key = 'refresh'
class DDL(Expression):
1441class DDL(Expression):
1442    @property
1443    def ctes(self) -> t.List[CTE]:
1444        """Returns a list of all the CTEs attached to this statement."""
1445        with_ = self.args.get("with")
1446        return with_.expressions if with_ else []
1447
1448    @property
1449    def selects(self) -> t.List[Expression]:
1450        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1451        return self.expression.selects if isinstance(self.expression, Query) else []
1452
1453    @property
1454    def named_selects(self) -> t.List[str]:
1455        """
1456        If this statement contains a query (e.g. a CTAS), this returns the output
1457        names of the query's projections.
1458        """
1459        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1442    @property
1443    def ctes(self) -> t.List[CTE]:
1444        """Returns a list of all the CTEs attached to this statement."""
1445        with_ = self.args.get("with")
1446        return with_.expressions if with_ else []

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

selects: List[Expression]
1448    @property
1449    def selects(self) -> t.List[Expression]:
1450        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1451        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]
1453    @property
1454    def named_selects(self) -> t.List[str]:
1455        """
1456        If this statement contains a query (e.g. a CTAS), this returns the output
1457        names of the query's projections.
1458        """
1459        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):
1463class LockingStatement(Expression):
1464    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'lockingstatement'
class DML(Expression):
1467class DML(Expression):
1468    def returning(
1469        self,
1470        expression: ExpOrStr,
1471        dialect: DialectType = None,
1472        copy: bool = True,
1473        **opts,
1474    ) -> "Self":
1475        """
1476        Set the RETURNING expression. Not supported by all dialects.
1477
1478        Example:
1479            >>> delete("tbl").returning("*", dialect="postgres").sql()
1480            'DELETE FROM tbl RETURNING *'
1481
1482        Args:
1483            expression: the SQL code strings to parse.
1484                If an `Expression` instance is passed, it will be used as-is.
1485            dialect: the dialect used to parse the input expressions.
1486            copy: if `False`, modify this expression instance in-place.
1487            opts: other options to use to parse the input expressions.
1488
1489        Returns:
1490            Delete: the modified expression.
1491        """
1492        return _apply_builder(
1493            expression=expression,
1494            instance=self,
1495            arg="returning",
1496            prefix="RETURNING",
1497            dialect=dialect,
1498            copy=copy,
1499            into=Returning,
1500            **opts,
1501        )
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:
1468    def returning(
1469        self,
1470        expression: ExpOrStr,
1471        dialect: DialectType = None,
1472        copy: bool = True,
1473        **opts,
1474    ) -> "Self":
1475        """
1476        Set the RETURNING expression. Not supported by all dialects.
1477
1478        Example:
1479            >>> delete("tbl").returning("*", dialect="postgres").sql()
1480            'DELETE FROM tbl RETURNING *'
1481
1482        Args:
1483            expression: the SQL code strings to parse.
1484                If an `Expression` instance is passed, it will be used as-is.
1485            dialect: the dialect used to parse the input expressions.
1486            copy: if `False`, modify this expression instance in-place.
1487            opts: other options to use to parse the input expressions.
1488
1489        Returns:
1490            Delete: the modified expression.
1491        """
1492        return _apply_builder(
1493            expression=expression,
1494            instance=self,
1495            arg="returning",
1496            prefix="RETURNING",
1497            dialect=dialect,
1498            copy=copy,
1499            into=Returning,
1500            **opts,
1501        )

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):
1504class Create(DDL):
1505    arg_types = {
1506        "with": False,
1507        "this": True,
1508        "kind": True,
1509        "expression": False,
1510        "exists": False,
1511        "properties": False,
1512        "replace": False,
1513        "refresh": False,
1514        "unique": False,
1515        "indexes": False,
1516        "no_schema_binding": False,
1517        "begin": False,
1518        "end": False,
1519        "clone": False,
1520        "concurrently": False,
1521        "clustered": False,
1522    }
1523
1524    @property
1525    def kind(self) -> t.Optional[str]:
1526        kind = self.args.get("kind")
1527        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]
1524    @property
1525    def kind(self) -> t.Optional[str]:
1526        kind = self.args.get("kind")
1527        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1530class SequenceProperties(Expression):
1531    arg_types = {
1532        "increment": False,
1533        "minvalue": False,
1534        "maxvalue": False,
1535        "cache": False,
1536        "start": False,
1537        "owned": False,
1538        "options": False,
1539    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1542class TruncateTable(Expression):
1543    arg_types = {
1544        "expressions": True,
1545        "is_database": False,
1546        "exists": False,
1547        "only": False,
1548        "cluster": False,
1549        "identity": False,
1550        "option": False,
1551        "partition": False,
1552    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1558class Clone(Expression):
1559    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1562class Describe(Expression):
1563    arg_types = {
1564        "this": True,
1565        "style": False,
1566        "kind": False,
1567        "expressions": False,
1568        "partition": False,
1569        "format": False,
1570    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1574class Attach(Expression):
1575    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1579class Detach(Expression):
1580    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1584class Summarize(Expression):
1585    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1588class Kill(Expression):
1589    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1592class Pragma(Expression):
1593    pass
key = 'pragma'
class Declare(Expression):
1596class Declare(Expression):
1597    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1600class DeclareItem(Expression):
1601    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
class Set(Expression):
1604class Set(Expression):
1605    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1608class Heredoc(Expression):
1609    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1612class SetItem(Expression):
1613    arg_types = {
1614        "this": False,
1615        "expressions": False,
1616        "kind": False,
1617        "collate": False,  # MySQL SET NAMES statement
1618        "global": False,
1619    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class QueryBand(Expression):
1622class QueryBand(Expression):
1623    arg_types = {"this": True, "scope": False, "update": False}
arg_types = {'this': True, 'scope': False, 'update': False}
key = 'queryband'
class Show(Expression):
1626class Show(Expression):
1627    arg_types = {
1628        "this": True,
1629        "history": False,
1630        "terse": False,
1631        "target": False,
1632        "offset": False,
1633        "starts_with": False,
1634        "limit": False,
1635        "from": False,
1636        "like": False,
1637        "where": False,
1638        "db": False,
1639        "scope": False,
1640        "scope_kind": False,
1641        "full": False,
1642        "mutex": False,
1643        "query": False,
1644        "channel": False,
1645        "global": False,
1646        "log": False,
1647        "position": False,
1648        "types": False,
1649        "privileges": False,
1650    }
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}
key = 'show'
class UserDefinedFunction(Expression):
1653class UserDefinedFunction(Expression):
1654    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1657class CharacterSet(Expression):
1658    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1661class RecursiveWithSearch(Expression):
1662    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):
1665class With(Expression):
1666    arg_types = {"expressions": True, "recursive": False, "search": False}
1667
1668    @property
1669    def recursive(self) -> bool:
1670        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1668    @property
1669    def recursive(self) -> bool:
1670        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1673class WithinGroup(Expression):
1674    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1679class CTE(DerivedTable):
1680    arg_types = {
1681        "this": True,
1682        "alias": True,
1683        "scalar": False,
1684        "materialized": False,
1685    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1688class ProjectionDef(Expression):
1689    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1692class TableAlias(Expression):
1693    arg_types = {"this": False, "columns": False}
1694
1695    @property
1696    def columns(self):
1697        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1695    @property
1696    def columns(self):
1697        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1700class BitString(Condition):
1701    pass
key = 'bitstring'
class HexString(Condition):
1704class HexString(Condition):
1705    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1708class ByteString(Condition):
1709    pass
key = 'bytestring'
class RawString(Condition):
1712class RawString(Condition):
1713    pass
key = 'rawstring'
class UnicodeString(Condition):
1716class UnicodeString(Condition):
1717    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1720class Column(Condition):
1721    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1722
1723    @property
1724    def table(self) -> str:
1725        return self.text("table")
1726
1727    @property
1728    def db(self) -> str:
1729        return self.text("db")
1730
1731    @property
1732    def catalog(self) -> str:
1733        return self.text("catalog")
1734
1735    @property
1736    def output_name(self) -> str:
1737        return self.name
1738
1739    @property
1740    def parts(self) -> t.List[Identifier]:
1741        """Return the parts of a column in order catalog, db, table, name."""
1742        return [
1743            t.cast(Identifier, self.args[part])
1744            for part in ("catalog", "db", "table", "this")
1745            if self.args.get(part)
1746        ]
1747
1748    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1749        """Converts the column into a dot expression."""
1750        parts = self.parts
1751        parent = self.parent
1752
1753        if include_dots:
1754            while isinstance(parent, Dot):
1755                parts.append(parent.expression)
1756                parent = parent.parent
1757
1758        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
1723    @property
1724    def table(self) -> str:
1725        return self.text("table")
db: str
1727    @property
1728    def db(self) -> str:
1729        return self.text("db")
catalog: str
1731    @property
1732    def catalog(self) -> str:
1733        return self.text("catalog")
output_name: str
1735    @property
1736    def output_name(self) -> str:
1737        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]
1739    @property
1740    def parts(self) -> t.List[Identifier]:
1741        """Return the parts of a column in order catalog, db, table, name."""
1742        return [
1743            t.cast(Identifier, self.args[part])
1744            for part in ("catalog", "db", "table", "this")
1745            if self.args.get(part)
1746        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1748    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1749        """Converts the column into a dot expression."""
1750        parts = self.parts
1751        parent = self.parent
1752
1753        if include_dots:
1754            while isinstance(parent, Dot):
1755                parts.append(parent.expression)
1756                parent = parent.parent
1757
1758        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1761class ColumnPosition(Expression):
1762    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1765class ColumnDef(Expression):
1766    arg_types = {
1767        "this": True,
1768        "kind": False,
1769        "constraints": False,
1770        "exists": False,
1771        "position": False,
1772        "default": False,
1773        "output": False,
1774    }
1775
1776    @property
1777    def constraints(self) -> t.List[ColumnConstraint]:
1778        return self.args.get("constraints") or []
1779
1780    @property
1781    def kind(self) -> t.Optional[DataType]:
1782        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1776    @property
1777    def constraints(self) -> t.List[ColumnConstraint]:
1778        return self.args.get("constraints") or []
kind: Optional[DataType]
1780    @property
1781    def kind(self) -> t.Optional[DataType]:
1782        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1785class AlterColumn(Expression):
1786    arg_types = {
1787        "this": True,
1788        "dtype": False,
1789        "collate": False,
1790        "using": False,
1791        "default": False,
1792        "drop": False,
1793        "comment": False,
1794        "allow_null": False,
1795        "visible": False,
1796    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False}
key = 'altercolumn'
class AlterIndex(Expression):
1800class AlterIndex(Expression):
1801    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1805class AlterDistStyle(Expression):
1806    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1809class AlterSortKey(Expression):
1810    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1813class AlterSet(Expression):
1814    arg_types = {
1815        "expressions": False,
1816        "option": False,
1817        "tablespace": False,
1818        "access_method": False,
1819        "file_format": False,
1820        "copy_options": False,
1821        "tag": False,
1822        "location": False,
1823        "serde": False,
1824    }
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):
1827class RenameColumn(Expression):
1828    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1831class AlterRename(Expression):
1832    pass
key = 'alterrename'
class SwapTable(Expression):
1835class SwapTable(Expression):
1836    pass
key = 'swaptable'
class Comment(Expression):
1839class Comment(Expression):
1840    arg_types = {
1841        "this": True,
1842        "kind": True,
1843        "expression": True,
1844        "exists": False,
1845        "materialized": False,
1846    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1849class Comprehension(Expression):
1850    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):
1854class MergeTreeTTLAction(Expression):
1855    arg_types = {
1856        "this": True,
1857        "delete": False,
1858        "recompress": False,
1859        "to_disk": False,
1860        "to_volume": False,
1861    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1865class MergeTreeTTL(Expression):
1866    arg_types = {
1867        "expressions": True,
1868        "where": False,
1869        "group": False,
1870        "aggregates": False,
1871    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1875class IndexConstraintOption(Expression):
1876    arg_types = {
1877        "key_block_size": False,
1878        "using": False,
1879        "parser": False,
1880        "comment": False,
1881        "visible": False,
1882        "engine_attr": False,
1883        "secondary_engine_attr": False,
1884    }
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):
1887class ColumnConstraint(Expression):
1888    arg_types = {"this": False, "kind": True}
1889
1890    @property
1891    def kind(self) -> ColumnConstraintKind:
1892        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1890    @property
1891    def kind(self) -> ColumnConstraintKind:
1892        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1895class ColumnConstraintKind(Expression):
1896    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1899class AutoIncrementColumnConstraint(ColumnConstraintKind):
1900    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1903class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1904    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1907class CaseSpecificColumnConstraint(ColumnConstraintKind):
1908    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1911class CharacterSetColumnConstraint(ColumnConstraintKind):
1912    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1915class CheckColumnConstraint(ColumnConstraintKind):
1916    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1919class ClusteredColumnConstraint(ColumnConstraintKind):
1920    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1923class CollateColumnConstraint(ColumnConstraintKind):
1924    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1927class CommentColumnConstraint(ColumnConstraintKind):
1928    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1931class CompressColumnConstraint(ColumnConstraintKind):
1932    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1935class DateFormatColumnConstraint(ColumnConstraintKind):
1936    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1939class DefaultColumnConstraint(ColumnConstraintKind):
1940    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1943class EncodeColumnConstraint(ColumnConstraintKind):
1944    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1948class ExcludeColumnConstraint(ColumnConstraintKind):
1949    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1952class EphemeralColumnConstraint(ColumnConstraintKind):
1953    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1956class WithOperator(Expression):
1957    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1960class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1961    # this: True -> ALWAYS, this: False -> BY DEFAULT
1962    arg_types = {
1963        "this": False,
1964        "expression": False,
1965        "on_null": False,
1966        "start": False,
1967        "increment": False,
1968        "minvalue": False,
1969        "maxvalue": False,
1970        "cycle": False,
1971        "order": False,
1972    }
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):
1975class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1976    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1981class IndexColumnConstraint(ColumnConstraintKind):
1982    arg_types = {
1983        "this": False,
1984        "expressions": False,
1985        "kind": False,
1986        "index_type": False,
1987        "options": False,
1988        "expression": False,  # Clickhouse
1989        "granularity": False,
1990    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1993class InlineLengthColumnConstraint(ColumnConstraintKind):
1994    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1997class NonClusteredColumnConstraint(ColumnConstraintKind):
1998    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
2001class NotForReplicationColumnConstraint(ColumnConstraintKind):
2002    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2006class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2007    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
2010class NotNullColumnConstraint(ColumnConstraintKind):
2011    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
2015class OnUpdateColumnConstraint(ColumnConstraintKind):
2016    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2019class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2020    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2023class TitleColumnConstraint(ColumnConstraintKind):
2024    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2027class UniqueColumnConstraint(ColumnConstraintKind):
2028    arg_types = {
2029        "this": False,
2030        "index_type": False,
2031        "on_conflict": False,
2032        "nulls": False,
2033        "options": False,
2034    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2037class UppercaseColumnConstraint(ColumnConstraintKind):
2038    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2042class WatermarkColumnConstraint(Expression):
2043    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2046class PathColumnConstraint(ColumnConstraintKind):
2047    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2051class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2052    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2057class ComputedColumnConstraint(ColumnConstraintKind):
2058    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2061class Constraint(Expression):
2062    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2065class Delete(DML):
2066    arg_types = {
2067        "with": False,
2068        "this": False,
2069        "using": False,
2070        "where": False,
2071        "returning": False,
2072        "limit": False,
2073        "tables": False,  # Multiple-Table Syntax (MySQL)
2074        "cluster": False,  # Clickhouse
2075    }
2076
2077    def delete(
2078        self,
2079        table: ExpOrStr,
2080        dialect: DialectType = None,
2081        copy: bool = True,
2082        **opts,
2083    ) -> Delete:
2084        """
2085        Create a DELETE expression or replace the table on an existing DELETE expression.
2086
2087        Example:
2088            >>> delete("tbl").sql()
2089            'DELETE FROM tbl'
2090
2091        Args:
2092            table: the table from which to delete.
2093            dialect: the dialect used to parse the input expression.
2094            copy: if `False`, modify this expression instance in-place.
2095            opts: other options to use to parse the input expressions.
2096
2097        Returns:
2098            Delete: the modified expression.
2099        """
2100        return _apply_builder(
2101            expression=table,
2102            instance=self,
2103            arg="this",
2104            dialect=dialect,
2105            into=Table,
2106            copy=copy,
2107            **opts,
2108        )
2109
2110    def where(
2111        self,
2112        *expressions: t.Optional[ExpOrStr],
2113        append: bool = True,
2114        dialect: DialectType = None,
2115        copy: bool = True,
2116        **opts,
2117    ) -> Delete:
2118        """
2119        Append to or set the WHERE expressions.
2120
2121        Example:
2122            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2123            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2124
2125        Args:
2126            *expressions: the SQL code strings to parse.
2127                If an `Expression` instance is passed, it will be used as-is.
2128                Multiple expressions are combined with an AND operator.
2129            append: if `True`, AND the new expressions to any existing expression.
2130                Otherwise, this resets the expression.
2131            dialect: the dialect used to parse the input expressions.
2132            copy: if `False`, modify this expression instance in-place.
2133            opts: other options to use to parse the input expressions.
2134
2135        Returns:
2136            Delete: the modified expression.
2137        """
2138        return _apply_conjunction_builder(
2139            *expressions,
2140            instance=self,
2141            arg="where",
2142            append=append,
2143            into=Where,
2144            dialect=dialect,
2145            copy=copy,
2146            **opts,
2147        )
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:
2077    def delete(
2078        self,
2079        table: ExpOrStr,
2080        dialect: DialectType = None,
2081        copy: bool = True,
2082        **opts,
2083    ) -> Delete:
2084        """
2085        Create a DELETE expression or replace the table on an existing DELETE expression.
2086
2087        Example:
2088            >>> delete("tbl").sql()
2089            'DELETE FROM tbl'
2090
2091        Args:
2092            table: the table from which to delete.
2093            dialect: the dialect used to parse the input expression.
2094            copy: if `False`, modify this expression instance in-place.
2095            opts: other options to use to parse the input expressions.
2096
2097        Returns:
2098            Delete: the modified expression.
2099        """
2100        return _apply_builder(
2101            expression=table,
2102            instance=self,
2103            arg="this",
2104            dialect=dialect,
2105            into=Table,
2106            copy=copy,
2107            **opts,
2108        )

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:
2110    def where(
2111        self,
2112        *expressions: t.Optional[ExpOrStr],
2113        append: bool = True,
2114        dialect: DialectType = None,
2115        copy: bool = True,
2116        **opts,
2117    ) -> Delete:
2118        """
2119        Append to or set the WHERE expressions.
2120
2121        Example:
2122            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2123            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2124
2125        Args:
2126            *expressions: the SQL code strings to parse.
2127                If an `Expression` instance is passed, it will be used as-is.
2128                Multiple expressions are combined with an AND operator.
2129            append: if `True`, AND the new expressions to any existing expression.
2130                Otherwise, this resets the expression.
2131            dialect: the dialect used to parse the input expressions.
2132            copy: if `False`, modify this expression instance in-place.
2133            opts: other options to use to parse the input expressions.
2134
2135        Returns:
2136            Delete: the modified expression.
2137        """
2138        return _apply_conjunction_builder(
2139            *expressions,
2140            instance=self,
2141            arg="where",
2142            append=append,
2143            into=Where,
2144            dialect=dialect,
2145            copy=copy,
2146            **opts,
2147        )

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):
2150class Drop(Expression):
2151    arg_types = {
2152        "this": False,
2153        "kind": False,
2154        "expressions": False,
2155        "exists": False,
2156        "temporary": False,
2157        "materialized": False,
2158        "cascade": False,
2159        "constraints": False,
2160        "purge": False,
2161        "cluster": False,
2162        "concurrently": False,
2163    }
2164
2165    @property
2166    def kind(self) -> t.Optional[str]:
2167        kind = self.args.get("kind")
2168        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]
2165    @property
2166    def kind(self) -> t.Optional[str]:
2167        kind = self.args.get("kind")
2168        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2172class Export(Expression):
2173    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2176class Filter(Expression):
2177    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2180class Check(Expression):
2181    pass
key = 'check'
class Changes(Expression):
2184class Changes(Expression):
2185    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2189class Connect(Expression):
2190    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2193class CopyParameter(Expression):
2194    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2197class Copy(DML):
2198    arg_types = {
2199        "this": True,
2200        "kind": True,
2201        "files": True,
2202        "credentials": False,
2203        "format": False,
2204        "params": False,
2205    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2208class Credentials(Expression):
2209    arg_types = {
2210        "credentials": False,
2211        "encryption": False,
2212        "storage": False,
2213        "iam_role": False,
2214        "region": False,
2215    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2218class Prior(Expression):
2219    pass
key = 'prior'
class Directory(Expression):
2222class Directory(Expression):
2223    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2224    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2227class ForeignKey(Expression):
2228    arg_types = {
2229        "expressions": False,
2230        "reference": False,
2231        "delete": False,
2232        "update": False,
2233        "options": False,
2234    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2237class ColumnPrefix(Expression):
2238    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2241class PrimaryKey(Expression):
2242    arg_types = {"expressions": True, "options": False, "include": False}
arg_types = {'expressions': True, 'options': False, 'include': False}
key = 'primarykey'
class Into(Expression):
2247class Into(Expression):
2248    arg_types = {
2249        "this": False,
2250        "temporary": False,
2251        "unlogged": False,
2252        "bulk_collect": False,
2253        "expressions": False,
2254    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2257class From(Expression):
2258    @property
2259    def name(self) -> str:
2260        return self.this.name
2261
2262    @property
2263    def alias_or_name(self) -> str:
2264        return self.this.alias_or_name
name: str
2258    @property
2259    def name(self) -> str:
2260        return self.this.name
alias_or_name: str
2262    @property
2263    def alias_or_name(self) -> str:
2264        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2267class Having(Expression):
2268    pass
key = 'having'
class Hint(Expression):
2271class Hint(Expression):
2272    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2275class JoinHint(Expression):
2276    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2279class Identifier(Expression):
2280    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2281
2282    @property
2283    def quoted(self) -> bool:
2284        return bool(self.args.get("quoted"))
2285
2286    @property
2287    def hashable_args(self) -> t.Any:
2288        return (self.this, self.quoted)
2289
2290    @property
2291    def output_name(self) -> str:
2292        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2282    @property
2283    def quoted(self) -> bool:
2284        return bool(self.args.get("quoted"))
hashable_args: Any
2286    @property
2287    def hashable_args(self) -> t.Any:
2288        return (self.this, self.quoted)
output_name: str
2290    @property
2291    def output_name(self) -> str:
2292        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):
2296class Opclass(Expression):
2297    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2300class Index(Expression):
2301    arg_types = {
2302        "this": False,
2303        "table": False,
2304        "unique": False,
2305        "primary": False,
2306        "amp": False,  # teradata
2307        "params": False,
2308    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2311class IndexParameters(Expression):
2312    arg_types = {
2313        "using": False,
2314        "include": False,
2315        "columns": False,
2316        "with_storage": False,
2317        "partition_by": False,
2318        "tablespace": False,
2319        "where": False,
2320        "on": False,
2321    }
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):
2324class Insert(DDL, DML):
2325    arg_types = {
2326        "hint": False,
2327        "with": False,
2328        "is_function": False,
2329        "this": False,
2330        "expression": False,
2331        "conflict": False,
2332        "returning": False,
2333        "overwrite": False,
2334        "exists": False,
2335        "alternative": False,
2336        "where": False,
2337        "ignore": False,
2338        "by_name": False,
2339        "stored": False,
2340        "partition": False,
2341        "settings": False,
2342        "source": False,
2343    }
2344
2345    def with_(
2346        self,
2347        alias: ExpOrStr,
2348        as_: ExpOrStr,
2349        recursive: t.Optional[bool] = None,
2350        materialized: t.Optional[bool] = None,
2351        append: bool = True,
2352        dialect: DialectType = None,
2353        copy: bool = True,
2354        **opts,
2355    ) -> Insert:
2356        """
2357        Append to or set the common table expressions.
2358
2359        Example:
2360            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2361            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2362
2363        Args:
2364            alias: the SQL code string to parse as the table name.
2365                If an `Expression` instance is passed, this is used as-is.
2366            as_: the SQL code string to parse as the table expression.
2367                If an `Expression` instance is passed, it will be used as-is.
2368            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2369            materialized: set the MATERIALIZED part of the expression.
2370            append: if `True`, add to any existing expressions.
2371                Otherwise, this resets the expressions.
2372            dialect: the dialect used to parse the input expression.
2373            copy: if `False`, modify this expression instance in-place.
2374            opts: other options to use to parse the input expressions.
2375
2376        Returns:
2377            The modified expression.
2378        """
2379        return _apply_cte_builder(
2380            self,
2381            alias,
2382            as_,
2383            recursive=recursive,
2384            materialized=materialized,
2385            append=append,
2386            dialect=dialect,
2387            copy=copy,
2388            **opts,
2389        )
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:
2345    def with_(
2346        self,
2347        alias: ExpOrStr,
2348        as_: ExpOrStr,
2349        recursive: t.Optional[bool] = None,
2350        materialized: t.Optional[bool] = None,
2351        append: bool = True,
2352        dialect: DialectType = None,
2353        copy: bool = True,
2354        **opts,
2355    ) -> Insert:
2356        """
2357        Append to or set the common table expressions.
2358
2359        Example:
2360            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2361            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2362
2363        Args:
2364            alias: the SQL code string to parse as the table name.
2365                If an `Expression` instance is passed, this is used as-is.
2366            as_: the SQL code string to parse as the table expression.
2367                If an `Expression` instance is passed, it will be used as-is.
2368            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2369            materialized: set the MATERIALIZED part of the expression.
2370            append: if `True`, add to any existing expressions.
2371                Otherwise, this resets the expressions.
2372            dialect: the dialect used to parse the input expression.
2373            copy: if `False`, modify this expression instance in-place.
2374            opts: other options to use to parse the input expressions.
2375
2376        Returns:
2377            The modified expression.
2378        """
2379        return _apply_cte_builder(
2380            self,
2381            alias,
2382            as_,
2383            recursive=recursive,
2384            materialized=materialized,
2385            append=append,
2386            dialect=dialect,
2387            copy=copy,
2388            **opts,
2389        )

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):
2392class ConditionalInsert(Expression):
2393    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2396class MultitableInserts(Expression):
2397    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2400class OnConflict(Expression):
2401    arg_types = {
2402        "duplicate": False,
2403        "expressions": False,
2404        "action": False,
2405        "conflict_keys": False,
2406        "constraint": False,
2407        "where": False,
2408    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2411class OnCondition(Expression):
2412    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2415class Returning(Expression):
2416    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2420class Introducer(Expression):
2421    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2425class National(Expression):
2426    pass
key = 'national'
class LoadData(Expression):
2429class LoadData(Expression):
2430    arg_types = {
2431        "this": True,
2432        "local": False,
2433        "overwrite": False,
2434        "inpath": True,
2435        "partition": False,
2436        "input_format": False,
2437        "serde": False,
2438    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2441class Partition(Expression):
2442    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2445class PartitionRange(Expression):
2446    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
class PartitionId(Expression):
2450class PartitionId(Expression):
2451    pass
key = 'partitionid'
class Fetch(Expression):
2454class Fetch(Expression):
2455    arg_types = {
2456        "direction": False,
2457        "count": False,
2458        "limit_options": False,
2459    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2462class Grant(Expression):
2463    arg_types = {
2464        "privileges": True,
2465        "kind": False,
2466        "securable": True,
2467        "principals": True,
2468        "grant_option": False,
2469    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Revoke(Expression):
2472class Revoke(Expression):
2473    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):
2476class Group(Expression):
2477    arg_types = {
2478        "expressions": False,
2479        "grouping_sets": False,
2480        "cube": False,
2481        "rollup": False,
2482        "totals": False,
2483        "all": False,
2484    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2487class Cube(Expression):
2488    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2491class Rollup(Expression):
2492    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2495class GroupingSets(Expression):
2496    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2499class Lambda(Expression):
2500    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2503class Limit(Expression):
2504    arg_types = {
2505        "this": False,
2506        "expression": True,
2507        "offset": False,
2508        "limit_options": False,
2509        "expressions": False,
2510    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2513class LimitOptions(Expression):
2514    arg_types = {
2515        "percent": False,
2516        "rows": False,
2517        "with_ties": False,
2518    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2521class Literal(Condition):
2522    arg_types = {"this": True, "is_string": True}
2523
2524    @property
2525    def hashable_args(self) -> t.Any:
2526        return (self.this, self.args.get("is_string"))
2527
2528    @classmethod
2529    def number(cls, number) -> Literal:
2530        return cls(this=str(number), is_string=False)
2531
2532    @classmethod
2533    def string(cls, string) -> Literal:
2534        return cls(this=str(string), is_string=True)
2535
2536    @property
2537    def output_name(self) -> str:
2538        return self.name
2539
2540    def to_py(self) -> int | str | Decimal:
2541        if self.is_number:
2542            try:
2543                return int(self.this)
2544            except ValueError:
2545                return Decimal(self.this)
2546        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2524    @property
2525    def hashable_args(self) -> t.Any:
2526        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2528    @classmethod
2529    def number(cls, number) -> Literal:
2530        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2532    @classmethod
2533    def string(cls, string) -> Literal:
2534        return cls(this=str(string), is_string=True)
output_name: str
2536    @property
2537    def output_name(self) -> str:
2538        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:
2540    def to_py(self) -> int | str | Decimal:
2541        if self.is_number:
2542            try:
2543                return int(self.this)
2544            except ValueError:
2545                return Decimal(self.this)
2546        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2549class Join(Expression):
2550    arg_types = {
2551        "this": True,
2552        "on": False,
2553        "side": False,
2554        "kind": False,
2555        "using": False,
2556        "method": False,
2557        "global": False,
2558        "hint": False,
2559        "match_condition": False,  # Snowflake
2560        "expressions": False,
2561        "pivots": False,
2562    }
2563
2564    @property
2565    def method(self) -> str:
2566        return self.text("method").upper()
2567
2568    @property
2569    def kind(self) -> str:
2570        return self.text("kind").upper()
2571
2572    @property
2573    def side(self) -> str:
2574        return self.text("side").upper()
2575
2576    @property
2577    def hint(self) -> str:
2578        return self.text("hint").upper()
2579
2580    @property
2581    def alias_or_name(self) -> str:
2582        return self.this.alias_or_name
2583
2584    @property
2585    def is_semi_or_anti_join(self) -> bool:
2586        return self.kind in ("SEMI", "ANTI")
2587
2588    def on(
2589        self,
2590        *expressions: t.Optional[ExpOrStr],
2591        append: bool = True,
2592        dialect: DialectType = None,
2593        copy: bool = True,
2594        **opts,
2595    ) -> Join:
2596        """
2597        Append to or set the ON expressions.
2598
2599        Example:
2600            >>> import sqlglot
2601            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2602            'JOIN x ON y = 1'
2603
2604        Args:
2605            *expressions: the SQL code strings to parse.
2606                If an `Expression` instance is passed, it will be used as-is.
2607                Multiple expressions are combined with an AND operator.
2608            append: if `True`, AND the new expressions to any existing expression.
2609                Otherwise, this resets the expression.
2610            dialect: the dialect used to parse the input expressions.
2611            copy: if `False`, modify this expression instance in-place.
2612            opts: other options to use to parse the input expressions.
2613
2614        Returns:
2615            The modified Join expression.
2616        """
2617        join = _apply_conjunction_builder(
2618            *expressions,
2619            instance=self,
2620            arg="on",
2621            append=append,
2622            dialect=dialect,
2623            copy=copy,
2624            **opts,
2625        )
2626
2627        if join.kind == "CROSS":
2628            join.set("kind", None)
2629
2630        return join
2631
2632    def using(
2633        self,
2634        *expressions: t.Optional[ExpOrStr],
2635        append: bool = True,
2636        dialect: DialectType = None,
2637        copy: bool = True,
2638        **opts,
2639    ) -> Join:
2640        """
2641        Append to or set the USING expressions.
2642
2643        Example:
2644            >>> import sqlglot
2645            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2646            'JOIN x USING (foo, bla)'
2647
2648        Args:
2649            *expressions: the SQL code strings to parse.
2650                If an `Expression` instance is passed, it will be used as-is.
2651            append: if `True`, concatenate the new expressions to the existing "using" list.
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_list_builder(
2661            *expressions,
2662            instance=self,
2663            arg="using",
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
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
2564    @property
2565    def method(self) -> str:
2566        return self.text("method").upper()
kind: str
2568    @property
2569    def kind(self) -> str:
2570        return self.text("kind").upper()
side: str
2572    @property
2573    def side(self) -> str:
2574        return self.text("side").upper()
hint: str
2576    @property
2577    def hint(self) -> str:
2578        return self.text("hint").upper()
alias_or_name: str
2580    @property
2581    def alias_or_name(self) -> str:
2582        return self.this.alias_or_name
is_semi_or_anti_join: bool
2584    @property
2585    def is_semi_or_anti_join(self) -> bool:
2586        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:
2588    def on(
2589        self,
2590        *expressions: t.Optional[ExpOrStr],
2591        append: bool = True,
2592        dialect: DialectType = None,
2593        copy: bool = True,
2594        **opts,
2595    ) -> Join:
2596        """
2597        Append to or set the ON expressions.
2598
2599        Example:
2600            >>> import sqlglot
2601            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2602            'JOIN x ON y = 1'
2603
2604        Args:
2605            *expressions: the SQL code strings to parse.
2606                If an `Expression` instance is passed, it will be used as-is.
2607                Multiple expressions are combined with an AND operator.
2608            append: if `True`, AND the new expressions to any existing expression.
2609                Otherwise, this resets the expression.
2610            dialect: the dialect used to parse the input expressions.
2611            copy: if `False`, modify this expression instance in-place.
2612            opts: other options to use to parse the input expressions.
2613
2614        Returns:
2615            The modified Join expression.
2616        """
2617        join = _apply_conjunction_builder(
2618            *expressions,
2619            instance=self,
2620            arg="on",
2621            append=append,
2622            dialect=dialect,
2623            copy=copy,
2624            **opts,
2625        )
2626
2627        if join.kind == "CROSS":
2628            join.set("kind", None)
2629
2630        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:
2632    def using(
2633        self,
2634        *expressions: t.Optional[ExpOrStr],
2635        append: bool = True,
2636        dialect: DialectType = None,
2637        copy: bool = True,
2638        **opts,
2639    ) -> Join:
2640        """
2641        Append to or set the USING expressions.
2642
2643        Example:
2644            >>> import sqlglot
2645            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2646            'JOIN x USING (foo, bla)'
2647
2648        Args:
2649            *expressions: the SQL code strings to parse.
2650                If an `Expression` instance is passed, it will be used as-is.
2651            append: if `True`, concatenate the new expressions to the existing "using" list.
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_list_builder(
2661            *expressions,
2662            instance=self,
2663            arg="using",
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 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):
2676class Lateral(UDTF):
2677    arg_types = {
2678        "this": True,
2679        "view": False,
2680        "outer": False,
2681        "alias": False,
2682        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2683        "ordinality": False,
2684    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2689class TableFromRows(UDTF):
2690    arg_types = {
2691        "this": True,
2692        "alias": False,
2693        "joins": False,
2694        "pivots": False,
2695        "sample": False,
2696    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2699class MatchRecognizeMeasure(Expression):
2700    arg_types = {
2701        "this": True,
2702        "window_frame": False,
2703    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2706class MatchRecognize(Expression):
2707    arg_types = {
2708        "partition_by": False,
2709        "order": False,
2710        "measures": False,
2711        "rows": False,
2712        "after": False,
2713        "pattern": False,
2714        "define": False,
2715        "alias": False,
2716    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2721class Final(Expression):
2722    pass
key = 'final'
class Offset(Expression):
2725class Offset(Expression):
2726    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2729class Order(Expression):
2730    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2734class WithFill(Expression):
2735    arg_types = {
2736        "from": False,
2737        "to": False,
2738        "step": False,
2739        "interpolate": False,
2740    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2745class Cluster(Order):
2746    pass
key = 'cluster'
class Distribute(Order):
2749class Distribute(Order):
2750    pass
key = 'distribute'
class Sort(Order):
2753class Sort(Order):
2754    pass
key = 'sort'
class Ordered(Expression):
2757class Ordered(Expression):
2758    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2759
2760    @property
2761    def name(self) -> str:
2762        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2760    @property
2761    def name(self) -> str:
2762        return self.this.name
key = 'ordered'
class Property(Expression):
2765class Property(Expression):
2766    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2769class GrantPrivilege(Expression):
2770    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2773class GrantPrincipal(Expression):
2774    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2777class AllowedValuesProperty(Expression):
2778    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2781class AlgorithmProperty(Property):
2782    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2785class AutoIncrementProperty(Property):
2786    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2790class AutoRefreshProperty(Property):
2791    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2794class BackupProperty(Property):
2795    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BuildProperty(Property):
2799class BuildProperty(Property):
2800    arg_types = {"this": True}
arg_types = {'this': True}
key = 'buildproperty'
class BlockCompressionProperty(Property):
2803class BlockCompressionProperty(Property):
2804    arg_types = {
2805        "autotemp": False,
2806        "always": False,
2807        "default": False,
2808        "manual": False,
2809        "never": False,
2810    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2813class CharacterSetProperty(Property):
2814    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2817class ChecksumProperty(Property):
2818    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2821class CollateProperty(Property):
2822    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2825class CopyGrantsProperty(Property):
2826    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2829class DataBlocksizeProperty(Property):
2830    arg_types = {
2831        "size": False,
2832        "units": False,
2833        "minimum": False,
2834        "maximum": False,
2835        "default": False,
2836    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2839class DataDeletionProperty(Property):
2840    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):
2843class DefinerProperty(Property):
2844    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2847class DistKeyProperty(Property):
2848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2853class DistributedByProperty(Property):
2854    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):
2857class DistStyleProperty(Property):
2858    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2861class DuplicateKeyProperty(Property):
2862    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2865class EngineProperty(Property):
2866    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2869class HeapProperty(Property):
2870    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2873class ToTableProperty(Property):
2874    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2877class ExecuteAsProperty(Property):
2878    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2881class ExternalProperty(Property):
2882    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2885class FallbackProperty(Property):
2886    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2890class FileFormatProperty(Property):
2891    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2894class CredentialsProperty(Property):
2895    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2898class FreespaceProperty(Property):
2899    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2902class GlobalProperty(Property):
2903    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2906class IcebergProperty(Property):
2907    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2910class InheritsProperty(Property):
2911    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2914class InputModelProperty(Property):
2915    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2918class OutputModelProperty(Property):
2919    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2922class IsolatedLoadingProperty(Property):
2923    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2926class JournalProperty(Property):
2927    arg_types = {
2928        "no": False,
2929        "dual": False,
2930        "before": False,
2931        "local": False,
2932        "after": False,
2933    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2936class LanguageProperty(Property):
2937    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2940class EnviromentProperty(Property):
2941    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2945class ClusteredByProperty(Property):
2946    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2949class DictProperty(Property):
2950    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2953class DictSubProperty(Property):
2954    pass
key = 'dictsubproperty'
class DictRange(Property):
2957class DictRange(Property):
2958    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2961class DynamicProperty(Property):
2962    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2967class OnCluster(Property):
2968    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2972class EmptyProperty(Property):
2973    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2976class LikeProperty(Property):
2977    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2980class LocationProperty(Property):
2981    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2984class LockProperty(Property):
2985    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2988class LockingProperty(Property):
2989    arg_types = {
2990        "this": False,
2991        "kind": True,
2992        "for_or_in": False,
2993        "lock_type": True,
2994        "override": False,
2995    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2998class LogProperty(Property):
2999    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
3002class MaterializedProperty(Property):
3003    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
3006class MergeBlockRatioProperty(Property):
3007    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):
3010class NoPrimaryIndexProperty(Property):
3011    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
3014class OnProperty(Property):
3015    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
3018class OnCommitProperty(Property):
3019    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3022class PartitionedByProperty(Property):
3023    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3026class PartitionedByBucket(Property):
3027    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3030class PartitionByTruncate(Property):
3031    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3035class PartitionByRangeProperty(Property):
3036    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3040class PartitionByRangePropertyDynamic(Expression):
3041    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):
3045class PartitionByListProperty(Property):
3046    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbylistproperty'
class PartitionList(Expression):
3050class PartitionList(Expression):
3051    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'partitionlist'
class RefreshTriggerProperty(Property):
3055class RefreshTriggerProperty(Property):
3056    arg_types = {
3057        "method": True,
3058        "kind": False,
3059        "every": False,
3060        "unit": False,
3061        "starts": False,
3062    }
arg_types = {'method': True, 'kind': False, 'every': False, 'unit': False, 'starts': False}
key = 'refreshtriggerproperty'
class UniqueKeyProperty(Property):
3066class UniqueKeyProperty(Property):
3067    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3071class PartitionBoundSpec(Expression):
3072    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3073    arg_types = {
3074        "this": False,
3075        "expression": False,
3076        "from_expressions": False,
3077        "to_expressions": False,
3078    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3081class PartitionedOfProperty(Property):
3082    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3083    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3086class StreamingTableProperty(Property):
3087    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3090class RemoteWithConnectionModelProperty(Property):
3091    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3094class ReturnsProperty(Property):
3095    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):
3098class StrictProperty(Property):
3099    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3102class RowFormatProperty(Property):
3103    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3106class RowFormatDelimitedProperty(Property):
3107    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3108    arg_types = {
3109        "fields": False,
3110        "escaped": False,
3111        "collection_items": False,
3112        "map_keys": False,
3113        "lines": False,
3114        "null": False,
3115        "serde": False,
3116    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3119class RowFormatSerdeProperty(Property):
3120    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3124class QueryTransform(Expression):
3125    arg_types = {
3126        "expressions": True,
3127        "command_script": True,
3128        "schema": False,
3129        "row_format_before": False,
3130        "record_writer": False,
3131        "row_format_after": False,
3132        "record_reader": False,
3133    }
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):
3136class SampleProperty(Property):
3137    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3141class SecurityProperty(Property):
3142    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3145class SchemaCommentProperty(Property):
3146    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3149class SemanticView(Expression):
3150    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):
3153class SerdeProperties(Property):
3154    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3157class SetProperty(Property):
3158    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3161class SharingProperty(Property):
3162    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3165class SetConfigProperty(Property):
3166    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3169class SettingsProperty(Property):
3170    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3173class SortKeyProperty(Property):
3174    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3177class SqlReadWriteProperty(Property):
3178    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3181class SqlSecurityProperty(Property):
3182    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3185class StabilityProperty(Property):
3186    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3189class StorageHandlerProperty(Property):
3190    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3193class TemporaryProperty(Property):
3194    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3197class SecureProperty(Property):
3198    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3202class Tags(ColumnConstraintKind, Property):
3203    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3206class TransformModelProperty(Property):
3207    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3210class TransientProperty(Property):
3211    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3214class UnloggedProperty(Property):
3215    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3219class UsingTemplateProperty(Property):
3220    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3224class ViewAttributeProperty(Property):
3225    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3228class VolatileProperty(Property):
3229    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3232class WithDataProperty(Property):
3233    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3236class WithJournalTableProperty(Property):
3237    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3240class WithSchemaBindingProperty(Property):
3241    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3244class WithSystemVersioningProperty(Property):
3245    arg_types = {
3246        "on": False,
3247        "this": False,
3248        "data_consistency": False,
3249        "retention_period": False,
3250        "with": True,
3251    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3254class WithProcedureOptions(Property):
3255    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3258class EncodeProperty(Property):
3259    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3262class IncludeProperty(Property):
3263    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3266class ForceProperty(Property):
3267    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3270class Properties(Expression):
3271    arg_types = {"expressions": True}
3272
3273    NAME_TO_PROPERTY = {
3274        "ALGORITHM": AlgorithmProperty,
3275        "AUTO_INCREMENT": AutoIncrementProperty,
3276        "CHARACTER SET": CharacterSetProperty,
3277        "CLUSTERED_BY": ClusteredByProperty,
3278        "COLLATE": CollateProperty,
3279        "COMMENT": SchemaCommentProperty,
3280        "CREDENTIALS": CredentialsProperty,
3281        "DEFINER": DefinerProperty,
3282        "DISTKEY": DistKeyProperty,
3283        "DISTRIBUTED_BY": DistributedByProperty,
3284        "DISTSTYLE": DistStyleProperty,
3285        "ENGINE": EngineProperty,
3286        "EXECUTE AS": ExecuteAsProperty,
3287        "FORMAT": FileFormatProperty,
3288        "LANGUAGE": LanguageProperty,
3289        "LOCATION": LocationProperty,
3290        "LOCK": LockProperty,
3291        "PARTITIONED_BY": PartitionedByProperty,
3292        "RETURNS": ReturnsProperty,
3293        "ROW_FORMAT": RowFormatProperty,
3294        "SORTKEY": SortKeyProperty,
3295        "ENCODE": EncodeProperty,
3296        "INCLUDE": IncludeProperty,
3297    }
3298
3299    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3300
3301    # CREATE property locations
3302    # Form: schema specified
3303    #   create [POST_CREATE]
3304    #     table a [POST_NAME]
3305    #     (b int) [POST_SCHEMA]
3306    #     with ([POST_WITH])
3307    #     index (b) [POST_INDEX]
3308    #
3309    # Form: alias selection
3310    #   create [POST_CREATE]
3311    #     table a [POST_NAME]
3312    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3313    #     index (c) [POST_INDEX]
3314    class Location(AutoName):
3315        POST_CREATE = auto()
3316        POST_NAME = auto()
3317        POST_SCHEMA = auto()
3318        POST_WITH = auto()
3319        POST_ALIAS = auto()
3320        POST_EXPRESSION = auto()
3321        POST_INDEX = auto()
3322        UNSUPPORTED = auto()
3323
3324    @classmethod
3325    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3326        expressions = []
3327        for key, value in properties_dict.items():
3328            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3329            if property_cls:
3330                expressions.append(property_cls(this=convert(value)))
3331            else:
3332                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3333
3334        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:
3324    @classmethod
3325    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3326        expressions = []
3327        for key, value in properties_dict.items():
3328            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3329            if property_cls:
3330                expressions.append(property_cls(this=convert(value)))
3331            else:
3332                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3333
3334        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3314    class Location(AutoName):
3315        POST_CREATE = auto()
3316        POST_NAME = auto()
3317        POST_SCHEMA = auto()
3318        POST_WITH = auto()
3319        POST_ALIAS = auto()
3320        POST_EXPRESSION = auto()
3321        POST_INDEX = auto()
3322        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):
3337class Qualify(Expression):
3338    pass
key = 'qualify'
class InputOutputFormat(Expression):
3341class InputOutputFormat(Expression):
3342    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3346class Return(Expression):
3347    pass
key = 'return'
class Reference(Expression):
3350class Reference(Expression):
3351    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3354class Tuple(Expression):
3355    arg_types = {"expressions": False}
3356
3357    def isin(
3358        self,
3359        *expressions: t.Any,
3360        query: t.Optional[ExpOrStr] = None,
3361        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3362        copy: bool = True,
3363        **opts,
3364    ) -> In:
3365        return In(
3366            this=maybe_copy(self, copy),
3367            expressions=[convert(e, copy=copy) for e in expressions],
3368            query=maybe_parse(query, copy=copy, **opts) if query else None,
3369            unnest=(
3370                Unnest(
3371                    expressions=[
3372                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3373                        for e in ensure_list(unnest)
3374                    ]
3375                )
3376                if unnest
3377                else None
3378            ),
3379        )
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:
3357    def isin(
3358        self,
3359        *expressions: t.Any,
3360        query: t.Optional[ExpOrStr] = None,
3361        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3362        copy: bool = True,
3363        **opts,
3364    ) -> In:
3365        return In(
3366            this=maybe_copy(self, copy),
3367            expressions=[convert(e, copy=copy) for e in expressions],
3368            query=maybe_parse(query, copy=copy, **opts) if query else None,
3369            unnest=(
3370                Unnest(
3371                    expressions=[
3372                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3373                        for e in ensure_list(unnest)
3374                    ]
3375                )
3376                if unnest
3377                else None
3378            ),
3379        )
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):
3410class QueryOption(Expression):
3411    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3415class WithTableHint(Expression):
3416    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3420class IndexTableHint(Expression):
3421    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3425class HistoricalData(Expression):
3426    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3430class Put(Expression):
3431    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3435class Get(Expression):
3436    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3439class Table(Expression):
3440    arg_types = {
3441        "this": False,
3442        "alias": False,
3443        "db": False,
3444        "catalog": False,
3445        "laterals": False,
3446        "joins": False,
3447        "pivots": False,
3448        "hints": False,
3449        "system_time": False,
3450        "version": False,
3451        "format": False,
3452        "pattern": False,
3453        "ordinality": False,
3454        "when": False,
3455        "only": False,
3456        "partition": False,
3457        "changes": False,
3458        "rows_from": False,
3459        "sample": False,
3460    }
3461
3462    @property
3463    def name(self) -> str:
3464        if not self.this or isinstance(self.this, Func):
3465            return ""
3466        return self.this.name
3467
3468    @property
3469    def db(self) -> str:
3470        return self.text("db")
3471
3472    @property
3473    def catalog(self) -> str:
3474        return self.text("catalog")
3475
3476    @property
3477    def selects(self) -> t.List[Expression]:
3478        return []
3479
3480    @property
3481    def named_selects(self) -> t.List[str]:
3482        return []
3483
3484    @property
3485    def parts(self) -> t.List[Expression]:
3486        """Return the parts of a table in order catalog, db, table."""
3487        parts: t.List[Expression] = []
3488
3489        for arg in ("catalog", "db", "this"):
3490            part = self.args.get(arg)
3491
3492            if isinstance(part, Dot):
3493                parts.extend(part.flatten())
3494            elif isinstance(part, Expression):
3495                parts.append(part)
3496
3497        return parts
3498
3499    def to_column(self, copy: bool = True) -> Expression:
3500        parts = self.parts
3501        last_part = parts[-1]
3502
3503        if isinstance(last_part, Identifier):
3504            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3505        else:
3506            # This branch will be reached if a function or array is wrapped in a `Table`
3507            col = last_part
3508
3509        alias = self.args.get("alias")
3510        if alias:
3511            col = alias_(col, alias.this, copy=copy)
3512
3513        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
3462    @property
3463    def name(self) -> str:
3464        if not self.this or isinstance(self.this, Func):
3465            return ""
3466        return self.this.name
db: str
3468    @property
3469    def db(self) -> str:
3470        return self.text("db")
catalog: str
3472    @property
3473    def catalog(self) -> str:
3474        return self.text("catalog")
selects: List[Expression]
3476    @property
3477    def selects(self) -> t.List[Expression]:
3478        return []
named_selects: List[str]
3480    @property
3481    def named_selects(self) -> t.List[str]:
3482        return []
parts: List[Expression]
3484    @property
3485    def parts(self) -> t.List[Expression]:
3486        """Return the parts of a table in order catalog, db, table."""
3487        parts: t.List[Expression] = []
3488
3489        for arg in ("catalog", "db", "this"):
3490            part = self.args.get(arg)
3491
3492            if isinstance(part, Dot):
3493                parts.extend(part.flatten())
3494            elif isinstance(part, Expression):
3495                parts.append(part)
3496
3497        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3499    def to_column(self, copy: bool = True) -> Expression:
3500        parts = self.parts
3501        last_part = parts[-1]
3502
3503        if isinstance(last_part, Identifier):
3504            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3505        else:
3506            # This branch will be reached if a function or array is wrapped in a `Table`
3507            col = last_part
3508
3509        alias = self.args.get("alias")
3510        if alias:
3511            col = alias_(col, alias.this, copy=copy)
3512
3513        return col
key = 'table'
class SetOperation(Query):
3516class SetOperation(Query):
3517    arg_types = {
3518        "with": False,
3519        "this": True,
3520        "expression": True,
3521        "distinct": False,
3522        "by_name": False,
3523        "side": False,
3524        "kind": False,
3525        "on": False,
3526        **QUERY_MODIFIERS,
3527    }
3528
3529    def select(
3530        self: S,
3531        *expressions: t.Optional[ExpOrStr],
3532        append: bool = True,
3533        dialect: DialectType = None,
3534        copy: bool = True,
3535        **opts,
3536    ) -> S:
3537        this = maybe_copy(self, copy)
3538        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3539        this.expression.unnest().select(
3540            *expressions, append=append, dialect=dialect, copy=False, **opts
3541        )
3542        return this
3543
3544    @property
3545    def named_selects(self) -> t.List[str]:
3546        return self.this.unnest().named_selects
3547
3548    @property
3549    def is_star(self) -> bool:
3550        return self.this.is_star or self.expression.is_star
3551
3552    @property
3553    def selects(self) -> t.List[Expression]:
3554        return self.this.unnest().selects
3555
3556    @property
3557    def left(self) -> Query:
3558        return self.this
3559
3560    @property
3561    def right(self) -> Query:
3562        return self.expression
3563
3564    @property
3565    def kind(self) -> str:
3566        return self.text("kind").upper()
3567
3568    @property
3569    def side(self) -> str:
3570        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:
3529    def select(
3530        self: S,
3531        *expressions: t.Optional[ExpOrStr],
3532        append: bool = True,
3533        dialect: DialectType = None,
3534        copy: bool = True,
3535        **opts,
3536    ) -> S:
3537        this = maybe_copy(self, copy)
3538        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3539        this.expression.unnest().select(
3540            *expressions, append=append, dialect=dialect, copy=False, **opts
3541        )
3542        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]
3544    @property
3545    def named_selects(self) -> t.List[str]:
3546        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3548    @property
3549    def is_star(self) -> bool:
3550        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3552    @property
3553    def selects(self) -> t.List[Expression]:
3554        return self.this.unnest().selects

Returns the query's projections.

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

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:
3629    def set_(
3630        self,
3631        *expressions: ExpOrStr,
3632        append: bool = True,
3633        dialect: DialectType = None,
3634        copy: bool = True,
3635        **opts,
3636    ) -> Update:
3637        """
3638        Append to or set the SET expressions.
3639
3640        Example:
3641            >>> Update().table("my_table").set_("x = 1").sql()
3642            'UPDATE my_table SET x = 1'
3643
3644        Args:
3645            *expressions: the SQL code strings to parse.
3646                If `Expression` instance(s) are passed, they will be used as-is.
3647                Multiple expressions are combined with a comma.
3648            append: if `True`, add the new expressions to any existing SET expressions.
3649                Otherwise, this resets the expressions.
3650            dialect: the dialect used to parse the input expressions.
3651            copy: if `False`, modify this expression instance in-place.
3652            opts: other options to use to parse the input expressions.
3653        """
3654        return _apply_list_builder(
3655            *expressions,
3656            instance=self,
3657            arg="expressions",
3658            append=append,
3659            into=Expression,
3660            prefix=None,
3661            dialect=dialect,
3662            copy=copy,
3663            **opts,
3664        )

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:
3666    def where(
3667        self,
3668        *expressions: t.Optional[ExpOrStr],
3669        append: bool = True,
3670        dialect: DialectType = None,
3671        copy: bool = True,
3672        **opts,
3673    ) -> Select:
3674        """
3675        Append to or set the WHERE expressions.
3676
3677        Example:
3678            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3679            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3680
3681        Args:
3682            *expressions: the SQL code strings to parse.
3683                If an `Expression` instance is passed, it will be used as-is.
3684                Multiple expressions are combined with an AND operator.
3685            append: if `True`, AND the new expressions to any existing expression.
3686                Otherwise, this resets the expression.
3687            dialect: the dialect used to parse the input expressions.
3688            copy: if `False`, modify this expression instance in-place.
3689            opts: other options to use to parse the input expressions.
3690
3691        Returns:
3692            Select: the modified expression.
3693        """
3694        return _apply_conjunction_builder(
3695            *expressions,
3696            instance=self,
3697            arg="where",
3698            append=append,
3699            into=Where,
3700            dialect=dialect,
3701            copy=copy,
3702            **opts,
3703        )

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:
3705    def from_(
3706        self,
3707        expression: t.Optional[ExpOrStr] = None,
3708        dialect: DialectType = None,
3709        copy: bool = True,
3710        **opts,
3711    ) -> Update:
3712        """
3713        Set the FROM expression.
3714
3715        Example:
3716            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3717            'UPDATE my_table SET x = 1 FROM baz'
3718
3719        Args:
3720            expression : the SQL code strings to parse.
3721                If a `From` instance is passed, this is used as-is.
3722                If another `Expression` instance is passed, it will be wrapped in a `From`.
3723                If nothing is passed in then a from is not applied to the expression
3724            dialect: the dialect used to parse the input expression.
3725            copy: if `False`, modify this expression instance in-place.
3726            opts: other options to use to parse the input expressions.
3727
3728        Returns:
3729            The modified Update expression.
3730        """
3731        if not expression:
3732            return maybe_copy(self, copy)
3733
3734        return _apply_builder(
3735            expression=expression,
3736            instance=self,
3737            arg="from",
3738            into=From,
3739            prefix="FROM",
3740            dialect=dialect,
3741            copy=copy,
3742            **opts,
3743        )

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:
3745    def with_(
3746        self,
3747        alias: ExpOrStr,
3748        as_: ExpOrStr,
3749        recursive: t.Optional[bool] = None,
3750        materialized: t.Optional[bool] = None,
3751        append: bool = True,
3752        dialect: DialectType = None,
3753        copy: bool = True,
3754        **opts,
3755    ) -> Update:
3756        """
3757        Append to or set the common table expressions.
3758
3759        Example:
3760            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3761            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3762
3763        Args:
3764            alias: the SQL code string to parse as the table name.
3765                If an `Expression` instance is passed, this is used as-is.
3766            as_: the SQL code string to parse as the table expression.
3767                If an `Expression` instance is passed, it will be used as-is.
3768            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3769            materialized: set the MATERIALIZED part of the expression.
3770            append: if `True`, add to any existing expressions.
3771                Otherwise, this resets the expressions.
3772            dialect: the dialect used to parse the input expression.
3773            copy: if `False`, modify this expression instance in-place.
3774            opts: other options to use to parse the input expressions.
3775
3776        Returns:
3777            The modified expression.
3778        """
3779        return _apply_cte_builder(
3780            self,
3781            alias,
3782            as_,
3783            recursive=recursive,
3784            materialized=materialized,
3785            append=append,
3786            dialect=dialect,
3787            copy=copy,
3788            **opts,
3789        )

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

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:
3869    def group_by(
3870        self,
3871        *expressions: t.Optional[ExpOrStr],
3872        append: bool = True,
3873        dialect: DialectType = None,
3874        copy: bool = True,
3875        **opts,
3876    ) -> Select:
3877        """
3878        Set the GROUP BY expression.
3879
3880        Example:
3881            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3882            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3883
3884        Args:
3885            *expressions: the SQL code strings to parse.
3886                If a `Group` instance is passed, this is used as-is.
3887                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3888                If nothing is passed in then a group by is not applied to the expression
3889            append: if `True`, add to any existing expressions.
3890                Otherwise, this flattens all the `Group` expression into a single expression.
3891            dialect: the dialect used to parse the input expression.
3892            copy: if `False`, modify this expression instance in-place.
3893            opts: other options to use to parse the input expressions.
3894
3895        Returns:
3896            The modified Select expression.
3897        """
3898        if not expressions:
3899            return self if not copy else self.copy()
3900
3901        return _apply_child_list_builder(
3902            *expressions,
3903            instance=self,
3904            arg="group",
3905            append=append,
3906            copy=copy,
3907            prefix="GROUP BY",
3908            into=Group,
3909            dialect=dialect,
3910            **opts,
3911        )

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:
3913    def sort_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 SORT BY expression.
3923
3924        Example:
3925            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3926            'SELECT x FROM tbl SORT BY x DESC'
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 `SORT`.
3932            append: if `True`, add to any existing expressions.
3933                Otherwise, this flattens all the `Order` 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        return _apply_child_list_builder(
3942            *expressions,
3943            instance=self,
3944            arg="sort",
3945            append=append,
3946            copy=copy,
3947            prefix="SORT BY",
3948            into=Sort,
3949            dialect=dialect,
3950            **opts,
3951        )

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

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:
3993    def select(
3994        self,
3995        *expressions: t.Optional[ExpOrStr],
3996        append: bool = True,
3997        dialect: DialectType = None,
3998        copy: bool = True,
3999        **opts,
4000    ) -> Select:
4001        return _apply_list_builder(
4002            *expressions,
4003            instance=self,
4004            arg="expressions",
4005            append=append,
4006            dialect=dialect,
4007            into=Expression,
4008            copy=copy,
4009            **opts,
4010        )

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:
4012    def lateral(
4013        self,
4014        *expressions: t.Optional[ExpOrStr],
4015        append: bool = True,
4016        dialect: DialectType = None,
4017        copy: bool = True,
4018        **opts,
4019    ) -> Select:
4020        """
4021        Append to or set the LATERAL expressions.
4022
4023        Example:
4024            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
4025            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
4026
4027        Args:
4028            *expressions: the SQL code strings to parse.
4029                If an `Expression` instance is passed, it will be used as-is.
4030            append: if `True`, add to any existing expressions.
4031                Otherwise, this resets the expressions.
4032            dialect: the dialect used to parse the input expressions.
4033            copy: if `False`, modify this expression instance in-place.
4034            opts: other options to use to parse the input expressions.
4035
4036        Returns:
4037            The modified Select expression.
4038        """
4039        return _apply_list_builder(
4040            *expressions,
4041            instance=self,
4042            arg="laterals",
4043            append=append,
4044            into=Lateral,
4045            prefix="LATERAL VIEW",
4046            dialect=dialect,
4047            copy=copy,
4048            **opts,
4049        )

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:
4051    def join(
4052        self,
4053        expression: ExpOrStr,
4054        on: t.Optional[ExpOrStr] = None,
4055        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4056        append: bool = True,
4057        join_type: t.Optional[str] = None,
4058        join_alias: t.Optional[Identifier | str] = None,
4059        dialect: DialectType = None,
4060        copy: bool = True,
4061        **opts,
4062    ) -> Select:
4063        """
4064        Append to or set the JOIN expressions.
4065
4066        Example:
4067            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4068            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4069
4070            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4071            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4072
4073            Use `join_type` to change the type of join:
4074
4075            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4076            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4077
4078        Args:
4079            expression: the SQL code string to parse.
4080                If an `Expression` instance is passed, it will be used as-is.
4081            on: optionally specify the join "on" criteria as a SQL string.
4082                If an `Expression` instance is passed, it will be used as-is.
4083            using: optionally specify the join "using" criteria as a SQL string.
4084                If an `Expression` instance is passed, it will be used as-is.
4085            append: if `True`, add to any existing expressions.
4086                Otherwise, this resets the expressions.
4087            join_type: if set, alter the parsed join type.
4088            join_alias: an optional alias for the joined source.
4089            dialect: the dialect used to parse the input expressions.
4090            copy: if `False`, modify this expression instance in-place.
4091            opts: other options to use to parse the input expressions.
4092
4093        Returns:
4094            Select: the modified expression.
4095        """
4096        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4097
4098        try:
4099            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4100        except ParseError:
4101            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4102
4103        join = expression if isinstance(expression, Join) else Join(this=expression)
4104
4105        if isinstance(join.this, Select):
4106            join.this.replace(join.this.subquery())
4107
4108        if join_type:
4109            method: t.Optional[Token]
4110            side: t.Optional[Token]
4111            kind: t.Optional[Token]
4112
4113            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4114
4115            if method:
4116                join.set("method", method.text)
4117            if side:
4118                join.set("side", side.text)
4119            if kind:
4120                join.set("kind", kind.text)
4121
4122        if on:
4123            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4124            join.set("on", on)
4125
4126        if using:
4127            join = _apply_list_builder(
4128                *ensure_list(using),
4129                instance=join,
4130                arg="using",
4131                append=append,
4132                copy=copy,
4133                into=Identifier,
4134                **opts,
4135            )
4136
4137        if join_alias:
4138            join.set("this", alias_(join.this, join_alias, table=True))
4139
4140        return _apply_list_builder(
4141            join,
4142            instance=self,
4143            arg="joins",
4144            append=append,
4145            copy=copy,
4146            **opts,
4147        )

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:
4149    def having(
4150        self,
4151        *expressions: t.Optional[ExpOrStr],
4152        append: bool = True,
4153        dialect: DialectType = None,
4154        copy: bool = True,
4155        **opts,
4156    ) -> Select:
4157        """
4158        Append to or set the HAVING expressions.
4159
4160        Example:
4161            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4162            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4163
4164        Args:
4165            *expressions: the SQL code strings to parse.
4166                If an `Expression` instance is passed, it will be used as-is.
4167                Multiple expressions are combined with an AND operator.
4168            append: if `True`, AND the new expressions to any existing expression.
4169                Otherwise, this resets the expression.
4170            dialect: the dialect used to parse the input expressions.
4171            copy: if `False`, modify this expression instance in-place.
4172            opts: other options to use to parse the input expressions.
4173
4174        Returns:
4175            The modified Select expression.
4176        """
4177        return _apply_conjunction_builder(
4178            *expressions,
4179            instance=self,
4180            arg="having",
4181            append=append,
4182            into=Having,
4183            dialect=dialect,
4184            copy=copy,
4185            **opts,
4186        )

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:
4188    def window(
4189        self,
4190        *expressions: t.Optional[ExpOrStr],
4191        append: bool = True,
4192        dialect: DialectType = None,
4193        copy: bool = True,
4194        **opts,
4195    ) -> Select:
4196        return _apply_list_builder(
4197            *expressions,
4198            instance=self,
4199            arg="windows",
4200            append=append,
4201            into=Window,
4202            dialect=dialect,
4203            copy=copy,
4204            **opts,
4205        )
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:
4207    def qualify(
4208        self,
4209        *expressions: t.Optional[ExpOrStr],
4210        append: bool = True,
4211        dialect: DialectType = None,
4212        copy: bool = True,
4213        **opts,
4214    ) -> Select:
4215        return _apply_conjunction_builder(
4216            *expressions,
4217            instance=self,
4218            arg="qualify",
4219            append=append,
4220            into=Qualify,
4221            dialect=dialect,
4222            copy=copy,
4223            **opts,
4224        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4226    def distinct(
4227        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4228    ) -> Select:
4229        """
4230        Set the OFFSET expression.
4231
4232        Example:
4233            >>> Select().from_("tbl").select("x").distinct().sql()
4234            'SELECT DISTINCT x FROM tbl'
4235
4236        Args:
4237            ons: the expressions to distinct on
4238            distinct: whether the Select should be distinct
4239            copy: if `False`, modify this expression instance in-place.
4240
4241        Returns:
4242            Select: the modified expression.
4243        """
4244        instance = maybe_copy(self, copy)
4245        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4246        instance.set("distinct", Distinct(on=on) if distinct else None)
4247        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:
4249    def ctas(
4250        self,
4251        table: ExpOrStr,
4252        properties: t.Optional[t.Dict] = None,
4253        dialect: DialectType = None,
4254        copy: bool = True,
4255        **opts,
4256    ) -> Create:
4257        """
4258        Convert this expression to a CREATE TABLE AS statement.
4259
4260        Example:
4261            >>> Select().select("*").from_("tbl").ctas("x").sql()
4262            'CREATE TABLE x AS SELECT * FROM tbl'
4263
4264        Args:
4265            table: the SQL code string to parse as the table name.
4266                If another `Expression` instance is passed, it will be used as-is.
4267            properties: an optional mapping of table properties
4268            dialect: the dialect used to parse the input table.
4269            copy: if `False`, modify this expression instance in-place.
4270            opts: other options to use to parse the input table.
4271
4272        Returns:
4273            The new Create expression.
4274        """
4275        instance = maybe_copy(self, copy)
4276        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4277
4278        properties_expression = None
4279        if properties:
4280            properties_expression = Properties.from_dict(properties)
4281
4282        return Create(
4283            this=table_expression,
4284            kind="TABLE",
4285            expression=instance,
4286            properties=properties_expression,
4287        )

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:
4289    def lock(self, update: bool = True, copy: bool = True) -> Select:
4290        """
4291        Set the locking read mode for this expression.
4292
4293        Examples:
4294            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4295            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4296
4297            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4298            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4299
4300        Args:
4301            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4302            copy: if `False`, modify this expression instance in-place.
4303
4304        Returns:
4305            The modified expression.
4306        """
4307        inst = maybe_copy(self, copy)
4308        inst.set("locks", [Lock(update=update)])
4309
4310        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:
4312    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4313        """
4314        Set hints for this expression.
4315
4316        Examples:
4317            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4318            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4319
4320        Args:
4321            hints: The SQL code strings to parse as the hints.
4322                If an `Expression` instance is passed, it will be used as-is.
4323            dialect: The dialect used to parse the hints.
4324            copy: If `False`, modify this expression instance in-place.
4325
4326        Returns:
4327            The modified expression.
4328        """
4329        inst = maybe_copy(self, copy)
4330        inst.set(
4331            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4332        )
4333
4334        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]
4336    @property
4337    def named_selects(self) -> t.List[str]:
4338        selects = []
4339
4340        for e in self.expressions:
4341            if e.alias_or_name:
4342                selects.append(e.output_name)
4343            elif isinstance(e, Aliases):
4344                selects.extend([a.name for a in e.aliases])
4345        return selects

Returns the output names of the query's projections.

is_star: bool
4347    @property
4348    def is_star(self) -> bool:
4349        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4351    @property
4352    def selects(self) -> t.List[Expression]:
4353        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4359class Subquery(DerivedTable, Query):
4360    arg_types = {
4361        "this": True,
4362        "alias": False,
4363        "with": False,
4364        **QUERY_MODIFIERS,
4365    }
4366
4367    def unnest(self):
4368        """Returns the first non subquery."""
4369        expression = self
4370        while isinstance(expression, Subquery):
4371            expression = expression.this
4372        return expression
4373
4374    def unwrap(self) -> Subquery:
4375        expression = self
4376        while expression.same_parent and expression.is_wrapper:
4377            expression = t.cast(Subquery, expression.parent)
4378        return expression
4379
4380    def select(
4381        self,
4382        *expressions: t.Optional[ExpOrStr],
4383        append: bool = True,
4384        dialect: DialectType = None,
4385        copy: bool = True,
4386        **opts,
4387    ) -> Subquery:
4388        this = maybe_copy(self, copy)
4389        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4390        return this
4391
4392    @property
4393    def is_wrapper(self) -> bool:
4394        """
4395        Whether this Subquery acts as a simple wrapper around another expression.
4396
4397        SELECT * FROM (((SELECT * FROM t)))
4398                      ^
4399                      This corresponds to a "wrapper" Subquery node
4400        """
4401        return all(v is None for k, v in self.args.items() if k != "this")
4402
4403    @property
4404    def is_star(self) -> bool:
4405        return self.this.is_star
4406
4407    @property
4408    def output_name(self) -> str:
4409        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):
4367    def unnest(self):
4368        """Returns the first non subquery."""
4369        expression = self
4370        while isinstance(expression, Subquery):
4371            expression = expression.this
4372        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4374    def unwrap(self) -> Subquery:
4375        expression = self
4376        while expression.same_parent and expression.is_wrapper:
4377            expression = t.cast(Subquery, expression.parent)
4378        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:
4380    def select(
4381        self,
4382        *expressions: t.Optional[ExpOrStr],
4383        append: bool = True,
4384        dialect: DialectType = None,
4385        copy: bool = True,
4386        **opts,
4387    ) -> Subquery:
4388        this = maybe_copy(self, copy)
4389        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4390        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
4392    @property
4393    def is_wrapper(self) -> bool:
4394        """
4395        Whether this Subquery acts as a simple wrapper around another expression.
4396
4397        SELECT * FROM (((SELECT * FROM t)))
4398                      ^
4399                      This corresponds to a "wrapper" Subquery node
4400        """
4401        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
4403    @property
4404    def is_star(self) -> bool:
4405        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4407    @property
4408    def output_name(self) -> str:
4409        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):
4412class TableSample(Expression):
4413    arg_types = {
4414        "expressions": False,
4415        "method": False,
4416        "bucket_numerator": False,
4417        "bucket_denominator": False,
4418        "bucket_field": False,
4419        "percent": False,
4420        "rows": False,
4421        "size": False,
4422        "seed": False,
4423    }
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):
4426class Tag(Expression):
4427    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4428
4429    arg_types = {
4430        "this": False,
4431        "prefix": False,
4432        "postfix": False,
4433    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4438class Pivot(Expression):
4439    arg_types = {
4440        "this": False,
4441        "alias": False,
4442        "expressions": False,
4443        "fields": False,
4444        "unpivot": False,
4445        "using": False,
4446        "group": False,
4447        "columns": False,
4448        "include_nulls": False,
4449        "default_on_null": False,
4450        "into": False,
4451    }
4452
4453    @property
4454    def unpivot(self) -> bool:
4455        return bool(self.args.get("unpivot"))
4456
4457    @property
4458    def fields(self) -> t.List[Expression]:
4459        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
4453    @property
4454    def unpivot(self) -> bool:
4455        return bool(self.args.get("unpivot"))
fields: List[Expression]
4457    @property
4458    def fields(self) -> t.List[Expression]:
4459        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4464class UnpivotColumns(Expression):
4465    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4468class Window(Condition):
4469    arg_types = {
4470        "this": True,
4471        "partition_by": False,
4472        "order": False,
4473        "spec": False,
4474        "alias": False,
4475        "over": False,
4476        "first": False,
4477    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4480class WindowSpec(Expression):
4481    arg_types = {
4482        "kind": False,
4483        "start": False,
4484        "start_side": False,
4485        "end": False,
4486        "end_side": False,
4487        "exclude": False,
4488    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4491class PreWhere(Expression):
4492    pass
key = 'prewhere'
class Where(Expression):
4495class Where(Expression):
4496    pass
key = 'where'
class Star(Expression):
4499class Star(Expression):
4500    arg_types = {"except": False, "replace": False, "rename": False}
4501
4502    @property
4503    def name(self) -> str:
4504        return "*"
4505
4506    @property
4507    def output_name(self) -> str:
4508        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4502    @property
4503    def name(self) -> str:
4504        return "*"
output_name: str
4506    @property
4507    def output_name(self) -> str:
4508        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):
4511class Parameter(Condition):
4512    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4515class SessionParameter(Condition):
4516    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4521class Placeholder(Condition):
4522    arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
4523
4524    @property
4525    def name(self) -> str:
4526        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False, 'jdbc': False}
name: str
4524    @property
4525    def name(self) -> str:
4526        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4529class Null(Condition):
4530    arg_types: t.Dict[str, t.Any] = {}
4531
4532    @property
4533    def name(self) -> str:
4534        return "NULL"
4535
4536    def to_py(self) -> Lit[None]:
4537        return None
arg_types: Dict[str, Any] = {}
name: str
4532    @property
4533    def name(self) -> str:
4534        return "NULL"
def to_py(self) -> Literal[None]:
4536    def to_py(self) -> Lit[None]:
4537        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4540class Boolean(Condition):
4541    def to_py(self) -> bool:
4542        return self.this
def to_py(self) -> bool:
4541    def to_py(self) -> bool:
4542        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4545class DataTypeParam(Expression):
4546    arg_types = {"this": True, "expression": False}
4547
4548    @property
4549    def name(self) -> str:
4550        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4548    @property
4549    def name(self) -> str:
4550        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4555class DataType(Expression):
4556    arg_types = {
4557        "this": True,
4558        "expressions": False,
4559        "nested": False,
4560        "values": False,
4561        "prefix": False,
4562        "kind": False,
4563        "nullable": False,
4564    }
4565
4566    class Type(AutoName):
4567        ARRAY = auto()
4568        AGGREGATEFUNCTION = auto()
4569        SIMPLEAGGREGATEFUNCTION = auto()
4570        BIGDECIMAL = auto()
4571        BIGINT = auto()
4572        BIGSERIAL = auto()
4573        BINARY = auto()
4574        BIT = auto()
4575        BLOB = auto()
4576        BOOLEAN = auto()
4577        BPCHAR = auto()
4578        CHAR = auto()
4579        DATE = auto()
4580        DATE32 = auto()
4581        DATEMULTIRANGE = auto()
4582        DATERANGE = auto()
4583        DATETIME = auto()
4584        DATETIME2 = auto()
4585        DATETIME64 = auto()
4586        DECIMAL = auto()
4587        DECIMAL32 = auto()
4588        DECIMAL64 = auto()
4589        DECIMAL128 = auto()
4590        DECIMAL256 = auto()
4591        DOUBLE = auto()
4592        DYNAMIC = auto()
4593        ENUM = auto()
4594        ENUM8 = auto()
4595        ENUM16 = auto()
4596        FIXEDSTRING = auto()
4597        FLOAT = auto()
4598        GEOGRAPHY = auto()
4599        GEOGRAPHYPOINT = auto()
4600        GEOMETRY = auto()
4601        POINT = auto()
4602        RING = auto()
4603        LINESTRING = auto()
4604        MULTILINESTRING = auto()
4605        POLYGON = auto()
4606        MULTIPOLYGON = auto()
4607        HLLSKETCH = auto()
4608        HSTORE = auto()
4609        IMAGE = auto()
4610        INET = auto()
4611        INT = auto()
4612        INT128 = auto()
4613        INT256 = auto()
4614        INT4MULTIRANGE = auto()
4615        INT4RANGE = auto()
4616        INT8MULTIRANGE = auto()
4617        INT8RANGE = auto()
4618        INTERVAL = auto()
4619        IPADDRESS = auto()
4620        IPPREFIX = auto()
4621        IPV4 = auto()
4622        IPV6 = auto()
4623        JSON = auto()
4624        JSONB = auto()
4625        LIST = auto()
4626        LONGBLOB = auto()
4627        LONGTEXT = auto()
4628        LOWCARDINALITY = auto()
4629        MAP = auto()
4630        MEDIUMBLOB = auto()
4631        MEDIUMINT = auto()
4632        MEDIUMTEXT = auto()
4633        MONEY = auto()
4634        NAME = auto()
4635        NCHAR = auto()
4636        NESTED = auto()
4637        NOTHING = auto()
4638        NULL = auto()
4639        NUMMULTIRANGE = auto()
4640        NUMRANGE = auto()
4641        NVARCHAR = auto()
4642        OBJECT = auto()
4643        RANGE = auto()
4644        ROWVERSION = auto()
4645        SERIAL = auto()
4646        SET = auto()
4647        SMALLDATETIME = auto()
4648        SMALLINT = auto()
4649        SMALLMONEY = auto()
4650        SMALLSERIAL = auto()
4651        STRUCT = auto()
4652        SUPER = auto()
4653        TEXT = auto()
4654        TINYBLOB = auto()
4655        TINYTEXT = auto()
4656        TIME = auto()
4657        TIMETZ = auto()
4658        TIMESTAMP = auto()
4659        TIMESTAMPNTZ = auto()
4660        TIMESTAMPLTZ = auto()
4661        TIMESTAMPTZ = auto()
4662        TIMESTAMP_S = auto()
4663        TIMESTAMP_MS = auto()
4664        TIMESTAMP_NS = auto()
4665        TINYINT = auto()
4666        TSMULTIRANGE = auto()
4667        TSRANGE = auto()
4668        TSTZMULTIRANGE = auto()
4669        TSTZRANGE = auto()
4670        UBIGINT = auto()
4671        UINT = auto()
4672        UINT128 = auto()
4673        UINT256 = auto()
4674        UMEDIUMINT = auto()
4675        UDECIMAL = auto()
4676        UDOUBLE = auto()
4677        UNION = auto()
4678        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4679        USERDEFINED = "USER-DEFINED"
4680        USMALLINT = auto()
4681        UTINYINT = auto()
4682        UUID = auto()
4683        VARBINARY = auto()
4684        VARCHAR = auto()
4685        VARIANT = auto()
4686        VECTOR = auto()
4687        XML = auto()
4688        YEAR = auto()
4689        TDIGEST = auto()
4690
4691    STRUCT_TYPES = {
4692        Type.NESTED,
4693        Type.OBJECT,
4694        Type.STRUCT,
4695        Type.UNION,
4696    }
4697
4698    ARRAY_TYPES = {
4699        Type.ARRAY,
4700        Type.LIST,
4701    }
4702
4703    NESTED_TYPES = {
4704        *STRUCT_TYPES,
4705        *ARRAY_TYPES,
4706        Type.MAP,
4707    }
4708
4709    TEXT_TYPES = {
4710        Type.CHAR,
4711        Type.NCHAR,
4712        Type.NVARCHAR,
4713        Type.TEXT,
4714        Type.VARCHAR,
4715        Type.NAME,
4716    }
4717
4718    SIGNED_INTEGER_TYPES = {
4719        Type.BIGINT,
4720        Type.INT,
4721        Type.INT128,
4722        Type.INT256,
4723        Type.MEDIUMINT,
4724        Type.SMALLINT,
4725        Type.TINYINT,
4726    }
4727
4728    UNSIGNED_INTEGER_TYPES = {
4729        Type.UBIGINT,
4730        Type.UINT,
4731        Type.UINT128,
4732        Type.UINT256,
4733        Type.UMEDIUMINT,
4734        Type.USMALLINT,
4735        Type.UTINYINT,
4736    }
4737
4738    INTEGER_TYPES = {
4739        *SIGNED_INTEGER_TYPES,
4740        *UNSIGNED_INTEGER_TYPES,
4741        Type.BIT,
4742    }
4743
4744    FLOAT_TYPES = {
4745        Type.DOUBLE,
4746        Type.FLOAT,
4747    }
4748
4749    REAL_TYPES = {
4750        *FLOAT_TYPES,
4751        Type.BIGDECIMAL,
4752        Type.DECIMAL,
4753        Type.DECIMAL32,
4754        Type.DECIMAL64,
4755        Type.DECIMAL128,
4756        Type.DECIMAL256,
4757        Type.MONEY,
4758        Type.SMALLMONEY,
4759        Type.UDECIMAL,
4760        Type.UDOUBLE,
4761    }
4762
4763    NUMERIC_TYPES = {
4764        *INTEGER_TYPES,
4765        *REAL_TYPES,
4766    }
4767
4768    TEMPORAL_TYPES = {
4769        Type.DATE,
4770        Type.DATE32,
4771        Type.DATETIME,
4772        Type.DATETIME2,
4773        Type.DATETIME64,
4774        Type.SMALLDATETIME,
4775        Type.TIME,
4776        Type.TIMESTAMP,
4777        Type.TIMESTAMPNTZ,
4778        Type.TIMESTAMPLTZ,
4779        Type.TIMESTAMPTZ,
4780        Type.TIMESTAMP_MS,
4781        Type.TIMESTAMP_NS,
4782        Type.TIMESTAMP_S,
4783        Type.TIMETZ,
4784    }
4785
4786    @classmethod
4787    def build(
4788        cls,
4789        dtype: DATA_TYPE,
4790        dialect: DialectType = None,
4791        udt: bool = False,
4792        copy: bool = True,
4793        **kwargs,
4794    ) -> DataType:
4795        """
4796        Constructs a DataType object.
4797
4798        Args:
4799            dtype: the data type of interest.
4800            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4801            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4802                DataType, thus creating a user-defined type.
4803            copy: whether to copy the data type.
4804            kwargs: additional arguments to pass in the constructor of DataType.
4805
4806        Returns:
4807            The constructed DataType object.
4808        """
4809        from sqlglot import parse_one
4810
4811        if isinstance(dtype, str):
4812            if dtype.upper() == "UNKNOWN":
4813                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4814
4815            try:
4816                data_type_exp = parse_one(
4817                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4818                )
4819            except ParseError:
4820                if udt:
4821                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4822                raise
4823        elif isinstance(dtype, (Identifier, Dot)) and udt:
4824            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4825        elif isinstance(dtype, DataType.Type):
4826            data_type_exp = DataType(this=dtype)
4827        elif isinstance(dtype, DataType):
4828            return maybe_copy(dtype, copy)
4829        else:
4830            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4831
4832        return DataType(**{**data_type_exp.args, **kwargs})
4833
4834    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4835        """
4836        Checks whether this DataType matches one of the provided data types. Nested types or precision
4837        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4838
4839        Args:
4840            dtypes: the data types to compare this DataType to.
4841            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4842                If false, it means that NULLABLE<INT> is equivalent to INT.
4843
4844        Returns:
4845            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4846        """
4847        self_is_nullable = self.args.get("nullable")
4848        for dtype in dtypes:
4849            other_type = DataType.build(dtype, copy=False, udt=True)
4850            other_is_nullable = other_type.args.get("nullable")
4851            if (
4852                other_type.expressions
4853                or (check_nullable and (self_is_nullable or other_is_nullable))
4854                or self.this == DataType.Type.USERDEFINED
4855                or other_type.this == DataType.Type.USERDEFINED
4856            ):
4857                matches = self == other_type
4858            else:
4859                matches = self.this == other_type.this
4860
4861            if matches:
4862                return True
4863        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.UNION: 'UNION'>, <Type.LIST: 'LIST'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>, <Type.NESTED: 'NESTED'>, <Type.ARRAY: 'ARRAY'>, <Type.STRUCT: 'STRUCT'>}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>}
SIGNED_INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>}
UNSIGNED_INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.UBIGINT: 'UBIGINT'>}
INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT128: 'UINT128'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT256: 'UINT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT: 'UINT'>, <Type.UBIGINT: 'UBIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.DECIMAL128: 'DECIMAL128'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.MONEY: 'MONEY'>}
NUMERIC_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UINT256: 'UINT256'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT: 'UINT'>, <Type.INT: 'INT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIT: 'BIT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DOUBLE: 'DOUBLE'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT128: 'UINT128'>, <Type.UBIGINT: 'UBIGINT'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATE32: 'DATE32'>, <Type.DATE: 'DATE'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>}
@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:
4786    @classmethod
4787    def build(
4788        cls,
4789        dtype: DATA_TYPE,
4790        dialect: DialectType = None,
4791        udt: bool = False,
4792        copy: bool = True,
4793        **kwargs,
4794    ) -> DataType:
4795        """
4796        Constructs a DataType object.
4797
4798        Args:
4799            dtype: the data type of interest.
4800            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4801            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4802                DataType, thus creating a user-defined type.
4803            copy: whether to copy the data type.
4804            kwargs: additional arguments to pass in the constructor of DataType.
4805
4806        Returns:
4807            The constructed DataType object.
4808        """
4809        from sqlglot import parse_one
4810
4811        if isinstance(dtype, str):
4812            if dtype.upper() == "UNKNOWN":
4813                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4814
4815            try:
4816                data_type_exp = parse_one(
4817                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4818                )
4819            except ParseError:
4820                if udt:
4821                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4822                raise
4823        elif isinstance(dtype, (Identifier, Dot)) and udt:
4824            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4825        elif isinstance(dtype, DataType.Type):
4826            data_type_exp = DataType(this=dtype)
4827        elif isinstance(dtype, DataType):
4828            return maybe_copy(dtype, copy)
4829        else:
4830            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4831
4832        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:
4834    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4835        """
4836        Checks whether this DataType matches one of the provided data types. Nested types or precision
4837        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4838
4839        Args:
4840            dtypes: the data types to compare this DataType to.
4841            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4842                If false, it means that NULLABLE<INT> is equivalent to INT.
4843
4844        Returns:
4845            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4846        """
4847        self_is_nullable = self.args.get("nullable")
4848        for dtype in dtypes:
4849            other_type = DataType.build(dtype, copy=False, udt=True)
4850            other_is_nullable = other_type.args.get("nullable")
4851            if (
4852                other_type.expressions
4853                or (check_nullable and (self_is_nullable or other_is_nullable))
4854                or self.this == DataType.Type.USERDEFINED
4855                or other_type.this == DataType.Type.USERDEFINED
4856            ):
4857                matches = self == other_type
4858            else:
4859                matches = self.this == other_type.this
4860
4861            if matches:
4862                return True
4863        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):
4566    class Type(AutoName):
4567        ARRAY = auto()
4568        AGGREGATEFUNCTION = auto()
4569        SIMPLEAGGREGATEFUNCTION = auto()
4570        BIGDECIMAL = auto()
4571        BIGINT = auto()
4572        BIGSERIAL = auto()
4573        BINARY = auto()
4574        BIT = auto()
4575        BLOB = auto()
4576        BOOLEAN = auto()
4577        BPCHAR = auto()
4578        CHAR = auto()
4579        DATE = auto()
4580        DATE32 = auto()
4581        DATEMULTIRANGE = auto()
4582        DATERANGE = auto()
4583        DATETIME = auto()
4584        DATETIME2 = auto()
4585        DATETIME64 = auto()
4586        DECIMAL = auto()
4587        DECIMAL32 = auto()
4588        DECIMAL64 = auto()
4589        DECIMAL128 = auto()
4590        DECIMAL256 = auto()
4591        DOUBLE = auto()
4592        DYNAMIC = auto()
4593        ENUM = auto()
4594        ENUM8 = auto()
4595        ENUM16 = auto()
4596        FIXEDSTRING = auto()
4597        FLOAT = auto()
4598        GEOGRAPHY = auto()
4599        GEOGRAPHYPOINT = auto()
4600        GEOMETRY = auto()
4601        POINT = auto()
4602        RING = auto()
4603        LINESTRING = auto()
4604        MULTILINESTRING = auto()
4605        POLYGON = auto()
4606        MULTIPOLYGON = auto()
4607        HLLSKETCH = auto()
4608        HSTORE = auto()
4609        IMAGE = auto()
4610        INET = auto()
4611        INT = auto()
4612        INT128 = auto()
4613        INT256 = auto()
4614        INT4MULTIRANGE = auto()
4615        INT4RANGE = auto()
4616        INT8MULTIRANGE = auto()
4617        INT8RANGE = auto()
4618        INTERVAL = auto()
4619        IPADDRESS = auto()
4620        IPPREFIX = auto()
4621        IPV4 = auto()
4622        IPV6 = auto()
4623        JSON = auto()
4624        JSONB = auto()
4625        LIST = auto()
4626        LONGBLOB = auto()
4627        LONGTEXT = auto()
4628        LOWCARDINALITY = auto()
4629        MAP = auto()
4630        MEDIUMBLOB = auto()
4631        MEDIUMINT = auto()
4632        MEDIUMTEXT = auto()
4633        MONEY = auto()
4634        NAME = auto()
4635        NCHAR = auto()
4636        NESTED = auto()
4637        NOTHING = auto()
4638        NULL = auto()
4639        NUMMULTIRANGE = auto()
4640        NUMRANGE = auto()
4641        NVARCHAR = auto()
4642        OBJECT = auto()
4643        RANGE = auto()
4644        ROWVERSION = auto()
4645        SERIAL = auto()
4646        SET = auto()
4647        SMALLDATETIME = auto()
4648        SMALLINT = auto()
4649        SMALLMONEY = auto()
4650        SMALLSERIAL = auto()
4651        STRUCT = auto()
4652        SUPER = auto()
4653        TEXT = auto()
4654        TINYBLOB = auto()
4655        TINYTEXT = auto()
4656        TIME = auto()
4657        TIMETZ = auto()
4658        TIMESTAMP = auto()
4659        TIMESTAMPNTZ = auto()
4660        TIMESTAMPLTZ = auto()
4661        TIMESTAMPTZ = auto()
4662        TIMESTAMP_S = auto()
4663        TIMESTAMP_MS = auto()
4664        TIMESTAMP_NS = auto()
4665        TINYINT = auto()
4666        TSMULTIRANGE = auto()
4667        TSRANGE = auto()
4668        TSTZMULTIRANGE = auto()
4669        TSTZRANGE = auto()
4670        UBIGINT = auto()
4671        UINT = auto()
4672        UINT128 = auto()
4673        UINT256 = auto()
4674        UMEDIUMINT = auto()
4675        UDECIMAL = auto()
4676        UDOUBLE = auto()
4677        UNION = auto()
4678        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4679        USERDEFINED = "USER-DEFINED"
4680        USMALLINT = auto()
4681        UTINYINT = auto()
4682        UUID = auto()
4683        VARBINARY = auto()
4684        VARCHAR = auto()
4685        VARIANT = auto()
4686        VECTOR = auto()
4687        XML = auto()
4688        YEAR = auto()
4689        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):
4867class PseudoType(DataType):
4868    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4872class ObjectIdentifier(DataType):
4873    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4877class SubqueryPredicate(Predicate):
4878    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4881class All(SubqueryPredicate):
4882    pass
key = 'all'
class Any(SubqueryPredicate):
4885class Any(SubqueryPredicate):
4886    pass
key = 'any'
class Command(Expression):
4891class Command(Expression):
4892    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4895class Transaction(Expression):
4896    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4899class Commit(Expression):
4900    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4903class Rollback(Expression):
4904    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4907class Alter(Expression):
4908    arg_types = {
4909        "this": True,
4910        "kind": True,
4911        "actions": True,
4912        "exists": False,
4913        "only": False,
4914        "options": False,
4915        "cluster": False,
4916        "not_valid": False,
4917        "check": False,
4918    }
4919
4920    @property
4921    def kind(self) -> t.Optional[str]:
4922        kind = self.args.get("kind")
4923        return kind and kind.upper()
4924
4925    @property
4926    def actions(self) -> t.List[Expression]:
4927        return self.args.get("actions") or []
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False, 'check': False}
kind: Optional[str]
4920    @property
4921    def kind(self) -> t.Optional[str]:
4922        kind = self.args.get("kind")
4923        return kind and kind.upper()
actions: List[Expression]
4925    @property
4926    def actions(self) -> t.List[Expression]:
4927        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4930class Analyze(Expression):
4931    arg_types = {
4932        "kind": False,
4933        "this": False,
4934        "options": False,
4935        "mode": False,
4936        "partition": False,
4937        "expression": False,
4938        "properties": False,
4939    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4942class AnalyzeStatistics(Expression):
4943    arg_types = {
4944        "kind": True,
4945        "option": False,
4946        "this": False,
4947        "expressions": False,
4948    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4951class AnalyzeHistogram(Expression):
4952    arg_types = {
4953        "this": True,
4954        "expressions": True,
4955        "expression": False,
4956        "update_options": False,
4957    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4960class AnalyzeSample(Expression):
4961    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4964class AnalyzeListChainedRows(Expression):
4965    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4968class AnalyzeDelete(Expression):
4969    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4972class AnalyzeWith(Expression):
4973    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4976class AnalyzeValidate(Expression):
4977    arg_types = {
4978        "kind": True,
4979        "this": False,
4980        "expression": False,
4981    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4984class AnalyzeColumns(Expression):
4985    pass
key = 'analyzecolumns'
class UsingData(Expression):
4988class UsingData(Expression):
4989    pass
key = 'usingdata'
class AddConstraint(Expression):
4992class AddConstraint(Expression):
4993    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AddPartition(Expression):
4996class AddPartition(Expression):
4997    arg_types = {"this": True, "exists": False, "location": False}
arg_types = {'this': True, 'exists': False, 'location': False}
key = 'addpartition'
class AttachOption(Expression):
5000class AttachOption(Expression):
5001    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
5004class DropPartition(Expression):
5005    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
5009class ReplacePartition(Expression):
5010    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
5014class Binary(Condition):
5015    arg_types = {"this": True, "expression": True}
5016
5017    @property
5018    def left(self) -> Expression:
5019        return self.this
5020
5021    @property
5022    def right(self) -> Expression:
5023        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
5017    @property
5018    def left(self) -> Expression:
5019        return self.this
right: Expression
5021    @property
5022    def right(self) -> Expression:
5023        return self.expression
key = 'binary'
class Add(Binary):
5026class Add(Binary):
5027    pass
key = 'add'
class Connector(Binary):
5030class Connector(Binary):
5031    pass
key = 'connector'
class BitwiseAnd(Binary):
5034class BitwiseAnd(Binary):
5035    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
5038class BitwiseLeftShift(Binary):
5039    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
5042class BitwiseOr(Binary):
5043    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
5046class BitwiseRightShift(Binary):
5047    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
5050class BitwiseXor(Binary):
5051    pass
key = 'bitwisexor'
class Div(Binary):
5054class Div(Binary):
5055    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):
5058class Overlaps(Binary):
5059    pass
key = 'overlaps'
class Dot(Binary):
5062class Dot(Binary):
5063    @property
5064    def is_star(self) -> bool:
5065        return self.expression.is_star
5066
5067    @property
5068    def name(self) -> str:
5069        return self.expression.name
5070
5071    @property
5072    def output_name(self) -> str:
5073        return self.name
5074
5075    @classmethod
5076    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5077        """Build a Dot object with a sequence of expressions."""
5078        if len(expressions) < 2:
5079            raise ValueError("Dot requires >= 2 expressions.")
5080
5081        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5082
5083    @property
5084    def parts(self) -> t.List[Expression]:
5085        """Return the parts of a table / column in order catalog, db, table."""
5086        this, *parts = self.flatten()
5087
5088        parts.reverse()
5089
5090        for arg in COLUMN_PARTS:
5091            part = this.args.get(arg)
5092
5093            if isinstance(part, Expression):
5094                parts.append(part)
5095
5096        parts.reverse()
5097        return parts
is_star: bool
5063    @property
5064    def is_star(self) -> bool:
5065        return self.expression.is_star

Checks whether an expression is a star.

name: str
5067    @property
5068    def name(self) -> str:
5069        return self.expression.name
output_name: str
5071    @property
5072    def output_name(self) -> str:
5073        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:
5075    @classmethod
5076    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5077        """Build a Dot object with a sequence of expressions."""
5078        if len(expressions) < 2:
5079            raise ValueError("Dot requires >= 2 expressions.")
5080
5081        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]
5083    @property
5084    def parts(self) -> t.List[Expression]:
5085        """Return the parts of a table / column in order catalog, db, table."""
5086        this, *parts = self.flatten()
5087
5088        parts.reverse()
5089
5090        for arg in COLUMN_PARTS:
5091            part = this.args.get(arg)
5092
5093            if isinstance(part, Expression):
5094                parts.append(part)
5095
5096        parts.reverse()
5097        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):
5103class DPipe(Binary):
5104    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5107class EQ(Binary, Predicate):
5108    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5111class NullSafeEQ(Binary, Predicate):
5112    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5115class NullSafeNEQ(Binary, Predicate):
5116    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5120class PropertyEQ(Binary):
5121    pass
key = 'propertyeq'
class Distance(Binary):
5124class Distance(Binary):
5125    pass
key = 'distance'
class Escape(Binary):
5128class Escape(Binary):
5129    pass
key = 'escape'
class Glob(Binary, Predicate):
5132class Glob(Binary, Predicate):
5133    pass
key = 'glob'
class GT(Binary, Predicate):
5136class GT(Binary, Predicate):
5137    pass
key = 'gt'
class GTE(Binary, Predicate):
5140class GTE(Binary, Predicate):
5141    pass
key = 'gte'
class ILike(Binary, Predicate):
5144class ILike(Binary, Predicate):
5145    pass
key = 'ilike'
class IntDiv(Binary):
5148class IntDiv(Binary):
5149    pass
key = 'intdiv'
class Is(Binary, Predicate):
5152class Is(Binary, Predicate):
5153    pass
key = 'is'
class Kwarg(Binary):
5156class Kwarg(Binary):
5157    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5160class Like(Binary, Predicate):
5161    pass
key = 'like'
class LT(Binary, Predicate):
5164class LT(Binary, Predicate):
5165    pass
key = 'lt'
class LTE(Binary, Predicate):
5168class LTE(Binary, Predicate):
5169    pass
key = 'lte'
class Mod(Binary):
5172class Mod(Binary):
5173    pass
key = 'mod'
class Mul(Binary):
5176class Mul(Binary):
5177    pass
key = 'mul'
class NEQ(Binary, Predicate):
5180class NEQ(Binary, Predicate):
5181    pass
key = 'neq'
class Operator(Binary):
5185class Operator(Binary):
5186    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5189class SimilarTo(Binary, Predicate):
5190    pass
key = 'similarto'
class Slice(Binary):
5193class Slice(Binary):
5194    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5197class Sub(Binary):
5198    pass
key = 'sub'
class Unary(Condition):
5203class Unary(Condition):
5204    pass
key = 'unary'
class BitwiseNot(Unary):
5207class BitwiseNot(Unary):
5208    pass
key = 'bitwisenot'
class Not(Unary):
5211class Not(Unary):
5212    pass
key = 'not'
class Paren(Unary):
5215class Paren(Unary):
5216    @property
5217    def output_name(self) -> str:
5218        return self.this.name
output_name: str
5216    @property
5217    def output_name(self) -> str:
5218        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):
5221class Neg(Unary):
5222    def to_py(self) -> int | Decimal:
5223        if self.is_number:
5224            return self.this.to_py() * -1
5225        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5222    def to_py(self) -> int | Decimal:
5223        if self.is_number:
5224            return self.this.to_py() * -1
5225        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5228class Alias(Expression):
5229    arg_types = {"this": True, "alias": False}
5230
5231    @property
5232    def output_name(self) -> str:
5233        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5231    @property
5232    def output_name(self) -> str:
5233        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):
5238class PivotAlias(Alias):
5239    pass
key = 'pivotalias'
class PivotAny(Expression):
5244class PivotAny(Expression):
5245    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5248class Aliases(Expression):
5249    arg_types = {"this": True, "expressions": True}
5250
5251    @property
5252    def aliases(self):
5253        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5251    @property
5252    def aliases(self):
5253        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5257class AtIndex(Expression):
5258    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5261class AtTimeZone(Expression):
5262    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5265class FromTimeZone(Expression):
5266    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class FormatPhrase(Expression):
5269class FormatPhrase(Expression):
5270    """Format override for a column in Teradata.
5271    Can be expanded to additional dialects as needed
5272
5273    https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT
5274    """
5275
5276    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):
5279class Between(Predicate):
5280    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):
5283class Bracket(Condition):
5284    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5285    arg_types = {
5286        "this": True,
5287        "expressions": True,
5288        "offset": False,
5289        "safe": False,
5290        "returns_list_for_maps": False,
5291    }
5292
5293    @property
5294    def output_name(self) -> str:
5295        if len(self.expressions) == 1:
5296            return self.expressions[0].output_name
5297
5298        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5293    @property
5294    def output_name(self) -> str:
5295        if len(self.expressions) == 1:
5296            return self.expressions[0].output_name
5297
5298        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):
5301class Distinct(Expression):
5302    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5305class In(Predicate):
5306    arg_types = {
5307        "this": True,
5308        "expressions": False,
5309        "query": False,
5310        "unnest": False,
5311        "field": False,
5312        "is_global": False,
5313    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5317class ForIn(Expression):
5318    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5321class TimeUnit(Expression):
5322    """Automatically converts unit arg into a var."""
5323
5324    arg_types = {"unit": False}
5325
5326    UNABBREVIATED_UNIT_NAME = {
5327        "D": "DAY",
5328        "H": "HOUR",
5329        "M": "MINUTE",
5330        "MS": "MILLISECOND",
5331        "NS": "NANOSECOND",
5332        "Q": "QUARTER",
5333        "S": "SECOND",
5334        "US": "MICROSECOND",
5335        "W": "WEEK",
5336        "Y": "YEAR",
5337    }
5338
5339    VAR_LIKE = (Column, Literal, Var)
5340
5341    def __init__(self, **args):
5342        unit = args.get("unit")
5343        if type(unit) in self.VAR_LIKE:
5344            args["unit"] = Var(
5345                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5346            )
5347        elif isinstance(unit, Week):
5348            unit.set("this", Var(this=unit.this.name.upper()))
5349
5350        super().__init__(**args)
5351
5352    @property
5353    def unit(self) -> t.Optional[Var | IntervalSpan]:
5354        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5341    def __init__(self, **args):
5342        unit = args.get("unit")
5343        if type(unit) in self.VAR_LIKE:
5344            args["unit"] = Var(
5345                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5346            )
5347        elif isinstance(unit, Week):
5348            unit.set("this", Var(this=unit.this.name.upper()))
5349
5350        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]
5352    @property
5353    def unit(self) -> t.Optional[Var | IntervalSpan]:
5354        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5357class IntervalOp(TimeUnit):
5358    arg_types = {"unit": False, "expression": True}
5359
5360    def interval(self):
5361        return Interval(
5362            this=self.expression.copy(),
5363            unit=self.unit.copy() if self.unit else None,
5364        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5360    def interval(self):
5361        return Interval(
5362            this=self.expression.copy(),
5363            unit=self.unit.copy() if self.unit else None,
5364        )
key = 'intervalop'
class IntervalSpan(DataType):
5370class IntervalSpan(DataType):
5371    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5374class Interval(TimeUnit):
5375    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5378class IgnoreNulls(Expression):
5379    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5382class RespectNulls(Expression):
5383    pass
key = 'respectnulls'
class HavingMax(Expression):
5387class HavingMax(Expression):
5388    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5392class Func(Condition):
5393    """
5394    The base class for all function expressions.
5395
5396    Attributes:
5397        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5398            treated as a variable length argument and the argument's value will be stored as a list.
5399        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5400            function expression. These values are used to map this node to a name during parsing as
5401            well as to provide the function's name during SQL string generation. By default the SQL
5402            name is set to the expression's class name transformed to snake case.
5403    """
5404
5405    is_var_len_args = False
5406
5407    @classmethod
5408    def from_arg_list(cls, args):
5409        if cls.is_var_len_args:
5410            all_arg_keys = list(cls.arg_types)
5411            # If this function supports variable length argument treat the last argument as such.
5412            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5413            num_non_var = len(non_var_len_arg_keys)
5414
5415            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5416            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5417        else:
5418            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5419
5420        return cls(**args_dict)
5421
5422    @classmethod
5423    def sql_names(cls):
5424        if cls is Func:
5425            raise NotImplementedError(
5426                "SQL name is only supported by concrete function implementations"
5427            )
5428        if "_sql_names" not in cls.__dict__:
5429            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5430        return cls._sql_names
5431
5432    @classmethod
5433    def sql_name(cls):
5434        sql_names = cls.sql_names()
5435        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5436        return sql_names[0]
5437
5438    @classmethod
5439    def default_parser_mappings(cls):
5440        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):
5407    @classmethod
5408    def from_arg_list(cls, args):
5409        if cls.is_var_len_args:
5410            all_arg_keys = list(cls.arg_types)
5411            # If this function supports variable length argument treat the last argument as such.
5412            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5413            num_non_var = len(non_var_len_arg_keys)
5414
5415            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5416            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5417        else:
5418            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5419
5420        return cls(**args_dict)
@classmethod
def sql_names(cls):
5422    @classmethod
5423    def sql_names(cls):
5424        if cls is Func:
5425            raise NotImplementedError(
5426                "SQL name is only supported by concrete function implementations"
5427            )
5428        if "_sql_names" not in cls.__dict__:
5429            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5430        return cls._sql_names
@classmethod
def sql_name(cls):
5432    @classmethod
5433    def sql_name(cls):
5434        sql_names = cls.sql_names()
5435        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5436        return sql_names[0]
@classmethod
def default_parser_mappings(cls):
5438    @classmethod
5439    def default_parser_mappings(cls):
5440        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5443class Typeof(Func):
5444    pass
key = 'typeof'
class AggFunc(Func):
5447class AggFunc(Func):
5448    pass
key = 'aggfunc'
class BitwiseAndAgg(AggFunc):
5451class BitwiseAndAgg(AggFunc):
5452    _sql_names = ["BIT_AND"]
key = 'bitwiseandagg'
class BitwiseOrAgg(AggFunc):
5455class BitwiseOrAgg(AggFunc):
5456    _sql_names = ["BIT_OR"]
key = 'bitwiseoragg'
class BitwiseXorAgg(AggFunc):
5459class BitwiseXorAgg(AggFunc):
5460    _sql_names = ["BIT_XOR"]
key = 'bitwisexoragg'
class BitwiseCountAgg(AggFunc):
5463class BitwiseCountAgg(AggFunc):
5464    _sql_names = ["BIT_COUNT"]
key = 'bitwisecountagg'
class ByteLength(Func):
5467class ByteLength(Func):
5468    pass
key = 'bytelength'
class JSONBool(Func):
5472class JSONBool(Func):
5473    pass
key = 'jsonbool'
class ArrayRemove(Func):
5476class ArrayRemove(Func):
5477    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5480class ParameterizedAgg(AggFunc):
5481    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5484class Abs(Func):
5485    pass
key = 'abs'
class ArgMax(AggFunc):
5488class ArgMax(AggFunc):
5489    arg_types = {"this": True, "expression": True, "count": False}
5490    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5493class ArgMin(AggFunc):
5494    arg_types = {"this": True, "expression": True, "count": False}
5495    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5498class ApproxTopK(AggFunc):
5499    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class ApproxTopSum(AggFunc):
5502class ApproxTopSum(AggFunc):
5503    arg_types = {"this": True, "expression": True, "count": True}
arg_types = {'this': True, 'expression': True, 'count': True}
key = 'approxtopsum'
class ApproxQuantiles(AggFunc):
5506class ApproxQuantiles(AggFunc):
5507    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'approxquantiles'
class FarmFingerprint(Func):
5510class FarmFingerprint(Func):
5511    arg_types = {"expressions": True}
5512    is_var_len_args = True
5513    _sql_names = ["FARM_FINGERPRINT", "FARMFINGERPRINT64"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'farmfingerprint'
class Flatten(Func):
5516class Flatten(Func):
5517    pass
key = 'flatten'
class Float64(Func):
5520class Float64(Func):
5521    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'float64'
class Transform(Func):
5525class Transform(Func):
5526    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Translate(Func):
5529class Translate(Func):
5530    arg_types = {"this": True, "from": True, "to": True}
arg_types = {'this': True, 'from': True, 'to': True}
key = 'translate'
class Grouping(AggFunc):
5533class Grouping(AggFunc):
5534    arg_types = {"expressions": True}
5535    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'grouping'
class Anonymous(Func):
5538class Anonymous(Func):
5539    arg_types = {"this": True, "expressions": False}
5540    is_var_len_args = True
5541
5542    @property
5543    def name(self) -> str:
5544        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
5542    @property
5543    def name(self) -> str:
5544        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5547class AnonymousAggFunc(AggFunc):
5548    arg_types = {"this": True, "expressions": False}
5549    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5553class CombinedAggFunc(AnonymousAggFunc):
5554    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5557class CombinedParameterizedAgg(ParameterizedAgg):
5558    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5563class Hll(AggFunc):
5564    arg_types = {"this": True, "expressions": False}
5565    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5568class ApproxDistinct(AggFunc):
5569    arg_types = {"this": True, "accuracy": False}
5570    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5573class Apply(Func):
5574    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5577class Array(Func):
5578    arg_types = {"expressions": False, "bracket_notation": False}
5579    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5582class Ascii(Func):
5583    pass
key = 'ascii'
class ToArray(Func):
5587class ToArray(Func):
5588    pass
key = 'toarray'
class List(Func):
5592class List(Func):
5593    arg_types = {"expressions": False}
5594    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5598class Pad(Func):
5599    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):
5604class ToChar(Func):
5605    arg_types = {
5606        "this": True,
5607        "format": False,
5608        "nlsparam": False,
5609        "is_numeric": False,
5610    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'is_numeric': False}
key = 'tochar'
class ToCodePoints(Func):
5613class ToCodePoints(Func):
5614    pass
key = 'tocodepoints'
class ToNumber(Func):
5619class ToNumber(Func):
5620    arg_types = {
5621        "this": True,
5622        "format": False,
5623        "nlsparam": False,
5624        "precision": False,
5625        "scale": False,
5626    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5630class ToDouble(Func):
5631    arg_types = {
5632        "this": True,
5633        "format": False,
5634    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class CodePointsToBytes(Func):
5637class CodePointsToBytes(Func):
5638    pass
key = 'codepointstobytes'
class Columns(Func):
5641class Columns(Func):
5642    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5646class Convert(Func):
5647    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5651class ConvertToCharset(Func):
5652    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5655class ConvertTimezone(Func):
5656    arg_types = {
5657        "source_tz": False,
5658        "target_tz": True,
5659        "timestamp": True,
5660        "options": False,
5661    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class CodePointsToString(Func):
5664class CodePointsToString(Func):
5665    pass
key = 'codepointstostring'
class GenerateSeries(Func):
5668class GenerateSeries(Func):
5669    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):
5675class ExplodingGenerateSeries(GenerateSeries):
5676    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5679class ArrayAgg(AggFunc):
5680    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5683class ArrayUniqueAgg(AggFunc):
5684    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5687class ArrayAll(Func):
5688    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5692class ArrayAny(Func):
5693    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5696class ArrayConcat(Func):
5697    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5698    arg_types = {"this": True, "expressions": False}
5699    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5702class ArrayConcatAgg(AggFunc):
5703    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5706class ArrayConstructCompact(Func):
5707    arg_types = {"expressions": True}
5708    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5711class ArrayContains(Binary, Func):
5712    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5715class ArrayContainsAll(Binary, Func):
5716    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5719class ArrayFilter(Func):
5720    arg_types = {"this": True, "expression": True}
5721    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5724class ArrayFirst(Func):
5725    pass
key = 'arrayfirst'
class ArrayLast(Func):
5728class ArrayLast(Func):
5729    pass
key = 'arraylast'
class ArrayReverse(Func):
5732class ArrayReverse(Func):
5733    pass
key = 'arrayreverse'
class ArraySlice(Func):
5736class ArraySlice(Func):
5737    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):
5740class ArrayToString(Func):
5741    arg_types = {"this": True, "expression": True, "null": False}
5742    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5745class ArrayIntersect(Func):
5746    arg_types = {"expressions": True}
5747    is_var_len_args = True
5748    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5751class StPoint(Func):
5752    arg_types = {"this": True, "expression": True, "null": False}
5753    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5756class StDistance(Func):
5757    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5761class String(Func):
5762    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5765class StringToArray(Func):
5766    arg_types = {"this": True, "expression": False, "null": False}
5767    _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):
5770class ArrayOverlaps(Binary, Func):
5771    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5774class ArraySize(Func):
5775    arg_types = {"this": True, "expression": False}
5776    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5779class ArraySort(Func):
5780    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5783class ArraySum(Func):
5784    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5787class ArrayUnionAgg(AggFunc):
5788    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5791class Avg(AggFunc):
5792    pass
key = 'avg'
class AnyValue(AggFunc):
5795class AnyValue(AggFunc):
5796    pass
key = 'anyvalue'
class Lag(AggFunc):
5799class Lag(AggFunc):
5800    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5803class Lead(AggFunc):
5804    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5809class First(AggFunc):
5810    pass
key = 'first'
class Last(AggFunc):
5813class Last(AggFunc):
5814    pass
key = 'last'
class FirstValue(AggFunc):
5817class FirstValue(AggFunc):
5818    pass
key = 'firstvalue'
class LastValue(AggFunc):
5821class LastValue(AggFunc):
5822    pass
key = 'lastvalue'
class NthValue(AggFunc):
5825class NthValue(AggFunc):
5826    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5829class Case(Func):
5830    arg_types = {"this": False, "ifs": True, "default": False}
5831
5832    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5833        instance = maybe_copy(self, copy)
5834        instance.append(
5835            "ifs",
5836            If(
5837                this=maybe_parse(condition, copy=copy, **opts),
5838                true=maybe_parse(then, copy=copy, **opts),
5839            ),
5840        )
5841        return instance
5842
5843    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5844        instance = maybe_copy(self, copy)
5845        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5846        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:
5832    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5833        instance = maybe_copy(self, copy)
5834        instance.append(
5835            "ifs",
5836            If(
5837                this=maybe_parse(condition, copy=copy, **opts),
5838                true=maybe_parse(then, copy=copy, **opts),
5839            ),
5840        )
5841        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5843    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5844        instance = maybe_copy(self, copy)
5845        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5846        return instance
key = 'case'
class Cast(Func):
5849class Cast(Func):
5850    arg_types = {
5851        "this": True,
5852        "to": True,
5853        "format": False,
5854        "safe": False,
5855        "action": False,
5856        "default": False,
5857    }
5858
5859    @property
5860    def name(self) -> str:
5861        return self.this.name
5862
5863    @property
5864    def to(self) -> DataType:
5865        return self.args["to"]
5866
5867    @property
5868    def output_name(self) -> str:
5869        return self.name
5870
5871    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5872        """
5873        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5874        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5875        array<int> != array<float>.
5876
5877        Args:
5878            dtypes: the data types to compare this Cast's DataType to.
5879
5880        Returns:
5881            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5882        """
5883        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5859    @property
5860    def name(self) -> str:
5861        return self.this.name
to: DataType
5863    @property
5864    def to(self) -> DataType:
5865        return self.args["to"]
output_name: str
5867    @property
5868    def output_name(self) -> str:
5869        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:
5871    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5872        """
5873        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5874        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5875        array<int> != array<float>.
5876
5877        Args:
5878            dtypes: the data types to compare this Cast's DataType to.
5879
5880        Returns:
5881            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5882        """
5883        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):
5886class TryCast(Cast):
5887    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):
5891class JSONCast(Cast):
5892    pass
key = 'jsoncast'
class JustifyDays(Func):
5895class JustifyDays(Func):
5896    pass
key = 'justifydays'
class JustifyHours(Func):
5899class JustifyHours(Func):
5900    pass
key = 'justifyhours'
class JustifyInterval(Func):
5903class JustifyInterval(Func):
5904    pass
key = 'justifyinterval'
class Try(Func):
5907class Try(Func):
5908    pass
key = 'try'
class CastToStrType(Func):
5911class CastToStrType(Func):
5912    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5916class TranslateCharacters(Expression):
5917    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5920class Collate(Binary, Func):
5921    pass
key = 'collate'
class Ceil(Func):
5924class Ceil(Func):
5925    arg_types = {"this": True, "decimals": False, "to": False}
5926    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5929class Coalesce(Func):
5930    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5931    is_var_len_args = True
5932    _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):
5935class Chr(Func):
5936    arg_types = {"expressions": True, "charset": False}
5937    is_var_len_args = True
5938    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5941class Concat(Func):
5942    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5943    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5946class ConcatWs(Concat):
5947    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5951class Contains(Func):
5952    arg_types = {"this": True, "expression": True, "json_scope": False}
arg_types = {'this': True, 'expression': True, 'json_scope': False}
key = 'contains'
class ConnectByRoot(Func):
5956class ConnectByRoot(Func):
5957    pass
key = 'connectbyroot'
class Count(AggFunc):
5960class Count(AggFunc):
5961    arg_types = {"this": False, "expressions": False, "big_int": False}
5962    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5965class CountIf(AggFunc):
5966    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5970class Cbrt(Func):
5971    pass
key = 'cbrt'
class CurrentDate(Func):
5974class CurrentDate(Func):
5975    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5978class CurrentDatetime(Func):
5979    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5982class CurrentTime(Func):
5983    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5986class CurrentTimestamp(Func):
5987    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
5990class CurrentTimestampLTZ(Func):
5991    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
5994class CurrentSchema(Func):
5995    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5998class CurrentUser(Func):
5999    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
6002class DateAdd(Func, IntervalOp):
6003    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
6006class DateBin(Func, IntervalOp):
6007    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):
6010class DateSub(Func, IntervalOp):
6011    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
6014class DateDiff(Func, TimeUnit):
6015    _sql_names = ["DATEDIFF", "DATE_DIFF"]
6016    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):
6019class DateTrunc(Func):
6020    arg_types = {"unit": True, "this": True, "zone": False}
6021
6022    def __init__(self, **args):
6023        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6024        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6025        unabbreviate = args.pop("unabbreviate", True)
6026
6027        unit = args.get("unit")
6028        if isinstance(unit, TimeUnit.VAR_LIKE):
6029            unit_name = unit.name.upper()
6030            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6031                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6032
6033            args["unit"] = Literal.string(unit_name)
6034
6035        super().__init__(**args)
6036
6037    @property
6038    def unit(self) -> Expression:
6039        return self.args["unit"]
DateTrunc(**args)
6022    def __init__(self, **args):
6023        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6024        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6025        unabbreviate = args.pop("unabbreviate", True)
6026
6027        unit = args.get("unit")
6028        if isinstance(unit, TimeUnit.VAR_LIKE):
6029            unit_name = unit.name.upper()
6030            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6031                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6032
6033            args["unit"] = Literal.string(unit_name)
6034
6035        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
6037    @property
6038    def unit(self) -> Expression:
6039        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
6044class Datetime(Func):
6045    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
6048class DatetimeAdd(Func, IntervalOp):
6049    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
6052class DatetimeSub(Func, IntervalOp):
6053    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
6056class DatetimeDiff(Func, TimeUnit):
6057    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
6060class DatetimeTrunc(Func, TimeUnit):
6061    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DateFromUnixDate(Func):
6064class DateFromUnixDate(Func):
6065    pass
key = 'datefromunixdate'
class DayOfWeek(Func):
6068class DayOfWeek(Func):
6069    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
6074class DayOfWeekIso(Func):
6075    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
6078class DayOfMonth(Func):
6079    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
6082class DayOfYear(Func):
6083    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
6086class ToDays(Func):
6087    pass
key = 'todays'
class WeekOfYear(Func):
6090class WeekOfYear(Func):
6091    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
6094class MonthsBetween(Func):
6095    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
6098class MakeInterval(Func):
6099    arg_types = {
6100        "year": False,
6101        "month": False,
6102        "day": False,
6103        "hour": False,
6104        "minute": False,
6105        "second": False,
6106    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
6109class LastDay(Func, TimeUnit):
6110    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
6111    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class LaxBool(Func):
6114class LaxBool(Func):
6115    pass
key = 'laxbool'
class LaxFloat64(Func):
6118class LaxFloat64(Func):
6119    pass
key = 'laxfloat64'
class LaxInt64(Func):
6122class LaxInt64(Func):
6123    pass
key = 'laxint64'
class LaxString(Func):
6126class LaxString(Func):
6127    pass
key = 'laxstring'
class Extract(Func):
6130class Extract(Func):
6131    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6134class Exists(Func, SubqueryPredicate):
6135    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6138class Timestamp(Func):
6139    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6142class TimestampAdd(Func, TimeUnit):
6143    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6146class TimestampSub(Func, TimeUnit):
6147    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6150class TimestampDiff(Func, TimeUnit):
6151    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6152    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6155class TimestampTrunc(Func, TimeUnit):
6156    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6159class TimeAdd(Func, TimeUnit):
6160    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6163class TimeSub(Func, TimeUnit):
6164    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6167class TimeDiff(Func, TimeUnit):
6168    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6171class TimeTrunc(Func, TimeUnit):
6172    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6175class DateFromParts(Func):
6176    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6177    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6180class TimeFromParts(Func):
6181    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6182    arg_types = {
6183        "hour": True,
6184        "min": True,
6185        "sec": True,
6186        "nano": False,
6187        "fractions": False,
6188        "precision": False,
6189    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6192class DateStrToDate(Func):
6193    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6196class DateToDateStr(Func):
6197    pass
key = 'datetodatestr'
class DateToDi(Func):
6200class DateToDi(Func):
6201    pass
key = 'datetodi'
class Date(Func):
6205class Date(Func):
6206    arg_types = {"this": False, "zone": False, "expressions": False}
6207    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6210class Day(Func):
6211    pass
key = 'day'
class Decode(Func):
6214class Decode(Func):
6215    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6218class DecodeCase(Func):
6219    arg_types = {"expressions": True}
6220    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DenseRank(AggFunc):
6223class DenseRank(AggFunc):
6224    arg_types = {"expressions": False}
6225    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'denserank'
class DiToDate(Func):
6228class DiToDate(Func):
6229    pass
key = 'ditodate'
class Encode(Func):
6232class Encode(Func):
6233    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6236class Exp(Func):
6237    pass
key = 'exp'
class Explode(Func, UDTF):
6241class Explode(Func, UDTF):
6242    arg_types = {"this": True, "expressions": False}
6243    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6247class Inline(Func):
6248    pass
key = 'inline'
class ExplodeOuter(Explode):
6251class ExplodeOuter(Explode):
6252    pass
key = 'explodeouter'
class Posexplode(Explode):
6255class Posexplode(Explode):
6256    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6259class PosexplodeOuter(Posexplode, ExplodeOuter):
6260    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6263class PositionalColumn(Expression):
6264    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6267class Unnest(Func, UDTF):
6268    arg_types = {
6269        "expressions": True,
6270        "alias": False,
6271        "offset": False,
6272        "explode_array": False,
6273    }
6274
6275    @property
6276    def selects(self) -> t.List[Expression]:
6277        columns = super().selects
6278        offset = self.args.get("offset")
6279        if offset:
6280            columns = columns + [to_identifier("offset") if offset is True else offset]
6281        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6275    @property
6276    def selects(self) -> t.List[Expression]:
6277        columns = super().selects
6278        offset = self.args.get("offset")
6279        if offset:
6280            columns = columns + [to_identifier("offset") if offset is True else offset]
6281        return columns
key = 'unnest'
class Floor(Func):
6284class Floor(Func):
6285    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase32(Func):
6288class FromBase32(Func):
6289    pass
key = 'frombase32'
class FromBase64(Func):
6292class FromBase64(Func):
6293    pass
key = 'frombase64'
class ToBase32(Func):
6296class ToBase32(Func):
6297    pass
key = 'tobase32'
class ToBase64(Func):
6300class ToBase64(Func):
6301    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6305class FromISO8601Timestamp(Func):
6306    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6309class GapFill(Func):
6310    arg_types = {
6311        "this": True,
6312        "ts_column": True,
6313        "bucket_width": True,
6314        "partitioning_columns": False,
6315        "value_columns": False,
6316        "origin": False,
6317        "ignore_nulls": False,
6318    }
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):
6322class GenerateDateArray(Func):
6323    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6327class GenerateTimestampArray(Func):
6328    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class GetExtract(Func):
6332class GetExtract(Func):
6333    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'getextract'
class Greatest(Func):
6336class Greatest(Func):
6337    arg_types = {"this": True, "expressions": False}
6338    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6343class OverflowTruncateBehavior(Expression):
6344    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6347class GroupConcat(AggFunc):
6348    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6351class Hex(Func):
6352    pass
key = 'hex'
class LowerHex(Hex):
6355class LowerHex(Hex):
6356    pass
key = 'lowerhex'
class And(Connector, Func):
6359class And(Connector, Func):
6360    pass
key = 'and'
class Or(Connector, Func):
6363class Or(Connector, Func):
6364    pass
key = 'or'
class Xor(Connector, Func):
6367class Xor(Connector, Func):
6368    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6371class If(Func):
6372    arg_types = {"this": True, "true": True, "false": False}
6373    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6376class Nullif(Func):
6377    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6380class Initcap(Func):
6381    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6384class IsAscii(Func):
6385    pass
key = 'isascii'
class IsNan(Func):
6388class IsNan(Func):
6389    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6393class Int64(Func):
6394    pass
key = 'int64'
class IsInf(Func):
6397class IsInf(Func):
6398    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6402class JSON(Expression):
6403    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6406class JSONPath(Expression):
6407    arg_types = {"expressions": True, "escape": False}
6408
6409    @property
6410    def output_name(self) -> str:
6411        last_segment = self.expressions[-1].this
6412        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6409    @property
6410    def output_name(self) -> str:
6411        last_segment = self.expressions[-1].this
6412        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):
6415class JSONPathPart(Expression):
6416    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6419class JSONPathFilter(JSONPathPart):
6420    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6423class JSONPathKey(JSONPathPart):
6424    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6427class JSONPathRecursive(JSONPathPart):
6428    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6431class JSONPathRoot(JSONPathPart):
6432    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6435class JSONPathScript(JSONPathPart):
6436    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6439class JSONPathSlice(JSONPathPart):
6440    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6443class JSONPathSelector(JSONPathPart):
6444    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6447class JSONPathSubscript(JSONPathPart):
6448    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6451class JSONPathUnion(JSONPathPart):
6452    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6455class JSONPathWildcard(JSONPathPart):
6456    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6459class FormatJson(Expression):
6460    pass
key = 'formatjson'
class Format(Func):
6463class Format(Func):
6464    arg_types = {"this": True, "expressions": True}
6465    is_var_len_args = True
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'format'
class JSONKeyValue(Expression):
6468class JSONKeyValue(Expression):
6469    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONKeysAtDepth(Func):
6473class JSONKeysAtDepth(Func):
6474    arg_types = {"this": True, "expression": False, "mode": False}
arg_types = {'this': True, 'expression': False, 'mode': False}
key = 'jsonkeysatdepth'
class JSONObject(Func):
6477class JSONObject(Func):
6478    arg_types = {
6479        "expressions": False,
6480        "null_handling": False,
6481        "unique_keys": False,
6482        "return_type": False,
6483        "encoding": False,
6484    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6487class JSONObjectAgg(AggFunc):
6488    arg_types = {
6489        "expressions": False,
6490        "null_handling": False,
6491        "unique_keys": False,
6492        "return_type": False,
6493        "encoding": False,
6494    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6498class JSONBObjectAgg(AggFunc):
6499    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6503class JSONArray(Func):
6504    arg_types = {
6505        "expressions": False,
6506        "null_handling": False,
6507        "return_type": False,
6508        "strict": False,
6509    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6513class JSONArrayAgg(Func):
6514    arg_types = {
6515        "this": True,
6516        "order": False,
6517        "null_handling": False,
6518        "return_type": False,
6519        "strict": False,
6520    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6523class JSONExists(Func):
6524    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):
6529class JSONColumnDef(Expression):
6530    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False}
key = 'jsoncolumndef'
class JSONSchema(Expression):
6533class JSONSchema(Expression):
6534    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONSet(Func):
6537class JSONSet(Func):
6538    arg_types = {"this": True, "expressions": True}
6539    is_var_len_args = True
6540    _sql_names = ["JSON_SET"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonset'
class JSONStripNulls(Func):
6544class JSONStripNulls(Func):
6545    arg_types = {
6546        "this": True,
6547        "expression": False,
6548        "include_arrays": False,
6549        "remove_empty": False,
6550    }
6551    _sql_names = ["JSON_STRIP_NULLS"]
arg_types = {'this': True, 'expression': False, 'include_arrays': False, 'remove_empty': False}
key = 'jsonstripnulls'
class JSONValue(Expression):
6555class JSONValue(Expression):
6556    arg_types = {
6557        "this": True,
6558        "path": True,
6559        "returning": False,
6560        "on_condition": False,
6561    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6564class JSONValueArray(Func):
6565    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONRemove(Func):
6568class JSONRemove(Func):
6569    arg_types = {"this": True, "expressions": True}
6570    is_var_len_args = True
6571    _sql_names = ["JSON_REMOVE"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonremove'
class JSONTable(Func):
6575class JSONTable(Func):
6576    arg_types = {
6577        "this": True,
6578        "schema": True,
6579        "path": False,
6580        "error_handling": False,
6581        "empty_handling": False,
6582    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6587class JSONType(Func):
6588    arg_types = {"this": True, "expression": False}
6589    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6593class ObjectInsert(Func):
6594    arg_types = {
6595        "this": True,
6596        "key": True,
6597        "value": True,
6598        "update_flag": False,
6599    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6602class OpenJSONColumnDef(Expression):
6603    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):
6606class OpenJSON(Func):
6607    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6610class JSONBContains(Binary, Func):
6611    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6614class JSONBExists(Func):
6615    arg_types = {"this": True, "path": True}
6616    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6619class JSONExtract(Binary, Func):
6620    arg_types = {
6621        "this": True,
6622        "expression": True,
6623        "only_json_types": False,
6624        "expressions": False,
6625        "variant_extract": False,
6626        "json_query": False,
6627        "option": False,
6628        "quote": False,
6629        "on_condition": False,
6630        "requires_json": False,
6631    }
6632    _sql_names = ["JSON_EXTRACT"]
6633    is_var_len_args = True
6634
6635    @property
6636    def output_name(self) -> str:
6637        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
6635    @property
6636    def output_name(self) -> str:
6637        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):
6641class JSONExtractQuote(Expression):
6642    arg_types = {
6643        "option": True,
6644        "scalar": False,
6645    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6648class JSONExtractArray(Func):
6649    arg_types = {"this": True, "expression": False}
6650    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6653class JSONExtractScalar(Binary, Func):
6654    arg_types = {
6655        "this": True,
6656        "expression": True,
6657        "only_json_types": False,
6658        "expressions": False,
6659        "json_type": False,
6660    }
6661    _sql_names = ["JSON_EXTRACT_SCALAR"]
6662    is_var_len_args = True
6663
6664    @property
6665    def output_name(self) -> str:
6666        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
6664    @property
6665    def output_name(self) -> str:
6666        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):
6669class JSONBExtract(Binary, Func):
6670    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6673class JSONBExtractScalar(Binary, Func):
6674    arg_types = {"this": True, "expression": True, "json_type": False}
6675    _sql_names = ["JSONB_EXTRACT_SCALAR"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonbextractscalar'
class JSONFormat(Func):
6678class JSONFormat(Func):
6679    arg_types = {"this": False, "options": False, "is_json": False}
6680    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayAppend(Func):
6683class JSONArrayAppend(Func):
6684    arg_types = {"this": True, "expressions": True}
6685    is_var_len_args = True
6686    _sql_names = ["JSON_ARRAY_APPEND"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayappend'
class JSONArrayContains(Binary, Predicate, Func):
6690class JSONArrayContains(Binary, Predicate, Func):
6691    arg_types = {"this": True, "expression": True, "json_type": False}
6692    _sql_names = ["JSON_ARRAY_CONTAINS"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonarraycontains'
class JSONArrayInsert(Func):
6695class JSONArrayInsert(Func):
6696    arg_types = {"this": True, "expressions": True}
6697    is_var_len_args = True
6698    _sql_names = ["JSON_ARRAY_INSERT"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayinsert'
class ParseBignumeric(Func):
6701class ParseBignumeric(Func):
6702    pass
key = 'parsebignumeric'
class ParseNumeric(Func):
6705class ParseNumeric(Func):
6706    pass
key = 'parsenumeric'
class ParseJSON(Func):
6709class ParseJSON(Func):
6710    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6711    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6712    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6713    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class ParseTime(Func):
6716class ParseTime(Func):
6717    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'parsetime'
class ParseDatetime(Func):
6720class ParseDatetime(Func):
6721    arg_types = {"this": True, "format": False, "zone": False}
arg_types = {'this': True, 'format': False, 'zone': False}
key = 'parsedatetime'
class Least(Func):
6724class Least(Func):
6725    arg_types = {"this": True, "expressions": False}
6726    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6729class Left(Func):
6730    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Reverse(Func):
6737class Reverse(Func):
6738    pass
key = 'reverse'
class Length(Func):
6741class Length(Func):
6742    arg_types = {"this": True, "binary": False, "encoding": False}
6743    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6746class Levenshtein(Func):
6747    arg_types = {
6748        "this": True,
6749        "expression": False,
6750        "ins_cost": False,
6751        "del_cost": False,
6752        "sub_cost": False,
6753        "max_dist": False,
6754    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6757class Ln(Func):
6758    pass
key = 'ln'
class Log(Func):
6761class Log(Func):
6762    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6765class LogicalOr(AggFunc):
6766    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6769class LogicalAnd(AggFunc):
6770    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6773class Lower(Func):
6774    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6777class Map(Func):
6778    arg_types = {"keys": False, "values": False}
6779
6780    @property
6781    def keys(self) -> t.List[Expression]:
6782        keys = self.args.get("keys")
6783        return keys.expressions if keys else []
6784
6785    @property
6786    def values(self) -> t.List[Expression]:
6787        values = self.args.get("values")
6788        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6780    @property
6781    def keys(self) -> t.List[Expression]:
6782        keys = self.args.get("keys")
6783        return keys.expressions if keys else []
values: List[Expression]
6785    @property
6786    def values(self) -> t.List[Expression]:
6787        values = self.args.get("values")
6788        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6792class ToMap(Func):
6793    pass
key = 'tomap'
class MapFromEntries(Func):
6796class MapFromEntries(Func):
6797    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6801class ScopeResolution(Expression):
6802    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6805class Stream(Expression):
6806    pass
key = 'stream'
class StarMap(Func):
6809class StarMap(Func):
6810    pass
key = 'starmap'
class VarMap(Func):
6813class VarMap(Func):
6814    arg_types = {"keys": True, "values": True}
6815    is_var_len_args = True
6816
6817    @property
6818    def keys(self) -> t.List[Expression]:
6819        return self.args["keys"].expressions
6820
6821    @property
6822    def values(self) -> t.List[Expression]:
6823        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6817    @property
6818    def keys(self) -> t.List[Expression]:
6819        return self.args["keys"].expressions
values: List[Expression]
6821    @property
6822    def values(self) -> t.List[Expression]:
6823        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6827class MatchAgainst(Func):
6828    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6831class Max(AggFunc):
6832    arg_types = {"this": True, "expressions": False}
6833    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6836class MD5(Func):
6837    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6841class MD5Digest(Func):
6842    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6845class Median(AggFunc):
6846    pass
key = 'median'
class Min(AggFunc):
6849class Min(AggFunc):
6850    arg_types = {"this": True, "expressions": False}
6851    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6854class Month(Func):
6855    pass
key = 'month'
class AddMonths(Func):
6858class AddMonths(Func):
6859    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6862class Nvl2(Func):
6863    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Ntile(AggFunc):
6866class Ntile(AggFunc):
6867    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ntile'
class Normalize(Func):
6870class Normalize(Func):
6871    arg_types = {"this": True, "form": False, "is_casefold": False}
arg_types = {'this': True, 'form': False, 'is_casefold': False}
key = 'normalize'
class Overlay(Func):
6874class Overlay(Func):
6875    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):
6879class Predict(Func):
6880    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class FeaturesAtTime(Func):
6884class FeaturesAtTime(Func):
6885    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):
6889class GenerateEmbedding(Func):
6890    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'generateembedding'
class VectorSearch(Func):
6894class VectorSearch(Func):
6895    arg_types = {
6896        "this": True,
6897        "column_to_search": True,
6898        "query_table": True,
6899        "query_column_to_search": False,
6900        "top_k": False,
6901        "distance_type": False,
6902        "options": False,
6903    }
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):
6906class Pow(Binary, Func):
6907    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6910class PercentileCont(AggFunc):
6911    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6914class PercentileDisc(AggFunc):
6915    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class PercentRank(AggFunc):
6918class PercentRank(AggFunc):
6919    arg_types = {"expressions": False}
6920    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'percentrank'
class Quantile(AggFunc):
6923class Quantile(AggFunc):
6924    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6927class ApproxQuantile(Quantile):
6928    arg_types = {
6929        "this": True,
6930        "quantile": True,
6931        "accuracy": False,
6932        "weight": False,
6933        "error_tolerance": False,
6934    }
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False, 'error_tolerance': False}
key = 'approxquantile'
class Quarter(Func):
6937class Quarter(Func):
6938    pass
key = 'quarter'
class Rand(Func):
6943class Rand(Func):
6944    _sql_names = ["RAND", "RANDOM"]
6945    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6948class Randn(Func):
6949    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6952class RangeN(Func):
6953    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class Rank(AggFunc):
6956class Rank(AggFunc):
6957    arg_types = {"expressions": False}
6958    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'rank'
class ReadCSV(Func):
6961class ReadCSV(Func):
6962    _sql_names = ["READ_CSV"]
6963    is_var_len_args = True
6964    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6967class Reduce(Func):
6968    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):
6971class RegexpExtract(Func):
6972    arg_types = {
6973        "this": True,
6974        "expression": True,
6975        "position": False,
6976        "occurrence": False,
6977        "parameters": False,
6978        "group": False,
6979    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6982class RegexpExtractAll(Func):
6983    arg_types = {
6984        "this": True,
6985        "expression": True,
6986        "position": False,
6987        "occurrence": False,
6988        "parameters": False,
6989        "group": False,
6990    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6993class RegexpReplace(Func):
6994    arg_types = {
6995        "this": True,
6996        "expression": True,
6997        "replacement": False,
6998        "position": False,
6999        "occurrence": False,
7000        "modifiers": False,
7001    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
7004class RegexpLike(Binary, Func):
7005    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
7008class RegexpILike(Binary, Func):
7009    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpInstr(Func):
7012class RegexpInstr(Func):
7013    arg_types = {
7014        "this": True,
7015        "expression": True,
7016        "position": False,
7017        "occurrence": False,
7018        "option": False,
7019        "parameters": False,
7020        "group": False,
7021    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'option': False, 'parameters': False, 'group': False}
key = 'regexpinstr'
class RegexpSplit(Func):
7026class RegexpSplit(Func):
7027    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
7030class Repeat(Func):
7031    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
7035class Replace(Func):
7036    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
7041class Round(Func):
7042    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
7045class RowNumber(Func):
7046    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
7049class SafeDivide(Func):
7050    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SafeConvertBytesToString(Func):
7053class SafeConvertBytesToString(Func):
7054    pass
key = 'safeconvertbytestostring'
class SHA(Func):
7057class SHA(Func):
7058    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
7061class SHA2(Func):
7062    _sql_names = ["SHA2"]
7063    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
7066class Sign(Func):
7067    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
7070class SortArray(Func):
7071    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Soundex(Func):
7074class Soundex(Func):
7075    pass
key = 'soundex'
class Split(Func):
7078class Split(Func):
7079    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
7083class SplitPart(Func):
7084    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
7089class Substring(Func):
7090    _sql_names = ["SUBSTRING", "SUBSTR"]
7091    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
7094class SubstringIndex(Func):
7095    """
7096    SUBSTRING_INDEX(str, delim, count)
7097
7098    *count* > 0  → left slice before the *count*-th delimiter
7099    *count* < 0  → right slice after the |count|-th delimiter
7100    """
7101
7102    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):
7105class StandardHash(Func):
7106    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
7109class StartsWith(Func):
7110    _sql_names = ["STARTS_WITH", "STARTSWITH"]
7111    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
7114class EndsWith(Func):
7115    _sql_names = ["ENDS_WITH", "ENDSWITH"]
7116    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
7119class StrPosition(Func):
7120    arg_types = {
7121        "this": True,
7122        "substr": True,
7123        "position": False,
7124        "occurrence": False,
7125    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
7128class StrToDate(Func):
7129    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
7132class StrToTime(Func):
7133    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):
7138class StrToUnix(Func):
7139    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
7144class StrToMap(Func):
7145    arg_types = {
7146        "this": True,
7147        "pair_delim": False,
7148        "key_value_delim": False,
7149        "duplicate_resolution_callback": False,
7150    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
7153class NumberToStr(Func):
7154    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
7157class FromBase(Func):
7158    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
7161class Space(Func):
7162    """
7163    SPACE(n) → string consisting of n blank characters
7164    """
7165
7166    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
7169class Struct(Func):
7170    arg_types = {"expressions": False}
7171    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
7174class StructExtract(Func):
7175    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
7180class Stuff(Func):
7181    _sql_names = ["STUFF", "INSERT"]
7182    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):
7185class Sum(AggFunc):
7186    pass
key = 'sum'
class Sqrt(Func):
7189class Sqrt(Func):
7190    pass
key = 'sqrt'
class Stddev(AggFunc):
7193class Stddev(AggFunc):
7194    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
7197class StddevPop(AggFunc):
7198    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
7201class StddevSamp(AggFunc):
7202    pass
key = 'stddevsamp'
class Time(Func):
7206class Time(Func):
7207    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
7210class TimeToStr(Func):
7211    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):
7214class TimeToTimeStr(Func):
7215    pass
key = 'timetotimestr'
class TimeToUnix(Func):
7218class TimeToUnix(Func):
7219    pass
key = 'timetounix'
class TimeStrToDate(Func):
7222class TimeStrToDate(Func):
7223    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
7226class TimeStrToTime(Func):
7227    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
7230class TimeStrToUnix(Func):
7231    pass
key = 'timestrtounix'
class Trim(Func):
7234class Trim(Func):
7235    arg_types = {
7236        "this": True,
7237        "expression": False,
7238        "position": False,
7239        "collation": False,
7240    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
7243class TsOrDsAdd(Func, TimeUnit):
7244    # return_type is used to correctly cast the arguments of this expression when transpiling it
7245    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
7246
7247    @property
7248    def return_type(self) -> DataType:
7249        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
7247    @property
7248    def return_type(self) -> DataType:
7249        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
7252class TsOrDsDiff(Func, TimeUnit):
7253    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
7256class TsOrDsToDateStr(Func):
7257    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
7260class TsOrDsToDate(Func):
7261    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
7264class TsOrDsToDatetime(Func):
7265    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
7268class TsOrDsToTime(Func):
7269    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
7272class TsOrDsToTimestamp(Func):
7273    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
7276class TsOrDiToDi(Func):
7277    pass
key = 'tsorditodi'
class Unhex(Func):
7280class Unhex(Func):
7281    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7284class Unicode(Func):
7285    pass
key = 'unicode'
class UnixDate(Func):
7289class UnixDate(Func):
7290    pass
key = 'unixdate'
class UnixToStr(Func):
7293class UnixToStr(Func):
7294    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7299class UnixToTime(Func):
7300    arg_types = {
7301        "this": True,
7302        "scale": False,
7303        "zone": False,
7304        "hours": False,
7305        "minutes": False,
7306        "format": False,
7307    }
7308
7309    SECONDS = Literal.number(0)
7310    DECIS = Literal.number(1)
7311    CENTIS = Literal.number(2)
7312    MILLIS = Literal.number(3)
7313    DECIMILLIS = Literal.number(4)
7314    CENTIMILLIS = Literal.number(5)
7315    MICROS = Literal.number(6)
7316    DECIMICROS = Literal.number(7)
7317    CENTIMICROS = Literal.number(8)
7318    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):
7321class UnixToTimeStr(Func):
7322    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7325class UnixSeconds(Func):
7326    pass
key = 'unixseconds'
class UnixMicros(Func):
7329class UnixMicros(Func):
7330    pass
key = 'unixmicros'
class UnixMillis(Func):
7333class UnixMillis(Func):
7334    pass
key = 'unixmillis'
class Uuid(Func):
7337class Uuid(Func):
7338    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7339
7340    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7343class TimestampFromParts(Func):
7344    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7345    arg_types = {
7346        "year": True,
7347        "month": True,
7348        "day": True,
7349        "hour": True,
7350        "min": True,
7351        "sec": True,
7352        "nano": False,
7353        "zone": False,
7354        "milli": False,
7355    }
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):
7358class Upper(Func):
7359    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7362class Corr(Binary, AggFunc):
7363    pass
key = 'corr'
class CumeDist(AggFunc):
7367class CumeDist(AggFunc):
7368    arg_types = {"expressions": False}
7369    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'cumedist'
class Variance(AggFunc):
7372class Variance(AggFunc):
7373    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7376class VariancePop(AggFunc):
7377    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7380class CovarSamp(Binary, AggFunc):
7381    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7384class CovarPop(Binary, AggFunc):
7385    pass
key = 'covarpop'
class Week(Func):
7388class Week(Func):
7389    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class WeekStart(Expression):
7392class WeekStart(Expression):
7393    pass
key = 'weekstart'
class XMLElement(Func):
7396class XMLElement(Func):
7397    _sql_names = ["XMLELEMENT"]
7398    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7401class XMLTable(Func):
7402    arg_types = {
7403        "this": True,
7404        "namespaces": False,
7405        "passing": False,
7406        "columns": False,
7407        "by_ref": False,
7408    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7411class XMLNamespace(Expression):
7412    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7416class XMLKeyValueOption(Expression):
7417    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7420class Year(Func):
7421    pass
key = 'year'
class Use(Expression):
7424class Use(Expression):
7425    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7428class Merge(DML):
7429    arg_types = {
7430        "this": True,
7431        "using": True,
7432        "on": True,
7433        "whens": True,
7434        "with": False,
7435        "returning": False,
7436    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7439class When(Expression):
7440    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):
7443class Whens(Expression):
7444    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7445
7446    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7451class NextValueFor(Func):
7452    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7457class Semicolon(Expression):
7458    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7463class TableColumn(Expression):
7464    pass
key = 'tablecolumn'
ALL_FUNCTIONS = [<class 'Abs'>, <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 'Avg'>, <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 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <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 'DenseRank'>, <class 'DiToDate'>, <class 'Encode'>, <class 'EndsWith'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <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 '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 '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 '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 '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 'ParseJSON'>, <class 'ParseNumeric'>, <class 'ParseTime'>, <class 'PercentRank'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'Rank'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpInstr'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Replace'>, <class 'Reverse'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeConvertBytesToString'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Soundex'>, <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 '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 'TryCast'>, <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 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'VectorSearch'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, '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'>, 'AVG': <class 'Avg'>, 'BIT_AND': <class 'BitwiseAndAgg'>, 'BIT_COUNT': <class 'BitwiseCountAgg'>, 'BIT_OR': <class 'BitwiseOrAgg'>, 'BIT_XOR': <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'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CONVERT_TO_CHARSET': <class 'ConvertToCharset'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, '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'>, 'DENSE_RANK': <class 'DenseRank'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'ENDS_WITH': <class 'EndsWith'>, 'ENDSWITH': <class 'EndsWith'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, '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'>, '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'>, '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'>, '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'>, '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_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PARSE_NUMERIC': <class 'ParseNumeric'>, 'PARSE_TIME': <class 'ParseTime'>, '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_N': <class 'RangeN'>, 'RANK': <class 'Rank'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, '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'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_CONVERT_BYTES_TO_STRING': <class 'SafeConvertBytesToString'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SOUNDEX': <class 'Soundex'>, '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'>, '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_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, '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'>, '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:
7504def maybe_parse(
7505    sql_or_expression: ExpOrStr,
7506    *,
7507    into: t.Optional[IntoType] = None,
7508    dialect: DialectType = None,
7509    prefix: t.Optional[str] = None,
7510    copy: bool = False,
7511    **opts,
7512) -> Expression:
7513    """Gracefully handle a possible string or expression.
7514
7515    Example:
7516        >>> maybe_parse("1")
7517        Literal(this=1, is_string=False)
7518        >>> maybe_parse(to_identifier("x"))
7519        Identifier(this=x, quoted=False)
7520
7521    Args:
7522        sql_or_expression: the SQL code string or an expression
7523        into: the SQLGlot Expression to parse into
7524        dialect: the dialect used to parse the input expressions (in the case that an
7525            input expression is a SQL string).
7526        prefix: a string to prefix the sql with before it gets parsed
7527            (automatically includes a space)
7528        copy: whether to copy the expression.
7529        **opts: other options to use to parse the input expressions (again, in the case
7530            that an input expression is a SQL string).
7531
7532    Returns:
7533        Expression: the parsed or given expression.
7534    """
7535    if isinstance(sql_or_expression, Expression):
7536        if copy:
7537            return sql_or_expression.copy()
7538        return sql_or_expression
7539
7540    if sql_or_expression is None:
7541        raise ParseError("SQL cannot be None")
7542
7543    import sqlglot
7544
7545    sql = str(sql_or_expression)
7546    if prefix:
7547        sql = f"{prefix} {sql}"
7548
7549    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):
7560def maybe_copy(instance, copy=True):
7561    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:
7816def union(
7817    *expressions: ExpOrStr,
7818    distinct: bool = True,
7819    dialect: DialectType = None,
7820    copy: bool = True,
7821    **opts,
7822) -> Union:
7823    """
7824    Initializes a syntax tree for the `UNION` operation.
7825
7826    Example:
7827        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7828        'SELECT * FROM foo UNION SELECT * FROM bla'
7829
7830    Args:
7831        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7832            If `Expression` instances are passed, they will be used as-is.
7833        distinct: set the DISTINCT flag if and only if this is true.
7834        dialect: the dialect used to parse the input expression.
7835        copy: whether to copy the expression.
7836        opts: other options to use to parse the input expressions.
7837
7838    Returns:
7839        The new Union instance.
7840    """
7841    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7842    return _apply_set_operation(
7843        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7844    )

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:
7847def intersect(
7848    *expressions: ExpOrStr,
7849    distinct: bool = True,
7850    dialect: DialectType = None,
7851    copy: bool = True,
7852    **opts,
7853) -> Intersect:
7854    """
7855    Initializes a syntax tree for the `INTERSECT` operation.
7856
7857    Example:
7858        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7859        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7860
7861    Args:
7862        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7863            If `Expression` instances are passed, they will be used as-is.
7864        distinct: set the DISTINCT flag if and only if this is true.
7865        dialect: the dialect used to parse the input expression.
7866        copy: whether to copy the expression.
7867        opts: other options to use to parse the input expressions.
7868
7869    Returns:
7870        The new Intersect instance.
7871    """
7872    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7873    return _apply_set_operation(
7874        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7875    )

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:
7878def except_(
7879    *expressions: ExpOrStr,
7880    distinct: bool = True,
7881    dialect: DialectType = None,
7882    copy: bool = True,
7883    **opts,
7884) -> Except:
7885    """
7886    Initializes a syntax tree for the `EXCEPT` operation.
7887
7888    Example:
7889        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7890        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7891
7892    Args:
7893        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7894            If `Expression` instances are passed, they will be used as-is.
7895        distinct: set the DISTINCT flag if and only if this is true.
7896        dialect: the dialect used to parse the input expression.
7897        copy: whether to copy the expression.
7898        opts: other options to use to parse the input expressions.
7899
7900    Returns:
7901        The new Except instance.
7902    """
7903    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7904    return _apply_set_operation(
7905        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7906    )

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:
7909def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7910    """
7911    Initializes a syntax tree from one or multiple SELECT expressions.
7912
7913    Example:
7914        >>> select("col1", "col2").from_("tbl").sql()
7915        'SELECT col1, col2 FROM tbl'
7916
7917    Args:
7918        *expressions: the SQL code string to parse as the expressions of a
7919            SELECT statement. If an Expression instance is passed, this is used as-is.
7920        dialect: the dialect used to parse the input expressions (in the case that an
7921            input expression is a SQL string).
7922        **opts: other options to use to parse the input expressions (again, in the case
7923            that an input expression is a SQL string).
7924
7925    Returns:
7926        Select: the syntax tree for the SELECT statement.
7927    """
7928    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:
7931def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7932    """
7933    Initializes a syntax tree from a FROM expression.
7934
7935    Example:
7936        >>> from_("tbl").select("col1", "col2").sql()
7937        'SELECT col1, col2 FROM tbl'
7938
7939    Args:
7940        *expression: the SQL code string to parse as the FROM expressions of a
7941            SELECT statement. If an Expression instance is passed, this is used as-is.
7942        dialect: the dialect used to parse the input expression (in the case that the
7943            input expression is a SQL string).
7944        **opts: other options to use to parse the input expressions (again, in the case
7945            that the input expression is a SQL string).
7946
7947    Returns:
7948        Select: the syntax tree for the SELECT statement.
7949    """
7950    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:
7953def update(
7954    table: str | Table,
7955    properties: t.Optional[dict] = None,
7956    where: t.Optional[ExpOrStr] = None,
7957    from_: t.Optional[ExpOrStr] = None,
7958    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7959    dialect: DialectType = None,
7960    **opts,
7961) -> Update:
7962    """
7963    Creates an update statement.
7964
7965    Example:
7966        >>> 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()
7967        "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"
7968
7969    Args:
7970        properties: dictionary of properties to SET which are
7971            auto converted to sql objects eg None -> NULL
7972        where: sql conditional parsed into a WHERE statement
7973        from_: sql statement parsed into a FROM statement
7974        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7975        dialect: the dialect used to parse the input expressions.
7976        **opts: other options to use to parse the input expressions.
7977
7978    Returns:
7979        Update: the syntax tree for the UPDATE statement.
7980    """
7981    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7982    if properties:
7983        update_expr.set(
7984            "expressions",
7985            [
7986                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7987                for k, v in properties.items()
7988            ],
7989        )
7990    if from_:
7991        update_expr.set(
7992            "from",
7993            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7994        )
7995    if isinstance(where, Condition):
7996        where = Where(this=where)
7997    if where:
7998        update_expr.set(
7999            "where",
8000            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
8001        )
8002    if with_:
8003        cte_list = [
8004            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
8005            for alias, qry in with_.items()
8006        ]
8007        update_expr.set(
8008            "with",
8009            With(expressions=cte_list),
8010        )
8011    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:
8014def delete(
8015    table: ExpOrStr,
8016    where: t.Optional[ExpOrStr] = None,
8017    returning: t.Optional[ExpOrStr] = None,
8018    dialect: DialectType = None,
8019    **opts,
8020) -> Delete:
8021    """
8022    Builds a delete statement.
8023
8024    Example:
8025        >>> delete("my_table", where="id > 1").sql()
8026        'DELETE FROM my_table WHERE id > 1'
8027
8028    Args:
8029        where: sql conditional parsed into a WHERE statement
8030        returning: sql conditional parsed into a RETURNING statement
8031        dialect: the dialect used to parse the input expressions.
8032        **opts: other options to use to parse the input expressions.
8033
8034    Returns:
8035        Delete: the syntax tree for the DELETE statement.
8036    """
8037    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
8038    if where:
8039        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
8040    if returning:
8041        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
8042    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:
8045def insert(
8046    expression: ExpOrStr,
8047    into: ExpOrStr,
8048    columns: t.Optional[t.Sequence[str | Identifier]] = None,
8049    overwrite: t.Optional[bool] = None,
8050    returning: t.Optional[ExpOrStr] = None,
8051    dialect: DialectType = None,
8052    copy: bool = True,
8053    **opts,
8054) -> Insert:
8055    """
8056    Builds an INSERT statement.
8057
8058    Example:
8059        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
8060        'INSERT INTO tbl VALUES (1, 2, 3)'
8061
8062    Args:
8063        expression: the sql string or expression of the INSERT statement
8064        into: the tbl to insert data to.
8065        columns: optionally the table's column names.
8066        overwrite: whether to INSERT OVERWRITE or not.
8067        returning: sql conditional parsed into a RETURNING statement
8068        dialect: the dialect used to parse the input expressions.
8069        copy: whether to copy the expression.
8070        **opts: other options to use to parse the input expressions.
8071
8072    Returns:
8073        Insert: the syntax tree for the INSERT statement.
8074    """
8075    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8076    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
8077
8078    if columns:
8079        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
8080
8081    insert = Insert(this=this, expression=expr, overwrite=overwrite)
8082
8083    if returning:
8084        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
8085
8086    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:
8089def merge(
8090    *when_exprs: ExpOrStr,
8091    into: ExpOrStr,
8092    using: ExpOrStr,
8093    on: ExpOrStr,
8094    returning: t.Optional[ExpOrStr] = None,
8095    dialect: DialectType = None,
8096    copy: bool = True,
8097    **opts,
8098) -> Merge:
8099    """
8100    Builds a MERGE statement.
8101
8102    Example:
8103        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
8104        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
8105        ...       into="my_table",
8106        ...       using="source_table",
8107        ...       on="my_table.id = source_table.id").sql()
8108        '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)'
8109
8110    Args:
8111        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
8112        into: The target table to merge data into.
8113        using: The source table to merge data from.
8114        on: The join condition for the merge.
8115        returning: The columns to return from the merge.
8116        dialect: The dialect used to parse the input expressions.
8117        copy: Whether to copy the expression.
8118        **opts: Other options to use to parse the input expressions.
8119
8120    Returns:
8121        Merge: The syntax tree for the MERGE statement.
8122    """
8123    expressions: t.List[Expression] = []
8124    for when_expr in when_exprs:
8125        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
8126        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
8127
8128    merge = Merge(
8129        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
8130        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
8131        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
8132        whens=Whens(expressions=expressions),
8133    )
8134    if returning:
8135        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
8136
8137    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:
8140def condition(
8141    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
8142) -> Condition:
8143    """
8144    Initialize a logical condition expression.
8145
8146    Example:
8147        >>> condition("x=1").sql()
8148        'x = 1'
8149
8150        This is helpful for composing larger logical syntax trees:
8151        >>> where = condition("x=1")
8152        >>> where = where.and_("y=1")
8153        >>> Select().from_("tbl").select("*").where(where).sql()
8154        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
8155
8156    Args:
8157        *expression: the SQL code string to parse.
8158            If an Expression instance is passed, this is used as-is.
8159        dialect: the dialect used to parse the input expression (in the case that the
8160            input expression is a SQL string).
8161        copy: Whether to copy `expression` (only applies to expressions).
8162        **opts: other options to use to parse the input expressions (again, in the case
8163            that the input expression is a SQL string).
8164
8165    Returns:
8166        The new Condition instance
8167    """
8168    return maybe_parse(
8169        expression,
8170        into=Condition,
8171        dialect=dialect,
8172        copy=copy,
8173        **opts,
8174    )

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:
8177def and_(
8178    *expressions: t.Optional[ExpOrStr],
8179    dialect: DialectType = None,
8180    copy: bool = True,
8181    wrap: bool = True,
8182    **opts,
8183) -> Condition:
8184    """
8185    Combine multiple conditions with an AND logical operator.
8186
8187    Example:
8188        >>> and_("x=1", and_("y=1", "z=1")).sql()
8189        'x = 1 AND (y = 1 AND z = 1)'
8190
8191    Args:
8192        *expressions: the SQL code strings to parse.
8193            If an Expression instance is passed, this is used as-is.
8194        dialect: the dialect used to parse the input expression.
8195        copy: whether to copy `expressions` (only applies to Expressions).
8196        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8197            precedence issues, but can be turned off when the produced AST is too deep and
8198            causes recursion-related issues.
8199        **opts: other options to use to parse the input expressions.
8200
8201    Returns:
8202        The new condition
8203    """
8204    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:
8207def or_(
8208    *expressions: t.Optional[ExpOrStr],
8209    dialect: DialectType = None,
8210    copy: bool = True,
8211    wrap: bool = True,
8212    **opts,
8213) -> Condition:
8214    """
8215    Combine multiple conditions with an OR logical operator.
8216
8217    Example:
8218        >>> or_("x=1", or_("y=1", "z=1")).sql()
8219        'x = 1 OR (y = 1 OR z = 1)'
8220
8221    Args:
8222        *expressions: the SQL code strings to parse.
8223            If an Expression instance is passed, this is used as-is.
8224        dialect: the dialect used to parse the input expression.
8225        copy: whether to copy `expressions` (only applies to Expressions).
8226        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8227            precedence issues, but can be turned off when the produced AST is too deep and
8228            causes recursion-related issues.
8229        **opts: other options to use to parse the input expressions.
8230
8231    Returns:
8232        The new condition
8233    """
8234    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:
8237def xor(
8238    *expressions: t.Optional[ExpOrStr],
8239    dialect: DialectType = None,
8240    copy: bool = True,
8241    wrap: bool = True,
8242    **opts,
8243) -> Condition:
8244    """
8245    Combine multiple conditions with an XOR logical operator.
8246
8247    Example:
8248        >>> xor("x=1", xor("y=1", "z=1")).sql()
8249        'x = 1 XOR (y = 1 XOR z = 1)'
8250
8251    Args:
8252        *expressions: the SQL code strings to parse.
8253            If an Expression instance is passed, this is used as-is.
8254        dialect: the dialect used to parse the input expression.
8255        copy: whether to copy `expressions` (only applies to Expressions).
8256        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8257            precedence issues, but can be turned off when the produced AST is too deep and
8258            causes recursion-related issues.
8259        **opts: other options to use to parse the input expressions.
8260
8261    Returns:
8262        The new condition
8263    """
8264    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:
8267def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
8268    """
8269    Wrap a condition with a NOT operator.
8270
8271    Example:
8272        >>> not_("this_suit='black'").sql()
8273        "NOT this_suit = 'black'"
8274
8275    Args:
8276        expression: the SQL code string to parse.
8277            If an Expression instance is passed, this is used as-is.
8278        dialect: the dialect used to parse the input expression.
8279        copy: whether to copy the expression or not.
8280        **opts: other options to use to parse the input expressions.
8281
8282    Returns:
8283        The new condition.
8284    """
8285    this = condition(
8286        expression,
8287        dialect=dialect,
8288        copy=copy,
8289        **opts,
8290    )
8291    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:
8294def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
8295    """
8296    Wrap an expression in parentheses.
8297
8298    Example:
8299        >>> paren("5 + 3").sql()
8300        '(5 + 3)'
8301
8302    Args:
8303        expression: the SQL code string to parse.
8304            If an Expression instance is passed, this is used as-is.
8305        copy: whether to copy the expression or not.
8306
8307    Returns:
8308        The wrapped expression.
8309    """
8310    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):
8326def to_identifier(name, quoted=None, copy=True):
8327    """Builds an identifier.
8328
8329    Args:
8330        name: The name to turn into an identifier.
8331        quoted: Whether to force quote the identifier.
8332        copy: Whether to copy name if it's an Identifier.
8333
8334    Returns:
8335        The identifier ast node.
8336    """
8337
8338    if name is None:
8339        return None
8340
8341    if isinstance(name, Identifier):
8342        identifier = maybe_copy(name, copy)
8343    elif isinstance(name, str):
8344        identifier = Identifier(
8345            this=name,
8346            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8347        )
8348    else:
8349        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8350    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:
8353def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8354    """
8355    Parses a given string into an identifier.
8356
8357    Args:
8358        name: The name to parse into an identifier.
8359        dialect: The dialect to parse against.
8360
8361    Returns:
8362        The identifier ast node.
8363    """
8364    try:
8365        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8366    except (ParseError, TokenError):
8367        expression = to_identifier(name)
8368
8369    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*')
def to_interval( interval: str | Literal) -> Interval:
8375def to_interval(interval: str | Literal) -> Interval:
8376    """Builds an interval expression from a string like '1 day' or '5 months'."""
8377    if isinstance(interval, Literal):
8378        if not interval.is_string:
8379            raise ValueError("Invalid interval string.")
8380
8381        interval = interval.this
8382
8383    interval = maybe_parse(f"INTERVAL {interval}")
8384    assert isinstance(interval, Interval)
8385    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:
8388def to_table(
8389    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8390) -> Table:
8391    """
8392    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8393    If a table is passed in then that table is returned.
8394
8395    Args:
8396        sql_path: a `[catalog].[schema].[table]` string.
8397        dialect: the source dialect according to which the table name will be parsed.
8398        copy: Whether to copy a table if it is passed in.
8399        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8400
8401    Returns:
8402        A table expression.
8403    """
8404    if isinstance(sql_path, Table):
8405        return maybe_copy(sql_path, copy=copy)
8406
8407    try:
8408        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8409    except ParseError:
8410        catalog, db, this = split_num_words(sql_path, ".", 3)
8411
8412        if not this:
8413            raise
8414
8415        table = table_(this, db=db, catalog=catalog)
8416
8417    for k, v in kwargs.items():
8418        table.set(k, v)
8419
8420    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:
8423def to_column(
8424    sql_path: str | Column,
8425    quoted: t.Optional[bool] = None,
8426    dialect: DialectType = None,
8427    copy: bool = True,
8428    **kwargs,
8429) -> Column:
8430    """
8431    Create a column from a `[table].[column]` sql path. Table is optional.
8432    If a column is passed in then that column is returned.
8433
8434    Args:
8435        sql_path: a `[table].[column]` string.
8436        quoted: Whether or not to force quote identifiers.
8437        dialect: the source dialect according to which the column name will be parsed.
8438        copy: Whether to copy a column if it is passed in.
8439        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8440
8441    Returns:
8442        A column expression.
8443    """
8444    if isinstance(sql_path, Column):
8445        return maybe_copy(sql_path, copy=copy)
8446
8447    try:
8448        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8449    except ParseError:
8450        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8451
8452    for k, v in kwargs.items():
8453        col.set(k, v)
8454
8455    if quoted:
8456        for i in col.find_all(Identifier):
8457            i.set("quoted", True)
8458
8459    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):
8462def alias_(
8463    expression: ExpOrStr,
8464    alias: t.Optional[str | Identifier],
8465    table: bool | t.Sequence[str | Identifier] = False,
8466    quoted: t.Optional[bool] = None,
8467    dialect: DialectType = None,
8468    copy: bool = True,
8469    **opts,
8470):
8471    """Create an Alias expression.
8472
8473    Example:
8474        >>> alias_('foo', 'bar').sql()
8475        'foo AS bar'
8476
8477        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8478        '(SELECT 1, 2) AS bar(a, b)'
8479
8480    Args:
8481        expression: the SQL code strings to parse.
8482            If an Expression instance is passed, this is used as-is.
8483        alias: the alias name to use. If the name has
8484            special characters it is quoted.
8485        table: Whether to create a table alias, can also be a list of columns.
8486        quoted: whether to quote the alias
8487        dialect: the dialect used to parse the input expression.
8488        copy: Whether to copy the expression.
8489        **opts: other options to use to parse the input expressions.
8490
8491    Returns:
8492        Alias: the aliased expression
8493    """
8494    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8495    alias = to_identifier(alias, quoted=quoted)
8496
8497    if table:
8498        table_alias = TableAlias(this=alias)
8499        exp.set("alias", table_alias)
8500
8501        if not isinstance(table, bool):
8502            for column in table:
8503                table_alias.append("columns", to_identifier(column, quoted=quoted))
8504
8505        return exp
8506
8507    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8508    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8509    # for the complete Window expression.
8510    #
8511    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8512
8513    if "alias" in exp.arg_types and not isinstance(exp, Window):
8514        exp.set("alias", alias)
8515        return exp
8516    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:
8519def subquery(
8520    expression: ExpOrStr,
8521    alias: t.Optional[Identifier | str] = None,
8522    dialect: DialectType = None,
8523    **opts,
8524) -> Select:
8525    """
8526    Build a subquery expression that's selected from.
8527
8528    Example:
8529        >>> subquery('select x from tbl', 'bar').select('x').sql()
8530        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8531
8532    Args:
8533        expression: the SQL code strings to parse.
8534            If an Expression instance is passed, this is used as-is.
8535        alias: the alias name to use.
8536        dialect: the dialect used to parse the input expression.
8537        **opts: other options to use to parse the input expressions.
8538
8539    Returns:
8540        A new Select instance with the subquery expression included.
8541    """
8542
8543    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8544    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):
8575def column(
8576    col,
8577    table=None,
8578    db=None,
8579    catalog=None,
8580    *,
8581    fields=None,
8582    quoted=None,
8583    copy=True,
8584):
8585    """
8586    Build a Column.
8587
8588    Args:
8589        col: Column name.
8590        table: Table name.
8591        db: Database name.
8592        catalog: Catalog name.
8593        fields: Additional fields using dots.
8594        quoted: Whether to force quotes on the column's identifiers.
8595        copy: Whether to copy identifiers if passed in.
8596
8597    Returns:
8598        The new Column instance.
8599    """
8600    if not isinstance(col, Star):
8601        col = to_identifier(col, quoted=quoted, copy=copy)
8602
8603    this = Column(
8604        this=col,
8605        table=to_identifier(table, quoted=quoted, copy=copy),
8606        db=to_identifier(db, quoted=quoted, copy=copy),
8607        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8608    )
8609
8610    if fields:
8611        this = Dot.build(
8612            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8613        )
8614    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:
8617def cast(
8618    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8619) -> Cast:
8620    """Cast an expression to a data type.
8621
8622    Example:
8623        >>> cast('x + 1', 'int').sql()
8624        'CAST(x + 1 AS INT)'
8625
8626    Args:
8627        expression: The expression to cast.
8628        to: The datatype to cast to.
8629        copy: Whether to copy the supplied expressions.
8630        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8631            - The expression to be cast is already a exp.Cast expression
8632            - The existing cast is to a type that is logically equivalent to new type
8633
8634            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8635            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8636            and instead just return the original expression `CAST(x as DATETIME)`.
8637
8638            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8639            mapping is applied in the target dialect generator.
8640
8641    Returns:
8642        The new Cast instance.
8643    """
8644    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8645    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8646
8647    # dont re-cast if the expression is already a cast to the correct type
8648    if isinstance(expr, Cast):
8649        from sqlglot.dialects.dialect import Dialect
8650
8651        target_dialect = Dialect.get_or_raise(dialect)
8652        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8653
8654        existing_cast_type: DataType.Type = expr.to.this
8655        new_cast_type: DataType.Type = data_type.this
8656        types_are_equivalent = type_mapping.get(
8657            existing_cast_type, existing_cast_type.value
8658        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8659
8660        if expr.is_type(data_type) or types_are_equivalent:
8661            return expr
8662
8663    expr = Cast(this=expr, to=data_type)
8664    expr.type = data_type
8665
8666    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:
8669def table_(
8670    table: Identifier | str,
8671    db: t.Optional[Identifier | str] = None,
8672    catalog: t.Optional[Identifier | str] = None,
8673    quoted: t.Optional[bool] = None,
8674    alias: t.Optional[Identifier | str] = None,
8675) -> Table:
8676    """Build a Table.
8677
8678    Args:
8679        table: Table name.
8680        db: Database name.
8681        catalog: Catalog name.
8682        quote: Whether to force quotes on the table's identifiers.
8683        alias: Table's alias.
8684
8685    Returns:
8686        The new Table instance.
8687    """
8688    return Table(
8689        this=to_identifier(table, quoted=quoted) if table else None,
8690        db=to_identifier(db, quoted=quoted) if db else None,
8691        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8692        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8693    )

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:
8696def values(
8697    values: t.Iterable[t.Tuple[t.Any, ...]],
8698    alias: t.Optional[str] = None,
8699    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8700) -> Values:
8701    """Build VALUES statement.
8702
8703    Example:
8704        >>> values([(1, '2')]).sql()
8705        "VALUES (1, '2')"
8706
8707    Args:
8708        values: values statements that will be converted to SQL
8709        alias: optional alias
8710        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8711         If either are provided then an alias is also required.
8712
8713    Returns:
8714        Values: the Values expression object
8715    """
8716    if columns and not alias:
8717        raise ValueError("Alias is required when providing columns")
8718
8719    return Values(
8720        expressions=[convert(tup) for tup in values],
8721        alias=(
8722            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8723            if columns
8724            else (TableAlias(this=to_identifier(alias)) if alias else None)
8725        ),
8726    )

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:
8729def var(name: t.Optional[ExpOrStr]) -> Var:
8730    """Build a SQL variable.
8731
8732    Example:
8733        >>> repr(var('x'))
8734        'Var(this=x)'
8735
8736        >>> repr(var(column('x', table='y')))
8737        'Var(this=x)'
8738
8739    Args:
8740        name: The name of the var or an expression who's name will become the var.
8741
8742    Returns:
8743        The new variable node.
8744    """
8745    if not name:
8746        raise ValueError("Cannot convert empty name into var.")
8747
8748    if isinstance(name, Expression):
8749        name = name.name
8750    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:
8753def rename_table(
8754    old_name: str | Table,
8755    new_name: str | Table,
8756    dialect: DialectType = None,
8757) -> Alter:
8758    """Build ALTER TABLE... RENAME... expression
8759
8760    Args:
8761        old_name: The old name of the table
8762        new_name: The new name of the table
8763        dialect: The dialect to parse the table.
8764
8765    Returns:
8766        Alter table expression
8767    """
8768    old_table = to_table(old_name, dialect=dialect)
8769    new_table = to_table(new_name, dialect=dialect)
8770    return Alter(
8771        this=old_table,
8772        kind="TABLE",
8773        actions=[
8774            AlterRename(this=new_table),
8775        ],
8776    )

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:
8779def rename_column(
8780    table_name: str | Table,
8781    old_column_name: str | Column,
8782    new_column_name: str | Column,
8783    exists: t.Optional[bool] = None,
8784    dialect: DialectType = None,
8785) -> Alter:
8786    """Build ALTER TABLE... RENAME COLUMN... expression
8787
8788    Args:
8789        table_name: Name of the table
8790        old_column: The old name of the column
8791        new_column: The new name of the column
8792        exists: Whether to add the `IF EXISTS` clause
8793        dialect: The dialect to parse the table/column.
8794
8795    Returns:
8796        Alter table expression
8797    """
8798    table = to_table(table_name, dialect=dialect)
8799    old_column = to_column(old_column_name, dialect=dialect)
8800    new_column = to_column(new_column_name, dialect=dialect)
8801    return Alter(
8802        this=table,
8803        kind="TABLE",
8804        actions=[
8805            RenameColumn(this=old_column, to=new_column, exists=exists),
8806        ],
8807    )

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:
8810def convert(value: t.Any, copy: bool = False) -> Expression:
8811    """Convert a python value into an expression object.
8812
8813    Raises an error if a conversion is not possible.
8814
8815    Args:
8816        value: A python object.
8817        copy: Whether to copy `value` (only applies to Expressions and collections).
8818
8819    Returns:
8820        The equivalent expression object.
8821    """
8822    if isinstance(value, Expression):
8823        return maybe_copy(value, copy)
8824    if isinstance(value, str):
8825        return Literal.string(value)
8826    if isinstance(value, bool):
8827        return Boolean(this=value)
8828    if value is None or (isinstance(value, float) and math.isnan(value)):
8829        return null()
8830    if isinstance(value, numbers.Number):
8831        return Literal.number(value)
8832    if isinstance(value, bytes):
8833        return HexString(this=value.hex())
8834    if isinstance(value, datetime.datetime):
8835        datetime_literal = Literal.string(value.isoformat(sep=" "))
8836
8837        tz = None
8838        if value.tzinfo:
8839            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8840            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8841            tz = Literal.string(str(value.tzinfo))
8842
8843        return TimeStrToTime(this=datetime_literal, zone=tz)
8844    if isinstance(value, datetime.date):
8845        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8846        return DateStrToDate(this=date_literal)
8847    if isinstance(value, datetime.time):
8848        time_literal = Literal.string(value.isoformat())
8849        return TsOrDsToTime(this=time_literal)
8850    if isinstance(value, tuple):
8851        if hasattr(value, "_fields"):
8852            return Struct(
8853                expressions=[
8854                    PropertyEQ(
8855                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8856                    )
8857                    for k in value._fields
8858                ]
8859            )
8860        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8861    if isinstance(value, list):
8862        return Array(expressions=[convert(v, copy=copy) for v in value])
8863    if isinstance(value, dict):
8864        return Map(
8865            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8866            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8867        )
8868    if hasattr(value, "__dict__"):
8869        return Struct(
8870            expressions=[
8871                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8872                for k, v in value.__dict__.items()
8873            ]
8874        )
8875    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:
8878def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8879    """
8880    Replace children of an expression with the result of a lambda fun(child) -> exp.
8881    """
8882    for k, v in tuple(expression.args.items()):
8883        is_list_arg = type(v) is list
8884
8885        child_nodes = v if is_list_arg else [v]
8886        new_child_nodes = []
8887
8888        for cn in child_nodes:
8889            if isinstance(cn, Expression):
8890                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8891                    new_child_nodes.append(child_node)
8892            else:
8893                new_child_nodes.append(cn)
8894
8895        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:
8898def replace_tree(
8899    expression: Expression,
8900    fun: t.Callable,
8901    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8902) -> Expression:
8903    """
8904    Replace an entire tree with the result of function calls on each node.
8905
8906    This will be traversed in reverse dfs, so leaves first.
8907    If new nodes are created as a result of function calls, they will also be traversed.
8908    """
8909    stack = list(expression.dfs(prune=prune))
8910
8911    while stack:
8912        node = stack.pop()
8913        new_node = fun(node)
8914
8915        if new_node is not node:
8916            node.replace(new_node)
8917
8918            if isinstance(new_node, Expression):
8919                stack.append(new_node)
8920
8921    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]:
8924def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8925    """
8926    Return all table names referenced through columns in an expression.
8927
8928    Example:
8929        >>> import sqlglot
8930        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8931        ['a', 'c']
8932
8933    Args:
8934        expression: expression to find table names.
8935        exclude: a table name to exclude
8936
8937    Returns:
8938        A list of unique names.
8939    """
8940    return {
8941        table
8942        for table in (column.table for column in expression.find_all(Column))
8943        if table and table != exclude
8944    }

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:
8947def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8948    """Get the full name of a table as a string.
8949
8950    Args:
8951        table: Table expression node or string.
8952        dialect: The dialect to generate the table name for.
8953        identify: Determines when an identifier should be quoted. Possible values are:
8954            False (default): Never quote, except in cases where it's mandatory by the dialect.
8955            True: Always quote.
8956
8957    Examples:
8958        >>> from sqlglot import exp, parse_one
8959        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8960        'a.b.c'
8961
8962    Returns:
8963        The table name.
8964    """
8965
8966    table = maybe_parse(table, into=Table, dialect=dialect)
8967
8968    if not table:
8969        raise ValueError(f"Cannot parse {table}")
8970
8971    return ".".join(
8972        (
8973            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8974            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8975            else part.name
8976        )
8977        for part in table.parts
8978    )

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:
8981def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8982    """Returns a case normalized table name without quotes.
8983
8984    Args:
8985        table: the table to normalize
8986        dialect: the dialect to use for normalization rules
8987        copy: whether to copy the expression.
8988
8989    Examples:
8990        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8991        'A-B.c'
8992    """
8993    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8994
8995    return ".".join(
8996        p.name
8997        for p in normalize_identifiers(
8998            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8999        ).parts
9000    )

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:
9003def replace_tables(
9004    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
9005) -> E:
9006    """Replace all tables in expression according to the mapping.
9007
9008    Args:
9009        expression: expression node to be transformed and replaced.
9010        mapping: mapping of table names.
9011        dialect: the dialect of the mapping table
9012        copy: whether to copy the expression.
9013
9014    Examples:
9015        >>> from sqlglot import exp, parse_one
9016        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
9017        'SELECT * FROM c /* a.b */'
9018
9019    Returns:
9020        The mapped expression.
9021    """
9022
9023    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
9024
9025    def _replace_tables(node: Expression) -> Expression:
9026        if isinstance(node, Table) and node.meta.get("replace") is not False:
9027            original = normalize_table_name(node, dialect=dialect)
9028            new_name = mapping.get(original)
9029
9030            if new_name:
9031                table = to_table(
9032                    new_name,
9033                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
9034                    dialect=dialect,
9035                )
9036                table.add_comments([original])
9037                return table
9038        return node
9039
9040    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:
9043def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
9044    """Replace placeholders in an expression.
9045
9046    Args:
9047        expression: expression node to be transformed and replaced.
9048        args: positional names that will substitute unnamed placeholders in the given order.
9049        kwargs: keyword arguments that will substitute named placeholders.
9050
9051    Examples:
9052        >>> from sqlglot import exp, parse_one
9053        >>> replace_placeholders(
9054        ...     parse_one("select * from :tbl where ? = ?"),
9055        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
9056        ... ).sql()
9057        "SELECT * FROM foo WHERE str_col = 'b'"
9058
9059    Returns:
9060        The mapped expression.
9061    """
9062
9063    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
9064        if isinstance(node, Placeholder):
9065            if node.this:
9066                new_name = kwargs.get(node.this)
9067                if new_name is not None:
9068                    return convert(new_name)
9069            else:
9070                try:
9071                    return convert(next(args))
9072                except StopIteration:
9073                    pass
9074        return node
9075
9076    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:
9079def expand(
9080    expression: Expression,
9081    sources: t.Dict[str, Query | t.Callable[[], Query]],
9082    dialect: DialectType = None,
9083    copy: bool = True,
9084) -> Expression:
9085    """Transforms an expression by expanding all referenced sources into subqueries.
9086
9087    Examples:
9088        >>> from sqlglot import parse_one
9089        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
9090        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
9091
9092        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
9093        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
9094
9095    Args:
9096        expression: The expression to expand.
9097        sources: A dict of name to query or a callable that provides a query on demand.
9098        dialect: The dialect of the sources dict or the callable.
9099        copy: Whether to copy the expression during transformation. Defaults to True.
9100
9101    Returns:
9102        The transformed expression.
9103    """
9104    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
9105
9106    def _expand(node: Expression):
9107        if isinstance(node, Table):
9108            name = normalize_table_name(node, dialect=dialect)
9109            source = normalized_sources.get(name)
9110
9111            if source:
9112                # Create a subquery with the same alias (or table name if no alias)
9113                parsed_source = source() if callable(source) else source
9114                subquery = parsed_source.subquery(node.alias or name)
9115                subquery.comments = [f"source: {name}"]
9116
9117                # Continue expanding within the subquery
9118                return subquery.transform(_expand, copy=False)
9119
9120        return node
9121
9122    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:
9125def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
9126    """
9127    Returns a Func expression.
9128
9129    Examples:
9130        >>> func("abs", 5).sql()
9131        'ABS(5)'
9132
9133        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
9134        'CAST(5 AS DOUBLE)'
9135
9136    Args:
9137        name: the name of the function to build.
9138        args: the args used to instantiate the function of interest.
9139        copy: whether to copy the argument expressions.
9140        dialect: the source dialect.
9141        kwargs: the kwargs used to instantiate the function of interest.
9142
9143    Note:
9144        The arguments `args` and `kwargs` are mutually exclusive.
9145
9146    Returns:
9147        An instance of the function of interest, or an anonymous function, if `name` doesn't
9148        correspond to an existing `sqlglot.expressions.Func` class.
9149    """
9150    if args and kwargs:
9151        raise ValueError("Can't use both args and kwargs to instantiate a function.")
9152
9153    from sqlglot.dialects.dialect import Dialect
9154
9155    dialect = Dialect.get_or_raise(dialect)
9156
9157    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
9158    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
9159
9160    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
9161    if constructor:
9162        if converted:
9163            if "dialect" in constructor.__code__.co_varnames:
9164                function = constructor(converted, dialect=dialect)
9165            else:
9166                function = constructor(converted)
9167        elif constructor.__name__ == "from_arg_list":
9168            function = constructor.__self__(**kwargs)  # type: ignore
9169        else:
9170            constructor = FUNCTION_BY_NAME.get(name.upper())
9171            if constructor:
9172                function = constructor(**kwargs)
9173            else:
9174                raise ValueError(
9175                    f"Unable to convert '{name}' into a Func. Either manually construct "
9176                    "the Func expression of interest or parse the function call."
9177                )
9178    else:
9179        kwargs = kwargs or {"expressions": converted}
9180        function = Anonymous(this=name, **kwargs)
9181
9182    for error_message in function.error_messages(converted):
9183        raise ValueError(error_message)
9184
9185    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:
9188def case(
9189    expression: t.Optional[ExpOrStr] = None,
9190    **opts,
9191) -> Case:
9192    """
9193    Initialize a CASE statement.
9194
9195    Example:
9196        case().when("a = 1", "foo").else_("bar")
9197
9198    Args:
9199        expression: Optionally, the input expression (not all dialects support this)
9200        **opts: Extra keyword arguments for parsing `expression`
9201    """
9202    if expression is not None:
9203        this = maybe_parse(expression, **opts)
9204    else:
9205        this = None
9206    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:
9209def array(
9210    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9211) -> Array:
9212    """
9213    Returns an array.
9214
9215    Examples:
9216        >>> array(1, 'x').sql()
9217        'ARRAY(1, x)'
9218
9219    Args:
9220        expressions: the expressions to add to the array.
9221        copy: whether to copy the argument expressions.
9222        dialect: the source dialect.
9223        kwargs: the kwargs used to instantiate the function of interest.
9224
9225    Returns:
9226        An array expression.
9227    """
9228    return Array(
9229        expressions=[
9230            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9231            for expression in expressions
9232        ]
9233    )

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:
9236def tuple_(
9237    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9238) -> Tuple:
9239    """
9240    Returns an tuple.
9241
9242    Examples:
9243        >>> tuple_(1, 'x').sql()
9244        '(1, x)'
9245
9246    Args:
9247        expressions: the expressions to add to the tuple.
9248        copy: whether to copy the argument expressions.
9249        dialect: the source dialect.
9250        kwargs: the kwargs used to instantiate the function of interest.
9251
9252    Returns:
9253        A tuple expression.
9254    """
9255    return Tuple(
9256        expressions=[
9257            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9258            for expression in expressions
9259        ]
9260    )

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:
9263def true() -> Boolean:
9264    """
9265    Returns a true Boolean expression.
9266    """
9267    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
9270def false() -> Boolean:
9271    """
9272    Returns a false Boolean expression.
9273    """
9274    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
9277def null() -> Null:
9278    """
9279    Returns a Null expression.
9280    """
9281    return Null()

Returns a Null expression.

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