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

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2545class Join(Expression):
2546    arg_types = {
2547        "this": True,
2548        "on": False,
2549        "side": False,
2550        "kind": False,
2551        "using": False,
2552        "method": False,
2553        "global": False,
2554        "hint": False,
2555        "match_condition": False,  # Snowflake
2556        "expressions": False,
2557        "pivots": False,
2558    }
2559
2560    @property
2561    def method(self) -> str:
2562        return self.text("method").upper()
2563
2564    @property
2565    def kind(self) -> str:
2566        return self.text("kind").upper()
2567
2568    @property
2569    def side(self) -> str:
2570        return self.text("side").upper()
2571
2572    @property
2573    def hint(self) -> str:
2574        return self.text("hint").upper()
2575
2576    @property
2577    def alias_or_name(self) -> str:
2578        return self.this.alias_or_name
2579
2580    @property
2581    def is_semi_or_anti_join(self) -> bool:
2582        return self.kind in ("SEMI", "ANTI")
2583
2584    def on(
2585        self,
2586        *expressions: t.Optional[ExpOrStr],
2587        append: bool = True,
2588        dialect: DialectType = None,
2589        copy: bool = True,
2590        **opts,
2591    ) -> Join:
2592        """
2593        Append to or set the ON expressions.
2594
2595        Example:
2596            >>> import sqlglot
2597            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2598            'JOIN x ON y = 1'
2599
2600        Args:
2601            *expressions: the SQL code strings to parse.
2602                If an `Expression` instance is passed, it will be used as-is.
2603                Multiple expressions are combined with an AND operator.
2604            append: if `True`, AND the new expressions to any existing expression.
2605                Otherwise, this resets the expression.
2606            dialect: the dialect used to parse the input expressions.
2607            copy: if `False`, modify this expression instance in-place.
2608            opts: other options to use to parse the input expressions.
2609
2610        Returns:
2611            The modified Join expression.
2612        """
2613        join = _apply_conjunction_builder(
2614            *expressions,
2615            instance=self,
2616            arg="on",
2617            append=append,
2618            dialect=dialect,
2619            copy=copy,
2620            **opts,
2621        )
2622
2623        if join.kind == "CROSS":
2624            join.set("kind", None)
2625
2626        return join
2627
2628    def using(
2629        self,
2630        *expressions: t.Optional[ExpOrStr],
2631        append: bool = True,
2632        dialect: DialectType = None,
2633        copy: bool = True,
2634        **opts,
2635    ) -> Join:
2636        """
2637        Append to or set the USING expressions.
2638
2639        Example:
2640            >>> import sqlglot
2641            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2642            'JOIN x USING (foo, bla)'
2643
2644        Args:
2645            *expressions: the SQL code strings to parse.
2646                If an `Expression` instance is passed, it will be used as-is.
2647            append: if `True`, concatenate the new expressions to the existing "using" list.
2648                Otherwise, this resets the expression.
2649            dialect: the dialect used to parse the input expressions.
2650            copy: if `False`, modify this expression instance in-place.
2651            opts: other options to use to parse the input expressions.
2652
2653        Returns:
2654            The modified Join expression.
2655        """
2656        join = _apply_list_builder(
2657            *expressions,
2658            instance=self,
2659            arg="using",
2660            append=append,
2661            dialect=dialect,
2662            copy=copy,
2663            **opts,
2664        )
2665
2666        if join.kind == "CROSS":
2667            join.set("kind", None)
2668
2669        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
2560    @property
2561    def method(self) -> str:
2562        return self.text("method").upper()
kind: str
2564    @property
2565    def kind(self) -> str:
2566        return self.text("kind").upper()
side: str
2568    @property
2569    def side(self) -> str:
2570        return self.text("side").upper()
hint: str
2572    @property
2573    def hint(self) -> str:
2574        return self.text("hint").upper()
alias_or_name: str
2576    @property
2577    def alias_or_name(self) -> str:
2578        return self.this.alias_or_name
is_semi_or_anti_join: bool
2580    @property
2581    def is_semi_or_anti_join(self) -> bool:
2582        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:
2584    def on(
2585        self,
2586        *expressions: t.Optional[ExpOrStr],
2587        append: bool = True,
2588        dialect: DialectType = None,
2589        copy: bool = True,
2590        **opts,
2591    ) -> Join:
2592        """
2593        Append to or set the ON expressions.
2594
2595        Example:
2596            >>> import sqlglot
2597            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2598            'JOIN x ON y = 1'
2599
2600        Args:
2601            *expressions: the SQL code strings to parse.
2602                If an `Expression` instance is passed, it will be used as-is.
2603                Multiple expressions are combined with an AND operator.
2604            append: if `True`, AND the new expressions to any existing expression.
2605                Otherwise, this resets the expression.
2606            dialect: the dialect used to parse the input expressions.
2607            copy: if `False`, modify this expression instance in-place.
2608            opts: other options to use to parse the input expressions.
2609
2610        Returns:
2611            The modified Join expression.
2612        """
2613        join = _apply_conjunction_builder(
2614            *expressions,
2615            instance=self,
2616            arg="on",
2617            append=append,
2618            dialect=dialect,
2619            copy=copy,
2620            **opts,
2621        )
2622
2623        if join.kind == "CROSS":
2624            join.set("kind", None)
2625
2626        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:
2628    def using(
2629        self,
2630        *expressions: t.Optional[ExpOrStr],
2631        append: bool = True,
2632        dialect: DialectType = None,
2633        copy: bool = True,
2634        **opts,
2635    ) -> Join:
2636        """
2637        Append to or set the USING expressions.
2638
2639        Example:
2640            >>> import sqlglot
2641            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2642            'JOIN x USING (foo, bla)'
2643
2644        Args:
2645            *expressions: the SQL code strings to parse.
2646                If an `Expression` instance is passed, it will be used as-is.
2647            append: if `True`, concatenate the new expressions to the existing "using" list.
2648                Otherwise, this resets the expression.
2649            dialect: the dialect used to parse the input expressions.
2650            copy: if `False`, modify this expression instance in-place.
2651            opts: other options to use to parse the input expressions.
2652
2653        Returns:
2654            The modified Join expression.
2655        """
2656        join = _apply_list_builder(
2657            *expressions,
2658            instance=self,
2659            arg="using",
2660            append=append,
2661            dialect=dialect,
2662            copy=copy,
2663            **opts,
2664        )
2665
2666        if join.kind == "CROSS":
2667            join.set("kind", None)
2668
2669        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):
2672class Lateral(UDTF):
2673    arg_types = {
2674        "this": True,
2675        "view": False,
2676        "outer": False,
2677        "alias": False,
2678        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2679        "ordinality": False,
2680    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2685class TableFromRows(UDTF):
2686    arg_types = {
2687        "this": True,
2688        "alias": False,
2689        "joins": False,
2690        "pivots": False,
2691        "sample": False,
2692    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2695class MatchRecognizeMeasure(Expression):
2696    arg_types = {
2697        "this": True,
2698        "window_frame": False,
2699    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2702class MatchRecognize(Expression):
2703    arg_types = {
2704        "partition_by": False,
2705        "order": False,
2706        "measures": False,
2707        "rows": False,
2708        "after": False,
2709        "pattern": False,
2710        "define": False,
2711        "alias": False,
2712    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2717class Final(Expression):
2718    pass
key = 'final'
class Offset(Expression):
2721class Offset(Expression):
2722    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2725class Order(Expression):
2726    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2730class WithFill(Expression):
2731    arg_types = {
2732        "from": False,
2733        "to": False,
2734        "step": False,
2735        "interpolate": False,
2736    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2741class Cluster(Order):
2742    pass
key = 'cluster'
class Distribute(Order):
2745class Distribute(Order):
2746    pass
key = 'distribute'
class Sort(Order):
2749class Sort(Order):
2750    pass
key = 'sort'
class Ordered(Expression):
2753class Ordered(Expression):
2754    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2755
2756    @property
2757    def name(self) -> str:
2758        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2756    @property
2757    def name(self) -> str:
2758        return self.this.name
key = 'ordered'
class Property(Expression):
2761class Property(Expression):
2762    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2765class GrantPrivilege(Expression):
2766    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2769class GrantPrincipal(Expression):
2770    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2773class AllowedValuesProperty(Expression):
2774    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2777class AlgorithmProperty(Property):
2778    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2781class AutoIncrementProperty(Property):
2782    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2786class AutoRefreshProperty(Property):
2787    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2790class BackupProperty(Property):
2791    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2794class BlockCompressionProperty(Property):
2795    arg_types = {
2796        "autotemp": False,
2797        "always": False,
2798        "default": False,
2799        "manual": False,
2800        "never": False,
2801    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2804class CharacterSetProperty(Property):
2805    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2808class ChecksumProperty(Property):
2809    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2812class CollateProperty(Property):
2813    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2816class CopyGrantsProperty(Property):
2817    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2820class DataBlocksizeProperty(Property):
2821    arg_types = {
2822        "size": False,
2823        "units": False,
2824        "minimum": False,
2825        "maximum": False,
2826        "default": False,
2827    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2830class DataDeletionProperty(Property):
2831    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):
2834class DefinerProperty(Property):
2835    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2838class DistKeyProperty(Property):
2839    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2844class DistributedByProperty(Property):
2845    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):
2848class DistStyleProperty(Property):
2849    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2852class DuplicateKeyProperty(Property):
2853    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2856class EngineProperty(Property):
2857    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2860class HeapProperty(Property):
2861    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2864class ToTableProperty(Property):
2865    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2868class ExecuteAsProperty(Property):
2869    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2872class ExternalProperty(Property):
2873    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2876class FallbackProperty(Property):
2877    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2881class FileFormatProperty(Property):
2882    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2885class CredentialsProperty(Property):
2886    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2889class FreespaceProperty(Property):
2890    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2893class GlobalProperty(Property):
2894    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2897class IcebergProperty(Property):
2898    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2901class InheritsProperty(Property):
2902    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2905class InputModelProperty(Property):
2906    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2909class OutputModelProperty(Property):
2910    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2913class IsolatedLoadingProperty(Property):
2914    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2917class JournalProperty(Property):
2918    arg_types = {
2919        "no": False,
2920        "dual": False,
2921        "before": False,
2922        "local": False,
2923        "after": False,
2924    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2927class LanguageProperty(Property):
2928    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2931class EnviromentProperty(Property):
2932    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2936class ClusteredByProperty(Property):
2937    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2940class DictProperty(Property):
2941    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2944class DictSubProperty(Property):
2945    pass
key = 'dictsubproperty'
class DictRange(Property):
2948class DictRange(Property):
2949    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2952class DynamicProperty(Property):
2953    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2958class OnCluster(Property):
2959    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2963class EmptyProperty(Property):
2964    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2967class LikeProperty(Property):
2968    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2971class LocationProperty(Property):
2972    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2975class LockProperty(Property):
2976    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2979class LockingProperty(Property):
2980    arg_types = {
2981        "this": False,
2982        "kind": True,
2983        "for_or_in": False,
2984        "lock_type": True,
2985        "override": False,
2986    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2989class LogProperty(Property):
2990    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2993class MaterializedProperty(Property):
2994    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2997class MergeBlockRatioProperty(Property):
2998    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):
3001class NoPrimaryIndexProperty(Property):
3002    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
3005class OnProperty(Property):
3006    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
3009class OnCommitProperty(Property):
3010    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3013class PartitionedByProperty(Property):
3014    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3017class PartitionedByBucket(Property):
3018    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3021class PartitionByTruncate(Property):
3022    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3026class PartitionByRangeProperty(Property):
3027    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3031class PartitionByRangePropertyDynamic(Expression):
3032    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class UniqueKeyProperty(Property):
3036class UniqueKeyProperty(Property):
3037    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3041class PartitionBoundSpec(Expression):
3042    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3043    arg_types = {
3044        "this": False,
3045        "expression": False,
3046        "from_expressions": False,
3047        "to_expressions": False,
3048    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3051class PartitionedOfProperty(Property):
3052    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3053    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3056class StreamingTableProperty(Property):
3057    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3060class RemoteWithConnectionModelProperty(Property):
3061    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3064class ReturnsProperty(Property):
3065    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):
3068class StrictProperty(Property):
3069    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3072class RowFormatProperty(Property):
3073    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3076class RowFormatDelimitedProperty(Property):
3077    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3078    arg_types = {
3079        "fields": False,
3080        "escaped": False,
3081        "collection_items": False,
3082        "map_keys": False,
3083        "lines": False,
3084        "null": False,
3085        "serde": False,
3086    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3089class RowFormatSerdeProperty(Property):
3090    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3094class QueryTransform(Expression):
3095    arg_types = {
3096        "expressions": True,
3097        "command_script": True,
3098        "schema": False,
3099        "row_format_before": False,
3100        "record_writer": False,
3101        "row_format_after": False,
3102        "record_reader": False,
3103    }
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):
3106class SampleProperty(Property):
3107    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3111class SecurityProperty(Property):
3112    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3115class SchemaCommentProperty(Property):
3116    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3119class SemanticView(Expression):
3120    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):
3123class SerdeProperties(Property):
3124    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3127class SetProperty(Property):
3128    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3131class SharingProperty(Property):
3132    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3135class SetConfigProperty(Property):
3136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3139class SettingsProperty(Property):
3140    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3143class SortKeyProperty(Property):
3144    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3147class SqlReadWriteProperty(Property):
3148    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3151class SqlSecurityProperty(Property):
3152    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3155class StabilityProperty(Property):
3156    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3159class StorageHandlerProperty(Property):
3160    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3163class TemporaryProperty(Property):
3164    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3167class SecureProperty(Property):
3168    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3172class Tags(ColumnConstraintKind, Property):
3173    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3176class TransformModelProperty(Property):
3177    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3180class TransientProperty(Property):
3181    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3184class UnloggedProperty(Property):
3185    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3189class UsingTemplateProperty(Property):
3190    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3194class ViewAttributeProperty(Property):
3195    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3198class VolatileProperty(Property):
3199    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3202class WithDataProperty(Property):
3203    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3206class WithJournalTableProperty(Property):
3207    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3210class WithSchemaBindingProperty(Property):
3211    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3214class WithSystemVersioningProperty(Property):
3215    arg_types = {
3216        "on": False,
3217        "this": False,
3218        "data_consistency": False,
3219        "retention_period": False,
3220        "with": True,
3221    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3224class WithProcedureOptions(Property):
3225    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3228class EncodeProperty(Property):
3229    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3232class IncludeProperty(Property):
3233    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3236class ForceProperty(Property):
3237    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3240class Properties(Expression):
3241    arg_types = {"expressions": True}
3242
3243    NAME_TO_PROPERTY = {
3244        "ALGORITHM": AlgorithmProperty,
3245        "AUTO_INCREMENT": AutoIncrementProperty,
3246        "CHARACTER SET": CharacterSetProperty,
3247        "CLUSTERED_BY": ClusteredByProperty,
3248        "COLLATE": CollateProperty,
3249        "COMMENT": SchemaCommentProperty,
3250        "CREDENTIALS": CredentialsProperty,
3251        "DEFINER": DefinerProperty,
3252        "DISTKEY": DistKeyProperty,
3253        "DISTRIBUTED_BY": DistributedByProperty,
3254        "DISTSTYLE": DistStyleProperty,
3255        "ENGINE": EngineProperty,
3256        "EXECUTE AS": ExecuteAsProperty,
3257        "FORMAT": FileFormatProperty,
3258        "LANGUAGE": LanguageProperty,
3259        "LOCATION": LocationProperty,
3260        "LOCK": LockProperty,
3261        "PARTITIONED_BY": PartitionedByProperty,
3262        "RETURNS": ReturnsProperty,
3263        "ROW_FORMAT": RowFormatProperty,
3264        "SORTKEY": SortKeyProperty,
3265        "ENCODE": EncodeProperty,
3266        "INCLUDE": IncludeProperty,
3267    }
3268
3269    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3270
3271    # CREATE property locations
3272    # Form: schema specified
3273    #   create [POST_CREATE]
3274    #     table a [POST_NAME]
3275    #     (b int) [POST_SCHEMA]
3276    #     with ([POST_WITH])
3277    #     index (b) [POST_INDEX]
3278    #
3279    # Form: alias selection
3280    #   create [POST_CREATE]
3281    #     table a [POST_NAME]
3282    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3283    #     index (c) [POST_INDEX]
3284    class Location(AutoName):
3285        POST_CREATE = auto()
3286        POST_NAME = auto()
3287        POST_SCHEMA = auto()
3288        POST_WITH = auto()
3289        POST_ALIAS = auto()
3290        POST_EXPRESSION = auto()
3291        POST_INDEX = auto()
3292        UNSUPPORTED = auto()
3293
3294    @classmethod
3295    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3296        expressions = []
3297        for key, value in properties_dict.items():
3298            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3299            if property_cls:
3300                expressions.append(property_cls(this=convert(value)))
3301            else:
3302                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3303
3304        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:
3294    @classmethod
3295    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3296        expressions = []
3297        for key, value in properties_dict.items():
3298            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3299            if property_cls:
3300                expressions.append(property_cls(this=convert(value)))
3301            else:
3302                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3303
3304        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3284    class Location(AutoName):
3285        POST_CREATE = auto()
3286        POST_NAME = auto()
3287        POST_SCHEMA = auto()
3288        POST_WITH = auto()
3289        POST_ALIAS = auto()
3290        POST_EXPRESSION = auto()
3291        POST_INDEX = auto()
3292        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):
3307class Qualify(Expression):
3308    pass
key = 'qualify'
class InputOutputFormat(Expression):
3311class InputOutputFormat(Expression):
3312    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3316class Return(Expression):
3317    pass
key = 'return'
class Reference(Expression):
3320class Reference(Expression):
3321    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3324class Tuple(Expression):
3325    arg_types = {"expressions": False}
3326
3327    def isin(
3328        self,
3329        *expressions: t.Any,
3330        query: t.Optional[ExpOrStr] = None,
3331        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3332        copy: bool = True,
3333        **opts,
3334    ) -> In:
3335        return In(
3336            this=maybe_copy(self, copy),
3337            expressions=[convert(e, copy=copy) for e in expressions],
3338            query=maybe_parse(query, copy=copy, **opts) if query else None,
3339            unnest=(
3340                Unnest(
3341                    expressions=[
3342                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3343                        for e in ensure_list(unnest)
3344                    ]
3345                )
3346                if unnest
3347                else None
3348            ),
3349        )
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:
3327    def isin(
3328        self,
3329        *expressions: t.Any,
3330        query: t.Optional[ExpOrStr] = None,
3331        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3332        copy: bool = True,
3333        **opts,
3334    ) -> In:
3335        return In(
3336            this=maybe_copy(self, copy),
3337            expressions=[convert(e, copy=copy) for e in expressions],
3338            query=maybe_parse(query, copy=copy, **opts) if query else None,
3339            unnest=(
3340                Unnest(
3341                    expressions=[
3342                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3343                        for e in ensure_list(unnest)
3344                    ]
3345                )
3346                if unnest
3347                else None
3348            ),
3349        )
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):
3380class QueryOption(Expression):
3381    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3385class WithTableHint(Expression):
3386    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3390class IndexTableHint(Expression):
3391    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3395class HistoricalData(Expression):
3396    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3400class Put(Expression):
3401    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3405class Get(Expression):
3406    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3409class Table(Expression):
3410    arg_types = {
3411        "this": False,
3412        "alias": False,
3413        "db": False,
3414        "catalog": False,
3415        "laterals": False,
3416        "joins": False,
3417        "pivots": False,
3418        "hints": False,
3419        "system_time": False,
3420        "version": False,
3421        "format": False,
3422        "pattern": False,
3423        "ordinality": False,
3424        "when": False,
3425        "only": False,
3426        "partition": False,
3427        "changes": False,
3428        "rows_from": False,
3429        "sample": False,
3430    }
3431
3432    @property
3433    def name(self) -> str:
3434        if not self.this or isinstance(self.this, Func):
3435            return ""
3436        return self.this.name
3437
3438    @property
3439    def db(self) -> str:
3440        return self.text("db")
3441
3442    @property
3443    def catalog(self) -> str:
3444        return self.text("catalog")
3445
3446    @property
3447    def selects(self) -> t.List[Expression]:
3448        return []
3449
3450    @property
3451    def named_selects(self) -> t.List[str]:
3452        return []
3453
3454    @property
3455    def parts(self) -> t.List[Expression]:
3456        """Return the parts of a table in order catalog, db, table."""
3457        parts: t.List[Expression] = []
3458
3459        for arg in ("catalog", "db", "this"):
3460            part = self.args.get(arg)
3461
3462            if isinstance(part, Dot):
3463                parts.extend(part.flatten())
3464            elif isinstance(part, Expression):
3465                parts.append(part)
3466
3467        return parts
3468
3469    def to_column(self, copy: bool = True) -> Expression:
3470        parts = self.parts
3471        last_part = parts[-1]
3472
3473        if isinstance(last_part, Identifier):
3474            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3475        else:
3476            # This branch will be reached if a function or array is wrapped in a `Table`
3477            col = last_part
3478
3479        alias = self.args.get("alias")
3480        if alias:
3481            col = alias_(col, alias.this, copy=copy)
3482
3483        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
3432    @property
3433    def name(self) -> str:
3434        if not self.this or isinstance(self.this, Func):
3435            return ""
3436        return self.this.name
db: str
3438    @property
3439    def db(self) -> str:
3440        return self.text("db")
catalog: str
3442    @property
3443    def catalog(self) -> str:
3444        return self.text("catalog")
selects: List[Expression]
3446    @property
3447    def selects(self) -> t.List[Expression]:
3448        return []
named_selects: List[str]
3450    @property
3451    def named_selects(self) -> t.List[str]:
3452        return []
parts: List[Expression]
3454    @property
3455    def parts(self) -> t.List[Expression]:
3456        """Return the parts of a table in order catalog, db, table."""
3457        parts: t.List[Expression] = []
3458
3459        for arg in ("catalog", "db", "this"):
3460            part = self.args.get(arg)
3461
3462            if isinstance(part, Dot):
3463                parts.extend(part.flatten())
3464            elif isinstance(part, Expression):
3465                parts.append(part)
3466
3467        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3469    def to_column(self, copy: bool = True) -> Expression:
3470        parts = self.parts
3471        last_part = parts[-1]
3472
3473        if isinstance(last_part, Identifier):
3474            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3475        else:
3476            # This branch will be reached if a function or array is wrapped in a `Table`
3477            col = last_part
3478
3479        alias = self.args.get("alias")
3480        if alias:
3481            col = alias_(col, alias.this, copy=copy)
3482
3483        return col
key = 'table'
class SetOperation(Query):
3486class SetOperation(Query):
3487    arg_types = {
3488        "with": False,
3489        "this": True,
3490        "expression": True,
3491        "distinct": False,
3492        "by_name": False,
3493        "side": False,
3494        "kind": False,
3495        "on": False,
3496        **QUERY_MODIFIERS,
3497    }
3498
3499    def select(
3500        self: S,
3501        *expressions: t.Optional[ExpOrStr],
3502        append: bool = True,
3503        dialect: DialectType = None,
3504        copy: bool = True,
3505        **opts,
3506    ) -> S:
3507        this = maybe_copy(self, copy)
3508        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3509        this.expression.unnest().select(
3510            *expressions, append=append, dialect=dialect, copy=False, **opts
3511        )
3512        return this
3513
3514    @property
3515    def named_selects(self) -> t.List[str]:
3516        return self.this.unnest().named_selects
3517
3518    @property
3519    def is_star(self) -> bool:
3520        return self.this.is_star or self.expression.is_star
3521
3522    @property
3523    def selects(self) -> t.List[Expression]:
3524        return self.this.unnest().selects
3525
3526    @property
3527    def left(self) -> Query:
3528        return self.this
3529
3530    @property
3531    def right(self) -> Query:
3532        return self.expression
3533
3534    @property
3535    def kind(self) -> str:
3536        return self.text("kind").upper()
3537
3538    @property
3539    def side(self) -> str:
3540        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:
3499    def select(
3500        self: S,
3501        *expressions: t.Optional[ExpOrStr],
3502        append: bool = True,
3503        dialect: DialectType = None,
3504        copy: bool = True,
3505        **opts,
3506    ) -> S:
3507        this = maybe_copy(self, copy)
3508        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3509        this.expression.unnest().select(
3510            *expressions, append=append, dialect=dialect, copy=False, **opts
3511        )
3512        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]
3514    @property
3515    def named_selects(self) -> t.List[str]:
3516        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3518    @property
3519    def is_star(self) -> bool:
3520        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3522    @property
3523    def selects(self) -> t.List[Expression]:
3524        return self.this.unnest().selects

Returns the query's projections.

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

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:
3599    def set_(
3600        self,
3601        *expressions: ExpOrStr,
3602        append: bool = True,
3603        dialect: DialectType = None,
3604        copy: bool = True,
3605        **opts,
3606    ) -> Update:
3607        """
3608        Append to or set the SET expressions.
3609
3610        Example:
3611            >>> Update().table("my_table").set_("x = 1").sql()
3612            'UPDATE my_table SET x = 1'
3613
3614        Args:
3615            *expressions: the SQL code strings to parse.
3616                If `Expression` instance(s) are passed, they will be used as-is.
3617                Multiple expressions are combined with a comma.
3618            append: if `True`, add the new expressions to any existing SET expressions.
3619                Otherwise, this resets the expressions.
3620            dialect: the dialect used to parse the input expressions.
3621            copy: if `False`, modify this expression instance in-place.
3622            opts: other options to use to parse the input expressions.
3623        """
3624        return _apply_list_builder(
3625            *expressions,
3626            instance=self,
3627            arg="expressions",
3628            append=append,
3629            into=Expression,
3630            prefix=None,
3631            dialect=dialect,
3632            copy=copy,
3633            **opts,
3634        )

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:
3636    def where(
3637        self,
3638        *expressions: t.Optional[ExpOrStr],
3639        append: bool = True,
3640        dialect: DialectType = None,
3641        copy: bool = True,
3642        **opts,
3643    ) -> Select:
3644        """
3645        Append to or set the WHERE expressions.
3646
3647        Example:
3648            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3649            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3650
3651        Args:
3652            *expressions: the SQL code strings to parse.
3653                If an `Expression` instance is passed, it will be used as-is.
3654                Multiple expressions are combined with an AND operator.
3655            append: if `True`, AND the new expressions to any existing expression.
3656                Otherwise, this resets the expression.
3657            dialect: the dialect used to parse the input expressions.
3658            copy: if `False`, modify this expression instance in-place.
3659            opts: other options to use to parse the input expressions.
3660
3661        Returns:
3662            Select: the modified expression.
3663        """
3664        return _apply_conjunction_builder(
3665            *expressions,
3666            instance=self,
3667            arg="where",
3668            append=append,
3669            into=Where,
3670            dialect=dialect,
3671            copy=copy,
3672            **opts,
3673        )

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:
3675    def from_(
3676        self,
3677        expression: t.Optional[ExpOrStr] = None,
3678        dialect: DialectType = None,
3679        copy: bool = True,
3680        **opts,
3681    ) -> Update:
3682        """
3683        Set the FROM expression.
3684
3685        Example:
3686            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3687            'UPDATE my_table SET x = 1 FROM baz'
3688
3689        Args:
3690            expression : the SQL code strings to parse.
3691                If a `From` instance is passed, this is used as-is.
3692                If another `Expression` instance is passed, it will be wrapped in a `From`.
3693                If nothing is passed in then a from is not applied to the expression
3694            dialect: the dialect used to parse the input expression.
3695            copy: if `False`, modify this expression instance in-place.
3696            opts: other options to use to parse the input expressions.
3697
3698        Returns:
3699            The modified Update expression.
3700        """
3701        if not expression:
3702            return maybe_copy(self, copy)
3703
3704        return _apply_builder(
3705            expression=expression,
3706            instance=self,
3707            arg="from",
3708            into=From,
3709            prefix="FROM",
3710            dialect=dialect,
3711            copy=copy,
3712            **opts,
3713        )

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:
3715    def with_(
3716        self,
3717        alias: ExpOrStr,
3718        as_: ExpOrStr,
3719        recursive: t.Optional[bool] = None,
3720        materialized: t.Optional[bool] = None,
3721        append: bool = True,
3722        dialect: DialectType = None,
3723        copy: bool = True,
3724        **opts,
3725    ) -> Update:
3726        """
3727        Append to or set the common table expressions.
3728
3729        Example:
3730            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3731            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3732
3733        Args:
3734            alias: the SQL code string to parse as the table name.
3735                If an `Expression` instance is passed, this is used as-is.
3736            as_: the SQL code string to parse as the table expression.
3737                If an `Expression` instance is passed, it will be used as-is.
3738            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3739            materialized: set the MATERIALIZED part of the expression.
3740            append: if `True`, add to any existing expressions.
3741                Otherwise, this resets the expressions.
3742            dialect: the dialect used to parse the input expression.
3743            copy: if `False`, modify this expression instance in-place.
3744            opts: other options to use to parse the input expressions.
3745
3746        Returns:
3747            The modified expression.
3748        """
3749        return _apply_cte_builder(
3750            self,
3751            alias,
3752            as_,
3753            recursive=recursive,
3754            materialized=materialized,
3755            append=append,
3756            dialect=dialect,
3757            copy=copy,
3758            **opts,
3759        )

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

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:
3839    def group_by(
3840        self,
3841        *expressions: t.Optional[ExpOrStr],
3842        append: bool = True,
3843        dialect: DialectType = None,
3844        copy: bool = True,
3845        **opts,
3846    ) -> Select:
3847        """
3848        Set the GROUP BY expression.
3849
3850        Example:
3851            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3852            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3853
3854        Args:
3855            *expressions: the SQL code strings to parse.
3856                If a `Group` instance is passed, this is used as-is.
3857                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3858                If nothing is passed in then a group by is not applied to the expression
3859            append: if `True`, add to any existing expressions.
3860                Otherwise, this flattens all the `Group` expression into a single expression.
3861            dialect: the dialect used to parse the input expression.
3862            copy: if `False`, modify this expression instance in-place.
3863            opts: other options to use to parse the input expressions.
3864
3865        Returns:
3866            The modified Select expression.
3867        """
3868        if not expressions:
3869            return self if not copy else self.copy()
3870
3871        return _apply_child_list_builder(
3872            *expressions,
3873            instance=self,
3874            arg="group",
3875            append=append,
3876            copy=copy,
3877            prefix="GROUP BY",
3878            into=Group,
3879            dialect=dialect,
3880            **opts,
3881        )

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:
3883    def sort_by(
3884        self,
3885        *expressions: t.Optional[ExpOrStr],
3886        append: bool = True,
3887        dialect: DialectType = None,
3888        copy: bool = True,
3889        **opts,
3890    ) -> Select:
3891        """
3892        Set the SORT BY expression.
3893
3894        Example:
3895            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3896            'SELECT x FROM tbl SORT BY x DESC'
3897
3898        Args:
3899            *expressions: the SQL code strings to parse.
3900                If a `Group` instance is passed, this is used as-is.
3901                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3902            append: if `True`, add to any existing expressions.
3903                Otherwise, this flattens all the `Order` expression into a single expression.
3904            dialect: the dialect used to parse the input expression.
3905            copy: if `False`, modify this expression instance in-place.
3906            opts: other options to use to parse the input expressions.
3907
3908        Returns:
3909            The modified Select expression.
3910        """
3911        return _apply_child_list_builder(
3912            *expressions,
3913            instance=self,
3914            arg="sort",
3915            append=append,
3916            copy=copy,
3917            prefix="SORT BY",
3918            into=Sort,
3919            dialect=dialect,
3920            **opts,
3921        )

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:
3923    def cluster_by(
3924        self,
3925        *expressions: t.Optional[ExpOrStr],
3926        append: bool = True,
3927        dialect: DialectType = None,
3928        copy: bool = True,
3929        **opts,
3930    ) -> Select:
3931        """
3932        Set the CLUSTER BY expression.
3933
3934        Example:
3935            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3936            'SELECT x FROM tbl CLUSTER BY x DESC'
3937
3938        Args:
3939            *expressions: the SQL code strings to parse.
3940                If a `Group` instance is passed, this is used as-is.
3941                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3942            append: if `True`, add to any existing expressions.
3943                Otherwise, this flattens all the `Order` expression into a single expression.
3944            dialect: the dialect used to parse the input expression.
3945            copy: if `False`, modify this expression instance in-place.
3946            opts: other options to use to parse the input expressions.
3947
3948        Returns:
3949            The modified Select expression.
3950        """
3951        return _apply_child_list_builder(
3952            *expressions,
3953            instance=self,
3954            arg="cluster",
3955            append=append,
3956            copy=copy,
3957            prefix="CLUSTER BY",
3958            into=Cluster,
3959            dialect=dialect,
3960            **opts,
3961        )

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:
3963    def select(
3964        self,
3965        *expressions: t.Optional[ExpOrStr],
3966        append: bool = True,
3967        dialect: DialectType = None,
3968        copy: bool = True,
3969        **opts,
3970    ) -> Select:
3971        return _apply_list_builder(
3972            *expressions,
3973            instance=self,
3974            arg="expressions",
3975            append=append,
3976            dialect=dialect,
3977            into=Expression,
3978            copy=copy,
3979            **opts,
3980        )

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:
3982    def lateral(
3983        self,
3984        *expressions: t.Optional[ExpOrStr],
3985        append: bool = True,
3986        dialect: DialectType = None,
3987        copy: bool = True,
3988        **opts,
3989    ) -> Select:
3990        """
3991        Append to or set the LATERAL expressions.
3992
3993        Example:
3994            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3995            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3996
3997        Args:
3998            *expressions: the SQL code strings to parse.
3999                If an `Expression` instance is passed, it will be used as-is.
4000            append: if `True`, add to any existing expressions.
4001                Otherwise, this resets the expressions.
4002            dialect: the dialect used to parse the input expressions.
4003            copy: if `False`, modify this expression instance in-place.
4004            opts: other options to use to parse the input expressions.
4005
4006        Returns:
4007            The modified Select expression.
4008        """
4009        return _apply_list_builder(
4010            *expressions,
4011            instance=self,
4012            arg="laterals",
4013            append=append,
4014            into=Lateral,
4015            prefix="LATERAL VIEW",
4016            dialect=dialect,
4017            copy=copy,
4018            **opts,
4019        )

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:
4021    def join(
4022        self,
4023        expression: ExpOrStr,
4024        on: t.Optional[ExpOrStr] = None,
4025        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4026        append: bool = True,
4027        join_type: t.Optional[str] = None,
4028        join_alias: t.Optional[Identifier | str] = None,
4029        dialect: DialectType = None,
4030        copy: bool = True,
4031        **opts,
4032    ) -> Select:
4033        """
4034        Append to or set the JOIN expressions.
4035
4036        Example:
4037            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4038            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4039
4040            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4041            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4042
4043            Use `join_type` to change the type of join:
4044
4045            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4046            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4047
4048        Args:
4049            expression: the SQL code string to parse.
4050                If an `Expression` instance is passed, it will be used as-is.
4051            on: optionally specify the join "on" criteria as a SQL string.
4052                If an `Expression` instance is passed, it will be used as-is.
4053            using: optionally specify the join "using" criteria as a SQL string.
4054                If an `Expression` instance is passed, it will be used as-is.
4055            append: if `True`, add to any existing expressions.
4056                Otherwise, this resets the expressions.
4057            join_type: if set, alter the parsed join type.
4058            join_alias: an optional alias for the joined source.
4059            dialect: the dialect used to parse the input expressions.
4060            copy: if `False`, modify this expression instance in-place.
4061            opts: other options to use to parse the input expressions.
4062
4063        Returns:
4064            Select: the modified expression.
4065        """
4066        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4067
4068        try:
4069            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4070        except ParseError:
4071            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4072
4073        join = expression if isinstance(expression, Join) else Join(this=expression)
4074
4075        if isinstance(join.this, Select):
4076            join.this.replace(join.this.subquery())
4077
4078        if join_type:
4079            method: t.Optional[Token]
4080            side: t.Optional[Token]
4081            kind: t.Optional[Token]
4082
4083            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4084
4085            if method:
4086                join.set("method", method.text)
4087            if side:
4088                join.set("side", side.text)
4089            if kind:
4090                join.set("kind", kind.text)
4091
4092        if on:
4093            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4094            join.set("on", on)
4095
4096        if using:
4097            join = _apply_list_builder(
4098                *ensure_list(using),
4099                instance=join,
4100                arg="using",
4101                append=append,
4102                copy=copy,
4103                into=Identifier,
4104                **opts,
4105            )
4106
4107        if join_alias:
4108            join.set("this", alias_(join.this, join_alias, table=True))
4109
4110        return _apply_list_builder(
4111            join,
4112            instance=self,
4113            arg="joins",
4114            append=append,
4115            copy=copy,
4116            **opts,
4117        )

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:
4119    def having(
4120        self,
4121        *expressions: t.Optional[ExpOrStr],
4122        append: bool = True,
4123        dialect: DialectType = None,
4124        copy: bool = True,
4125        **opts,
4126    ) -> Select:
4127        """
4128        Append to or set the HAVING expressions.
4129
4130        Example:
4131            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4132            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4133
4134        Args:
4135            *expressions: the SQL code strings to parse.
4136                If an `Expression` instance is passed, it will be used as-is.
4137                Multiple expressions are combined with an AND operator.
4138            append: if `True`, AND the new expressions to any existing expression.
4139                Otherwise, this resets the expression.
4140            dialect: the dialect used to parse the input expressions.
4141            copy: if `False`, modify this expression instance in-place.
4142            opts: other options to use to parse the input expressions.
4143
4144        Returns:
4145            The modified Select expression.
4146        """
4147        return _apply_conjunction_builder(
4148            *expressions,
4149            instance=self,
4150            arg="having",
4151            append=append,
4152            into=Having,
4153            dialect=dialect,
4154            copy=copy,
4155            **opts,
4156        )

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:
4158    def window(
4159        self,
4160        *expressions: t.Optional[ExpOrStr],
4161        append: bool = True,
4162        dialect: DialectType = None,
4163        copy: bool = True,
4164        **opts,
4165    ) -> Select:
4166        return _apply_list_builder(
4167            *expressions,
4168            instance=self,
4169            arg="windows",
4170            append=append,
4171            into=Window,
4172            dialect=dialect,
4173            copy=copy,
4174            **opts,
4175        )
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:
4177    def qualify(
4178        self,
4179        *expressions: t.Optional[ExpOrStr],
4180        append: bool = True,
4181        dialect: DialectType = None,
4182        copy: bool = True,
4183        **opts,
4184    ) -> Select:
4185        return _apply_conjunction_builder(
4186            *expressions,
4187            instance=self,
4188            arg="qualify",
4189            append=append,
4190            into=Qualify,
4191            dialect=dialect,
4192            copy=copy,
4193            **opts,
4194        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4196    def distinct(
4197        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4198    ) -> Select:
4199        """
4200        Set the OFFSET expression.
4201
4202        Example:
4203            >>> Select().from_("tbl").select("x").distinct().sql()
4204            'SELECT DISTINCT x FROM tbl'
4205
4206        Args:
4207            ons: the expressions to distinct on
4208            distinct: whether the Select should be distinct
4209            copy: if `False`, modify this expression instance in-place.
4210
4211        Returns:
4212            Select: the modified expression.
4213        """
4214        instance = maybe_copy(self, copy)
4215        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4216        instance.set("distinct", Distinct(on=on) if distinct else None)
4217        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:
4219    def ctas(
4220        self,
4221        table: ExpOrStr,
4222        properties: t.Optional[t.Dict] = None,
4223        dialect: DialectType = None,
4224        copy: bool = True,
4225        **opts,
4226    ) -> Create:
4227        """
4228        Convert this expression to a CREATE TABLE AS statement.
4229
4230        Example:
4231            >>> Select().select("*").from_("tbl").ctas("x").sql()
4232            'CREATE TABLE x AS SELECT * FROM tbl'
4233
4234        Args:
4235            table: the SQL code string to parse as the table name.
4236                If another `Expression` instance is passed, it will be used as-is.
4237            properties: an optional mapping of table properties
4238            dialect: the dialect used to parse the input table.
4239            copy: if `False`, modify this expression instance in-place.
4240            opts: other options to use to parse the input table.
4241
4242        Returns:
4243            The new Create expression.
4244        """
4245        instance = maybe_copy(self, copy)
4246        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4247
4248        properties_expression = None
4249        if properties:
4250            properties_expression = Properties.from_dict(properties)
4251
4252        return Create(
4253            this=table_expression,
4254            kind="TABLE",
4255            expression=instance,
4256            properties=properties_expression,
4257        )

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:
4259    def lock(self, update: bool = True, copy: bool = True) -> Select:
4260        """
4261        Set the locking read mode for this expression.
4262
4263        Examples:
4264            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4265            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4266
4267            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4268            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4269
4270        Args:
4271            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4272            copy: if `False`, modify this expression instance in-place.
4273
4274        Returns:
4275            The modified expression.
4276        """
4277        inst = maybe_copy(self, copy)
4278        inst.set("locks", [Lock(update=update)])
4279
4280        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:
4282    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4283        """
4284        Set hints for this expression.
4285
4286        Examples:
4287            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4288            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4289
4290        Args:
4291            hints: The SQL code strings to parse as the hints.
4292                If an `Expression` instance is passed, it will be used as-is.
4293            dialect: The dialect used to parse the hints.
4294            copy: If `False`, modify this expression instance in-place.
4295
4296        Returns:
4297            The modified expression.
4298        """
4299        inst = maybe_copy(self, copy)
4300        inst.set(
4301            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4302        )
4303
4304        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]
4306    @property
4307    def named_selects(self) -> t.List[str]:
4308        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
4310    @property
4311    def is_star(self) -> bool:
4312        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4314    @property
4315    def selects(self) -> t.List[Expression]:
4316        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4322class Subquery(DerivedTable, Query):
4323    arg_types = {
4324        "this": True,
4325        "alias": False,
4326        "with": False,
4327        **QUERY_MODIFIERS,
4328    }
4329
4330    def unnest(self):
4331        """Returns the first non subquery."""
4332        expression = self
4333        while isinstance(expression, Subquery):
4334            expression = expression.this
4335        return expression
4336
4337    def unwrap(self) -> Subquery:
4338        expression = self
4339        while expression.same_parent and expression.is_wrapper:
4340            expression = t.cast(Subquery, expression.parent)
4341        return expression
4342
4343    def select(
4344        self,
4345        *expressions: t.Optional[ExpOrStr],
4346        append: bool = True,
4347        dialect: DialectType = None,
4348        copy: bool = True,
4349        **opts,
4350    ) -> Subquery:
4351        this = maybe_copy(self, copy)
4352        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4353        return this
4354
4355    @property
4356    def is_wrapper(self) -> bool:
4357        """
4358        Whether this Subquery acts as a simple wrapper around another expression.
4359
4360        SELECT * FROM (((SELECT * FROM t)))
4361                      ^
4362                      This corresponds to a "wrapper" Subquery node
4363        """
4364        return all(v is None for k, v in self.args.items() if k != "this")
4365
4366    @property
4367    def is_star(self) -> bool:
4368        return self.this.is_star
4369
4370    @property
4371    def output_name(self) -> str:
4372        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):
4330    def unnest(self):
4331        """Returns the first non subquery."""
4332        expression = self
4333        while isinstance(expression, Subquery):
4334            expression = expression.this
4335        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4337    def unwrap(self) -> Subquery:
4338        expression = self
4339        while expression.same_parent and expression.is_wrapper:
4340            expression = t.cast(Subquery, expression.parent)
4341        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:
4343    def select(
4344        self,
4345        *expressions: t.Optional[ExpOrStr],
4346        append: bool = True,
4347        dialect: DialectType = None,
4348        copy: bool = True,
4349        **opts,
4350    ) -> Subquery:
4351        this = maybe_copy(self, copy)
4352        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4353        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
4355    @property
4356    def is_wrapper(self) -> bool:
4357        """
4358        Whether this Subquery acts as a simple wrapper around another expression.
4359
4360        SELECT * FROM (((SELECT * FROM t)))
4361                      ^
4362                      This corresponds to a "wrapper" Subquery node
4363        """
4364        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
4366    @property
4367    def is_star(self) -> bool:
4368        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4370    @property
4371    def output_name(self) -> str:
4372        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):
4375class TableSample(Expression):
4376    arg_types = {
4377        "expressions": False,
4378        "method": False,
4379        "bucket_numerator": False,
4380        "bucket_denominator": False,
4381        "bucket_field": False,
4382        "percent": False,
4383        "rows": False,
4384        "size": False,
4385        "seed": False,
4386    }
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):
4389class Tag(Expression):
4390    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4391
4392    arg_types = {
4393        "this": False,
4394        "prefix": False,
4395        "postfix": False,
4396    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4401class Pivot(Expression):
4402    arg_types = {
4403        "this": False,
4404        "alias": False,
4405        "expressions": False,
4406        "fields": False,
4407        "unpivot": False,
4408        "using": False,
4409        "group": False,
4410        "columns": False,
4411        "include_nulls": False,
4412        "default_on_null": False,
4413        "into": False,
4414    }
4415
4416    @property
4417    def unpivot(self) -> bool:
4418        return bool(self.args.get("unpivot"))
4419
4420    @property
4421    def fields(self) -> t.List[Expression]:
4422        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
4416    @property
4417    def unpivot(self) -> bool:
4418        return bool(self.args.get("unpivot"))
fields: List[Expression]
4420    @property
4421    def fields(self) -> t.List[Expression]:
4422        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4427class UnpivotColumns(Expression):
4428    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4431class Window(Condition):
4432    arg_types = {
4433        "this": True,
4434        "partition_by": False,
4435        "order": False,
4436        "spec": False,
4437        "alias": False,
4438        "over": False,
4439        "first": False,
4440    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4443class WindowSpec(Expression):
4444    arg_types = {
4445        "kind": False,
4446        "start": False,
4447        "start_side": False,
4448        "end": False,
4449        "end_side": False,
4450        "exclude": False,
4451    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4454class PreWhere(Expression):
4455    pass
key = 'prewhere'
class Where(Expression):
4458class Where(Expression):
4459    pass
key = 'where'
class Star(Expression):
4462class Star(Expression):
4463    arg_types = {"except": False, "replace": False, "rename": False}
4464
4465    @property
4466    def name(self) -> str:
4467        return "*"
4468
4469    @property
4470    def output_name(self) -> str:
4471        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4465    @property
4466    def name(self) -> str:
4467        return "*"
output_name: str
4469    @property
4470    def output_name(self) -> str:
4471        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):
4474class Parameter(Condition):
4475    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4478class SessionParameter(Condition):
4479    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4484class Placeholder(Condition):
4485    arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
4486
4487    @property
4488    def name(self) -> str:
4489        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False, 'jdbc': False}
name: str
4487    @property
4488    def name(self) -> str:
4489        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4492class Null(Condition):
4493    arg_types: t.Dict[str, t.Any] = {}
4494
4495    @property
4496    def name(self) -> str:
4497        return "NULL"
4498
4499    def to_py(self) -> Lit[None]:
4500        return None
arg_types: Dict[str, Any] = {}
name: str
4495    @property
4496    def name(self) -> str:
4497        return "NULL"
def to_py(self) -> Literal[None]:
4499    def to_py(self) -> Lit[None]:
4500        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4503class Boolean(Condition):
4504    def to_py(self) -> bool:
4505        return self.this
def to_py(self) -> bool:
4504    def to_py(self) -> bool:
4505        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
5029    @property
5030    def name(self) -> str:
5031        return self.expression.name
output_name: str
5033    @property
5034    def output_name(self) -> str:
5035        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:
5037    @classmethod
5038    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5039        """Build a Dot object with a sequence of expressions."""
5040        if len(expressions) < 2:
5041            raise ValueError("Dot requires >= 2 expressions.")
5042
5043        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]
5045    @property
5046    def parts(self) -> t.List[Expression]:
5047        """Return the parts of a table / column in order catalog, db, table."""
5048        this, *parts = self.flatten()
5049
5050        parts.reverse()
5051
5052        for arg in COLUMN_PARTS:
5053            part = this.args.get(arg)
5054
5055            if isinstance(part, Expression):
5056                parts.append(part)
5057
5058        parts.reverse()
5059        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):
5065class DPipe(Binary):
5066    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5069class EQ(Binary, Predicate):
5070    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5073class NullSafeEQ(Binary, Predicate):
5074    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5077class NullSafeNEQ(Binary, Predicate):
5078    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5082class PropertyEQ(Binary):
5083    pass
key = 'propertyeq'
class Distance(Binary):
5086class Distance(Binary):
5087    pass
key = 'distance'
class Escape(Binary):
5090class Escape(Binary):
5091    pass
key = 'escape'
class Glob(Binary, Predicate):
5094class Glob(Binary, Predicate):
5095    pass
key = 'glob'
class GT(Binary, Predicate):
5098class GT(Binary, Predicate):
5099    pass
key = 'gt'
class GTE(Binary, Predicate):
5102class GTE(Binary, Predicate):
5103    pass
key = 'gte'
class ILike(Binary, Predicate):
5106class ILike(Binary, Predicate):
5107    pass
key = 'ilike'
class IntDiv(Binary):
5110class IntDiv(Binary):
5111    pass
key = 'intdiv'
class Is(Binary, Predicate):
5114class Is(Binary, Predicate):
5115    pass
key = 'is'
class Kwarg(Binary):
5118class Kwarg(Binary):
5119    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5122class Like(Binary, Predicate):
5123    pass
key = 'like'
class LT(Binary, Predicate):
5126class LT(Binary, Predicate):
5127    pass
key = 'lt'
class LTE(Binary, Predicate):
5130class LTE(Binary, Predicate):
5131    pass
key = 'lte'
class Mod(Binary):
5134class Mod(Binary):
5135    pass
key = 'mod'
class Mul(Binary):
5138class Mul(Binary):
5139    pass
key = 'mul'
class NEQ(Binary, Predicate):
5142class NEQ(Binary, Predicate):
5143    pass
key = 'neq'
class Operator(Binary):
5147class Operator(Binary):
5148    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5151class SimilarTo(Binary, Predicate):
5152    pass
key = 'similarto'
class Slice(Binary):
5155class Slice(Binary):
5156    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5159class Sub(Binary):
5160    pass
key = 'sub'
class Unary(Condition):
5165class Unary(Condition):
5166    pass
key = 'unary'
class BitwiseNot(Unary):
5169class BitwiseNot(Unary):
5170    pass
key = 'bitwisenot'
class Not(Unary):
5173class Not(Unary):
5174    pass
key = 'not'
class Paren(Unary):
5177class Paren(Unary):
5178    @property
5179    def output_name(self) -> str:
5180        return self.this.name
output_name: str
5178    @property
5179    def output_name(self) -> str:
5180        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):
5183class Neg(Unary):
5184    def to_py(self) -> int | Decimal:
5185        if self.is_number:
5186            return self.this.to_py() * -1
5187        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5184    def to_py(self) -> int | Decimal:
5185        if self.is_number:
5186            return self.this.to_py() * -1
5187        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5190class Alias(Expression):
5191    arg_types = {"this": True, "alias": False}
5192
5193    @property
5194    def output_name(self) -> str:
5195        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5193    @property
5194    def output_name(self) -> str:
5195        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):
5200class PivotAlias(Alias):
5201    pass
key = 'pivotalias'
class PivotAny(Expression):
5206class PivotAny(Expression):
5207    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5210class Aliases(Expression):
5211    arg_types = {"this": True, "expressions": True}
5212
5213    @property
5214    def aliases(self):
5215        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5213    @property
5214    def aliases(self):
5215        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5219class AtIndex(Expression):
5220    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5223class AtTimeZone(Expression):
5224    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5227class FromTimeZone(Expression):
5228    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class FormatPhrase(Expression):
5231class FormatPhrase(Expression):
5232    """Format override for a column in Teradata.
5233    Can be expanded to additional dialects as needed
5234
5235    https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT
5236    """
5237
5238    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):
5241class Between(Predicate):
5242    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):
5245class Bracket(Condition):
5246    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5247    arg_types = {
5248        "this": True,
5249        "expressions": True,
5250        "offset": False,
5251        "safe": False,
5252        "returns_list_for_maps": False,
5253    }
5254
5255    @property
5256    def output_name(self) -> str:
5257        if len(self.expressions) == 1:
5258            return self.expressions[0].output_name
5259
5260        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5255    @property
5256    def output_name(self) -> str:
5257        if len(self.expressions) == 1:
5258            return self.expressions[0].output_name
5259
5260        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):
5263class Distinct(Expression):
5264    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5267class In(Predicate):
5268    arg_types = {
5269        "this": True,
5270        "expressions": False,
5271        "query": False,
5272        "unnest": False,
5273        "field": False,
5274        "is_global": False,
5275    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5279class ForIn(Expression):
5280    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5283class TimeUnit(Expression):
5284    """Automatically converts unit arg into a var."""
5285
5286    arg_types = {"unit": False}
5287
5288    UNABBREVIATED_UNIT_NAME = {
5289        "D": "DAY",
5290        "H": "HOUR",
5291        "M": "MINUTE",
5292        "MS": "MILLISECOND",
5293        "NS": "NANOSECOND",
5294        "Q": "QUARTER",
5295        "S": "SECOND",
5296        "US": "MICROSECOND",
5297        "W": "WEEK",
5298        "Y": "YEAR",
5299    }
5300
5301    VAR_LIKE = (Column, Literal, Var)
5302
5303    def __init__(self, **args):
5304        unit = args.get("unit")
5305        if type(unit) in self.VAR_LIKE:
5306            args["unit"] = Var(
5307                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5308            )
5309        elif isinstance(unit, Week):
5310            unit.set("this", Var(this=unit.this.name.upper()))
5311
5312        super().__init__(**args)
5313
5314    @property
5315    def unit(self) -> t.Optional[Var | IntervalSpan]:
5316        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5303    def __init__(self, **args):
5304        unit = args.get("unit")
5305        if type(unit) in self.VAR_LIKE:
5306            args["unit"] = Var(
5307                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5308            )
5309        elif isinstance(unit, Week):
5310            unit.set("this", Var(this=unit.this.name.upper()))
5311
5312        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]
5314    @property
5315    def unit(self) -> t.Optional[Var | IntervalSpan]:
5316        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5319class IntervalOp(TimeUnit):
5320    arg_types = {"unit": False, "expression": True}
5321
5322    def interval(self):
5323        return Interval(
5324            this=self.expression.copy(),
5325            unit=self.unit.copy() if self.unit else None,
5326        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5322    def interval(self):
5323        return Interval(
5324            this=self.expression.copy(),
5325            unit=self.unit.copy() if self.unit else None,
5326        )
key = 'intervalop'
class IntervalSpan(DataType):
5332class IntervalSpan(DataType):
5333    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5336class Interval(TimeUnit):
5337    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5340class IgnoreNulls(Expression):
5341    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5344class RespectNulls(Expression):
5345    pass
key = 'respectnulls'
class HavingMax(Expression):
5349class HavingMax(Expression):
5350    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5354class Func(Condition):
5355    """
5356    The base class for all function expressions.
5357
5358    Attributes:
5359        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5360            treated as a variable length argument and the argument's value will be stored as a list.
5361        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5362            function expression. These values are used to map this node to a name during parsing as
5363            well as to provide the function's name during SQL string generation. By default the SQL
5364            name is set to the expression's class name transformed to snake case.
5365    """
5366
5367    is_var_len_args = False
5368
5369    @classmethod
5370    def from_arg_list(cls, args):
5371        if cls.is_var_len_args:
5372            all_arg_keys = list(cls.arg_types)
5373            # If this function supports variable length argument treat the last argument as such.
5374            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5375            num_non_var = len(non_var_len_arg_keys)
5376
5377            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5378            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5379        else:
5380            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5381
5382        return cls(**args_dict)
5383
5384    @classmethod
5385    def sql_names(cls):
5386        if cls is Func:
5387            raise NotImplementedError(
5388                "SQL name is only supported by concrete function implementations"
5389            )
5390        if "_sql_names" not in cls.__dict__:
5391            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5392        return cls._sql_names
5393
5394    @classmethod
5395    def sql_name(cls):
5396        sql_names = cls.sql_names()
5397        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5398        return sql_names[0]
5399
5400    @classmethod
5401    def default_parser_mappings(cls):
5402        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):
5369    @classmethod
5370    def from_arg_list(cls, args):
5371        if cls.is_var_len_args:
5372            all_arg_keys = list(cls.arg_types)
5373            # If this function supports variable length argument treat the last argument as such.
5374            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5375            num_non_var = len(non_var_len_arg_keys)
5376
5377            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5378            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5379        else:
5380            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5381
5382        return cls(**args_dict)
@classmethod
def sql_names(cls):
5384    @classmethod
5385    def sql_names(cls):
5386        if cls is Func:
5387            raise NotImplementedError(
5388                "SQL name is only supported by concrete function implementations"
5389            )
5390        if "_sql_names" not in cls.__dict__:
5391            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5392        return cls._sql_names
@classmethod
def sql_name(cls):
5394    @classmethod
5395    def sql_name(cls):
5396        sql_names = cls.sql_names()
5397        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5398        return sql_names[0]
@classmethod
def default_parser_mappings(cls):
5400    @classmethod
5401    def default_parser_mappings(cls):
5402        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5405class Typeof(Func):
5406    pass
key = 'typeof'
class AggFunc(Func):
5409class AggFunc(Func):
5410    pass
key = 'aggfunc'
class BitwiseAndAgg(AggFunc):
5413class BitwiseAndAgg(AggFunc):
5414    _sql_names = ["BIT_AND"]
key = 'bitwiseandagg'
class BitwiseOrAgg(AggFunc):
5417class BitwiseOrAgg(AggFunc):
5418    _sql_names = ["BIT_OR"]
key = 'bitwiseoragg'
class BitwiseXorAgg(AggFunc):
5421class BitwiseXorAgg(AggFunc):
5422    _sql_names = ["BIT_XOR"]
key = 'bitwisexoragg'
class BitwiseCountAgg(AggFunc):
5425class BitwiseCountAgg(AggFunc):
5426    _sql_names = ["BIT_COUNT"]
key = 'bitwisecountagg'
class ByteLength(Func):
5429class ByteLength(Func):
5430    pass
key = 'bytelength'
class ArrayRemove(Func):
5433class ArrayRemove(Func):
5434    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5437class ParameterizedAgg(AggFunc):
5438    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5441class Abs(Func):
5442    pass
key = 'abs'
class ArgMax(AggFunc):
5445class ArgMax(AggFunc):
5446    arg_types = {"this": True, "expression": True, "count": False}
5447    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5450class ArgMin(AggFunc):
5451    arg_types = {"this": True, "expression": True, "count": False}
5452    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5455class ApproxTopK(AggFunc):
5456    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5459class Flatten(Func):
5460    pass
key = 'flatten'
class Transform(Func):
5464class Transform(Func):
5465    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Translate(Func):
5468class Translate(Func):
5469    arg_types = {"this": True, "from": True, "to": True}
arg_types = {'this': True, 'from': True, 'to': True}
key = 'translate'
class Grouping(AggFunc):
5472class Grouping(AggFunc):
5473    arg_types = {"expressions": True}
5474    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'grouping'
class Anonymous(Func):
5477class Anonymous(Func):
5478    arg_types = {"this": True, "expressions": False}
5479    is_var_len_args = True
5480
5481    @property
5482    def name(self) -> str:
5483        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
5481    @property
5482    def name(self) -> str:
5483        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5486class AnonymousAggFunc(AggFunc):
5487    arg_types = {"this": True, "expressions": False}
5488    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5492class CombinedAggFunc(AnonymousAggFunc):
5493    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5496class CombinedParameterizedAgg(ParameterizedAgg):
5497    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5502class Hll(AggFunc):
5503    arg_types = {"this": True, "expressions": False}
5504    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5507class ApproxDistinct(AggFunc):
5508    arg_types = {"this": True, "accuracy": False}
5509    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5512class Apply(Func):
5513    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5516class Array(Func):
5517    arg_types = {"expressions": False, "bracket_notation": False}
5518    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5521class Ascii(Func):
5522    pass
key = 'ascii'
class ToArray(Func):
5526class ToArray(Func):
5527    pass
key = 'toarray'
class List(Func):
5531class List(Func):
5532    arg_types = {"expressions": False}
5533    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5537class Pad(Func):
5538    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):
5543class ToChar(Func):
5544    arg_types = {
5545        "this": True,
5546        "format": False,
5547        "nlsparam": False,
5548        "is_numeric": False,
5549    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'is_numeric': False}
key = 'tochar'
class ToNumber(Func):
5554class ToNumber(Func):
5555    arg_types = {
5556        "this": True,
5557        "format": False,
5558        "nlsparam": False,
5559        "precision": False,
5560        "scale": False,
5561    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5565class ToDouble(Func):
5566    arg_types = {
5567        "this": True,
5568        "format": False,
5569    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5572class Columns(Func):
5573    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5577class Convert(Func):
5578    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5582class ConvertToCharset(Func):
5583    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5586class ConvertTimezone(Func):
5587    arg_types = {
5588        "source_tz": False,
5589        "target_tz": True,
5590        "timestamp": True,
5591        "options": False,
5592    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class CodePointsToString(Func):
5595class CodePointsToString(Func):
5596    pass
key = 'codepointstostring'
class GenerateSeries(Func):
5599class GenerateSeries(Func):
5600    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):
5606class ExplodingGenerateSeries(GenerateSeries):
5607    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5610class ArrayAgg(AggFunc):
5611    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5614class ArrayUniqueAgg(AggFunc):
5615    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5618class ArrayAll(Func):
5619    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5623class ArrayAny(Func):
5624    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5627class ArrayConcat(Func):
5628    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5629    arg_types = {"this": True, "expressions": False}
5630    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5633class ArrayConcatAgg(AggFunc):
5634    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5637class ArrayConstructCompact(Func):
5638    arg_types = {"expressions": True}
5639    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5642class ArrayContains(Binary, Func):
5643    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5646class ArrayContainsAll(Binary, Func):
5647    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5650class ArrayFilter(Func):
5651    arg_types = {"this": True, "expression": True}
5652    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5655class ArrayFirst(Func):
5656    pass
key = 'arrayfirst'
class ArrayLast(Func):
5659class ArrayLast(Func):
5660    pass
key = 'arraylast'
class ArrayReverse(Func):
5663class ArrayReverse(Func):
5664    pass
key = 'arrayreverse'
class ArraySlice(Func):
5667class ArraySlice(Func):
5668    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):
5671class ArrayToString(Func):
5672    arg_types = {"this": True, "expression": True, "null": False}
5673    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5676class ArrayIntersect(Func):
5677    arg_types = {"expressions": True}
5678    is_var_len_args = True
5679    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5682class StPoint(Func):
5683    arg_types = {"this": True, "expression": True, "null": False}
5684    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5687class StDistance(Func):
5688    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5692class String(Func):
5693    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5696class StringToArray(Func):
5697    arg_types = {"this": True, "expression": False, "null": False}
5698    _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):
5701class ArrayOverlaps(Binary, Func):
5702    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5705class ArraySize(Func):
5706    arg_types = {"this": True, "expression": False}
5707    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5710class ArraySort(Func):
5711    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5714class ArraySum(Func):
5715    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5718class ArrayUnionAgg(AggFunc):
5719    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5722class Avg(AggFunc):
5723    pass
key = 'avg'
class AnyValue(AggFunc):
5726class AnyValue(AggFunc):
5727    pass
key = 'anyvalue'
class Lag(AggFunc):
5730class Lag(AggFunc):
5731    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5734class Lead(AggFunc):
5735    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5740class First(AggFunc):
5741    pass
key = 'first'
class Last(AggFunc):
5744class Last(AggFunc):
5745    pass
key = 'last'
class FirstValue(AggFunc):
5748class FirstValue(AggFunc):
5749    pass
key = 'firstvalue'
class LastValue(AggFunc):
5752class LastValue(AggFunc):
5753    pass
key = 'lastvalue'
class NthValue(AggFunc):
5756class NthValue(AggFunc):
5757    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5760class Case(Func):
5761    arg_types = {"this": False, "ifs": True, "default": False}
5762
5763    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5764        instance = maybe_copy(self, copy)
5765        instance.append(
5766            "ifs",
5767            If(
5768                this=maybe_parse(condition, copy=copy, **opts),
5769                true=maybe_parse(then, copy=copy, **opts),
5770            ),
5771        )
5772        return instance
5773
5774    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5775        instance = maybe_copy(self, copy)
5776        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5777        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:
5763    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5764        instance = maybe_copy(self, copy)
5765        instance.append(
5766            "ifs",
5767            If(
5768                this=maybe_parse(condition, copy=copy, **opts),
5769                true=maybe_parse(then, copy=copy, **opts),
5770            ),
5771        )
5772        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5774    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5775        instance = maybe_copy(self, copy)
5776        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5777        return instance
key = 'case'
class Cast(Func):
5780class Cast(Func):
5781    arg_types = {
5782        "this": True,
5783        "to": True,
5784        "format": False,
5785        "safe": False,
5786        "action": False,
5787        "default": False,
5788    }
5789
5790    @property
5791    def name(self) -> str:
5792        return self.this.name
5793
5794    @property
5795    def to(self) -> DataType:
5796        return self.args["to"]
5797
5798    @property
5799    def output_name(self) -> str:
5800        return self.name
5801
5802    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5803        """
5804        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5805        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5806        array<int> != array<float>.
5807
5808        Args:
5809            dtypes: the data types to compare this Cast's DataType to.
5810
5811        Returns:
5812            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5813        """
5814        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5790    @property
5791    def name(self) -> str:
5792        return self.this.name
to: DataType
5794    @property
5795    def to(self) -> DataType:
5796        return self.args["to"]
output_name: str
5798    @property
5799    def output_name(self) -> str:
5800        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:
5802    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5803        """
5804        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5805        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5806        array<int> != array<float>.
5807
5808        Args:
5809            dtypes: the data types to compare this Cast's DataType to.
5810
5811        Returns:
5812            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5813        """
5814        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):
5817class TryCast(Cast):
5818    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):
5822class JSONCast(Cast):
5823    pass
key = 'jsoncast'
class JustifyDays(Func):
5826class JustifyDays(Func):
5827    pass
key = 'justifydays'
class JustifyHours(Func):
5830class JustifyHours(Func):
5831    pass
key = 'justifyhours'
class JustifyInterval(Func):
5834class JustifyInterval(Func):
5835    pass
key = 'justifyinterval'
class Try(Func):
5838class Try(Func):
5839    pass
key = 'try'
class CastToStrType(Func):
5842class CastToStrType(Func):
5843    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5847class TranslateCharacters(Expression):
5848    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5851class Collate(Binary, Func):
5852    pass
key = 'collate'
class Ceil(Func):
5855class Ceil(Func):
5856    arg_types = {"this": True, "decimals": False, "to": False}
5857    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5860class Coalesce(Func):
5861    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5862    is_var_len_args = True
5863    _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):
5866class Chr(Func):
5867    arg_types = {"expressions": True, "charset": False}
5868    is_var_len_args = True
5869    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5872class Concat(Func):
5873    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5874    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5877class ConcatWs(Concat):
5878    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5881class Contains(Func):
5882    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5886class ConnectByRoot(Func):
5887    pass
key = 'connectbyroot'
class Count(AggFunc):
5890class Count(AggFunc):
5891    arg_types = {"this": False, "expressions": False, "big_int": False}
5892    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5895class CountIf(AggFunc):
5896    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5900class Cbrt(Func):
5901    pass
key = 'cbrt'
class CurrentDate(Func):
5904class CurrentDate(Func):
5905    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5908class CurrentDatetime(Func):
5909    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5912class CurrentTime(Func):
5913    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5916class CurrentTimestamp(Func):
5917    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
5920class CurrentTimestampLTZ(Func):
5921    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
5924class CurrentSchema(Func):
5925    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5928class CurrentUser(Func):
5929    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5932class DateAdd(Func, IntervalOp):
5933    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5936class DateBin(Func, IntervalOp):
5937    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
5940class DateSub(Func, IntervalOp):
5941    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5944class DateDiff(Func, TimeUnit):
5945    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5946    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):
5949class DateTrunc(Func):
5950    arg_types = {"unit": True, "this": True, "zone": False}
5951
5952    def __init__(self, **args):
5953        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5954        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5955        unabbreviate = args.pop("unabbreviate", True)
5956
5957        unit = args.get("unit")
5958        if isinstance(unit, TimeUnit.VAR_LIKE):
5959            unit_name = unit.name.upper()
5960            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5961                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5962
5963            args["unit"] = Literal.string(unit_name)
5964
5965        super().__init__(**args)
5966
5967    @property
5968    def unit(self) -> Expression:
5969        return self.args["unit"]
DateTrunc(**args)
5952    def __init__(self, **args):
5953        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5954        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5955        unabbreviate = args.pop("unabbreviate", True)
5956
5957        unit = args.get("unit")
5958        if isinstance(unit, TimeUnit.VAR_LIKE):
5959            unit_name = unit.name.upper()
5960            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5961                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5962
5963            args["unit"] = Literal.string(unit_name)
5964
5965        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5967    @property
5968    def unit(self) -> Expression:
5969        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5974class Datetime(Func):
5975    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5978class DatetimeAdd(Func, IntervalOp):
5979    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5982class DatetimeSub(Func, IntervalOp):
5983    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5986class DatetimeDiff(Func, TimeUnit):
5987    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5990class DatetimeTrunc(Func, TimeUnit):
5991    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DateFromUnixDate(Func):
5994class DateFromUnixDate(Func):
5995    pass
key = 'datefromunixdate'
class DayOfWeek(Func):
5998class DayOfWeek(Func):
5999    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
6004class DayOfWeekIso(Func):
6005    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
6008class DayOfMonth(Func):
6009    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
6012class DayOfYear(Func):
6013    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
6016class ToDays(Func):
6017    pass
key = 'todays'
class WeekOfYear(Func):
6020class WeekOfYear(Func):
6021    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
6024class MonthsBetween(Func):
6025    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
6028class MakeInterval(Func):
6029    arg_types = {
6030        "year": False,
6031        "month": False,
6032        "day": False,
6033        "hour": False,
6034        "minute": False,
6035        "second": False,
6036    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
6039class LastDay(Func, TimeUnit):
6040    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
6041    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
6044class Extract(Func):
6045    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6048class Exists(Func, SubqueryPredicate):
6049    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6052class Timestamp(Func):
6053    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6056class TimestampAdd(Func, TimeUnit):
6057    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6060class TimestampSub(Func, TimeUnit):
6061    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6064class TimestampDiff(Func, TimeUnit):
6065    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6066    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6069class TimestampTrunc(Func, TimeUnit):
6070    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6073class TimeAdd(Func, TimeUnit):
6074    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6077class TimeSub(Func, TimeUnit):
6078    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6081class TimeDiff(Func, TimeUnit):
6082    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6085class TimeTrunc(Func, TimeUnit):
6086    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6089class DateFromParts(Func):
6090    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6091    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6094class TimeFromParts(Func):
6095    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6096    arg_types = {
6097        "hour": True,
6098        "min": True,
6099        "sec": True,
6100        "nano": False,
6101        "fractions": False,
6102        "precision": False,
6103    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6106class DateStrToDate(Func):
6107    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6110class DateToDateStr(Func):
6111    pass
key = 'datetodatestr'
class DateToDi(Func):
6114class DateToDi(Func):
6115    pass
key = 'datetodi'
class Date(Func):
6119class Date(Func):
6120    arg_types = {"this": False, "zone": False, "expressions": False}
6121    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6124class Day(Func):
6125    pass
key = 'day'
class Decode(Func):
6128class Decode(Func):
6129    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6132class DecodeCase(Func):
6133    arg_types = {"expressions": True}
6134    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DiToDate(Func):
6137class DiToDate(Func):
6138    pass
key = 'ditodate'
class Encode(Func):
6141class Encode(Func):
6142    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6145class Exp(Func):
6146    pass
key = 'exp'
class Explode(Func, UDTF):
6150class Explode(Func, UDTF):
6151    arg_types = {"this": True, "expressions": False}
6152    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6156class Inline(Func):
6157    pass
key = 'inline'
class ExplodeOuter(Explode):
6160class ExplodeOuter(Explode):
6161    pass
key = 'explodeouter'
class Posexplode(Explode):
6164class Posexplode(Explode):
6165    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6168class PosexplodeOuter(Posexplode, ExplodeOuter):
6169    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6172class PositionalColumn(Expression):
6173    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6176class Unnest(Func, UDTF):
6177    arg_types = {
6178        "expressions": True,
6179        "alias": False,
6180        "offset": False,
6181        "explode_array": False,
6182    }
6183
6184    @property
6185    def selects(self) -> t.List[Expression]:
6186        columns = super().selects
6187        offset = self.args.get("offset")
6188        if offset:
6189            columns = columns + [to_identifier("offset") if offset is True else offset]
6190        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6184    @property
6185    def selects(self) -> t.List[Expression]:
6186        columns = super().selects
6187        offset = self.args.get("offset")
6188        if offset:
6189            columns = columns + [to_identifier("offset") if offset is True else offset]
6190        return columns
key = 'unnest'
class Floor(Func):
6193class Floor(Func):
6194    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6197class FromBase64(Func):
6198    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6201class FeaturesAtTime(Func):
6202    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 ToBase64(Func):
6205class ToBase64(Func):
6206    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6210class FromISO8601Timestamp(Func):
6211    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6214class GapFill(Func):
6215    arg_types = {
6216        "this": True,
6217        "ts_column": True,
6218        "bucket_width": True,
6219        "partitioning_columns": False,
6220        "value_columns": False,
6221        "origin": False,
6222        "ignore_nulls": False,
6223    }
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):
6227class GenerateDateArray(Func):
6228    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6232class GenerateTimestampArray(Func):
6233    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class GetExtract(Func):
6237class GetExtract(Func):
6238    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'getextract'
class Greatest(Func):
6241class Greatest(Func):
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 = 'greatest'
class OverflowTruncateBehavior(Expression):
6248class OverflowTruncateBehavior(Expression):
6249    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6252class GroupConcat(AggFunc):
6253    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6256class Hex(Func):
6257    pass
key = 'hex'
class LowerHex(Hex):
6260class LowerHex(Hex):
6261    pass
key = 'lowerhex'
class And(Connector, Func):
6264class And(Connector, Func):
6265    pass
key = 'and'
class Or(Connector, Func):
6268class Or(Connector, Func):
6269    pass
key = 'or'
class Xor(Connector, Func):
6272class Xor(Connector, Func):
6273    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6276class If(Func):
6277    arg_types = {"this": True, "true": True, "false": False}
6278    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6281class Nullif(Func):
6282    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6285class Initcap(Func):
6286    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6289class IsAscii(Func):
6290    pass
key = 'isascii'
class IsNan(Func):
6293class IsNan(Func):
6294    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6298class Int64(Func):
6299    pass
key = 'int64'
class IsInf(Func):
6302class IsInf(Func):
6303    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6307class JSON(Expression):
6308    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6311class JSONPath(Expression):
6312    arg_types = {"expressions": True, "escape": False}
6313
6314    @property
6315    def output_name(self) -> str:
6316        last_segment = self.expressions[-1].this
6317        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6314    @property
6315    def output_name(self) -> str:
6316        last_segment = self.expressions[-1].this
6317        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):
6320class JSONPathPart(Expression):
6321    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6324class JSONPathFilter(JSONPathPart):
6325    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6328class JSONPathKey(JSONPathPart):
6329    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6332class JSONPathRecursive(JSONPathPart):
6333    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6336class JSONPathRoot(JSONPathPart):
6337    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6340class JSONPathScript(JSONPathPart):
6341    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6344class JSONPathSlice(JSONPathPart):
6345    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6348class JSONPathSelector(JSONPathPart):
6349    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6352class JSONPathSubscript(JSONPathPart):
6353    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6356class JSONPathUnion(JSONPathPart):
6357    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6360class JSONPathWildcard(JSONPathPart):
6361    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6364class FormatJson(Expression):
6365    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6368class JSONKeyValue(Expression):
6369    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6372class JSONObject(Func):
6373    arg_types = {
6374        "expressions": False,
6375        "null_handling": False,
6376        "unique_keys": False,
6377        "return_type": False,
6378        "encoding": False,
6379    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6382class JSONObjectAgg(AggFunc):
6383    arg_types = {
6384        "expressions": False,
6385        "null_handling": False,
6386        "unique_keys": False,
6387        "return_type": False,
6388        "encoding": False,
6389    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6393class JSONBObjectAgg(AggFunc):
6394    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6398class JSONArray(Func):
6399    arg_types = {
6400        "expressions": False,
6401        "null_handling": False,
6402        "return_type": False,
6403        "strict": False,
6404    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6408class JSONArrayAgg(Func):
6409    arg_types = {
6410        "this": True,
6411        "order": False,
6412        "null_handling": False,
6413        "return_type": False,
6414        "strict": False,
6415    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6418class JSONExists(Func):
6419    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):
6424class JSONColumnDef(Expression):
6425    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):
6428class JSONSchema(Expression):
6429    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6433class JSONValue(Expression):
6434    arg_types = {
6435        "this": True,
6436        "path": True,
6437        "returning": False,
6438        "on_condition": False,
6439    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6442class JSONValueArray(Func):
6443    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6447class JSONTable(Func):
6448    arg_types = {
6449        "this": True,
6450        "schema": True,
6451        "path": False,
6452        "error_handling": False,
6453        "empty_handling": False,
6454    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6459class JSONType(Func):
6460    arg_types = {"this": True, "expression": False}
6461    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6465class ObjectInsert(Func):
6466    arg_types = {
6467        "this": True,
6468        "key": True,
6469        "value": True,
6470        "update_flag": False,
6471    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6474class OpenJSONColumnDef(Expression):
6475    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):
6478class OpenJSON(Func):
6479    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6482class JSONBContains(Binary, Func):
6483    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6486class JSONBExists(Func):
6487    arg_types = {"this": True, "path": True}
6488    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6491class JSONExtract(Binary, Func):
6492    arg_types = {
6493        "this": True,
6494        "expression": True,
6495        "only_json_types": False,
6496        "expressions": False,
6497        "variant_extract": False,
6498        "json_query": False,
6499        "option": False,
6500        "quote": False,
6501        "on_condition": False,
6502        "requires_json": False,
6503    }
6504    _sql_names = ["JSON_EXTRACT"]
6505    is_var_len_args = True
6506
6507    @property
6508    def output_name(self) -> str:
6509        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
6507    @property
6508    def output_name(self) -> str:
6509        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):
6513class JSONExtractQuote(Expression):
6514    arg_types = {
6515        "option": True,
6516        "scalar": False,
6517    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6520class JSONExtractArray(Func):
6521    arg_types = {"this": True, "expression": False}
6522    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6525class JSONExtractScalar(Binary, Func):
6526    arg_types = {
6527        "this": True,
6528        "expression": True,
6529        "only_json_types": False,
6530        "expressions": False,
6531        "json_type": False,
6532    }
6533    _sql_names = ["JSON_EXTRACT_SCALAR"]
6534    is_var_len_args = True
6535
6536    @property
6537    def output_name(self) -> str:
6538        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
6536    @property
6537    def output_name(self) -> str:
6538        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):
6541class JSONBExtract(Binary, Func):
6542    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6545class JSONBExtractScalar(Binary, Func):
6546    arg_types = {"this": True, "expression": True, "json_type": False}
6547    _sql_names = ["JSONB_EXTRACT_SCALAR"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonbextractscalar'
class JSONFormat(Func):
6550class JSONFormat(Func):
6551    arg_types = {"this": False, "options": False, "is_json": False}
6552    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6556class JSONArrayContains(Binary, Predicate, Func):
6557    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6560class ParseJSON(Func):
6561    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6562    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6563    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6564    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class ParseTime(Func):
6567class ParseTime(Func):
6568    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'parsetime'
class ParseDatetime(Func):
6571class ParseDatetime(Func):
6572    arg_types = {"this": True, "format": False, "zone": False}
arg_types = {'this': True, 'format': False, 'zone': False}
key = 'parsedatetime'
class Least(Func):
6575class Least(Func):
6576    arg_types = {"this": True, "expressions": False}
6577    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6580class Left(Func):
6581    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Reverse(Func):
6588class Reverse(Func):
6589    pass
key = 'reverse'
class Length(Func):
6592class Length(Func):
6593    arg_types = {"this": True, "binary": False, "encoding": False}
6594    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6597class Levenshtein(Func):
6598    arg_types = {
6599        "this": True,
6600        "expression": False,
6601        "ins_cost": False,
6602        "del_cost": False,
6603        "sub_cost": False,
6604        "max_dist": False,
6605    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6608class Ln(Func):
6609    pass
key = 'ln'
class Log(Func):
6612class Log(Func):
6613    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6616class LogicalOr(AggFunc):
6617    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6620class LogicalAnd(AggFunc):
6621    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6624class Lower(Func):
6625    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6628class Map(Func):
6629    arg_types = {"keys": False, "values": False}
6630
6631    @property
6632    def keys(self) -> t.List[Expression]:
6633        keys = self.args.get("keys")
6634        return keys.expressions if keys else []
6635
6636    @property
6637    def values(self) -> t.List[Expression]:
6638        values = self.args.get("values")
6639        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6631    @property
6632    def keys(self) -> t.List[Expression]:
6633        keys = self.args.get("keys")
6634        return keys.expressions if keys else []
values: List[Expression]
6636    @property
6637    def values(self) -> t.List[Expression]:
6638        values = self.args.get("values")
6639        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6643class ToMap(Func):
6644    pass
key = 'tomap'
class MapFromEntries(Func):
6647class MapFromEntries(Func):
6648    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6652class ScopeResolution(Expression):
6653    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6656class Stream(Expression):
6657    pass
key = 'stream'
class StarMap(Func):
6660class StarMap(Func):
6661    pass
key = 'starmap'
class VarMap(Func):
6664class VarMap(Func):
6665    arg_types = {"keys": True, "values": True}
6666    is_var_len_args = True
6667
6668    @property
6669    def keys(self) -> t.List[Expression]:
6670        return self.args["keys"].expressions
6671
6672    @property
6673    def values(self) -> t.List[Expression]:
6674        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6668    @property
6669    def keys(self) -> t.List[Expression]:
6670        return self.args["keys"].expressions
values: List[Expression]
6672    @property
6673    def values(self) -> t.List[Expression]:
6674        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6678class MatchAgainst(Func):
6679    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6682class Max(AggFunc):
6683    arg_types = {"this": True, "expressions": False}
6684    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6687class MD5(Func):
6688    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6692class MD5Digest(Func):
6693    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6696class Median(AggFunc):
6697    pass
key = 'median'
class Min(AggFunc):
6700class Min(AggFunc):
6701    arg_types = {"this": True, "expressions": False}
6702    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6705class Month(Func):
6706    pass
key = 'month'
class AddMonths(Func):
6709class AddMonths(Func):
6710    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6713class Nvl2(Func):
6714    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6717class Normalize(Func):
6718    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6721class Overlay(Func):
6722    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):
6726class Predict(Func):
6727    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6730class Pow(Binary, Func):
6731    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6734class PercentileCont(AggFunc):
6735    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6738class PercentileDisc(AggFunc):
6739    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6742class Quantile(AggFunc):
6743    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6746class ApproxQuantile(Quantile):
6747    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
6750class Quarter(Func):
6751    pass
key = 'quarter'
class Rand(Func):
6756class Rand(Func):
6757    _sql_names = ["RAND", "RANDOM"]
6758    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6761class Randn(Func):
6762    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6765class RangeN(Func):
6766    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6769class ReadCSV(Func):
6770    _sql_names = ["READ_CSV"]
6771    is_var_len_args = True
6772    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6775class Reduce(Func):
6776    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):
6779class RegexpExtract(Func):
6780    arg_types = {
6781        "this": True,
6782        "expression": True,
6783        "position": False,
6784        "occurrence": False,
6785        "parameters": False,
6786        "group": False,
6787    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6790class RegexpExtractAll(Func):
6791    arg_types = {
6792        "this": True,
6793        "expression": True,
6794        "position": False,
6795        "occurrence": False,
6796        "parameters": False,
6797        "group": False,
6798    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6801class RegexpReplace(Func):
6802    arg_types = {
6803        "this": True,
6804        "expression": True,
6805        "replacement": False,
6806        "position": False,
6807        "occurrence": False,
6808        "modifiers": False,
6809    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6812class RegexpLike(Binary, Func):
6813    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6816class RegexpILike(Binary, Func):
6817    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6822class RegexpSplit(Func):
6823    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6826class Repeat(Func):
6827    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
6831class Replace(Func):
6832    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
6837class Round(Func):
6838    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6841class RowNumber(Func):
6842    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6845class SafeDivide(Func):
6846    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6849class SHA(Func):
6850    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6853class SHA2(Func):
6854    _sql_names = ["SHA2"]
6855    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6858class Sign(Func):
6859    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6862class SortArray(Func):
6863    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Soundex(Func):
6866class Soundex(Func):
6867    pass
key = 'soundex'
class Split(Func):
6870class Split(Func):
6871    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6875class SplitPart(Func):
6876    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6881class Substring(Func):
6882    _sql_names = ["SUBSTRING", "SUBSTR"]
6883    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
6886class SubstringIndex(Func):
6887    """
6888    SUBSTRING_INDEX(str, delim, count)
6889
6890    *count* > 0  → left slice before the *count*-th delimiter
6891    *count* < 0  → right slice after the |count|-th delimiter
6892    """
6893
6894    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):
6897class StandardHash(Func):
6898    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6901class StartsWith(Func):
6902    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6903    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
6906class EndsWith(Func):
6907    _sql_names = ["ENDS_WITH", "ENDSWITH"]
6908    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
6911class StrPosition(Func):
6912    arg_types = {
6913        "this": True,
6914        "substr": True,
6915        "position": False,
6916        "occurrence": False,
6917    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6920class StrToDate(Func):
6921    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6924class StrToTime(Func):
6925    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):
6930class StrToUnix(Func):
6931    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6936class StrToMap(Func):
6937    arg_types = {
6938        "this": True,
6939        "pair_delim": False,
6940        "key_value_delim": False,
6941        "duplicate_resolution_callback": False,
6942    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6945class NumberToStr(Func):
6946    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6949class FromBase(Func):
6950    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
6953class Space(Func):
6954    """
6955    SPACE(n) → string consisting of n blank characters
6956    """
6957
6958    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
6961class Struct(Func):
6962    arg_types = {"expressions": False}
6963    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6966class StructExtract(Func):
6967    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6972class Stuff(Func):
6973    _sql_names = ["STUFF", "INSERT"]
6974    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):
6977class Sum(AggFunc):
6978    pass
key = 'sum'
class Sqrt(Func):
6981class Sqrt(Func):
6982    pass
key = 'sqrt'
class Stddev(AggFunc):
6985class Stddev(AggFunc):
6986    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6989class StddevPop(AggFunc):
6990    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6993class StddevSamp(AggFunc):
6994    pass
key = 'stddevsamp'
class Time(Func):
6998class Time(Func):
6999    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
7002class TimeToStr(Func):
7003    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):
7006class TimeToTimeStr(Func):
7007    pass
key = 'timetotimestr'
class TimeToUnix(Func):
7010class TimeToUnix(Func):
7011    pass
key = 'timetounix'
class TimeStrToDate(Func):
7014class TimeStrToDate(Func):
7015    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
7018class TimeStrToTime(Func):
7019    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
7022class TimeStrToUnix(Func):
7023    pass
key = 'timestrtounix'
class Trim(Func):
7026class Trim(Func):
7027    arg_types = {
7028        "this": True,
7029        "expression": False,
7030        "position": False,
7031        "collation": False,
7032    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
7035class TsOrDsAdd(Func, TimeUnit):
7036    # return_type is used to correctly cast the arguments of this expression when transpiling it
7037    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
7038
7039    @property
7040    def return_type(self) -> DataType:
7041        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
7039    @property
7040    def return_type(self) -> DataType:
7041        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
7044class TsOrDsDiff(Func, TimeUnit):
7045    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
7048class TsOrDsToDateStr(Func):
7049    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
7052class TsOrDsToDate(Func):
7053    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
7056class TsOrDsToDatetime(Func):
7057    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
7060class TsOrDsToTime(Func):
7061    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
7064class TsOrDsToTimestamp(Func):
7065    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
7068class TsOrDiToDi(Func):
7069    pass
key = 'tsorditodi'
class Unhex(Func):
7072class Unhex(Func):
7073    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7076class Unicode(Func):
7077    pass
key = 'unicode'
class UnixDate(Func):
7081class UnixDate(Func):
7082    pass
key = 'unixdate'
class UnixToStr(Func):
7085class UnixToStr(Func):
7086    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7091class UnixToTime(Func):
7092    arg_types = {
7093        "this": True,
7094        "scale": False,
7095        "zone": False,
7096        "hours": False,
7097        "minutes": False,
7098        "format": False,
7099    }
7100
7101    SECONDS = Literal.number(0)
7102    DECIS = Literal.number(1)
7103    CENTIS = Literal.number(2)
7104    MILLIS = Literal.number(3)
7105    DECIMILLIS = Literal.number(4)
7106    CENTIMILLIS = Literal.number(5)
7107    MICROS = Literal.number(6)
7108    DECIMICROS = Literal.number(7)
7109    CENTIMICROS = Literal.number(8)
7110    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):
7113class UnixToTimeStr(Func):
7114    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7117class UnixSeconds(Func):
7118    pass
key = 'unixseconds'
class UnixMicros(Func):
7121class UnixMicros(Func):
7122    pass
key = 'unixmicros'
class UnixMillis(Func):
7125class UnixMillis(Func):
7126    pass
key = 'unixmillis'
class Uuid(Func):
7129class Uuid(Func):
7130    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7131
7132    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7135class TimestampFromParts(Func):
7136    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7137    arg_types = {
7138        "year": True,
7139        "month": True,
7140        "day": True,
7141        "hour": True,
7142        "min": True,
7143        "sec": True,
7144        "nano": False,
7145        "zone": False,
7146        "milli": False,
7147    }
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):
7150class Upper(Func):
7151    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7154class Corr(Binary, AggFunc):
7155    pass
key = 'corr'
class Variance(AggFunc):
7158class Variance(AggFunc):
7159    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7162class VariancePop(AggFunc):
7163    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7166class CovarSamp(Binary, AggFunc):
7167    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7170class CovarPop(Binary, AggFunc):
7171    pass
key = 'covarpop'
class Week(Func):
7174class Week(Func):
7175    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class WeekStart(Expression):
7178class WeekStart(Expression):
7179    pass
key = 'weekstart'
class XMLElement(Func):
7182class XMLElement(Func):
7183    _sql_names = ["XMLELEMENT"]
7184    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7187class XMLTable(Func):
7188    arg_types = {
7189        "this": True,
7190        "namespaces": False,
7191        "passing": False,
7192        "columns": False,
7193        "by_ref": False,
7194    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7197class XMLNamespace(Expression):
7198    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7202class XMLKeyValueOption(Expression):
7203    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7206class Year(Func):
7207    pass
key = 'year'
class Use(Expression):
7210class Use(Expression):
7211    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7214class Merge(DML):
7215    arg_types = {
7216        "this": True,
7217        "using": True,
7218        "on": True,
7219        "whens": True,
7220        "with": False,
7221        "returning": False,
7222    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7225class When(Expression):
7226    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):
7229class Whens(Expression):
7230    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7231
7232    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7237class NextValueFor(Func):
7238    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7243class Semicolon(Expression):
7244    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7249class TableColumn(Expression):
7250    pass
key = 'tablecolumn'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class '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 '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 '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 'DiToDate'>, <class 'Encode'>, <class 'EndsWith'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <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 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONType'>, <class 'JSONValueArray'>, <class 'JustifyDays'>, <class 'JustifyHours'>, <class 'JustifyInterval'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseDatetime'>, <class 'ParseJSON'>, <class 'ParseTime'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Replace'>, <class 'Reverse'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <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 'ToBase64'>, <class 'ToChar'>, <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 '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_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_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_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'>, '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'>, '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'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, '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_CONTAINS': <class 'JSONArrayContains'>, '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_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_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, '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'>, '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'>, '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_DATETIME': <class 'ParseDatetime'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PARSE_TIME': <class 'ParseTime'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, '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_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_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, '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'>, '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:
7290def maybe_parse(
7291    sql_or_expression: ExpOrStr,
7292    *,
7293    into: t.Optional[IntoType] = None,
7294    dialect: DialectType = None,
7295    prefix: t.Optional[str] = None,
7296    copy: bool = False,
7297    **opts,
7298) -> Expression:
7299    """Gracefully handle a possible string or expression.
7300
7301    Example:
7302        >>> maybe_parse("1")
7303        Literal(this=1, is_string=False)
7304        >>> maybe_parse(to_identifier("x"))
7305        Identifier(this=x, quoted=False)
7306
7307    Args:
7308        sql_or_expression: the SQL code string or an expression
7309        into: the SQLGlot Expression to parse into
7310        dialect: the dialect used to parse the input expressions (in the case that an
7311            input expression is a SQL string).
7312        prefix: a string to prefix the sql with before it gets parsed
7313            (automatically includes a space)
7314        copy: whether to copy the expression.
7315        **opts: other options to use to parse the input expressions (again, in the case
7316            that an input expression is a SQL string).
7317
7318    Returns:
7319        Expression: the parsed or given expression.
7320    """
7321    if isinstance(sql_or_expression, Expression):
7322        if copy:
7323            return sql_or_expression.copy()
7324        return sql_or_expression
7325
7326    if sql_or_expression is None:
7327        raise ParseError("SQL cannot be None")
7328
7329    import sqlglot
7330
7331    sql = str(sql_or_expression)
7332    if prefix:
7333        sql = f"{prefix} {sql}"
7334
7335    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):
7346def maybe_copy(instance, copy=True):
7347    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:
7602def union(
7603    *expressions: ExpOrStr,
7604    distinct: bool = True,
7605    dialect: DialectType = None,
7606    copy: bool = True,
7607    **opts,
7608) -> Union:
7609    """
7610    Initializes a syntax tree for the `UNION` operation.
7611
7612    Example:
7613        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7614        'SELECT * FROM foo UNION SELECT * FROM bla'
7615
7616    Args:
7617        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7618            If `Expression` instances are passed, they will be used as-is.
7619        distinct: set the DISTINCT flag if and only if this is true.
7620        dialect: the dialect used to parse the input expression.
7621        copy: whether to copy the expression.
7622        opts: other options to use to parse the input expressions.
7623
7624    Returns:
7625        The new Union instance.
7626    """
7627    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7628    return _apply_set_operation(
7629        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7630    )

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:
7633def intersect(
7634    *expressions: ExpOrStr,
7635    distinct: bool = True,
7636    dialect: DialectType = None,
7637    copy: bool = True,
7638    **opts,
7639) -> Intersect:
7640    """
7641    Initializes a syntax tree for the `INTERSECT` operation.
7642
7643    Example:
7644        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7645        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7646
7647    Args:
7648        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7649            If `Expression` instances are passed, they will be used as-is.
7650        distinct: set the DISTINCT flag if and only if this is true.
7651        dialect: the dialect used to parse the input expression.
7652        copy: whether to copy the expression.
7653        opts: other options to use to parse the input expressions.
7654
7655    Returns:
7656        The new Intersect instance.
7657    """
7658    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7659    return _apply_set_operation(
7660        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7661    )

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:
7664def except_(
7665    *expressions: ExpOrStr,
7666    distinct: bool = True,
7667    dialect: DialectType = None,
7668    copy: bool = True,
7669    **opts,
7670) -> Except:
7671    """
7672    Initializes a syntax tree for the `EXCEPT` operation.
7673
7674    Example:
7675        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7676        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7677
7678    Args:
7679        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7680            If `Expression` instances are passed, they will be used as-is.
7681        distinct: set the DISTINCT flag if and only if this is true.
7682        dialect: the dialect used to parse the input expression.
7683        copy: whether to copy the expression.
7684        opts: other options to use to parse the input expressions.
7685
7686    Returns:
7687        The new Except instance.
7688    """
7689    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7690    return _apply_set_operation(
7691        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7692    )

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:
7695def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7696    """
7697    Initializes a syntax tree from one or multiple SELECT expressions.
7698
7699    Example:
7700        >>> select("col1", "col2").from_("tbl").sql()
7701        'SELECT col1, col2 FROM tbl'
7702
7703    Args:
7704        *expressions: the SQL code string to parse as the expressions of a
7705            SELECT statement. If an Expression instance is passed, this is used as-is.
7706        dialect: the dialect used to parse the input expressions (in the case that an
7707            input expression is a SQL string).
7708        **opts: other options to use to parse the input expressions (again, in the case
7709            that an input expression is a SQL string).
7710
7711    Returns:
7712        Select: the syntax tree for the SELECT statement.
7713    """
7714    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:
7717def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7718    """
7719    Initializes a syntax tree from a FROM expression.
7720
7721    Example:
7722        >>> from_("tbl").select("col1", "col2").sql()
7723        'SELECT col1, col2 FROM tbl'
7724
7725    Args:
7726        *expression: the SQL code string to parse as the FROM expressions of a
7727            SELECT statement. If an Expression instance is passed, this is used as-is.
7728        dialect: the dialect used to parse the input expression (in the case that the
7729            input expression is a SQL string).
7730        **opts: other options to use to parse the input expressions (again, in the case
7731            that the input expression is a SQL string).
7732
7733    Returns:
7734        Select: the syntax tree for the SELECT statement.
7735    """
7736    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:
7739def update(
7740    table: str | Table,
7741    properties: t.Optional[dict] = None,
7742    where: t.Optional[ExpOrStr] = None,
7743    from_: t.Optional[ExpOrStr] = None,
7744    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7745    dialect: DialectType = None,
7746    **opts,
7747) -> Update:
7748    """
7749    Creates an update statement.
7750
7751    Example:
7752        >>> 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()
7753        "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"
7754
7755    Args:
7756        properties: dictionary of properties to SET which are
7757            auto converted to sql objects eg None -> NULL
7758        where: sql conditional parsed into a WHERE statement
7759        from_: sql statement parsed into a FROM statement
7760        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7761        dialect: the dialect used to parse the input expressions.
7762        **opts: other options to use to parse the input expressions.
7763
7764    Returns:
7765        Update: the syntax tree for the UPDATE statement.
7766    """
7767    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7768    if properties:
7769        update_expr.set(
7770            "expressions",
7771            [
7772                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7773                for k, v in properties.items()
7774            ],
7775        )
7776    if from_:
7777        update_expr.set(
7778            "from",
7779            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7780        )
7781    if isinstance(where, Condition):
7782        where = Where(this=where)
7783    if where:
7784        update_expr.set(
7785            "where",
7786            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7787        )
7788    if with_:
7789        cte_list = [
7790            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7791            for alias, qry in with_.items()
7792        ]
7793        update_expr.set(
7794            "with",
7795            With(expressions=cte_list),
7796        )
7797    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:
7800def delete(
7801    table: ExpOrStr,
7802    where: t.Optional[ExpOrStr] = None,
7803    returning: t.Optional[ExpOrStr] = None,
7804    dialect: DialectType = None,
7805    **opts,
7806) -> Delete:
7807    """
7808    Builds a delete statement.
7809
7810    Example:
7811        >>> delete("my_table", where="id > 1").sql()
7812        'DELETE FROM my_table WHERE id > 1'
7813
7814    Args:
7815        where: sql conditional parsed into a WHERE statement
7816        returning: sql conditional parsed into a RETURNING statement
7817        dialect: the dialect used to parse the input expressions.
7818        **opts: other options to use to parse the input expressions.
7819
7820    Returns:
7821        Delete: the syntax tree for the DELETE statement.
7822    """
7823    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7824    if where:
7825        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7826    if returning:
7827        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7828    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:
7831def insert(
7832    expression: ExpOrStr,
7833    into: ExpOrStr,
7834    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7835    overwrite: t.Optional[bool] = None,
7836    returning: t.Optional[ExpOrStr] = None,
7837    dialect: DialectType = None,
7838    copy: bool = True,
7839    **opts,
7840) -> Insert:
7841    """
7842    Builds an INSERT statement.
7843
7844    Example:
7845        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7846        'INSERT INTO tbl VALUES (1, 2, 3)'
7847
7848    Args:
7849        expression: the sql string or expression of the INSERT statement
7850        into: the tbl to insert data to.
7851        columns: optionally the table's column names.
7852        overwrite: whether to INSERT OVERWRITE or not.
7853        returning: sql conditional parsed into a RETURNING statement
7854        dialect: the dialect used to parse the input expressions.
7855        copy: whether to copy the expression.
7856        **opts: other options to use to parse the input expressions.
7857
7858    Returns:
7859        Insert: the syntax tree for the INSERT statement.
7860    """
7861    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7862    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7863
7864    if columns:
7865        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7866
7867    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7868
7869    if returning:
7870        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7871
7872    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:
7875def merge(
7876    *when_exprs: ExpOrStr,
7877    into: ExpOrStr,
7878    using: ExpOrStr,
7879    on: ExpOrStr,
7880    returning: t.Optional[ExpOrStr] = None,
7881    dialect: DialectType = None,
7882    copy: bool = True,
7883    **opts,
7884) -> Merge:
7885    """
7886    Builds a MERGE statement.
7887
7888    Example:
7889        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7890        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7891        ...       into="my_table",
7892        ...       using="source_table",
7893        ...       on="my_table.id = source_table.id").sql()
7894        '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)'
7895
7896    Args:
7897        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7898        into: The target table to merge data into.
7899        using: The source table to merge data from.
7900        on: The join condition for the merge.
7901        returning: The columns to return from the merge.
7902        dialect: The dialect used to parse the input expressions.
7903        copy: Whether to copy the expression.
7904        **opts: Other options to use to parse the input expressions.
7905
7906    Returns:
7907        Merge: The syntax tree for the MERGE statement.
7908    """
7909    expressions: t.List[Expression] = []
7910    for when_expr in when_exprs:
7911        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7912        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7913
7914    merge = Merge(
7915        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7916        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7917        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7918        whens=Whens(expressions=expressions),
7919    )
7920    if returning:
7921        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7922
7923    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:
7926def condition(
7927    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7928) -> Condition:
7929    """
7930    Initialize a logical condition expression.
7931
7932    Example:
7933        >>> condition("x=1").sql()
7934        'x = 1'
7935
7936        This is helpful for composing larger logical syntax trees:
7937        >>> where = condition("x=1")
7938        >>> where = where.and_("y=1")
7939        >>> Select().from_("tbl").select("*").where(where).sql()
7940        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7941
7942    Args:
7943        *expression: the SQL code string to parse.
7944            If an Expression instance is passed, this is used as-is.
7945        dialect: the dialect used to parse the input expression (in the case that the
7946            input expression is a SQL string).
7947        copy: Whether to copy `expression` (only applies to expressions).
7948        **opts: other options to use to parse the input expressions (again, in the case
7949            that the input expression is a SQL string).
7950
7951    Returns:
7952        The new Condition instance
7953    """
7954    return maybe_parse(
7955        expression,
7956        into=Condition,
7957        dialect=dialect,
7958        copy=copy,
7959        **opts,
7960    )

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:
7963def and_(
7964    *expressions: t.Optional[ExpOrStr],
7965    dialect: DialectType = None,
7966    copy: bool = True,
7967    wrap: bool = True,
7968    **opts,
7969) -> Condition:
7970    """
7971    Combine multiple conditions with an AND logical operator.
7972
7973    Example:
7974        >>> and_("x=1", and_("y=1", "z=1")).sql()
7975        'x = 1 AND (y = 1 AND z = 1)'
7976
7977    Args:
7978        *expressions: the SQL code strings to parse.
7979            If an Expression instance is passed, this is used as-is.
7980        dialect: the dialect used to parse the input expression.
7981        copy: whether to copy `expressions` (only applies to Expressions).
7982        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7983            precedence issues, but can be turned off when the produced AST is too deep and
7984            causes recursion-related issues.
7985        **opts: other options to use to parse the input expressions.
7986
7987    Returns:
7988        The new condition
7989    """
7990    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:
7993def or_(
7994    *expressions: t.Optional[ExpOrStr],
7995    dialect: DialectType = None,
7996    copy: bool = True,
7997    wrap: bool = True,
7998    **opts,
7999) -> Condition:
8000    """
8001    Combine multiple conditions with an OR logical operator.
8002
8003    Example:
8004        >>> or_("x=1", or_("y=1", "z=1")).sql()
8005        'x = 1 OR (y = 1 OR z = 1)'
8006
8007    Args:
8008        *expressions: the SQL code strings to parse.
8009            If an Expression instance is passed, this is used as-is.
8010        dialect: the dialect used to parse the input expression.
8011        copy: whether to copy `expressions` (only applies to Expressions).
8012        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8013            precedence issues, but can be turned off when the produced AST is too deep and
8014            causes recursion-related issues.
8015        **opts: other options to use to parse the input expressions.
8016
8017    Returns:
8018        The new condition
8019    """
8020    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:
8023def xor(
8024    *expressions: t.Optional[ExpOrStr],
8025    dialect: DialectType = None,
8026    copy: bool = True,
8027    wrap: bool = True,
8028    **opts,
8029) -> Condition:
8030    """
8031    Combine multiple conditions with an XOR logical operator.
8032
8033    Example:
8034        >>> xor("x=1", xor("y=1", "z=1")).sql()
8035        'x = 1 XOR (y = 1 XOR z = 1)'
8036
8037    Args:
8038        *expressions: the SQL code strings to parse.
8039            If an Expression instance is passed, this is used as-is.
8040        dialect: the dialect used to parse the input expression.
8041        copy: whether to copy `expressions` (only applies to Expressions).
8042        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8043            precedence issues, but can be turned off when the produced AST is too deep and
8044            causes recursion-related issues.
8045        **opts: other options to use to parse the input expressions.
8046
8047    Returns:
8048        The new condition
8049    """
8050    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:
8053def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
8054    """
8055    Wrap a condition with a NOT operator.
8056
8057    Example:
8058        >>> not_("this_suit='black'").sql()
8059        "NOT this_suit = 'black'"
8060
8061    Args:
8062        expression: the SQL code string to parse.
8063            If an Expression instance is passed, this is used as-is.
8064        dialect: the dialect used to parse the input expression.
8065        copy: whether to copy the expression or not.
8066        **opts: other options to use to parse the input expressions.
8067
8068    Returns:
8069        The new condition.
8070    """
8071    this = condition(
8072        expression,
8073        dialect=dialect,
8074        copy=copy,
8075        **opts,
8076    )
8077    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:
8080def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
8081    """
8082    Wrap an expression in parentheses.
8083
8084    Example:
8085        >>> paren("5 + 3").sql()
8086        '(5 + 3)'
8087
8088    Args:
8089        expression: the SQL code string to parse.
8090            If an Expression instance is passed, this is used as-is.
8091        copy: whether to copy the expression or not.
8092
8093    Returns:
8094        The wrapped expression.
8095    """
8096    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):
8112def to_identifier(name, quoted=None, copy=True):
8113    """Builds an identifier.
8114
8115    Args:
8116        name: The name to turn into an identifier.
8117        quoted: Whether to force quote the identifier.
8118        copy: Whether to copy name if it's an Identifier.
8119
8120    Returns:
8121        The identifier ast node.
8122    """
8123
8124    if name is None:
8125        return None
8126
8127    if isinstance(name, Identifier):
8128        identifier = maybe_copy(name, copy)
8129    elif isinstance(name, str):
8130        identifier = Identifier(
8131            this=name,
8132            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8133        )
8134    else:
8135        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8136    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:
8139def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8140    """
8141    Parses a given string into an identifier.
8142
8143    Args:
8144        name: The name to parse into an identifier.
8145        dialect: The dialect to parse against.
8146
8147    Returns:
8148        The identifier ast node.
8149    """
8150    try:
8151        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8152    except (ParseError, TokenError):
8153        expression = to_identifier(name)
8154
8155    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:
8161def to_interval(interval: str | Literal) -> Interval:
8162    """Builds an interval expression from a string like '1 day' or '5 months'."""
8163    if isinstance(interval, Literal):
8164        if not interval.is_string:
8165            raise ValueError("Invalid interval string.")
8166
8167        interval = interval.this
8168
8169    interval = maybe_parse(f"INTERVAL {interval}")
8170    assert isinstance(interval, Interval)
8171    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:
8174def to_table(
8175    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8176) -> Table:
8177    """
8178    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8179    If a table is passed in then that table is returned.
8180
8181    Args:
8182        sql_path: a `[catalog].[schema].[table]` string.
8183        dialect: the source dialect according to which the table name will be parsed.
8184        copy: Whether to copy a table if it is passed in.
8185        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8186
8187    Returns:
8188        A table expression.
8189    """
8190    if isinstance(sql_path, Table):
8191        return maybe_copy(sql_path, copy=copy)
8192
8193    try:
8194        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8195    except ParseError:
8196        catalog, db, this = split_num_words(sql_path, ".", 3)
8197
8198        if not this:
8199            raise
8200
8201        table = table_(this, db=db, catalog=catalog)
8202
8203    for k, v in kwargs.items():
8204        table.set(k, v)
8205
8206    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:
8209def to_column(
8210    sql_path: str | Column,
8211    quoted: t.Optional[bool] = None,
8212    dialect: DialectType = None,
8213    copy: bool = True,
8214    **kwargs,
8215) -> Column:
8216    """
8217    Create a column from a `[table].[column]` sql path. Table is optional.
8218    If a column is passed in then that column is returned.
8219
8220    Args:
8221        sql_path: a `[table].[column]` string.
8222        quoted: Whether or not to force quote identifiers.
8223        dialect: the source dialect according to which the column name will be parsed.
8224        copy: Whether to copy a column if it is passed in.
8225        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8226
8227    Returns:
8228        A column expression.
8229    """
8230    if isinstance(sql_path, Column):
8231        return maybe_copy(sql_path, copy=copy)
8232
8233    try:
8234        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8235    except ParseError:
8236        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8237
8238    for k, v in kwargs.items():
8239        col.set(k, v)
8240
8241    if quoted:
8242        for i in col.find_all(Identifier):
8243            i.set("quoted", True)
8244
8245    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):
8248def alias_(
8249    expression: ExpOrStr,
8250    alias: t.Optional[str | Identifier],
8251    table: bool | t.Sequence[str | Identifier] = False,
8252    quoted: t.Optional[bool] = None,
8253    dialect: DialectType = None,
8254    copy: bool = True,
8255    **opts,
8256):
8257    """Create an Alias expression.
8258
8259    Example:
8260        >>> alias_('foo', 'bar').sql()
8261        'foo AS bar'
8262
8263        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8264        '(SELECT 1, 2) AS bar(a, b)'
8265
8266    Args:
8267        expression: the SQL code strings to parse.
8268            If an Expression instance is passed, this is used as-is.
8269        alias: the alias name to use. If the name has
8270            special characters it is quoted.
8271        table: Whether to create a table alias, can also be a list of columns.
8272        quoted: whether to quote the alias
8273        dialect: the dialect used to parse the input expression.
8274        copy: Whether to copy the expression.
8275        **opts: other options to use to parse the input expressions.
8276
8277    Returns:
8278        Alias: the aliased expression
8279    """
8280    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8281    alias = to_identifier(alias, quoted=quoted)
8282
8283    if table:
8284        table_alias = TableAlias(this=alias)
8285        exp.set("alias", table_alias)
8286
8287        if not isinstance(table, bool):
8288            for column in table:
8289                table_alias.append("columns", to_identifier(column, quoted=quoted))
8290
8291        return exp
8292
8293    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8294    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8295    # for the complete Window expression.
8296    #
8297    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8298
8299    if "alias" in exp.arg_types and not isinstance(exp, Window):
8300        exp.set("alias", alias)
8301        return exp
8302    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:
8305def subquery(
8306    expression: ExpOrStr,
8307    alias: t.Optional[Identifier | str] = None,
8308    dialect: DialectType = None,
8309    **opts,
8310) -> Select:
8311    """
8312    Build a subquery expression that's selected from.
8313
8314    Example:
8315        >>> subquery('select x from tbl', 'bar').select('x').sql()
8316        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8317
8318    Args:
8319        expression: the SQL code strings to parse.
8320            If an Expression instance is passed, this is used as-is.
8321        alias: the alias name to use.
8322        dialect: the dialect used to parse the input expression.
8323        **opts: other options to use to parse the input expressions.
8324
8325    Returns:
8326        A new Select instance with the subquery expression included.
8327    """
8328
8329    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8330    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):
8361def column(
8362    col,
8363    table=None,
8364    db=None,
8365    catalog=None,
8366    *,
8367    fields=None,
8368    quoted=None,
8369    copy=True,
8370):
8371    """
8372    Build a Column.
8373
8374    Args:
8375        col: Column name.
8376        table: Table name.
8377        db: Database name.
8378        catalog: Catalog name.
8379        fields: Additional fields using dots.
8380        quoted: Whether to force quotes on the column's identifiers.
8381        copy: Whether to copy identifiers if passed in.
8382
8383    Returns:
8384        The new Column instance.
8385    """
8386    if not isinstance(col, Star):
8387        col = to_identifier(col, quoted=quoted, copy=copy)
8388
8389    this = Column(
8390        this=col,
8391        table=to_identifier(table, quoted=quoted, copy=copy),
8392        db=to_identifier(db, quoted=quoted, copy=copy),
8393        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8394    )
8395
8396    if fields:
8397        this = Dot.build(
8398            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8399        )
8400    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:
8403def cast(
8404    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8405) -> Cast:
8406    """Cast an expression to a data type.
8407
8408    Example:
8409        >>> cast('x + 1', 'int').sql()
8410        'CAST(x + 1 AS INT)'
8411
8412    Args:
8413        expression: The expression to cast.
8414        to: The datatype to cast to.
8415        copy: Whether to copy the supplied expressions.
8416        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8417            - The expression to be cast is already a exp.Cast expression
8418            - The existing cast is to a type that is logically equivalent to new type
8419
8420            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8421            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8422            and instead just return the original expression `CAST(x as DATETIME)`.
8423
8424            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8425            mapping is applied in the target dialect generator.
8426
8427    Returns:
8428        The new Cast instance.
8429    """
8430    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8431    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8432
8433    # dont re-cast if the expression is already a cast to the correct type
8434    if isinstance(expr, Cast):
8435        from sqlglot.dialects.dialect import Dialect
8436
8437        target_dialect = Dialect.get_or_raise(dialect)
8438        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8439
8440        existing_cast_type: DataType.Type = expr.to.this
8441        new_cast_type: DataType.Type = data_type.this
8442        types_are_equivalent = type_mapping.get(
8443            existing_cast_type, existing_cast_type.value
8444        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8445
8446        if expr.is_type(data_type) or types_are_equivalent:
8447            return expr
8448
8449    expr = Cast(this=expr, to=data_type)
8450    expr.type = data_type
8451
8452    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:
8455def table_(
8456    table: Identifier | str,
8457    db: t.Optional[Identifier | str] = None,
8458    catalog: t.Optional[Identifier | str] = None,
8459    quoted: t.Optional[bool] = None,
8460    alias: t.Optional[Identifier | str] = None,
8461) -> Table:
8462    """Build a Table.
8463
8464    Args:
8465        table: Table name.
8466        db: Database name.
8467        catalog: Catalog name.
8468        quote: Whether to force quotes on the table's identifiers.
8469        alias: Table's alias.
8470
8471    Returns:
8472        The new Table instance.
8473    """
8474    return Table(
8475        this=to_identifier(table, quoted=quoted) if table else None,
8476        db=to_identifier(db, quoted=quoted) if db else None,
8477        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8478        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8479    )

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:
8482def values(
8483    values: t.Iterable[t.Tuple[t.Any, ...]],
8484    alias: t.Optional[str] = None,
8485    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8486) -> Values:
8487    """Build VALUES statement.
8488
8489    Example:
8490        >>> values([(1, '2')]).sql()
8491        "VALUES (1, '2')"
8492
8493    Args:
8494        values: values statements that will be converted to SQL
8495        alias: optional alias
8496        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8497         If either are provided then an alias is also required.
8498
8499    Returns:
8500        Values: the Values expression object
8501    """
8502    if columns and not alias:
8503        raise ValueError("Alias is required when providing columns")
8504
8505    return Values(
8506        expressions=[convert(tup) for tup in values],
8507        alias=(
8508            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8509            if columns
8510            else (TableAlias(this=to_identifier(alias)) if alias else None)
8511        ),
8512    )

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:
8515def var(name: t.Optional[ExpOrStr]) -> Var:
8516    """Build a SQL variable.
8517
8518    Example:
8519        >>> repr(var('x'))
8520        'Var(this=x)'
8521
8522        >>> repr(var(column('x', table='y')))
8523        'Var(this=x)'
8524
8525    Args:
8526        name: The name of the var or an expression who's name will become the var.
8527
8528    Returns:
8529        The new variable node.
8530    """
8531    if not name:
8532        raise ValueError("Cannot convert empty name into var.")
8533
8534    if isinstance(name, Expression):
8535        name = name.name
8536    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:
8539def rename_table(
8540    old_name: str | Table,
8541    new_name: str | Table,
8542    dialect: DialectType = None,
8543) -> Alter:
8544    """Build ALTER TABLE... RENAME... expression
8545
8546    Args:
8547        old_name: The old name of the table
8548        new_name: The new name of the table
8549        dialect: The dialect to parse the table.
8550
8551    Returns:
8552        Alter table expression
8553    """
8554    old_table = to_table(old_name, dialect=dialect)
8555    new_table = to_table(new_name, dialect=dialect)
8556    return Alter(
8557        this=old_table,
8558        kind="TABLE",
8559        actions=[
8560            AlterRename(this=new_table),
8561        ],
8562    )

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:
8565def rename_column(
8566    table_name: str | Table,
8567    old_column_name: str | Column,
8568    new_column_name: str | Column,
8569    exists: t.Optional[bool] = None,
8570    dialect: DialectType = None,
8571) -> Alter:
8572    """Build ALTER TABLE... RENAME COLUMN... expression
8573
8574    Args:
8575        table_name: Name of the table
8576        old_column: The old name of the column
8577        new_column: The new name of the column
8578        exists: Whether to add the `IF EXISTS` clause
8579        dialect: The dialect to parse the table/column.
8580
8581    Returns:
8582        Alter table expression
8583    """
8584    table = to_table(table_name, dialect=dialect)
8585    old_column = to_column(old_column_name, dialect=dialect)
8586    new_column = to_column(new_column_name, dialect=dialect)
8587    return Alter(
8588        this=table,
8589        kind="TABLE",
8590        actions=[
8591            RenameColumn(this=old_column, to=new_column, exists=exists),
8592        ],
8593    )

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:
8596def convert(value: t.Any, copy: bool = False) -> Expression:
8597    """Convert a python value into an expression object.
8598
8599    Raises an error if a conversion is not possible.
8600
8601    Args:
8602        value: A python object.
8603        copy: Whether to copy `value` (only applies to Expressions and collections).
8604
8605    Returns:
8606        The equivalent expression object.
8607    """
8608    if isinstance(value, Expression):
8609        return maybe_copy(value, copy)
8610    if isinstance(value, str):
8611        return Literal.string(value)
8612    if isinstance(value, bool):
8613        return Boolean(this=value)
8614    if value is None or (isinstance(value, float) and math.isnan(value)):
8615        return null()
8616    if isinstance(value, numbers.Number):
8617        return Literal.number(value)
8618    if isinstance(value, bytes):
8619        return HexString(this=value.hex())
8620    if isinstance(value, datetime.datetime):
8621        datetime_literal = Literal.string(value.isoformat(sep=" "))
8622
8623        tz = None
8624        if value.tzinfo:
8625            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8626            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8627            tz = Literal.string(str(value.tzinfo))
8628
8629        return TimeStrToTime(this=datetime_literal, zone=tz)
8630    if isinstance(value, datetime.date):
8631        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8632        return DateStrToDate(this=date_literal)
8633    if isinstance(value, datetime.time):
8634        time_literal = Literal.string(value.isoformat())
8635        return TsOrDsToTime(this=time_literal)
8636    if isinstance(value, tuple):
8637        if hasattr(value, "_fields"):
8638            return Struct(
8639                expressions=[
8640                    PropertyEQ(
8641                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8642                    )
8643                    for k in value._fields
8644                ]
8645            )
8646        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8647    if isinstance(value, list):
8648        return Array(expressions=[convert(v, copy=copy) for v in value])
8649    if isinstance(value, dict):
8650        return Map(
8651            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8652            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8653        )
8654    if hasattr(value, "__dict__"):
8655        return Struct(
8656            expressions=[
8657                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8658                for k, v in value.__dict__.items()
8659            ]
8660        )
8661    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:
8664def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8665    """
8666    Replace children of an expression with the result of a lambda fun(child) -> exp.
8667    """
8668    for k, v in tuple(expression.args.items()):
8669        is_list_arg = type(v) is list
8670
8671        child_nodes = v if is_list_arg else [v]
8672        new_child_nodes = []
8673
8674        for cn in child_nodes:
8675            if isinstance(cn, Expression):
8676                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8677                    new_child_nodes.append(child_node)
8678            else:
8679                new_child_nodes.append(cn)
8680
8681        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:
8684def replace_tree(
8685    expression: Expression,
8686    fun: t.Callable,
8687    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8688) -> Expression:
8689    """
8690    Replace an entire tree with the result of function calls on each node.
8691
8692    This will be traversed in reverse dfs, so leaves first.
8693    If new nodes are created as a result of function calls, they will also be traversed.
8694    """
8695    stack = list(expression.dfs(prune=prune))
8696
8697    while stack:
8698        node = stack.pop()
8699        new_node = fun(node)
8700
8701        if new_node is not node:
8702            node.replace(new_node)
8703
8704            if isinstance(new_node, Expression):
8705                stack.append(new_node)
8706
8707    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]:
8710def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8711    """
8712    Return all table names referenced through columns in an expression.
8713
8714    Example:
8715        >>> import sqlglot
8716        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8717        ['a', 'c']
8718
8719    Args:
8720        expression: expression to find table names.
8721        exclude: a table name to exclude
8722
8723    Returns:
8724        A list of unique names.
8725    """
8726    return {
8727        table
8728        for table in (column.table for column in expression.find_all(Column))
8729        if table and table != exclude
8730    }

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:
8733def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8734    """Get the full name of a table as a string.
8735
8736    Args:
8737        table: Table expression node or string.
8738        dialect: The dialect to generate the table name for.
8739        identify: Determines when an identifier should be quoted. Possible values are:
8740            False (default): Never quote, except in cases where it's mandatory by the dialect.
8741            True: Always quote.
8742
8743    Examples:
8744        >>> from sqlglot import exp, parse_one
8745        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8746        'a.b.c'
8747
8748    Returns:
8749        The table name.
8750    """
8751
8752    table = maybe_parse(table, into=Table, dialect=dialect)
8753
8754    if not table:
8755        raise ValueError(f"Cannot parse {table}")
8756
8757    return ".".join(
8758        (
8759            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8760            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8761            else part.name
8762        )
8763        for part in table.parts
8764    )

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:
8767def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8768    """Returns a case normalized table name without quotes.
8769
8770    Args:
8771        table: the table to normalize
8772        dialect: the dialect to use for normalization rules
8773        copy: whether to copy the expression.
8774
8775    Examples:
8776        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8777        'A-B.c'
8778    """
8779    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8780
8781    return ".".join(
8782        p.name
8783        for p in normalize_identifiers(
8784            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8785        ).parts
8786    )

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:
8789def replace_tables(
8790    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8791) -> E:
8792    """Replace all tables in expression according to the mapping.
8793
8794    Args:
8795        expression: expression node to be transformed and replaced.
8796        mapping: mapping of table names.
8797        dialect: the dialect of the mapping table
8798        copy: whether to copy the expression.
8799
8800    Examples:
8801        >>> from sqlglot import exp, parse_one
8802        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8803        'SELECT * FROM c /* a.b */'
8804
8805    Returns:
8806        The mapped expression.
8807    """
8808
8809    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8810
8811    def _replace_tables(node: Expression) -> Expression:
8812        if isinstance(node, Table) and node.meta.get("replace") is not False:
8813            original = normalize_table_name(node, dialect=dialect)
8814            new_name = mapping.get(original)
8815
8816            if new_name:
8817                table = to_table(
8818                    new_name,
8819                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8820                    dialect=dialect,
8821                )
8822                table.add_comments([original])
8823                return table
8824        return node
8825
8826    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:
8829def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8830    """Replace placeholders in an expression.
8831
8832    Args:
8833        expression: expression node to be transformed and replaced.
8834        args: positional names that will substitute unnamed placeholders in the given order.
8835        kwargs: keyword arguments that will substitute named placeholders.
8836
8837    Examples:
8838        >>> from sqlglot import exp, parse_one
8839        >>> replace_placeholders(
8840        ...     parse_one("select * from :tbl where ? = ?"),
8841        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8842        ... ).sql()
8843        "SELECT * FROM foo WHERE str_col = 'b'"
8844
8845    Returns:
8846        The mapped expression.
8847    """
8848
8849    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8850        if isinstance(node, Placeholder):
8851            if node.this:
8852                new_name = kwargs.get(node.this)
8853                if new_name is not None:
8854                    return convert(new_name)
8855            else:
8856                try:
8857                    return convert(next(args))
8858                except StopIteration:
8859                    pass
8860        return node
8861
8862    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:
8865def expand(
8866    expression: Expression,
8867    sources: t.Dict[str, Query | t.Callable[[], Query]],
8868    dialect: DialectType = None,
8869    copy: bool = True,
8870) -> Expression:
8871    """Transforms an expression by expanding all referenced sources into subqueries.
8872
8873    Examples:
8874        >>> from sqlglot import parse_one
8875        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8876        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8877
8878        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8879        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8880
8881    Args:
8882        expression: The expression to expand.
8883        sources: A dict of name to query or a callable that provides a query on demand.
8884        dialect: The dialect of the sources dict or the callable.
8885        copy: Whether to copy the expression during transformation. Defaults to True.
8886
8887    Returns:
8888        The transformed expression.
8889    """
8890    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8891
8892    def _expand(node: Expression):
8893        if isinstance(node, Table):
8894            name = normalize_table_name(node, dialect=dialect)
8895            source = normalized_sources.get(name)
8896
8897            if source:
8898                # Create a subquery with the same alias (or table name if no alias)
8899                parsed_source = source() if callable(source) else source
8900                subquery = parsed_source.subquery(node.alias or name)
8901                subquery.comments = [f"source: {name}"]
8902
8903                # Continue expanding within the subquery
8904                return subquery.transform(_expand, copy=False)
8905
8906        return node
8907
8908    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:
8911def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8912    """
8913    Returns a Func expression.
8914
8915    Examples:
8916        >>> func("abs", 5).sql()
8917        'ABS(5)'
8918
8919        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8920        'CAST(5 AS DOUBLE)'
8921
8922    Args:
8923        name: the name of the function to build.
8924        args: the args used to instantiate the function of interest.
8925        copy: whether to copy the argument expressions.
8926        dialect: the source dialect.
8927        kwargs: the kwargs used to instantiate the function of interest.
8928
8929    Note:
8930        The arguments `args` and `kwargs` are mutually exclusive.
8931
8932    Returns:
8933        An instance of the function of interest, or an anonymous function, if `name` doesn't
8934        correspond to an existing `sqlglot.expressions.Func` class.
8935    """
8936    if args and kwargs:
8937        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8938
8939    from sqlglot.dialects.dialect import Dialect
8940
8941    dialect = Dialect.get_or_raise(dialect)
8942
8943    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8944    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8945
8946    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8947    if constructor:
8948        if converted:
8949            if "dialect" in constructor.__code__.co_varnames:
8950                function = constructor(converted, dialect=dialect)
8951            else:
8952                function = constructor(converted)
8953        elif constructor.__name__ == "from_arg_list":
8954            function = constructor.__self__(**kwargs)  # type: ignore
8955        else:
8956            constructor = FUNCTION_BY_NAME.get(name.upper())
8957            if constructor:
8958                function = constructor(**kwargs)
8959            else:
8960                raise ValueError(
8961                    f"Unable to convert '{name}' into a Func. Either manually construct "
8962                    "the Func expression of interest or parse the function call."
8963                )
8964    else:
8965        kwargs = kwargs or {"expressions": converted}
8966        function = Anonymous(this=name, **kwargs)
8967
8968    for error_message in function.error_messages(converted):
8969        raise ValueError(error_message)
8970
8971    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:
8974def case(
8975    expression: t.Optional[ExpOrStr] = None,
8976    **opts,
8977) -> Case:
8978    """
8979    Initialize a CASE statement.
8980
8981    Example:
8982        case().when("a = 1", "foo").else_("bar")
8983
8984    Args:
8985        expression: Optionally, the input expression (not all dialects support this)
8986        **opts: Extra keyword arguments for parsing `expression`
8987    """
8988    if expression is not None:
8989        this = maybe_parse(expression, **opts)
8990    else:
8991        this = None
8992    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:
8995def array(
8996    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8997) -> Array:
8998    """
8999    Returns an array.
9000
9001    Examples:
9002        >>> array(1, 'x').sql()
9003        'ARRAY(1, x)'
9004
9005    Args:
9006        expressions: the expressions to add to the array.
9007        copy: whether to copy the argument expressions.
9008        dialect: the source dialect.
9009        kwargs: the kwargs used to instantiate the function of interest.
9010
9011    Returns:
9012        An array expression.
9013    """
9014    return Array(
9015        expressions=[
9016            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9017            for expression in expressions
9018        ]
9019    )

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:
9022def tuple_(
9023    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9024) -> Tuple:
9025    """
9026    Returns an tuple.
9027
9028    Examples:
9029        >>> tuple_(1, 'x').sql()
9030        '(1, x)'
9031
9032    Args:
9033        expressions: the expressions to add to the tuple.
9034        copy: whether to copy the argument expressions.
9035        dialect: the source dialect.
9036        kwargs: the kwargs used to instantiate the function of interest.
9037
9038    Returns:
9039        A tuple expression.
9040    """
9041    return Tuple(
9042        expressions=[
9043            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9044            for expression in expressions
9045        ]
9046    )

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:
9049def true() -> Boolean:
9050    """
9051    Returns a true Boolean expression.
9052    """
9053    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
9056def false() -> Boolean:
9057    """
9058    Returns a false Boolean expression.
9059    """
9060    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
9063def null() -> Null:
9064    """
9065    Returns a Null expression.
9066    """
9067    return Null()

Returns a Null expression.

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