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 isinstance(unit, 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 Anonymous(Func):
5468    arg_types = {"this": True, "expressions": False}
5469    is_var_len_args = True
5470
5471    @property
5472    def name(self) -> str:
5473        return self.this if isinstance(self.this, str) else self.this.name
5474
5475
5476class AnonymousAggFunc(AggFunc):
5477    arg_types = {"this": True, "expressions": False}
5478    is_var_len_args = True
5479
5480
5481# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
5482class CombinedAggFunc(AnonymousAggFunc):
5483    arg_types = {"this": True, "expressions": False}
5484
5485
5486class CombinedParameterizedAgg(ParameterizedAgg):
5487    arg_types = {"this": True, "expressions": True, "params": True}
5488
5489
5490# https://docs.snowflake.com/en/sql-reference/functions/hll
5491# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
5492class Hll(AggFunc):
5493    arg_types = {"this": True, "expressions": False}
5494    is_var_len_args = True
5495
5496
5497class ApproxDistinct(AggFunc):
5498    arg_types = {"this": True, "accuracy": False}
5499    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
5500
5501
5502class Apply(Func):
5503    arg_types = {"this": True, "expression": True}
5504
5505
5506class Array(Func):
5507    arg_types = {"expressions": False, "bracket_notation": False}
5508    is_var_len_args = True
5509
5510
5511class Ascii(Func):
5512    pass
5513
5514
5515# https://docs.snowflake.com/en/sql-reference/functions/to_array
5516class ToArray(Func):
5517    pass
5518
5519
5520# https://materialize.com/docs/sql/types/list/
5521class List(Func):
5522    arg_types = {"expressions": False}
5523    is_var_len_args = True
5524
5525
5526# String pad, kind True -> LPAD, False -> RPAD
5527class Pad(Func):
5528    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
5529
5530
5531# https://docs.snowflake.com/en/sql-reference/functions/to_char
5532# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
5533class ToChar(Func):
5534    arg_types = {"this": True, "format": False, "nlsparam": False}
5535
5536
5537# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
5538# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
5539class ToNumber(Func):
5540    arg_types = {
5541        "this": True,
5542        "format": False,
5543        "nlsparam": False,
5544        "precision": False,
5545        "scale": False,
5546    }
5547
5548
5549# https://docs.snowflake.com/en/sql-reference/functions/to_double
5550class ToDouble(Func):
5551    arg_types = {
5552        "this": True,
5553        "format": False,
5554    }
5555
5556
5557class Columns(Func):
5558    arg_types = {"this": True, "unpack": False}
5559
5560
5561# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
5562class Convert(Func):
5563    arg_types = {"this": True, "expression": True, "style": False}
5564
5565
5566# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/CONVERT.html
5567class ConvertToCharset(Func):
5568    arg_types = {"this": True, "dest": True, "source": False}
5569
5570
5571class ConvertTimezone(Func):
5572    arg_types = {
5573        "source_tz": False,
5574        "target_tz": True,
5575        "timestamp": True,
5576        "options": False,
5577    }
5578
5579
5580class CodePointsToString(Func):
5581    pass
5582
5583
5584class GenerateSeries(Func):
5585    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
5586
5587
5588# Postgres' GENERATE_SERIES function returns a row set, i.e. it implicitly explodes when it's
5589# used in a projection, so this expression is a helper that facilitates transpilation to other
5590# dialects. For example, we'd generate UNNEST(GENERATE_SERIES(...)) in DuckDB
5591class ExplodingGenerateSeries(GenerateSeries):
5592    pass
5593
5594
5595class ArrayAgg(AggFunc):
5596    arg_types = {"this": True, "nulls_excluded": False}
5597
5598
5599class ArrayUniqueAgg(AggFunc):
5600    pass
5601
5602
5603class ArrayAll(Func):
5604    arg_types = {"this": True, "expression": True}
5605
5606
5607# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
5608class ArrayAny(Func):
5609    arg_types = {"this": True, "expression": True}
5610
5611
5612class ArrayConcat(Func):
5613    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5614    arg_types = {"this": True, "expressions": False}
5615    is_var_len_args = True
5616
5617
5618class ArrayConcatAgg(AggFunc):
5619    pass
5620
5621
5622class ArrayConstructCompact(Func):
5623    arg_types = {"expressions": True}
5624    is_var_len_args = True
5625
5626
5627class ArrayContains(Binary, Func):
5628    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5629
5630
5631class ArrayContainsAll(Binary, Func):
5632    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5633
5634
5635class ArrayFilter(Func):
5636    arg_types = {"this": True, "expression": True}
5637    _sql_names = ["FILTER", "ARRAY_FILTER"]
5638
5639
5640class ArrayFirst(Func):
5641    pass
5642
5643
5644class ArrayLast(Func):
5645    pass
5646
5647
5648class ArrayReverse(Func):
5649    pass
5650
5651
5652class ArraySlice(Func):
5653    arg_types = {"this": True, "start": True, "end": False, "step": False}
5654
5655
5656class ArrayToString(Func):
5657    arg_types = {"this": True, "expression": True, "null": False}
5658    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5659
5660
5661class ArrayIntersect(Func):
5662    arg_types = {"expressions": True}
5663    is_var_len_args = True
5664    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
5665
5666
5667class StPoint(Func):
5668    arg_types = {"this": True, "expression": True, "null": False}
5669    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
5670
5671
5672class StDistance(Func):
5673    arg_types = {"this": True, "expression": True, "use_spheroid": False}
5674
5675
5676# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5677class String(Func):
5678    arg_types = {"this": True, "zone": False}
5679
5680
5681class StringToArray(Func):
5682    arg_types = {"this": True, "expression": False, "null": False}
5683    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
5684
5685
5686class ArrayOverlaps(Binary, Func):
5687    pass
5688
5689
5690class ArraySize(Func):
5691    arg_types = {"this": True, "expression": False}
5692    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5693
5694
5695class ArraySort(Func):
5696    arg_types = {"this": True, "expression": False}
5697
5698
5699class ArraySum(Func):
5700    arg_types = {"this": True, "expression": False}
5701
5702
5703class ArrayUnionAgg(AggFunc):
5704    pass
5705
5706
5707class Avg(AggFunc):
5708    pass
5709
5710
5711class AnyValue(AggFunc):
5712    pass
5713
5714
5715class Lag(AggFunc):
5716    arg_types = {"this": True, "offset": False, "default": False}
5717
5718
5719class Lead(AggFunc):
5720    arg_types = {"this": True, "offset": False, "default": False}
5721
5722
5723# some dialects have a distinction between first and first_value, usually first is an aggregate func
5724# and first_value is a window func
5725class First(AggFunc):
5726    pass
5727
5728
5729class Last(AggFunc):
5730    pass
5731
5732
5733class FirstValue(AggFunc):
5734    pass
5735
5736
5737class LastValue(AggFunc):
5738    pass
5739
5740
5741class NthValue(AggFunc):
5742    arg_types = {"this": True, "offset": True}
5743
5744
5745class Case(Func):
5746    arg_types = {"this": False, "ifs": True, "default": False}
5747
5748    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5749        instance = maybe_copy(self, copy)
5750        instance.append(
5751            "ifs",
5752            If(
5753                this=maybe_parse(condition, copy=copy, **opts),
5754                true=maybe_parse(then, copy=copy, **opts),
5755            ),
5756        )
5757        return instance
5758
5759    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5760        instance = maybe_copy(self, copy)
5761        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5762        return instance
5763
5764
5765class Cast(Func):
5766    arg_types = {
5767        "this": True,
5768        "to": True,
5769        "format": False,
5770        "safe": False,
5771        "action": False,
5772        "default": False,
5773    }
5774
5775    @property
5776    def name(self) -> str:
5777        return self.this.name
5778
5779    @property
5780    def to(self) -> DataType:
5781        return self.args["to"]
5782
5783    @property
5784    def output_name(self) -> str:
5785        return self.name
5786
5787    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5788        """
5789        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5790        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5791        array<int> != array<float>.
5792
5793        Args:
5794            dtypes: the data types to compare this Cast's DataType to.
5795
5796        Returns:
5797            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5798        """
5799        return self.to.is_type(*dtypes)
5800
5801
5802class TryCast(Cast):
5803    arg_types = {**Cast.arg_types, "requires_string": False}
5804
5805
5806# https://clickhouse.com/docs/sql-reference/data-types/newjson#reading-json-paths-as-sub-columns
5807class JSONCast(Cast):
5808    pass
5809
5810
5811class JustifyDays(Func):
5812    pass
5813
5814
5815class JustifyHours(Func):
5816    pass
5817
5818
5819class JustifyInterval(Func):
5820    pass
5821
5822
5823class Try(Func):
5824    pass
5825
5826
5827class CastToStrType(Func):
5828    arg_types = {"this": True, "to": True}
5829
5830
5831# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/String-Operators-and-Functions/TRANSLATE/TRANSLATE-Function-Syntax
5832class TranslateCharacters(Expression):
5833    arg_types = {"this": True, "expression": True, "with_error": False}
5834
5835
5836class Collate(Binary, Func):
5837    pass
5838
5839
5840class Ceil(Func):
5841    arg_types = {"this": True, "decimals": False, "to": False}
5842    _sql_names = ["CEIL", "CEILING"]
5843
5844
5845class Coalesce(Func):
5846    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5847    is_var_len_args = True
5848    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5849
5850
5851class Chr(Func):
5852    arg_types = {"expressions": True, "charset": False}
5853    is_var_len_args = True
5854    _sql_names = ["CHR", "CHAR"]
5855
5856
5857class Concat(Func):
5858    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5859    is_var_len_args = True
5860
5861
5862class ConcatWs(Concat):
5863    _sql_names = ["CONCAT_WS"]
5864
5865
5866class Contains(Func):
5867    arg_types = {"this": True, "expression": True}
5868
5869
5870# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5871class ConnectByRoot(Func):
5872    pass
5873
5874
5875class Count(AggFunc):
5876    arg_types = {"this": False, "expressions": False, "big_int": False}
5877    is_var_len_args = True
5878
5879
5880class CountIf(AggFunc):
5881    _sql_names = ["COUNT_IF", "COUNTIF"]
5882
5883
5884# cube root
5885class Cbrt(Func):
5886    pass
5887
5888
5889class CurrentDate(Func):
5890    arg_types = {"this": False}
5891
5892
5893class CurrentDatetime(Func):
5894    arg_types = {"this": False}
5895
5896
5897class CurrentTime(Func):
5898    arg_types = {"this": False}
5899
5900
5901class CurrentTimestamp(Func):
5902    arg_types = {"this": False, "sysdate": False}
5903
5904
5905class CurrentTimestampLTZ(Func):
5906    arg_types = {}
5907
5908
5909class CurrentSchema(Func):
5910    arg_types = {"this": False}
5911
5912
5913class CurrentUser(Func):
5914    arg_types = {"this": False}
5915
5916
5917class DateAdd(Func, IntervalOp):
5918    arg_types = {"this": True, "expression": True, "unit": False}
5919
5920
5921class DateBin(Func, IntervalOp):
5922    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5923
5924
5925class DateSub(Func, IntervalOp):
5926    arg_types = {"this": True, "expression": True, "unit": False}
5927
5928
5929class DateDiff(Func, TimeUnit):
5930    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5931    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5932
5933
5934class DateTrunc(Func):
5935    arg_types = {"unit": True, "this": True, "zone": False}
5936
5937    def __init__(self, **args):
5938        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5939        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5940        unabbreviate = args.pop("unabbreviate", True)
5941
5942        unit = args.get("unit")
5943        if isinstance(unit, TimeUnit.VAR_LIKE):
5944            unit_name = unit.name.upper()
5945            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5946                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5947
5948            args["unit"] = Literal.string(unit_name)
5949
5950        super().__init__(**args)
5951
5952    @property
5953    def unit(self) -> Expression:
5954        return self.args["unit"]
5955
5956
5957# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5958# expression can either be time_expr or time_zone
5959class Datetime(Func):
5960    arg_types = {"this": True, "expression": False}
5961
5962
5963class DatetimeAdd(Func, IntervalOp):
5964    arg_types = {"this": True, "expression": True, "unit": False}
5965
5966
5967class DatetimeSub(Func, IntervalOp):
5968    arg_types = {"this": True, "expression": True, "unit": False}
5969
5970
5971class DatetimeDiff(Func, TimeUnit):
5972    arg_types = {"this": True, "expression": True, "unit": False}
5973
5974
5975class DatetimeTrunc(Func, TimeUnit):
5976    arg_types = {"this": True, "unit": True, "zone": False}
5977
5978
5979class DateFromUnixDate(Func):
5980    pass
5981
5982
5983class DayOfWeek(Func):
5984    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5985
5986
5987# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5988# ISO day of week function in duckdb is ISODOW
5989class DayOfWeekIso(Func):
5990    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5991
5992
5993class DayOfMonth(Func):
5994    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5995
5996
5997class DayOfYear(Func):
5998    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5999
6000
6001class ToDays(Func):
6002    pass
6003
6004
6005class WeekOfYear(Func):
6006    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
6007
6008
6009class MonthsBetween(Func):
6010    arg_types = {"this": True, "expression": True, "roundoff": False}
6011
6012
6013class MakeInterval(Func):
6014    arg_types = {
6015        "year": False,
6016        "month": False,
6017        "day": False,
6018        "hour": False,
6019        "minute": False,
6020        "second": False,
6021    }
6022
6023
6024class LastDay(Func, TimeUnit):
6025    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
6026    arg_types = {"this": True, "unit": False}
6027
6028
6029class Extract(Func):
6030    arg_types = {"this": True, "expression": True}
6031
6032
6033class Exists(Func, SubqueryPredicate):
6034    arg_types = {"this": True, "expression": False}
6035
6036
6037class Timestamp(Func):
6038    arg_types = {"this": False, "zone": False, "with_tz": False}
6039
6040
6041class TimestampAdd(Func, TimeUnit):
6042    arg_types = {"this": True, "expression": True, "unit": False}
6043
6044
6045class TimestampSub(Func, TimeUnit):
6046    arg_types = {"this": True, "expression": True, "unit": False}
6047
6048
6049class TimestampDiff(Func, TimeUnit):
6050    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6051    arg_types = {"this": True, "expression": True, "unit": False}
6052
6053
6054class TimestampTrunc(Func, TimeUnit):
6055    arg_types = {"this": True, "unit": True, "zone": False}
6056
6057
6058class TimeAdd(Func, TimeUnit):
6059    arg_types = {"this": True, "expression": True, "unit": False}
6060
6061
6062class TimeSub(Func, TimeUnit):
6063    arg_types = {"this": True, "expression": True, "unit": False}
6064
6065
6066class TimeDiff(Func, TimeUnit):
6067    arg_types = {"this": True, "expression": True, "unit": False}
6068
6069
6070class TimeTrunc(Func, TimeUnit):
6071    arg_types = {"this": True, "unit": True, "zone": False}
6072
6073
6074class DateFromParts(Func):
6075    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6076    arg_types = {"year": True, "month": True, "day": True}
6077
6078
6079class TimeFromParts(Func):
6080    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6081    arg_types = {
6082        "hour": True,
6083        "min": True,
6084        "sec": True,
6085        "nano": False,
6086        "fractions": False,
6087        "precision": False,
6088    }
6089
6090
6091class DateStrToDate(Func):
6092    pass
6093
6094
6095class DateToDateStr(Func):
6096    pass
6097
6098
6099class DateToDi(Func):
6100    pass
6101
6102
6103# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
6104class Date(Func):
6105    arg_types = {"this": False, "zone": False, "expressions": False}
6106    is_var_len_args = True
6107
6108
6109class Day(Func):
6110    pass
6111
6112
6113class Decode(Func):
6114    arg_types = {"this": True, "charset": True, "replace": False}
6115
6116
6117class DecodeCase(Func):
6118    arg_types = {"expressions": True}
6119    is_var_len_args = True
6120
6121
6122class DiToDate(Func):
6123    pass
6124
6125
6126class Encode(Func):
6127    arg_types = {"this": True, "charset": True}
6128
6129
6130class Exp(Func):
6131    pass
6132
6133
6134# https://docs.snowflake.com/en/sql-reference/functions/flatten
6135class Explode(Func, UDTF):
6136    arg_types = {"this": True, "expressions": False}
6137    is_var_len_args = True
6138
6139
6140# https://spark.apache.org/docs/latest/api/sql/#inline
6141class Inline(Func):
6142    pass
6143
6144
6145class ExplodeOuter(Explode):
6146    pass
6147
6148
6149class Posexplode(Explode):
6150    pass
6151
6152
6153class PosexplodeOuter(Posexplode, ExplodeOuter):
6154    pass
6155
6156
6157class PositionalColumn(Expression):
6158    pass
6159
6160
6161class Unnest(Func, UDTF):
6162    arg_types = {
6163        "expressions": True,
6164        "alias": False,
6165        "offset": False,
6166        "explode_array": False,
6167    }
6168
6169    @property
6170    def selects(self) -> t.List[Expression]:
6171        columns = super().selects
6172        offset = self.args.get("offset")
6173        if offset:
6174            columns = columns + [to_identifier("offset") if offset is True else offset]
6175        return columns
6176
6177
6178class Floor(Func):
6179    arg_types = {"this": True, "decimals": False, "to": False}
6180
6181
6182class FromBase64(Func):
6183    pass
6184
6185
6186class FeaturesAtTime(Func):
6187    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
6188
6189
6190class ToBase64(Func):
6191    pass
6192
6193
6194# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
6195class FromISO8601Timestamp(Func):
6196    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
6197
6198
6199class GapFill(Func):
6200    arg_types = {
6201        "this": True,
6202        "ts_column": True,
6203        "bucket_width": True,
6204        "partitioning_columns": False,
6205        "value_columns": False,
6206        "origin": False,
6207        "ignore_nulls": False,
6208    }
6209
6210
6211# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
6212class GenerateDateArray(Func):
6213    arg_types = {"start": True, "end": True, "step": False}
6214
6215
6216# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
6217class GenerateTimestampArray(Func):
6218    arg_types = {"start": True, "end": True, "step": True}
6219
6220
6221# https://docs.snowflake.com/en/sql-reference/functions/get
6222class GetExtract(Func):
6223    arg_types = {"this": True, "expression": True}
6224
6225
6226class Greatest(Func):
6227    arg_types = {"this": True, "expressions": False}
6228    is_var_len_args = True
6229
6230
6231# Trino's `ON OVERFLOW TRUNCATE [filler_string] {WITH | WITHOUT} COUNT`
6232# https://trino.io/docs/current/functions/aggregate.html#listagg
6233class OverflowTruncateBehavior(Expression):
6234    arg_types = {"this": False, "with_count": True}
6235
6236
6237class GroupConcat(AggFunc):
6238    arg_types = {"this": True, "separator": False, "on_overflow": False}
6239
6240
6241class Hex(Func):
6242    pass
6243
6244
6245class LowerHex(Hex):
6246    pass
6247
6248
6249class And(Connector, Func):
6250    pass
6251
6252
6253class Or(Connector, Func):
6254    pass
6255
6256
6257class Xor(Connector, Func):
6258    arg_types = {"this": False, "expression": False, "expressions": False}
6259
6260
6261class If(Func):
6262    arg_types = {"this": True, "true": True, "false": False}
6263    _sql_names = ["IF", "IIF"]
6264
6265
6266class Nullif(Func):
6267    arg_types = {"this": True, "expression": True}
6268
6269
6270class Initcap(Func):
6271    arg_types = {"this": True, "expression": False}
6272
6273
6274class IsAscii(Func):
6275    pass
6276
6277
6278class IsNan(Func):
6279    _sql_names = ["IS_NAN", "ISNAN"]
6280
6281
6282# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#int64_for_json
6283class Int64(Func):
6284    pass
6285
6286
6287class IsInf(Func):
6288    _sql_names = ["IS_INF", "ISINF"]
6289
6290
6291# https://www.postgresql.org/docs/current/functions-json.html
6292class JSON(Expression):
6293    arg_types = {"this": False, "with": False, "unique": False}
6294
6295
6296class JSONPath(Expression):
6297    arg_types = {"expressions": True, "escape": False}
6298
6299    @property
6300    def output_name(self) -> str:
6301        last_segment = self.expressions[-1].this
6302        return last_segment if isinstance(last_segment, str) else ""
6303
6304
6305class JSONPathPart(Expression):
6306    arg_types = {}
6307
6308
6309class JSONPathFilter(JSONPathPart):
6310    arg_types = {"this": True}
6311
6312
6313class JSONPathKey(JSONPathPart):
6314    arg_types = {"this": True}
6315
6316
6317class JSONPathRecursive(JSONPathPart):
6318    arg_types = {"this": False}
6319
6320
6321class JSONPathRoot(JSONPathPart):
6322    pass
6323
6324
6325class JSONPathScript(JSONPathPart):
6326    arg_types = {"this": True}
6327
6328
6329class JSONPathSlice(JSONPathPart):
6330    arg_types = {"start": False, "end": False, "step": False}
6331
6332
6333class JSONPathSelector(JSONPathPart):
6334    arg_types = {"this": True}
6335
6336
6337class JSONPathSubscript(JSONPathPart):
6338    arg_types = {"this": True}
6339
6340
6341class JSONPathUnion(JSONPathPart):
6342    arg_types = {"expressions": True}
6343
6344
6345class JSONPathWildcard(JSONPathPart):
6346    pass
6347
6348
6349class FormatJson(Expression):
6350    pass
6351
6352
6353class JSONKeyValue(Expression):
6354    arg_types = {"this": True, "expression": True}
6355
6356
6357class JSONObject(Func):
6358    arg_types = {
6359        "expressions": False,
6360        "null_handling": False,
6361        "unique_keys": False,
6362        "return_type": False,
6363        "encoding": False,
6364    }
6365
6366
6367class JSONObjectAgg(AggFunc):
6368    arg_types = {
6369        "expressions": False,
6370        "null_handling": False,
6371        "unique_keys": False,
6372        "return_type": False,
6373        "encoding": False,
6374    }
6375
6376
6377# https://www.postgresql.org/docs/9.5/functions-aggregate.html
6378class JSONBObjectAgg(AggFunc):
6379    arg_types = {"this": True, "expression": True}
6380
6381
6382# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
6383class JSONArray(Func):
6384    arg_types = {
6385        "expressions": False,
6386        "null_handling": False,
6387        "return_type": False,
6388        "strict": False,
6389    }
6390
6391
6392# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
6393class JSONArrayAgg(Func):
6394    arg_types = {
6395        "this": True,
6396        "order": False,
6397        "null_handling": False,
6398        "return_type": False,
6399        "strict": False,
6400    }
6401
6402
6403class JSONExists(Func):
6404    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
6405
6406
6407# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6408# Note: parsing of JSON column definitions is currently incomplete.
6409class JSONColumnDef(Expression):
6410    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
6411
6412
6413class JSONSchema(Expression):
6414    arg_types = {"expressions": True}
6415
6416
6417# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
6418class JSONValue(Expression):
6419    arg_types = {
6420        "this": True,
6421        "path": True,
6422        "returning": False,
6423        "on_condition": False,
6424    }
6425
6426
6427class JSONValueArray(Func):
6428    arg_types = {"this": True, "expression": False}
6429
6430
6431# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6432class JSONTable(Func):
6433    arg_types = {
6434        "this": True,
6435        "schema": True,
6436        "path": False,
6437        "error_handling": False,
6438        "empty_handling": False,
6439    }
6440
6441
6442# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#json_type
6443# https://doris.apache.org/docs/sql-manual/sql-functions/scalar-functions/json-functions/json-type#description
6444class JSONType(Func):
6445    arg_types = {"this": True, "expression": False}
6446    _sql_names = ["JSON_TYPE"]
6447
6448
6449# https://docs.snowflake.com/en/sql-reference/functions/object_insert
6450class ObjectInsert(Func):
6451    arg_types = {
6452        "this": True,
6453        "key": True,
6454        "value": True,
6455        "update_flag": False,
6456    }
6457
6458
6459class OpenJSONColumnDef(Expression):
6460    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
6461
6462
6463class OpenJSON(Func):
6464    arg_types = {"this": True, "path": False, "expressions": False}
6465
6466
6467class JSONBContains(Binary, Func):
6468    _sql_names = ["JSONB_CONTAINS"]
6469
6470
6471class JSONBExists(Func):
6472    arg_types = {"this": True, "path": True}
6473    _sql_names = ["JSONB_EXISTS"]
6474
6475
6476class JSONExtract(Binary, Func):
6477    arg_types = {
6478        "this": True,
6479        "expression": True,
6480        "only_json_types": False,
6481        "expressions": False,
6482        "variant_extract": False,
6483        "json_query": False,
6484        "option": False,
6485        "quote": False,
6486        "on_condition": False,
6487        "requires_json": False,
6488    }
6489    _sql_names = ["JSON_EXTRACT"]
6490    is_var_len_args = True
6491
6492    @property
6493    def output_name(self) -> str:
6494        return self.expression.output_name if not self.expressions else ""
6495
6496
6497# https://trino.io/docs/current/functions/json.html#json-query
6498class JSONExtractQuote(Expression):
6499    arg_types = {
6500        "option": True,
6501        "scalar": False,
6502    }
6503
6504
6505class JSONExtractArray(Func):
6506    arg_types = {"this": True, "expression": False}
6507    _sql_names = ["JSON_EXTRACT_ARRAY"]
6508
6509
6510class JSONExtractScalar(Binary, Func):
6511    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6512    _sql_names = ["JSON_EXTRACT_SCALAR"]
6513    is_var_len_args = True
6514
6515    @property
6516    def output_name(self) -> str:
6517        return self.expression.output_name
6518
6519
6520class JSONBExtract(Binary, Func):
6521    _sql_names = ["JSONB_EXTRACT"]
6522
6523
6524class JSONBExtractScalar(Binary, Func):
6525    _sql_names = ["JSONB_EXTRACT_SCALAR"]
6526
6527
6528class JSONFormat(Func):
6529    arg_types = {"this": False, "options": False, "is_json": False}
6530    _sql_names = ["JSON_FORMAT"]
6531
6532
6533# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
6534class JSONArrayContains(Binary, Predicate, Func):
6535    _sql_names = ["JSON_ARRAY_CONTAINS"]
6536
6537
6538class ParseJSON(Func):
6539    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6540    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6541    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6542    arg_types = {"this": True, "expression": False, "safe": False}
6543
6544
6545class ParseTime(Func):
6546    arg_types = {"this": True, "format": True}
6547
6548
6549class ParseDatetime(Func):
6550    arg_types = {"this": True, "format": False, "zone": False}
6551
6552
6553class Least(Func):
6554    arg_types = {"this": True, "expressions": False}
6555    is_var_len_args = True
6556
6557
6558class Left(Func):
6559    arg_types = {"this": True, "expression": True}
6560
6561
6562class Right(Func):
6563    arg_types = {"this": True, "expression": True}
6564
6565
6566class Reverse(Func):
6567    pass
6568
6569
6570class Length(Func):
6571    arg_types = {"this": True, "binary": False, "encoding": False}
6572    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
6573
6574
6575class Levenshtein(Func):
6576    arg_types = {
6577        "this": True,
6578        "expression": False,
6579        "ins_cost": False,
6580        "del_cost": False,
6581        "sub_cost": False,
6582        "max_dist": False,
6583    }
6584
6585
6586class Ln(Func):
6587    pass
6588
6589
6590class Log(Func):
6591    arg_types = {"this": True, "expression": False}
6592
6593
6594class LogicalOr(AggFunc):
6595    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
6596
6597
6598class LogicalAnd(AggFunc):
6599    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
6600
6601
6602class Lower(Func):
6603    _sql_names = ["LOWER", "LCASE"]
6604
6605
6606class Map(Func):
6607    arg_types = {"keys": False, "values": False}
6608
6609    @property
6610    def keys(self) -> t.List[Expression]:
6611        keys = self.args.get("keys")
6612        return keys.expressions if keys else []
6613
6614    @property
6615    def values(self) -> t.List[Expression]:
6616        values = self.args.get("values")
6617        return values.expressions if values else []
6618
6619
6620# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
6621class ToMap(Func):
6622    pass
6623
6624
6625class MapFromEntries(Func):
6626    pass
6627
6628
6629# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
6630class ScopeResolution(Expression):
6631    arg_types = {"this": False, "expression": True}
6632
6633
6634class Stream(Expression):
6635    pass
6636
6637
6638class StarMap(Func):
6639    pass
6640
6641
6642class VarMap(Func):
6643    arg_types = {"keys": True, "values": True}
6644    is_var_len_args = True
6645
6646    @property
6647    def keys(self) -> t.List[Expression]:
6648        return self.args["keys"].expressions
6649
6650    @property
6651    def values(self) -> t.List[Expression]:
6652        return self.args["values"].expressions
6653
6654
6655# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
6656class MatchAgainst(Func):
6657    arg_types = {"this": True, "expressions": True, "modifier": False}
6658
6659
6660class Max(AggFunc):
6661    arg_types = {"this": True, "expressions": False}
6662    is_var_len_args = True
6663
6664
6665class MD5(Func):
6666    _sql_names = ["MD5"]
6667
6668
6669# Represents the variant of the MD5 function that returns a binary value
6670class MD5Digest(Func):
6671    _sql_names = ["MD5_DIGEST"]
6672
6673
6674class Median(AggFunc):
6675    pass
6676
6677
6678class Min(AggFunc):
6679    arg_types = {"this": True, "expressions": False}
6680    is_var_len_args = True
6681
6682
6683class Month(Func):
6684    pass
6685
6686
6687class AddMonths(Func):
6688    arg_types = {"this": True, "expression": True}
6689
6690
6691class Nvl2(Func):
6692    arg_types = {"this": True, "true": True, "false": False}
6693
6694
6695class Normalize(Func):
6696    arg_types = {"this": True, "form": False}
6697
6698
6699class Overlay(Func):
6700    arg_types = {"this": True, "expression": True, "from": True, "for": False}
6701
6702
6703# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
6704class Predict(Func):
6705    arg_types = {"this": True, "expression": True, "params_struct": False}
6706
6707
6708class Pow(Binary, Func):
6709    _sql_names = ["POWER", "POW"]
6710
6711
6712class PercentileCont(AggFunc):
6713    arg_types = {"this": True, "expression": False}
6714
6715
6716class PercentileDisc(AggFunc):
6717    arg_types = {"this": True, "expression": False}
6718
6719
6720class Quantile(AggFunc):
6721    arg_types = {"this": True, "quantile": True}
6722
6723
6724class ApproxQuantile(Quantile):
6725    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
6726
6727
6728class Quarter(Func):
6729    pass
6730
6731
6732# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
6733# teradata lower and upper bounds
6734class Rand(Func):
6735    _sql_names = ["RAND", "RANDOM"]
6736    arg_types = {"this": False, "lower": False, "upper": False}
6737
6738
6739class Randn(Func):
6740    arg_types = {"this": False}
6741
6742
6743class RangeN(Func):
6744    arg_types = {"this": True, "expressions": True, "each": False}
6745
6746
6747class ReadCSV(Func):
6748    _sql_names = ["READ_CSV"]
6749    is_var_len_args = True
6750    arg_types = {"this": True, "expressions": False}
6751
6752
6753class Reduce(Func):
6754    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
6755
6756
6757class RegexpExtract(Func):
6758    arg_types = {
6759        "this": True,
6760        "expression": True,
6761        "position": False,
6762        "occurrence": False,
6763        "parameters": False,
6764        "group": False,
6765    }
6766
6767
6768class RegexpExtractAll(Func):
6769    arg_types = {
6770        "this": True,
6771        "expression": True,
6772        "position": False,
6773        "occurrence": False,
6774        "parameters": False,
6775        "group": False,
6776    }
6777
6778
6779class RegexpReplace(Func):
6780    arg_types = {
6781        "this": True,
6782        "expression": True,
6783        "replacement": False,
6784        "position": False,
6785        "occurrence": False,
6786        "modifiers": False,
6787    }
6788
6789
6790class RegexpLike(Binary, Func):
6791    arg_types = {"this": True, "expression": True, "flag": False}
6792
6793
6794class RegexpILike(Binary, Func):
6795    arg_types = {"this": True, "expression": True, "flag": False}
6796
6797
6798# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6799# limit is the number of times a pattern is applied
6800class RegexpSplit(Func):
6801    arg_types = {"this": True, "expression": True, "limit": False}
6802
6803
6804class Repeat(Func):
6805    arg_types = {"this": True, "times": True}
6806
6807
6808# Some dialects like Snowflake support two argument replace
6809class Replace(Func):
6810    arg_types = {"this": True, "expression": True, "replacement": False}
6811
6812
6813# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6814# tsql third argument function == trunctaion if not 0
6815class Round(Func):
6816    arg_types = {"this": True, "decimals": False, "truncate": False}
6817
6818
6819class RowNumber(Func):
6820    arg_types = {"this": False}
6821
6822
6823class SafeDivide(Func):
6824    arg_types = {"this": True, "expression": True}
6825
6826
6827class SHA(Func):
6828    _sql_names = ["SHA", "SHA1"]
6829
6830
6831class SHA2(Func):
6832    _sql_names = ["SHA2"]
6833    arg_types = {"this": True, "length": False}
6834
6835
6836class Sign(Func):
6837    _sql_names = ["SIGN", "SIGNUM"]
6838
6839
6840class SortArray(Func):
6841    arg_types = {"this": True, "asc": False}
6842
6843
6844class Split(Func):
6845    arg_types = {"this": True, "expression": True, "limit": False}
6846
6847
6848# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split_part.html
6849class SplitPart(Func):
6850    arg_types = {"this": True, "delimiter": True, "part_index": True}
6851
6852
6853# Start may be omitted in the case of postgres
6854# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6855class Substring(Func):
6856    _sql_names = ["SUBSTRING", "SUBSTR"]
6857    arg_types = {"this": True, "start": False, "length": False}
6858
6859
6860class SubstringIndex(Func):
6861    """
6862    SUBSTRING_INDEX(str, delim, count)
6863
6864    *count* > 0  → left slice before the *count*-th delimiter
6865    *count* < 0  → right slice after the |count|-th delimiter
6866    """
6867
6868    arg_types = {"this": True, "delimiter": True, "count": True}
6869
6870
6871class StandardHash(Func):
6872    arg_types = {"this": True, "expression": False}
6873
6874
6875class StartsWith(Func):
6876    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6877    arg_types = {"this": True, "expression": True}
6878
6879
6880class EndsWith(Func):
6881    _sql_names = ["ENDS_WITH", "ENDSWITH"]
6882    arg_types = {"this": True, "expression": True}
6883
6884
6885class StrPosition(Func):
6886    arg_types = {
6887        "this": True,
6888        "substr": True,
6889        "position": False,
6890        "occurrence": False,
6891    }
6892
6893
6894class StrToDate(Func):
6895    arg_types = {"this": True, "format": False, "safe": False}
6896
6897
6898class StrToTime(Func):
6899    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6900
6901
6902# Spark allows unix_timestamp()
6903# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6904class StrToUnix(Func):
6905    arg_types = {"this": False, "format": False}
6906
6907
6908# https://prestodb.io/docs/current/functions/string.html
6909# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6910class StrToMap(Func):
6911    arg_types = {
6912        "this": True,
6913        "pair_delim": False,
6914        "key_value_delim": False,
6915        "duplicate_resolution_callback": False,
6916    }
6917
6918
6919class NumberToStr(Func):
6920    arg_types = {"this": True, "format": True, "culture": False}
6921
6922
6923class FromBase(Func):
6924    arg_types = {"this": True, "expression": True}
6925
6926
6927class Space(Func):
6928    """
6929    SPACE(n) → string consisting of n blank characters
6930    """
6931
6932    pass
6933
6934
6935class Struct(Func):
6936    arg_types = {"expressions": False}
6937    is_var_len_args = True
6938
6939
6940class StructExtract(Func):
6941    arg_types = {"this": True, "expression": True}
6942
6943
6944# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6945# https://docs.snowflake.com/en/sql-reference/functions/insert
6946class Stuff(Func):
6947    _sql_names = ["STUFF", "INSERT"]
6948    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6949
6950
6951class Sum(AggFunc):
6952    pass
6953
6954
6955class Sqrt(Func):
6956    pass
6957
6958
6959class Stddev(AggFunc):
6960    _sql_names = ["STDDEV", "STDEV"]
6961
6962
6963class StddevPop(AggFunc):
6964    pass
6965
6966
6967class StddevSamp(AggFunc):
6968    pass
6969
6970
6971# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6972class Time(Func):
6973    arg_types = {"this": False, "zone": False}
6974
6975
6976class TimeToStr(Func):
6977    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6978
6979
6980class TimeToTimeStr(Func):
6981    pass
6982
6983
6984class TimeToUnix(Func):
6985    pass
6986
6987
6988class TimeStrToDate(Func):
6989    pass
6990
6991
6992class TimeStrToTime(Func):
6993    arg_types = {"this": True, "zone": False}
6994
6995
6996class TimeStrToUnix(Func):
6997    pass
6998
6999
7000class Trim(Func):
7001    arg_types = {
7002        "this": True,
7003        "expression": False,
7004        "position": False,
7005        "collation": False,
7006    }
7007
7008
7009class TsOrDsAdd(Func, TimeUnit):
7010    # return_type is used to correctly cast the arguments of this expression when transpiling it
7011    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
7012
7013    @property
7014    def return_type(self) -> DataType:
7015        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
7016
7017
7018class TsOrDsDiff(Func, TimeUnit):
7019    arg_types = {"this": True, "expression": True, "unit": False}
7020
7021
7022class TsOrDsToDateStr(Func):
7023    pass
7024
7025
7026class TsOrDsToDate(Func):
7027    arg_types = {"this": True, "format": False, "safe": False}
7028
7029
7030class TsOrDsToDatetime(Func):
7031    pass
7032
7033
7034class TsOrDsToTime(Func):
7035    arg_types = {"this": True, "format": False, "safe": False}
7036
7037
7038class TsOrDsToTimestamp(Func):
7039    pass
7040
7041
7042class TsOrDiToDi(Func):
7043    pass
7044
7045
7046class Unhex(Func):
7047    arg_types = {"this": True, "expression": False}
7048
7049
7050class Unicode(Func):
7051    pass
7052
7053
7054# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
7055class UnixDate(Func):
7056    pass
7057
7058
7059class UnixToStr(Func):
7060    arg_types = {"this": True, "format": False}
7061
7062
7063# https://prestodb.io/docs/current/functions/datetime.html
7064# presto has weird zone/hours/minutes
7065class UnixToTime(Func):
7066    arg_types = {
7067        "this": True,
7068        "scale": False,
7069        "zone": False,
7070        "hours": False,
7071        "minutes": False,
7072        "format": False,
7073    }
7074
7075    SECONDS = Literal.number(0)
7076    DECIS = Literal.number(1)
7077    CENTIS = Literal.number(2)
7078    MILLIS = Literal.number(3)
7079    DECIMILLIS = Literal.number(4)
7080    CENTIMILLIS = Literal.number(5)
7081    MICROS = Literal.number(6)
7082    DECIMICROS = Literal.number(7)
7083    CENTIMICROS = Literal.number(8)
7084    NANOS = Literal.number(9)
7085
7086
7087class UnixToTimeStr(Func):
7088    pass
7089
7090
7091class UnixSeconds(Func):
7092    pass
7093
7094
7095class UnixMicros(Func):
7096    pass
7097
7098
7099class UnixMillis(Func):
7100    pass
7101
7102
7103class Uuid(Func):
7104    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7105
7106    arg_types = {"this": False, "name": False}
7107
7108
7109class TimestampFromParts(Func):
7110    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7111    arg_types = {
7112        "year": True,
7113        "month": True,
7114        "day": True,
7115        "hour": True,
7116        "min": True,
7117        "sec": True,
7118        "nano": False,
7119        "zone": False,
7120        "milli": False,
7121    }
7122
7123
7124class Upper(Func):
7125    _sql_names = ["UPPER", "UCASE"]
7126
7127
7128class Corr(Binary, AggFunc):
7129    pass
7130
7131
7132class Variance(AggFunc):
7133    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
7134
7135
7136class VariancePop(AggFunc):
7137    _sql_names = ["VARIANCE_POP", "VAR_POP"]
7138
7139
7140class CovarSamp(Binary, AggFunc):
7141    pass
7142
7143
7144class CovarPop(Binary, AggFunc):
7145    pass
7146
7147
7148class Week(Func):
7149    arg_types = {"this": True, "mode": False}
7150
7151
7152class WeekStart(Expression):
7153    pass
7154
7155
7156class XMLElement(Func):
7157    _sql_names = ["XMLELEMENT"]
7158    arg_types = {"this": True, "expressions": False}
7159
7160
7161class XMLTable(Func):
7162    arg_types = {
7163        "this": True,
7164        "namespaces": False,
7165        "passing": False,
7166        "columns": False,
7167        "by_ref": False,
7168    }
7169
7170
7171class XMLNamespace(Expression):
7172    pass
7173
7174
7175# https://learn.microsoft.com/en-us/sql/t-sql/queries/select-for-clause-transact-sql?view=sql-server-ver17#syntax
7176class XMLKeyValueOption(Expression):
7177    arg_types = {"this": True, "expression": False}
7178
7179
7180class Year(Func):
7181    pass
7182
7183
7184class Use(Expression):
7185    arg_types = {"this": False, "expressions": False, "kind": False}
7186
7187
7188class Merge(DML):
7189    arg_types = {
7190        "this": True,
7191        "using": True,
7192        "on": True,
7193        "whens": True,
7194        "with": False,
7195        "returning": False,
7196    }
7197
7198
7199class When(Expression):
7200    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
7201
7202
7203class Whens(Expression):
7204    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7205
7206    arg_types = {"expressions": True}
7207
7208
7209# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
7210# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
7211class NextValueFor(Func):
7212    arg_types = {"this": True, "order": False}
7213
7214
7215# Refers to a trailing semi-colon. This is only used to preserve trailing comments
7216# select 1; -- my comment
7217class Semicolon(Expression):
7218    arg_types = {}
7219
7220
7221# BigQuery allows SELECT t FROM t and treats the projection as a struct value. This expression
7222# type is intended to be constructed by qualify so that we can properly annotate its type later
7223class TableColumn(Expression):
7224    pass
7225
7226
7227def _norm_arg(arg):
7228    return arg.lower() if type(arg) is str else arg
7229
7230
7231ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
7232FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
7233
7234JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
7235
7236PERCENTILES = (PercentileCont, PercentileDisc)
7237
7238
7239# Helpers
7240@t.overload
7241def maybe_parse(
7242    sql_or_expression: ExpOrStr,
7243    *,
7244    into: t.Type[E],
7245    dialect: DialectType = None,
7246    prefix: t.Optional[str] = None,
7247    copy: bool = False,
7248    **opts,
7249) -> E: ...
7250
7251
7252@t.overload
7253def maybe_parse(
7254    sql_or_expression: str | E,
7255    *,
7256    into: t.Optional[IntoType] = None,
7257    dialect: DialectType = None,
7258    prefix: t.Optional[str] = None,
7259    copy: bool = False,
7260    **opts,
7261) -> E: ...
7262
7263
7264def maybe_parse(
7265    sql_or_expression: ExpOrStr,
7266    *,
7267    into: t.Optional[IntoType] = None,
7268    dialect: DialectType = None,
7269    prefix: t.Optional[str] = None,
7270    copy: bool = False,
7271    **opts,
7272) -> Expression:
7273    """Gracefully handle a possible string or expression.
7274
7275    Example:
7276        >>> maybe_parse("1")
7277        Literal(this=1, is_string=False)
7278        >>> maybe_parse(to_identifier("x"))
7279        Identifier(this=x, quoted=False)
7280
7281    Args:
7282        sql_or_expression: the SQL code string or an expression
7283        into: the SQLGlot Expression to parse into
7284        dialect: the dialect used to parse the input expressions (in the case that an
7285            input expression is a SQL string).
7286        prefix: a string to prefix the sql with before it gets parsed
7287            (automatically includes a space)
7288        copy: whether to copy the expression.
7289        **opts: other options to use to parse the input expressions (again, in the case
7290            that an input expression is a SQL string).
7291
7292    Returns:
7293        Expression: the parsed or given expression.
7294    """
7295    if isinstance(sql_or_expression, Expression):
7296        if copy:
7297            return sql_or_expression.copy()
7298        return sql_or_expression
7299
7300    if sql_or_expression is None:
7301        raise ParseError("SQL cannot be None")
7302
7303    import sqlglot
7304
7305    sql = str(sql_or_expression)
7306    if prefix:
7307        sql = f"{prefix} {sql}"
7308
7309    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
7310
7311
7312@t.overload
7313def maybe_copy(instance: None, copy: bool = True) -> None: ...
7314
7315
7316@t.overload
7317def maybe_copy(instance: E, copy: bool = True) -> E: ...
7318
7319
7320def maybe_copy(instance, copy=True):
7321    return instance.copy() if copy and instance else instance
7322
7323
7324def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = False) -> str:
7325    """Generate a textual representation of an Expression tree"""
7326    indent = "\n" + ("  " * (level + 1))
7327    delim = f",{indent}"
7328
7329    if isinstance(node, Expression):
7330        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
7331
7332        if (node.type or verbose) and not isinstance(node, DataType):
7333            args["_type"] = node.type
7334        if node.comments or verbose:
7335            args["_comments"] = node.comments
7336
7337        if verbose:
7338            args["_id"] = id(node)
7339
7340        # Inline leaves for a more compact representation
7341        if node.is_leaf():
7342            indent = ""
7343            delim = ", "
7344
7345        repr_str = node.is_string or (isinstance(node, Identifier) and node.quoted)
7346        items = delim.join(
7347            [f"{k}={_to_s(v, verbose, level + 1, repr_str=repr_str)}" for k, v in args.items()]
7348        )
7349        return f"{node.__class__.__name__}({indent}{items})"
7350
7351    if isinstance(node, list):
7352        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
7353        items = f"{indent}{items}" if items else ""
7354        return f"[{items}]"
7355
7356    # We use the representation of the string to avoid stripping out important whitespace
7357    if repr_str and isinstance(node, str):
7358        node = repr(node)
7359
7360    # Indent multiline strings to match the current level
7361    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
7362
7363
7364def _is_wrong_expression(expression, into):
7365    return isinstance(expression, Expression) and not isinstance(expression, into)
7366
7367
7368def _apply_builder(
7369    expression,
7370    instance,
7371    arg,
7372    copy=True,
7373    prefix=None,
7374    into=None,
7375    dialect=None,
7376    into_arg="this",
7377    **opts,
7378):
7379    if _is_wrong_expression(expression, into):
7380        expression = into(**{into_arg: expression})
7381    instance = maybe_copy(instance, copy)
7382    expression = maybe_parse(
7383        sql_or_expression=expression,
7384        prefix=prefix,
7385        into=into,
7386        dialect=dialect,
7387        **opts,
7388    )
7389    instance.set(arg, expression)
7390    return instance
7391
7392
7393def _apply_child_list_builder(
7394    *expressions,
7395    instance,
7396    arg,
7397    append=True,
7398    copy=True,
7399    prefix=None,
7400    into=None,
7401    dialect=None,
7402    properties=None,
7403    **opts,
7404):
7405    instance = maybe_copy(instance, copy)
7406    parsed = []
7407    properties = {} if properties is None else properties
7408
7409    for expression in expressions:
7410        if expression is not None:
7411            if _is_wrong_expression(expression, into):
7412                expression = into(expressions=[expression])
7413
7414            expression = maybe_parse(
7415                expression,
7416                into=into,
7417                dialect=dialect,
7418                prefix=prefix,
7419                **opts,
7420            )
7421            for k, v in expression.args.items():
7422                if k == "expressions":
7423                    parsed.extend(v)
7424                else:
7425                    properties[k] = v
7426
7427    existing = instance.args.get(arg)
7428    if append and existing:
7429        parsed = existing.expressions + parsed
7430
7431    child = into(expressions=parsed)
7432    for k, v in properties.items():
7433        child.set(k, v)
7434    instance.set(arg, child)
7435
7436    return instance
7437
7438
7439def _apply_list_builder(
7440    *expressions,
7441    instance,
7442    arg,
7443    append=True,
7444    copy=True,
7445    prefix=None,
7446    into=None,
7447    dialect=None,
7448    **opts,
7449):
7450    inst = maybe_copy(instance, copy)
7451
7452    expressions = [
7453        maybe_parse(
7454            sql_or_expression=expression,
7455            into=into,
7456            prefix=prefix,
7457            dialect=dialect,
7458            **opts,
7459        )
7460        for expression in expressions
7461        if expression is not None
7462    ]
7463
7464    existing_expressions = inst.args.get(arg)
7465    if append and existing_expressions:
7466        expressions = existing_expressions + expressions
7467
7468    inst.set(arg, expressions)
7469    return inst
7470
7471
7472def _apply_conjunction_builder(
7473    *expressions,
7474    instance,
7475    arg,
7476    into=None,
7477    append=True,
7478    copy=True,
7479    dialect=None,
7480    **opts,
7481):
7482    expressions = [exp for exp in expressions if exp is not None and exp != ""]
7483    if not expressions:
7484        return instance
7485
7486    inst = maybe_copy(instance, copy)
7487
7488    existing = inst.args.get(arg)
7489    if append and existing is not None:
7490        expressions = [existing.this if into else existing] + list(expressions)
7491
7492    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
7493
7494    inst.set(arg, into(this=node) if into else node)
7495    return inst
7496
7497
7498def _apply_cte_builder(
7499    instance: E,
7500    alias: ExpOrStr,
7501    as_: ExpOrStr,
7502    recursive: t.Optional[bool] = None,
7503    materialized: t.Optional[bool] = None,
7504    append: bool = True,
7505    dialect: DialectType = None,
7506    copy: bool = True,
7507    scalar: bool = False,
7508    **opts,
7509) -> E:
7510    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
7511    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
7512    if scalar and not isinstance(as_expression, Subquery):
7513        # scalar CTE must be wrapped in a subquery
7514        as_expression = Subquery(this=as_expression)
7515    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
7516    return _apply_child_list_builder(
7517        cte,
7518        instance=instance,
7519        arg="with",
7520        append=append,
7521        copy=copy,
7522        into=With,
7523        properties={"recursive": recursive or False},
7524    )
7525
7526
7527def _combine(
7528    expressions: t.Sequence[t.Optional[ExpOrStr]],
7529    operator: t.Type[Connector],
7530    dialect: DialectType = None,
7531    copy: bool = True,
7532    wrap: bool = True,
7533    **opts,
7534) -> Expression:
7535    conditions = [
7536        condition(expression, dialect=dialect, copy=copy, **opts)
7537        for expression in expressions
7538        if expression is not None
7539    ]
7540
7541    this, *rest = conditions
7542    if rest and wrap:
7543        this = _wrap(this, Connector)
7544    for expression in rest:
7545        this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression)
7546
7547    return this
7548
7549
7550@t.overload
7551def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
7552
7553
7554@t.overload
7555def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
7556
7557
7558def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
7559    return Paren(this=expression) if isinstance(expression, kind) else expression
7560
7561
7562def _apply_set_operation(
7563    *expressions: ExpOrStr,
7564    set_operation: t.Type[S],
7565    distinct: bool = True,
7566    dialect: DialectType = None,
7567    copy: bool = True,
7568    **opts,
7569) -> S:
7570    return reduce(
7571        lambda x, y: set_operation(this=x, expression=y, distinct=distinct, **opts),
7572        (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7573    )
7574
7575
7576def union(
7577    *expressions: ExpOrStr,
7578    distinct: bool = True,
7579    dialect: DialectType = None,
7580    copy: bool = True,
7581    **opts,
7582) -> Union:
7583    """
7584    Initializes a syntax tree for the `UNION` operation.
7585
7586    Example:
7587        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7588        'SELECT * FROM foo UNION SELECT * FROM bla'
7589
7590    Args:
7591        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7592            If `Expression` instances are passed, they will be used as-is.
7593        distinct: set the DISTINCT flag if and only if this is true.
7594        dialect: the dialect used to parse the input expression.
7595        copy: whether to copy the expression.
7596        opts: other options to use to parse the input expressions.
7597
7598    Returns:
7599        The new Union instance.
7600    """
7601    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7602    return _apply_set_operation(
7603        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7604    )
7605
7606
7607def intersect(
7608    *expressions: ExpOrStr,
7609    distinct: bool = True,
7610    dialect: DialectType = None,
7611    copy: bool = True,
7612    **opts,
7613) -> Intersect:
7614    """
7615    Initializes a syntax tree for the `INTERSECT` operation.
7616
7617    Example:
7618        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7619        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7620
7621    Args:
7622        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7623            If `Expression` instances are passed, they will be used as-is.
7624        distinct: set the DISTINCT flag if and only if this is true.
7625        dialect: the dialect used to parse the input expression.
7626        copy: whether to copy the expression.
7627        opts: other options to use to parse the input expressions.
7628
7629    Returns:
7630        The new Intersect instance.
7631    """
7632    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7633    return _apply_set_operation(
7634        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7635    )
7636
7637
7638def except_(
7639    *expressions: ExpOrStr,
7640    distinct: bool = True,
7641    dialect: DialectType = None,
7642    copy: bool = True,
7643    **opts,
7644) -> Except:
7645    """
7646    Initializes a syntax tree for the `EXCEPT` operation.
7647
7648    Example:
7649        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7650        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7651
7652    Args:
7653        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7654            If `Expression` instances are passed, they will be used as-is.
7655        distinct: set the DISTINCT flag if and only if this is true.
7656        dialect: the dialect used to parse the input expression.
7657        copy: whether to copy the expression.
7658        opts: other options to use to parse the input expressions.
7659
7660    Returns:
7661        The new Except instance.
7662    """
7663    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7664    return _apply_set_operation(
7665        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7666    )
7667
7668
7669def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7670    """
7671    Initializes a syntax tree from one or multiple SELECT expressions.
7672
7673    Example:
7674        >>> select("col1", "col2").from_("tbl").sql()
7675        'SELECT col1, col2 FROM tbl'
7676
7677    Args:
7678        *expressions: the SQL code string to parse as the expressions of a
7679            SELECT statement. If an Expression instance is passed, this is used as-is.
7680        dialect: the dialect used to parse the input expressions (in the case that an
7681            input expression is a SQL string).
7682        **opts: other options to use to parse the input expressions (again, in the case
7683            that an input expression is a SQL string).
7684
7685    Returns:
7686        Select: the syntax tree for the SELECT statement.
7687    """
7688    return Select().select(*expressions, dialect=dialect, **opts)
7689
7690
7691def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7692    """
7693    Initializes a syntax tree from a FROM expression.
7694
7695    Example:
7696        >>> from_("tbl").select("col1", "col2").sql()
7697        'SELECT col1, col2 FROM tbl'
7698
7699    Args:
7700        *expression: the SQL code string to parse as the FROM expressions of a
7701            SELECT statement. If an Expression instance is passed, this is used as-is.
7702        dialect: the dialect used to parse the input expression (in the case that the
7703            input expression is a SQL string).
7704        **opts: other options to use to parse the input expressions (again, in the case
7705            that the input expression is a SQL string).
7706
7707    Returns:
7708        Select: the syntax tree for the SELECT statement.
7709    """
7710    return Select().from_(expression, dialect=dialect, **opts)
7711
7712
7713def update(
7714    table: str | Table,
7715    properties: t.Optional[dict] = None,
7716    where: t.Optional[ExpOrStr] = None,
7717    from_: t.Optional[ExpOrStr] = None,
7718    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7719    dialect: DialectType = None,
7720    **opts,
7721) -> Update:
7722    """
7723    Creates an update statement.
7724
7725    Example:
7726        >>> 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()
7727        "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"
7728
7729    Args:
7730        properties: dictionary of properties to SET which are
7731            auto converted to sql objects eg None -> NULL
7732        where: sql conditional parsed into a WHERE statement
7733        from_: sql statement parsed into a FROM statement
7734        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7735        dialect: the dialect used to parse the input expressions.
7736        **opts: other options to use to parse the input expressions.
7737
7738    Returns:
7739        Update: the syntax tree for the UPDATE statement.
7740    """
7741    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7742    if properties:
7743        update_expr.set(
7744            "expressions",
7745            [
7746                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7747                for k, v in properties.items()
7748            ],
7749        )
7750    if from_:
7751        update_expr.set(
7752            "from",
7753            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7754        )
7755    if isinstance(where, Condition):
7756        where = Where(this=where)
7757    if where:
7758        update_expr.set(
7759            "where",
7760            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7761        )
7762    if with_:
7763        cte_list = [
7764            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7765            for alias, qry in with_.items()
7766        ]
7767        update_expr.set(
7768            "with",
7769            With(expressions=cte_list),
7770        )
7771    return update_expr
7772
7773
7774def delete(
7775    table: ExpOrStr,
7776    where: t.Optional[ExpOrStr] = None,
7777    returning: t.Optional[ExpOrStr] = None,
7778    dialect: DialectType = None,
7779    **opts,
7780) -> Delete:
7781    """
7782    Builds a delete statement.
7783
7784    Example:
7785        >>> delete("my_table", where="id > 1").sql()
7786        'DELETE FROM my_table WHERE id > 1'
7787
7788    Args:
7789        where: sql conditional parsed into a WHERE statement
7790        returning: sql conditional parsed into a RETURNING statement
7791        dialect: the dialect used to parse the input expressions.
7792        **opts: other options to use to parse the input expressions.
7793
7794    Returns:
7795        Delete: the syntax tree for the DELETE statement.
7796    """
7797    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7798    if where:
7799        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7800    if returning:
7801        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7802    return delete_expr
7803
7804
7805def insert(
7806    expression: ExpOrStr,
7807    into: ExpOrStr,
7808    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7809    overwrite: t.Optional[bool] = None,
7810    returning: t.Optional[ExpOrStr] = None,
7811    dialect: DialectType = None,
7812    copy: bool = True,
7813    **opts,
7814) -> Insert:
7815    """
7816    Builds an INSERT statement.
7817
7818    Example:
7819        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7820        'INSERT INTO tbl VALUES (1, 2, 3)'
7821
7822    Args:
7823        expression: the sql string or expression of the INSERT statement
7824        into: the tbl to insert data to.
7825        columns: optionally the table's column names.
7826        overwrite: whether to INSERT OVERWRITE or not.
7827        returning: sql conditional parsed into a RETURNING statement
7828        dialect: the dialect used to parse the input expressions.
7829        copy: whether to copy the expression.
7830        **opts: other options to use to parse the input expressions.
7831
7832    Returns:
7833        Insert: the syntax tree for the INSERT statement.
7834    """
7835    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7836    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7837
7838    if columns:
7839        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7840
7841    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7842
7843    if returning:
7844        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7845
7846    return insert
7847
7848
7849def merge(
7850    *when_exprs: ExpOrStr,
7851    into: ExpOrStr,
7852    using: ExpOrStr,
7853    on: ExpOrStr,
7854    returning: t.Optional[ExpOrStr] = None,
7855    dialect: DialectType = None,
7856    copy: bool = True,
7857    **opts,
7858) -> Merge:
7859    """
7860    Builds a MERGE statement.
7861
7862    Example:
7863        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7864        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7865        ...       into="my_table",
7866        ...       using="source_table",
7867        ...       on="my_table.id = source_table.id").sql()
7868        '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)'
7869
7870    Args:
7871        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7872        into: The target table to merge data into.
7873        using: The source table to merge data from.
7874        on: The join condition for the merge.
7875        returning: The columns to return from the merge.
7876        dialect: The dialect used to parse the input expressions.
7877        copy: Whether to copy the expression.
7878        **opts: Other options to use to parse the input expressions.
7879
7880    Returns:
7881        Merge: The syntax tree for the MERGE statement.
7882    """
7883    expressions: t.List[Expression] = []
7884    for when_expr in when_exprs:
7885        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7886        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7887
7888    merge = Merge(
7889        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7890        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7891        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7892        whens=Whens(expressions=expressions),
7893    )
7894    if returning:
7895        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7896
7897    return merge
7898
7899
7900def condition(
7901    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7902) -> Condition:
7903    """
7904    Initialize a logical condition expression.
7905
7906    Example:
7907        >>> condition("x=1").sql()
7908        'x = 1'
7909
7910        This is helpful for composing larger logical syntax trees:
7911        >>> where = condition("x=1")
7912        >>> where = where.and_("y=1")
7913        >>> Select().from_("tbl").select("*").where(where).sql()
7914        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7915
7916    Args:
7917        *expression: the SQL code string to parse.
7918            If an Expression instance is passed, this is used as-is.
7919        dialect: the dialect used to parse the input expression (in the case that the
7920            input expression is a SQL string).
7921        copy: Whether to copy `expression` (only applies to expressions).
7922        **opts: other options to use to parse the input expressions (again, in the case
7923            that the input expression is a SQL string).
7924
7925    Returns:
7926        The new Condition instance
7927    """
7928    return maybe_parse(
7929        expression,
7930        into=Condition,
7931        dialect=dialect,
7932        copy=copy,
7933        **opts,
7934    )
7935
7936
7937def and_(
7938    *expressions: t.Optional[ExpOrStr],
7939    dialect: DialectType = None,
7940    copy: bool = True,
7941    wrap: bool = True,
7942    **opts,
7943) -> Condition:
7944    """
7945    Combine multiple conditions with an AND logical operator.
7946
7947    Example:
7948        >>> and_("x=1", and_("y=1", "z=1")).sql()
7949        'x = 1 AND (y = 1 AND z = 1)'
7950
7951    Args:
7952        *expressions: the SQL code strings to parse.
7953            If an Expression instance is passed, this is used as-is.
7954        dialect: the dialect used to parse the input expression.
7955        copy: whether to copy `expressions` (only applies to Expressions).
7956        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7957            precedence issues, but can be turned off when the produced AST is too deep and
7958            causes recursion-related issues.
7959        **opts: other options to use to parse the input expressions.
7960
7961    Returns:
7962        The new condition
7963    """
7964    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
7965
7966
7967def or_(
7968    *expressions: t.Optional[ExpOrStr],
7969    dialect: DialectType = None,
7970    copy: bool = True,
7971    wrap: bool = True,
7972    **opts,
7973) -> Condition:
7974    """
7975    Combine multiple conditions with an OR logical operator.
7976
7977    Example:
7978        >>> or_("x=1", or_("y=1", "z=1")).sql()
7979        'x = 1 OR (y = 1 OR z = 1)'
7980
7981    Args:
7982        *expressions: the SQL code strings to parse.
7983            If an Expression instance is passed, this is used as-is.
7984        dialect: the dialect used to parse the input expression.
7985        copy: whether to copy `expressions` (only applies to Expressions).
7986        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7987            precedence issues, but can be turned off when the produced AST is too deep and
7988            causes recursion-related issues.
7989        **opts: other options to use to parse the input expressions.
7990
7991    Returns:
7992        The new condition
7993    """
7994    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
7995
7996
7997def xor(
7998    *expressions: t.Optional[ExpOrStr],
7999    dialect: DialectType = None,
8000    copy: bool = True,
8001    wrap: bool = True,
8002    **opts,
8003) -> Condition:
8004    """
8005    Combine multiple conditions with an XOR logical operator.
8006
8007    Example:
8008        >>> xor("x=1", xor("y=1", "z=1")).sql()
8009        'x = 1 XOR (y = 1 XOR z = 1)'
8010
8011    Args:
8012        *expressions: the SQL code strings to parse.
8013            If an Expression instance is passed, this is used as-is.
8014        dialect: the dialect used to parse the input expression.
8015        copy: whether to copy `expressions` (only applies to Expressions).
8016        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8017            precedence issues, but can be turned off when the produced AST is too deep and
8018            causes recursion-related issues.
8019        **opts: other options to use to parse the input expressions.
8020
8021    Returns:
8022        The new condition
8023    """
8024    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
8025
8026
8027def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
8028    """
8029    Wrap a condition with a NOT operator.
8030
8031    Example:
8032        >>> not_("this_suit='black'").sql()
8033        "NOT this_suit = 'black'"
8034
8035    Args:
8036        expression: the SQL code string to parse.
8037            If an Expression instance is passed, this is used as-is.
8038        dialect: the dialect used to parse the input expression.
8039        copy: whether to copy the expression or not.
8040        **opts: other options to use to parse the input expressions.
8041
8042    Returns:
8043        The new condition.
8044    """
8045    this = condition(
8046        expression,
8047        dialect=dialect,
8048        copy=copy,
8049        **opts,
8050    )
8051    return Not(this=_wrap(this, Connector))
8052
8053
8054def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
8055    """
8056    Wrap an expression in parentheses.
8057
8058    Example:
8059        >>> paren("5 + 3").sql()
8060        '(5 + 3)'
8061
8062    Args:
8063        expression: the SQL code string to parse.
8064            If an Expression instance is passed, this is used as-is.
8065        copy: whether to copy the expression or not.
8066
8067    Returns:
8068        The wrapped expression.
8069    """
8070    return Paren(this=maybe_parse(expression, copy=copy))
8071
8072
8073SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
8074
8075
8076@t.overload
8077def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
8078
8079
8080@t.overload
8081def to_identifier(
8082    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
8083) -> Identifier: ...
8084
8085
8086def to_identifier(name, quoted=None, copy=True):
8087    """Builds an identifier.
8088
8089    Args:
8090        name: The name to turn into an identifier.
8091        quoted: Whether to force quote the identifier.
8092        copy: Whether to copy name if it's an Identifier.
8093
8094    Returns:
8095        The identifier ast node.
8096    """
8097
8098    if name is None:
8099        return None
8100
8101    if isinstance(name, Identifier):
8102        identifier = maybe_copy(name, copy)
8103    elif isinstance(name, str):
8104        identifier = Identifier(
8105            this=name,
8106            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8107        )
8108    else:
8109        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8110    return identifier
8111
8112
8113def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8114    """
8115    Parses a given string into an identifier.
8116
8117    Args:
8118        name: The name to parse into an identifier.
8119        dialect: The dialect to parse against.
8120
8121    Returns:
8122        The identifier ast node.
8123    """
8124    try:
8125        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8126    except (ParseError, TokenError):
8127        expression = to_identifier(name)
8128
8129    return expression
8130
8131
8132INTERVAL_STRING_RE = re.compile(r"\s*(-?[0-9]+(?:\.[0-9]+)?)\s*([a-zA-Z]+)\s*")
8133
8134
8135def to_interval(interval: str | Literal) -> Interval:
8136    """Builds an interval expression from a string like '1 day' or '5 months'."""
8137    if isinstance(interval, Literal):
8138        if not interval.is_string:
8139            raise ValueError("Invalid interval string.")
8140
8141        interval = interval.this
8142
8143    interval = maybe_parse(f"INTERVAL {interval}")
8144    assert isinstance(interval, Interval)
8145    return interval
8146
8147
8148def to_table(
8149    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8150) -> Table:
8151    """
8152    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8153    If a table is passed in then that table is returned.
8154
8155    Args:
8156        sql_path: a `[catalog].[schema].[table]` string.
8157        dialect: the source dialect according to which the table name will be parsed.
8158        copy: Whether to copy a table if it is passed in.
8159        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8160
8161    Returns:
8162        A table expression.
8163    """
8164    if isinstance(sql_path, Table):
8165        return maybe_copy(sql_path, copy=copy)
8166
8167    try:
8168        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8169    except ParseError:
8170        catalog, db, this = split_num_words(sql_path, ".", 3)
8171
8172        if not this:
8173            raise
8174
8175        table = table_(this, db=db, catalog=catalog)
8176
8177    for k, v in kwargs.items():
8178        table.set(k, v)
8179
8180    return table
8181
8182
8183def to_column(
8184    sql_path: str | Column,
8185    quoted: t.Optional[bool] = None,
8186    dialect: DialectType = None,
8187    copy: bool = True,
8188    **kwargs,
8189) -> Column:
8190    """
8191    Create a column from a `[table].[column]` sql path. Table is optional.
8192    If a column is passed in then that column is returned.
8193
8194    Args:
8195        sql_path: a `[table].[column]` string.
8196        quoted: Whether or not to force quote identifiers.
8197        dialect: the source dialect according to which the column name will be parsed.
8198        copy: Whether to copy a column if it is passed in.
8199        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8200
8201    Returns:
8202        A column expression.
8203    """
8204    if isinstance(sql_path, Column):
8205        return maybe_copy(sql_path, copy=copy)
8206
8207    try:
8208        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8209    except ParseError:
8210        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8211
8212    for k, v in kwargs.items():
8213        col.set(k, v)
8214
8215    if quoted:
8216        for i in col.find_all(Identifier):
8217            i.set("quoted", True)
8218
8219    return col
8220
8221
8222def alias_(
8223    expression: ExpOrStr,
8224    alias: t.Optional[str | Identifier],
8225    table: bool | t.Sequence[str | Identifier] = False,
8226    quoted: t.Optional[bool] = None,
8227    dialect: DialectType = None,
8228    copy: bool = True,
8229    **opts,
8230):
8231    """Create an Alias expression.
8232
8233    Example:
8234        >>> alias_('foo', 'bar').sql()
8235        'foo AS bar'
8236
8237        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8238        '(SELECT 1, 2) AS bar(a, b)'
8239
8240    Args:
8241        expression: the SQL code strings to parse.
8242            If an Expression instance is passed, this is used as-is.
8243        alias: the alias name to use. If the name has
8244            special characters it is quoted.
8245        table: Whether to create a table alias, can also be a list of columns.
8246        quoted: whether to quote the alias
8247        dialect: the dialect used to parse the input expression.
8248        copy: Whether to copy the expression.
8249        **opts: other options to use to parse the input expressions.
8250
8251    Returns:
8252        Alias: the aliased expression
8253    """
8254    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8255    alias = to_identifier(alias, quoted=quoted)
8256
8257    if table:
8258        table_alias = TableAlias(this=alias)
8259        exp.set("alias", table_alias)
8260
8261        if not isinstance(table, bool):
8262            for column in table:
8263                table_alias.append("columns", to_identifier(column, quoted=quoted))
8264
8265        return exp
8266
8267    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8268    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8269    # for the complete Window expression.
8270    #
8271    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8272
8273    if "alias" in exp.arg_types and not isinstance(exp, Window):
8274        exp.set("alias", alias)
8275        return exp
8276    return Alias(this=exp, alias=alias)
8277
8278
8279def subquery(
8280    expression: ExpOrStr,
8281    alias: t.Optional[Identifier | str] = None,
8282    dialect: DialectType = None,
8283    **opts,
8284) -> Select:
8285    """
8286    Build a subquery expression that's selected from.
8287
8288    Example:
8289        >>> subquery('select x from tbl', 'bar').select('x').sql()
8290        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8291
8292    Args:
8293        expression: the SQL code strings to parse.
8294            If an Expression instance is passed, this is used as-is.
8295        alias: the alias name to use.
8296        dialect: the dialect used to parse the input expression.
8297        **opts: other options to use to parse the input expressions.
8298
8299    Returns:
8300        A new Select instance with the subquery expression included.
8301    """
8302
8303    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8304    return Select().from_(expression, dialect=dialect, **opts)
8305
8306
8307@t.overload
8308def column(
8309    col: str | Identifier,
8310    table: t.Optional[str | Identifier] = None,
8311    db: t.Optional[str | Identifier] = None,
8312    catalog: t.Optional[str | Identifier] = None,
8313    *,
8314    fields: t.Collection[t.Union[str, Identifier]],
8315    quoted: t.Optional[bool] = None,
8316    copy: bool = True,
8317) -> Dot:
8318    pass
8319
8320
8321@t.overload
8322def column(
8323    col: str | Identifier | Star,
8324    table: t.Optional[str | Identifier] = None,
8325    db: t.Optional[str | Identifier] = None,
8326    catalog: t.Optional[str | Identifier] = None,
8327    *,
8328    fields: Lit[None] = None,
8329    quoted: t.Optional[bool] = None,
8330    copy: bool = True,
8331) -> Column:
8332    pass
8333
8334
8335def column(
8336    col,
8337    table=None,
8338    db=None,
8339    catalog=None,
8340    *,
8341    fields=None,
8342    quoted=None,
8343    copy=True,
8344):
8345    """
8346    Build a Column.
8347
8348    Args:
8349        col: Column name.
8350        table: Table name.
8351        db: Database name.
8352        catalog: Catalog name.
8353        fields: Additional fields using dots.
8354        quoted: Whether to force quotes on the column's identifiers.
8355        copy: Whether to copy identifiers if passed in.
8356
8357    Returns:
8358        The new Column instance.
8359    """
8360    if not isinstance(col, Star):
8361        col = to_identifier(col, quoted=quoted, copy=copy)
8362
8363    this = Column(
8364        this=col,
8365        table=to_identifier(table, quoted=quoted, copy=copy),
8366        db=to_identifier(db, quoted=quoted, copy=copy),
8367        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8368    )
8369
8370    if fields:
8371        this = Dot.build(
8372            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8373        )
8374    return this
8375
8376
8377def cast(
8378    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8379) -> Cast:
8380    """Cast an expression to a data type.
8381
8382    Example:
8383        >>> cast('x + 1', 'int').sql()
8384        'CAST(x + 1 AS INT)'
8385
8386    Args:
8387        expression: The expression to cast.
8388        to: The datatype to cast to.
8389        copy: Whether to copy the supplied expressions.
8390        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8391            - The expression to be cast is already a exp.Cast expression
8392            - The existing cast is to a type that is logically equivalent to new type
8393
8394            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8395            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8396            and instead just return the original expression `CAST(x as DATETIME)`.
8397
8398            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8399            mapping is applied in the target dialect generator.
8400
8401    Returns:
8402        The new Cast instance.
8403    """
8404    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8405    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8406
8407    # dont re-cast if the expression is already a cast to the correct type
8408    if isinstance(expr, Cast):
8409        from sqlglot.dialects.dialect import Dialect
8410
8411        target_dialect = Dialect.get_or_raise(dialect)
8412        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8413
8414        existing_cast_type: DataType.Type = expr.to.this
8415        new_cast_type: DataType.Type = data_type.this
8416        types_are_equivalent = type_mapping.get(
8417            existing_cast_type, existing_cast_type.value
8418        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8419
8420        if expr.is_type(data_type) or types_are_equivalent:
8421            return expr
8422
8423    expr = Cast(this=expr, to=data_type)
8424    expr.type = data_type
8425
8426    return expr
8427
8428
8429def table_(
8430    table: Identifier | str,
8431    db: t.Optional[Identifier | str] = None,
8432    catalog: t.Optional[Identifier | str] = None,
8433    quoted: t.Optional[bool] = None,
8434    alias: t.Optional[Identifier | str] = None,
8435) -> Table:
8436    """Build a Table.
8437
8438    Args:
8439        table: Table name.
8440        db: Database name.
8441        catalog: Catalog name.
8442        quote: Whether to force quotes on the table's identifiers.
8443        alias: Table's alias.
8444
8445    Returns:
8446        The new Table instance.
8447    """
8448    return Table(
8449        this=to_identifier(table, quoted=quoted) if table else None,
8450        db=to_identifier(db, quoted=quoted) if db else None,
8451        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8452        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8453    )
8454
8455
8456def values(
8457    values: t.Iterable[t.Tuple[t.Any, ...]],
8458    alias: t.Optional[str] = None,
8459    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8460) -> Values:
8461    """Build VALUES statement.
8462
8463    Example:
8464        >>> values([(1, '2')]).sql()
8465        "VALUES (1, '2')"
8466
8467    Args:
8468        values: values statements that will be converted to SQL
8469        alias: optional alias
8470        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8471         If either are provided then an alias is also required.
8472
8473    Returns:
8474        Values: the Values expression object
8475    """
8476    if columns and not alias:
8477        raise ValueError("Alias is required when providing columns")
8478
8479    return Values(
8480        expressions=[convert(tup) for tup in values],
8481        alias=(
8482            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8483            if columns
8484            else (TableAlias(this=to_identifier(alias)) if alias else None)
8485        ),
8486    )
8487
8488
8489def var(name: t.Optional[ExpOrStr]) -> Var:
8490    """Build a SQL variable.
8491
8492    Example:
8493        >>> repr(var('x'))
8494        'Var(this=x)'
8495
8496        >>> repr(var(column('x', table='y')))
8497        'Var(this=x)'
8498
8499    Args:
8500        name: The name of the var or an expression who's name will become the var.
8501
8502    Returns:
8503        The new variable node.
8504    """
8505    if not name:
8506        raise ValueError("Cannot convert empty name into var.")
8507
8508    if isinstance(name, Expression):
8509        name = name.name
8510    return Var(this=name)
8511
8512
8513def rename_table(
8514    old_name: str | Table,
8515    new_name: str | Table,
8516    dialect: DialectType = None,
8517) -> Alter:
8518    """Build ALTER TABLE... RENAME... expression
8519
8520    Args:
8521        old_name: The old name of the table
8522        new_name: The new name of the table
8523        dialect: The dialect to parse the table.
8524
8525    Returns:
8526        Alter table expression
8527    """
8528    old_table = to_table(old_name, dialect=dialect)
8529    new_table = to_table(new_name, dialect=dialect)
8530    return Alter(
8531        this=old_table,
8532        kind="TABLE",
8533        actions=[
8534            AlterRename(this=new_table),
8535        ],
8536    )
8537
8538
8539def rename_column(
8540    table_name: str | Table,
8541    old_column_name: str | Column,
8542    new_column_name: str | Column,
8543    exists: t.Optional[bool] = None,
8544    dialect: DialectType = None,
8545) -> Alter:
8546    """Build ALTER TABLE... RENAME COLUMN... expression
8547
8548    Args:
8549        table_name: Name of the table
8550        old_column: The old name of the column
8551        new_column: The new name of the column
8552        exists: Whether to add the `IF EXISTS` clause
8553        dialect: The dialect to parse the table/column.
8554
8555    Returns:
8556        Alter table expression
8557    """
8558    table = to_table(table_name, dialect=dialect)
8559    old_column = to_column(old_column_name, dialect=dialect)
8560    new_column = to_column(new_column_name, dialect=dialect)
8561    return Alter(
8562        this=table,
8563        kind="TABLE",
8564        actions=[
8565            RenameColumn(this=old_column, to=new_column, exists=exists),
8566        ],
8567    )
8568
8569
8570def convert(value: t.Any, copy: bool = False) -> Expression:
8571    """Convert a python value into an expression object.
8572
8573    Raises an error if a conversion is not possible.
8574
8575    Args:
8576        value: A python object.
8577        copy: Whether to copy `value` (only applies to Expressions and collections).
8578
8579    Returns:
8580        The equivalent expression object.
8581    """
8582    if isinstance(value, Expression):
8583        return maybe_copy(value, copy)
8584    if isinstance(value, str):
8585        return Literal.string(value)
8586    if isinstance(value, bool):
8587        return Boolean(this=value)
8588    if value is None or (isinstance(value, float) and math.isnan(value)):
8589        return null()
8590    if isinstance(value, numbers.Number):
8591        return Literal.number(value)
8592    if isinstance(value, bytes):
8593        return HexString(this=value.hex())
8594    if isinstance(value, datetime.datetime):
8595        datetime_literal = Literal.string(value.isoformat(sep=" "))
8596
8597        tz = None
8598        if value.tzinfo:
8599            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8600            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8601            tz = Literal.string(str(value.tzinfo))
8602
8603        return TimeStrToTime(this=datetime_literal, zone=tz)
8604    if isinstance(value, datetime.date):
8605        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8606        return DateStrToDate(this=date_literal)
8607    if isinstance(value, datetime.time):
8608        time_literal = Literal.string(value.isoformat())
8609        return TsOrDsToTime(this=time_literal)
8610    if isinstance(value, tuple):
8611        if hasattr(value, "_fields"):
8612            return Struct(
8613                expressions=[
8614                    PropertyEQ(
8615                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8616                    )
8617                    for k in value._fields
8618                ]
8619            )
8620        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8621    if isinstance(value, list):
8622        return Array(expressions=[convert(v, copy=copy) for v in value])
8623    if isinstance(value, dict):
8624        return Map(
8625            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8626            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8627        )
8628    if hasattr(value, "__dict__"):
8629        return Struct(
8630            expressions=[
8631                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8632                for k, v in value.__dict__.items()
8633            ]
8634        )
8635    raise ValueError(f"Cannot convert {value}")
8636
8637
8638def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8639    """
8640    Replace children of an expression with the result of a lambda fun(child) -> exp.
8641    """
8642    for k, v in tuple(expression.args.items()):
8643        is_list_arg = type(v) is list
8644
8645        child_nodes = v if is_list_arg else [v]
8646        new_child_nodes = []
8647
8648        for cn in child_nodes:
8649            if isinstance(cn, Expression):
8650                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8651                    new_child_nodes.append(child_node)
8652            else:
8653                new_child_nodes.append(cn)
8654
8655        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
8656
8657
8658def replace_tree(
8659    expression: Expression,
8660    fun: t.Callable,
8661    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8662) -> Expression:
8663    """
8664    Replace an entire tree with the result of function calls on each node.
8665
8666    This will be traversed in reverse dfs, so leaves first.
8667    If new nodes are created as a result of function calls, they will also be traversed.
8668    """
8669    stack = list(expression.dfs(prune=prune))
8670
8671    while stack:
8672        node = stack.pop()
8673        new_node = fun(node)
8674
8675        if new_node is not node:
8676            node.replace(new_node)
8677
8678            if isinstance(new_node, Expression):
8679                stack.append(new_node)
8680
8681    return new_node
8682
8683
8684def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8685    """
8686    Return all table names referenced through columns in an expression.
8687
8688    Example:
8689        >>> import sqlglot
8690        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8691        ['a', 'c']
8692
8693    Args:
8694        expression: expression to find table names.
8695        exclude: a table name to exclude
8696
8697    Returns:
8698        A list of unique names.
8699    """
8700    return {
8701        table
8702        for table in (column.table for column in expression.find_all(Column))
8703        if table and table != exclude
8704    }
8705
8706
8707def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8708    """Get the full name of a table as a string.
8709
8710    Args:
8711        table: Table expression node or string.
8712        dialect: The dialect to generate the table name for.
8713        identify: Determines when an identifier should be quoted. Possible values are:
8714            False (default): Never quote, except in cases where it's mandatory by the dialect.
8715            True: Always quote.
8716
8717    Examples:
8718        >>> from sqlglot import exp, parse_one
8719        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8720        'a.b.c'
8721
8722    Returns:
8723        The table name.
8724    """
8725
8726    table = maybe_parse(table, into=Table, dialect=dialect)
8727
8728    if not table:
8729        raise ValueError(f"Cannot parse {table}")
8730
8731    return ".".join(
8732        (
8733            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8734            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8735            else part.name
8736        )
8737        for part in table.parts
8738    )
8739
8740
8741def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8742    """Returns a case normalized table name without quotes.
8743
8744    Args:
8745        table: the table to normalize
8746        dialect: the dialect to use for normalization rules
8747        copy: whether to copy the expression.
8748
8749    Examples:
8750        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8751        'A-B.c'
8752    """
8753    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8754
8755    return ".".join(
8756        p.name
8757        for p in normalize_identifiers(
8758            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8759        ).parts
8760    )
8761
8762
8763def replace_tables(
8764    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8765) -> E:
8766    """Replace all tables in expression according to the mapping.
8767
8768    Args:
8769        expression: expression node to be transformed and replaced.
8770        mapping: mapping of table names.
8771        dialect: the dialect of the mapping table
8772        copy: whether to copy the expression.
8773
8774    Examples:
8775        >>> from sqlglot import exp, parse_one
8776        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8777        'SELECT * FROM c /* a.b */'
8778
8779    Returns:
8780        The mapped expression.
8781    """
8782
8783    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8784
8785    def _replace_tables(node: Expression) -> Expression:
8786        if isinstance(node, Table) and node.meta.get("replace") is not False:
8787            original = normalize_table_name(node, dialect=dialect)
8788            new_name = mapping.get(original)
8789
8790            if new_name:
8791                table = to_table(
8792                    new_name,
8793                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8794                    dialect=dialect,
8795                )
8796                table.add_comments([original])
8797                return table
8798        return node
8799
8800    return expression.transform(_replace_tables, copy=copy)  # type: ignore
8801
8802
8803def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8804    """Replace placeholders in an expression.
8805
8806    Args:
8807        expression: expression node to be transformed and replaced.
8808        args: positional names that will substitute unnamed placeholders in the given order.
8809        kwargs: keyword arguments that will substitute named placeholders.
8810
8811    Examples:
8812        >>> from sqlglot import exp, parse_one
8813        >>> replace_placeholders(
8814        ...     parse_one("select * from :tbl where ? = ?"),
8815        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8816        ... ).sql()
8817        "SELECT * FROM foo WHERE str_col = 'b'"
8818
8819    Returns:
8820        The mapped expression.
8821    """
8822
8823    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8824        if isinstance(node, Placeholder):
8825            if node.this:
8826                new_name = kwargs.get(node.this)
8827                if new_name is not None:
8828                    return convert(new_name)
8829            else:
8830                try:
8831                    return convert(next(args))
8832                except StopIteration:
8833                    pass
8834        return node
8835
8836    return expression.transform(_replace_placeholders, iter(args), **kwargs)
8837
8838
8839def expand(
8840    expression: Expression,
8841    sources: t.Dict[str, Query | t.Callable[[], Query]],
8842    dialect: DialectType = None,
8843    copy: bool = True,
8844) -> Expression:
8845    """Transforms an expression by expanding all referenced sources into subqueries.
8846
8847    Examples:
8848        >>> from sqlglot import parse_one
8849        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8850        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8851
8852        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8853        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8854
8855    Args:
8856        expression: The expression to expand.
8857        sources: A dict of name to query or a callable that provides a query on demand.
8858        dialect: The dialect of the sources dict or the callable.
8859        copy: Whether to copy the expression during transformation. Defaults to True.
8860
8861    Returns:
8862        The transformed expression.
8863    """
8864    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8865
8866    def _expand(node: Expression):
8867        if isinstance(node, Table):
8868            name = normalize_table_name(node, dialect=dialect)
8869            source = normalized_sources.get(name)
8870
8871            if source:
8872                # Create a subquery with the same alias (or table name if no alias)
8873                parsed_source = source() if callable(source) else source
8874                subquery = parsed_source.subquery(node.alias or name)
8875                subquery.comments = [f"source: {name}"]
8876
8877                # Continue expanding within the subquery
8878                return subquery.transform(_expand, copy=False)
8879
8880        return node
8881
8882    return expression.transform(_expand, copy=copy)
8883
8884
8885def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8886    """
8887    Returns a Func expression.
8888
8889    Examples:
8890        >>> func("abs", 5).sql()
8891        'ABS(5)'
8892
8893        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8894        'CAST(5 AS DOUBLE)'
8895
8896    Args:
8897        name: the name of the function to build.
8898        args: the args used to instantiate the function of interest.
8899        copy: whether to copy the argument expressions.
8900        dialect: the source dialect.
8901        kwargs: the kwargs used to instantiate the function of interest.
8902
8903    Note:
8904        The arguments `args` and `kwargs` are mutually exclusive.
8905
8906    Returns:
8907        An instance of the function of interest, or an anonymous function, if `name` doesn't
8908        correspond to an existing `sqlglot.expressions.Func` class.
8909    """
8910    if args and kwargs:
8911        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8912
8913    from sqlglot.dialects.dialect import Dialect
8914
8915    dialect = Dialect.get_or_raise(dialect)
8916
8917    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8918    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8919
8920    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8921    if constructor:
8922        if converted:
8923            if "dialect" in constructor.__code__.co_varnames:
8924                function = constructor(converted, dialect=dialect)
8925            else:
8926                function = constructor(converted)
8927        elif constructor.__name__ == "from_arg_list":
8928            function = constructor.__self__(**kwargs)  # type: ignore
8929        else:
8930            constructor = FUNCTION_BY_NAME.get(name.upper())
8931            if constructor:
8932                function = constructor(**kwargs)
8933            else:
8934                raise ValueError(
8935                    f"Unable to convert '{name}' into a Func. Either manually construct "
8936                    "the Func expression of interest or parse the function call."
8937                )
8938    else:
8939        kwargs = kwargs or {"expressions": converted}
8940        function = Anonymous(this=name, **kwargs)
8941
8942    for error_message in function.error_messages(converted):
8943        raise ValueError(error_message)
8944
8945    return function
8946
8947
8948def case(
8949    expression: t.Optional[ExpOrStr] = None,
8950    **opts,
8951) -> Case:
8952    """
8953    Initialize a CASE statement.
8954
8955    Example:
8956        case().when("a = 1", "foo").else_("bar")
8957
8958    Args:
8959        expression: Optionally, the input expression (not all dialects support this)
8960        **opts: Extra keyword arguments for parsing `expression`
8961    """
8962    if expression is not None:
8963        this = maybe_parse(expression, **opts)
8964    else:
8965        this = None
8966    return Case(this=this, ifs=[])
8967
8968
8969def array(
8970    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8971) -> Array:
8972    """
8973    Returns an array.
8974
8975    Examples:
8976        >>> array(1, 'x').sql()
8977        'ARRAY(1, x)'
8978
8979    Args:
8980        expressions: the expressions to add to the array.
8981        copy: whether to copy the argument expressions.
8982        dialect: the source dialect.
8983        kwargs: the kwargs used to instantiate the function of interest.
8984
8985    Returns:
8986        An array expression.
8987    """
8988    return Array(
8989        expressions=[
8990            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8991            for expression in expressions
8992        ]
8993    )
8994
8995
8996def tuple_(
8997    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8998) -> Tuple:
8999    """
9000    Returns an tuple.
9001
9002    Examples:
9003        >>> tuple_(1, 'x').sql()
9004        '(1, x)'
9005
9006    Args:
9007        expressions: the expressions to add to the tuple.
9008        copy: whether to copy the argument expressions.
9009        dialect: the source dialect.
9010        kwargs: the kwargs used to instantiate the function of interest.
9011
9012    Returns:
9013        A tuple expression.
9014    """
9015    return Tuple(
9016        expressions=[
9017            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9018            for expression in expressions
9019        ]
9020    )
9021
9022
9023def true() -> Boolean:
9024    """
9025    Returns a true Boolean expression.
9026    """
9027    return Boolean(this=True)
9028
9029
9030def false() -> Boolean:
9031    """
9032    Returns a false Boolean expression.
9033    """
9034    return Boolean(this=False)
9035
9036
9037def null() -> Null:
9038    """
9039    Returns a Null expression.
9040    """
9041    return Null()
9042
9043
9044NONNULL_CONSTANTS = (
9045    Literal,
9046    Boolean,
9047)
9048
9049CONSTANTS = (
9050    Literal,
9051    Boolean,
9052    Null,
9053)
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.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.UNION: 'UNION'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.NESTED: 'NESTED'>, <Type.LIST: 'LIST'>, <Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.UNION: 'UNION'>}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>}
INTEGER_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT: 'INT'>, <Type.BIT: 'BIT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>}
NUMERIC_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.MONEY: 'MONEY'>, <Type.INT: 'INT'>, <Type.FLOAT: 'FLOAT'>, <Type.BIT: 'BIT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DOUBLE: 'DOUBLE'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>}
TEMPORAL_TYPES = {<Type.DATETIME: 'DATETIME'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME2: 'DATETIME2'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}
@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 isinstance(unit, 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 isinstance(unit, 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 Anonymous(Func):
5468class Anonymous(Func):
5469    arg_types = {"this": True, "expressions": False}
5470    is_var_len_args = True
5471
5472    @property
5473    def name(self) -> str:
5474        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
5472    @property
5473    def name(self) -> str:
5474        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5477class AnonymousAggFunc(AggFunc):
5478    arg_types = {"this": True, "expressions": False}
5479    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5483class CombinedAggFunc(AnonymousAggFunc):
5484    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5487class CombinedParameterizedAgg(ParameterizedAgg):
5488    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5493class Hll(AggFunc):
5494    arg_types = {"this": True, "expressions": False}
5495    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5498class ApproxDistinct(AggFunc):
5499    arg_types = {"this": True, "accuracy": False}
5500    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5503class Apply(Func):
5504    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5507class Array(Func):
5508    arg_types = {"expressions": False, "bracket_notation": False}
5509    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5512class Ascii(Func):
5513    pass
key = 'ascii'
class ToArray(Func):
5517class ToArray(Func):
5518    pass
key = 'toarray'
class List(Func):
5522class List(Func):
5523    arg_types = {"expressions": False}
5524    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5528class Pad(Func):
5529    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):
5534class ToChar(Func):
5535    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5540class ToNumber(Func):
5541    arg_types = {
5542        "this": True,
5543        "format": False,
5544        "nlsparam": False,
5545        "precision": False,
5546        "scale": False,
5547    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5551class ToDouble(Func):
5552    arg_types = {
5553        "this": True,
5554        "format": False,
5555    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5558class Columns(Func):
5559    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5563class Convert(Func):
5564    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5568class ConvertToCharset(Func):
5569    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5572class ConvertTimezone(Func):
5573    arg_types = {
5574        "source_tz": False,
5575        "target_tz": True,
5576        "timestamp": True,
5577        "options": False,
5578    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class CodePointsToString(Func):
5581class CodePointsToString(Func):
5582    pass
key = 'codepointstostring'
class GenerateSeries(Func):
5585class GenerateSeries(Func):
5586    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):
5592class ExplodingGenerateSeries(GenerateSeries):
5593    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5596class ArrayAgg(AggFunc):
5597    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5600class ArrayUniqueAgg(AggFunc):
5601    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5604class ArrayAll(Func):
5605    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5609class ArrayAny(Func):
5610    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5613class ArrayConcat(Func):
5614    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5615    arg_types = {"this": True, "expressions": False}
5616    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5619class ArrayConcatAgg(AggFunc):
5620    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5623class ArrayConstructCompact(Func):
5624    arg_types = {"expressions": True}
5625    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5628class ArrayContains(Binary, Func):
5629    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5632class ArrayContainsAll(Binary, Func):
5633    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5636class ArrayFilter(Func):
5637    arg_types = {"this": True, "expression": True}
5638    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5641class ArrayFirst(Func):
5642    pass
key = 'arrayfirst'
class ArrayLast(Func):
5645class ArrayLast(Func):
5646    pass
key = 'arraylast'
class ArrayReverse(Func):
5649class ArrayReverse(Func):
5650    pass
key = 'arrayreverse'
class ArraySlice(Func):
5653class ArraySlice(Func):
5654    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):
5657class ArrayToString(Func):
5658    arg_types = {"this": True, "expression": True, "null": False}
5659    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5662class ArrayIntersect(Func):
5663    arg_types = {"expressions": True}
5664    is_var_len_args = True
5665    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5668class StPoint(Func):
5669    arg_types = {"this": True, "expression": True, "null": False}
5670    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5673class StDistance(Func):
5674    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5678class String(Func):
5679    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5682class StringToArray(Func):
5683    arg_types = {"this": True, "expression": False, "null": False}
5684    _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):
5687class ArrayOverlaps(Binary, Func):
5688    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5691class ArraySize(Func):
5692    arg_types = {"this": True, "expression": False}
5693    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5696class ArraySort(Func):
5697    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5700class ArraySum(Func):
5701    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5704class ArrayUnionAgg(AggFunc):
5705    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5708class Avg(AggFunc):
5709    pass
key = 'avg'
class AnyValue(AggFunc):
5712class AnyValue(AggFunc):
5713    pass
key = 'anyvalue'
class Lag(AggFunc):
5716class Lag(AggFunc):
5717    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5720class Lead(AggFunc):
5721    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5726class First(AggFunc):
5727    pass
key = 'first'
class Last(AggFunc):
5730class Last(AggFunc):
5731    pass
key = 'last'
class FirstValue(AggFunc):
5734class FirstValue(AggFunc):
5735    pass
key = 'firstvalue'
class LastValue(AggFunc):
5738class LastValue(AggFunc):
5739    pass
key = 'lastvalue'
class NthValue(AggFunc):
5742class NthValue(AggFunc):
5743    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5746class Case(Func):
5747    arg_types = {"this": False, "ifs": True, "default": False}
5748
5749    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5750        instance = maybe_copy(self, copy)
5751        instance.append(
5752            "ifs",
5753            If(
5754                this=maybe_parse(condition, copy=copy, **opts),
5755                true=maybe_parse(then, copy=copy, **opts),
5756            ),
5757        )
5758        return instance
5759
5760    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5761        instance = maybe_copy(self, copy)
5762        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5763        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:
5749    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5750        instance = maybe_copy(self, copy)
5751        instance.append(
5752            "ifs",
5753            If(
5754                this=maybe_parse(condition, copy=copy, **opts),
5755                true=maybe_parse(then, copy=copy, **opts),
5756            ),
5757        )
5758        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5760    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5761        instance = maybe_copy(self, copy)
5762        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5763        return instance
key = 'case'
class Cast(Func):
5766class Cast(Func):
5767    arg_types = {
5768        "this": True,
5769        "to": True,
5770        "format": False,
5771        "safe": False,
5772        "action": False,
5773        "default": False,
5774    }
5775
5776    @property
5777    def name(self) -> str:
5778        return self.this.name
5779
5780    @property
5781    def to(self) -> DataType:
5782        return self.args["to"]
5783
5784    @property
5785    def output_name(self) -> str:
5786        return self.name
5787
5788    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5789        """
5790        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5791        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5792        array<int> != array<float>.
5793
5794        Args:
5795            dtypes: the data types to compare this Cast's DataType to.
5796
5797        Returns:
5798            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5799        """
5800        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5776    @property
5777    def name(self) -> str:
5778        return self.this.name
to: DataType
5780    @property
5781    def to(self) -> DataType:
5782        return self.args["to"]
output_name: str
5784    @property
5785    def output_name(self) -> str:
5786        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:
5788    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5789        """
5790        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5791        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5792        array<int> != array<float>.
5793
5794        Args:
5795            dtypes: the data types to compare this Cast's DataType to.
5796
5797        Returns:
5798            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5799        """
5800        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):
5803class TryCast(Cast):
5804    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):
5808class JSONCast(Cast):
5809    pass
key = 'jsoncast'
class JustifyDays(Func):
5812class JustifyDays(Func):
5813    pass
key = 'justifydays'
class JustifyHours(Func):
5816class JustifyHours(Func):
5817    pass
key = 'justifyhours'
class JustifyInterval(Func):
5820class JustifyInterval(Func):
5821    pass
key = 'justifyinterval'
class Try(Func):
5824class Try(Func):
5825    pass
key = 'try'
class CastToStrType(Func):
5828class CastToStrType(Func):
5829    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5833class TranslateCharacters(Expression):
5834    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5837class Collate(Binary, Func):
5838    pass
key = 'collate'
class Ceil(Func):
5841class Ceil(Func):
5842    arg_types = {"this": True, "decimals": False, "to": False}
5843    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5846class Coalesce(Func):
5847    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5848    is_var_len_args = True
5849    _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):
5852class Chr(Func):
5853    arg_types = {"expressions": True, "charset": False}
5854    is_var_len_args = True
5855    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5858class Concat(Func):
5859    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5860    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5863class ConcatWs(Concat):
5864    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5867class Contains(Func):
5868    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5872class ConnectByRoot(Func):
5873    pass
key = 'connectbyroot'
class Count(AggFunc):
5876class Count(AggFunc):
5877    arg_types = {"this": False, "expressions": False, "big_int": False}
5878    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5881class CountIf(AggFunc):
5882    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5886class Cbrt(Func):
5887    pass
key = 'cbrt'
class CurrentDate(Func):
5890class CurrentDate(Func):
5891    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5894class CurrentDatetime(Func):
5895    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5898class CurrentTime(Func):
5899    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5902class CurrentTimestamp(Func):
5903    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
5906class CurrentTimestampLTZ(Func):
5907    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
5910class CurrentSchema(Func):
5911    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5914class CurrentUser(Func):
5915    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5918class DateAdd(Func, IntervalOp):
5919    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5922class DateBin(Func, IntervalOp):
5923    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):
5926class DateSub(Func, IntervalOp):
5927    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5930class DateDiff(Func, TimeUnit):
5931    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5932    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):
5935class DateTrunc(Func):
5936    arg_types = {"unit": True, "this": True, "zone": False}
5937
5938    def __init__(self, **args):
5939        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5940        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5941        unabbreviate = args.pop("unabbreviate", True)
5942
5943        unit = args.get("unit")
5944        if isinstance(unit, TimeUnit.VAR_LIKE):
5945            unit_name = unit.name.upper()
5946            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5947                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5948
5949            args["unit"] = Literal.string(unit_name)
5950
5951        super().__init__(**args)
5952
5953    @property
5954    def unit(self) -> Expression:
5955        return self.args["unit"]
DateTrunc(**args)
5938    def __init__(self, **args):
5939        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5940        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5941        unabbreviate = args.pop("unabbreviate", True)
5942
5943        unit = args.get("unit")
5944        if isinstance(unit, TimeUnit.VAR_LIKE):
5945            unit_name = unit.name.upper()
5946            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5947                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5948
5949            args["unit"] = Literal.string(unit_name)
5950
5951        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5953    @property
5954    def unit(self) -> Expression:
5955        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5960class Datetime(Func):
5961    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5964class DatetimeAdd(Func, IntervalOp):
5965    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5968class DatetimeSub(Func, IntervalOp):
5969    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5972class DatetimeDiff(Func, TimeUnit):
5973    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5976class DatetimeTrunc(Func, TimeUnit):
5977    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DateFromUnixDate(Func):
5980class DateFromUnixDate(Func):
5981    pass
key = 'datefromunixdate'
class DayOfWeek(Func):
5984class DayOfWeek(Func):
5985    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5990class DayOfWeekIso(Func):
5991    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5994class DayOfMonth(Func):
5995    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5998class DayOfYear(Func):
5999    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
6002class ToDays(Func):
6003    pass
key = 'todays'
class WeekOfYear(Func):
6006class WeekOfYear(Func):
6007    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
6010class MonthsBetween(Func):
6011    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
6014class MakeInterval(Func):
6015    arg_types = {
6016        "year": False,
6017        "month": False,
6018        "day": False,
6019        "hour": False,
6020        "minute": False,
6021        "second": False,
6022    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
6025class LastDay(Func, TimeUnit):
6026    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
6027    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
6030class Extract(Func):
6031    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6034class Exists(Func, SubqueryPredicate):
6035    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6038class Timestamp(Func):
6039    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6042class TimestampAdd(Func, TimeUnit):
6043    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6046class TimestampSub(Func, TimeUnit):
6047    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6050class TimestampDiff(Func, TimeUnit):
6051    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6052    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6055class TimestampTrunc(Func, TimeUnit):
6056    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6059class TimeAdd(Func, TimeUnit):
6060    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6063class TimeSub(Func, TimeUnit):
6064    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6067class TimeDiff(Func, TimeUnit):
6068    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6071class TimeTrunc(Func, TimeUnit):
6072    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6075class DateFromParts(Func):
6076    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6077    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6080class TimeFromParts(Func):
6081    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6082    arg_types = {
6083        "hour": True,
6084        "min": True,
6085        "sec": True,
6086        "nano": False,
6087        "fractions": False,
6088        "precision": False,
6089    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6092class DateStrToDate(Func):
6093    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6096class DateToDateStr(Func):
6097    pass
key = 'datetodatestr'
class DateToDi(Func):
6100class DateToDi(Func):
6101    pass
key = 'datetodi'
class Date(Func):
6105class Date(Func):
6106    arg_types = {"this": False, "zone": False, "expressions": False}
6107    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6110class Day(Func):
6111    pass
key = 'day'
class Decode(Func):
6114class Decode(Func):
6115    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6118class DecodeCase(Func):
6119    arg_types = {"expressions": True}
6120    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DiToDate(Func):
6123class DiToDate(Func):
6124    pass
key = 'ditodate'
class Encode(Func):
6127class Encode(Func):
6128    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6131class Exp(Func):
6132    pass
key = 'exp'
class Explode(Func, UDTF):
6136class Explode(Func, UDTF):
6137    arg_types = {"this": True, "expressions": False}
6138    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6142class Inline(Func):
6143    pass
key = 'inline'
class ExplodeOuter(Explode):
6146class ExplodeOuter(Explode):
6147    pass
key = 'explodeouter'
class Posexplode(Explode):
6150class Posexplode(Explode):
6151    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6154class PosexplodeOuter(Posexplode, ExplodeOuter):
6155    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6158class PositionalColumn(Expression):
6159    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6162class Unnest(Func, UDTF):
6163    arg_types = {
6164        "expressions": True,
6165        "alias": False,
6166        "offset": False,
6167        "explode_array": False,
6168    }
6169
6170    @property
6171    def selects(self) -> t.List[Expression]:
6172        columns = super().selects
6173        offset = self.args.get("offset")
6174        if offset:
6175            columns = columns + [to_identifier("offset") if offset is True else offset]
6176        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6170    @property
6171    def selects(self) -> t.List[Expression]:
6172        columns = super().selects
6173        offset = self.args.get("offset")
6174        if offset:
6175            columns = columns + [to_identifier("offset") if offset is True else offset]
6176        return columns
key = 'unnest'
class Floor(Func):
6179class Floor(Func):
6180    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6183class FromBase64(Func):
6184    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6187class FeaturesAtTime(Func):
6188    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):
6191class ToBase64(Func):
6192    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6196class FromISO8601Timestamp(Func):
6197    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6200class GapFill(Func):
6201    arg_types = {
6202        "this": True,
6203        "ts_column": True,
6204        "bucket_width": True,
6205        "partitioning_columns": False,
6206        "value_columns": False,
6207        "origin": False,
6208        "ignore_nulls": False,
6209    }
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):
6213class GenerateDateArray(Func):
6214    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6218class GenerateTimestampArray(Func):
6219    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class GetExtract(Func):
6223class GetExtract(Func):
6224    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'getextract'
class Greatest(Func):
6227class Greatest(Func):
6228    arg_types = {"this": True, "expressions": False}
6229    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6234class OverflowTruncateBehavior(Expression):
6235    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6238class GroupConcat(AggFunc):
6239    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6242class Hex(Func):
6243    pass
key = 'hex'
class LowerHex(Hex):
6246class LowerHex(Hex):
6247    pass
key = 'lowerhex'
class And(Connector, Func):
6250class And(Connector, Func):
6251    pass
key = 'and'
class Or(Connector, Func):
6254class Or(Connector, Func):
6255    pass
key = 'or'
class Xor(Connector, Func):
6258class Xor(Connector, Func):
6259    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6262class If(Func):
6263    arg_types = {"this": True, "true": True, "false": False}
6264    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6267class Nullif(Func):
6268    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6271class Initcap(Func):
6272    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6275class IsAscii(Func):
6276    pass
key = 'isascii'
class IsNan(Func):
6279class IsNan(Func):
6280    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6284class Int64(Func):
6285    pass
key = 'int64'
class IsInf(Func):
6288class IsInf(Func):
6289    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6293class JSON(Expression):
6294    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6297class JSONPath(Expression):
6298    arg_types = {"expressions": True, "escape": False}
6299
6300    @property
6301    def output_name(self) -> str:
6302        last_segment = self.expressions[-1].this
6303        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6300    @property
6301    def output_name(self) -> str:
6302        last_segment = self.expressions[-1].this
6303        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):
6306class JSONPathPart(Expression):
6307    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6310class JSONPathFilter(JSONPathPart):
6311    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6314class JSONPathKey(JSONPathPart):
6315    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6318class JSONPathRecursive(JSONPathPart):
6319    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6322class JSONPathRoot(JSONPathPart):
6323    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6326class JSONPathScript(JSONPathPart):
6327    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6330class JSONPathSlice(JSONPathPart):
6331    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6334class JSONPathSelector(JSONPathPart):
6335    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6338class JSONPathSubscript(JSONPathPart):
6339    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6342class JSONPathUnion(JSONPathPart):
6343    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6346class JSONPathWildcard(JSONPathPart):
6347    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6350class FormatJson(Expression):
6351    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6354class JSONKeyValue(Expression):
6355    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6358class JSONObject(Func):
6359    arg_types = {
6360        "expressions": False,
6361        "null_handling": False,
6362        "unique_keys": False,
6363        "return_type": False,
6364        "encoding": False,
6365    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6368class JSONObjectAgg(AggFunc):
6369    arg_types = {
6370        "expressions": False,
6371        "null_handling": False,
6372        "unique_keys": False,
6373        "return_type": False,
6374        "encoding": False,
6375    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6379class JSONBObjectAgg(AggFunc):
6380    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6384class JSONArray(Func):
6385    arg_types = {
6386        "expressions": False,
6387        "null_handling": False,
6388        "return_type": False,
6389        "strict": False,
6390    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6394class JSONArrayAgg(Func):
6395    arg_types = {
6396        "this": True,
6397        "order": False,
6398        "null_handling": False,
6399        "return_type": False,
6400        "strict": False,
6401    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6404class JSONExists(Func):
6405    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):
6410class JSONColumnDef(Expression):
6411    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):
6414class JSONSchema(Expression):
6415    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6419class JSONValue(Expression):
6420    arg_types = {
6421        "this": True,
6422        "path": True,
6423        "returning": False,
6424        "on_condition": False,
6425    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6428class JSONValueArray(Func):
6429    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6433class JSONTable(Func):
6434    arg_types = {
6435        "this": True,
6436        "schema": True,
6437        "path": False,
6438        "error_handling": False,
6439        "empty_handling": False,
6440    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6445class JSONType(Func):
6446    arg_types = {"this": True, "expression": False}
6447    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6451class ObjectInsert(Func):
6452    arg_types = {
6453        "this": True,
6454        "key": True,
6455        "value": True,
6456        "update_flag": False,
6457    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6460class OpenJSONColumnDef(Expression):
6461    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):
6464class OpenJSON(Func):
6465    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6468class JSONBContains(Binary, Func):
6469    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6472class JSONBExists(Func):
6473    arg_types = {"this": True, "path": True}
6474    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6477class JSONExtract(Binary, Func):
6478    arg_types = {
6479        "this": True,
6480        "expression": True,
6481        "only_json_types": False,
6482        "expressions": False,
6483        "variant_extract": False,
6484        "json_query": False,
6485        "option": False,
6486        "quote": False,
6487        "on_condition": False,
6488        "requires_json": False,
6489    }
6490    _sql_names = ["JSON_EXTRACT"]
6491    is_var_len_args = True
6492
6493    @property
6494    def output_name(self) -> str:
6495        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
6493    @property
6494    def output_name(self) -> str:
6495        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):
6499class JSONExtractQuote(Expression):
6500    arg_types = {
6501        "option": True,
6502        "scalar": False,
6503    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6506class JSONExtractArray(Func):
6507    arg_types = {"this": True, "expression": False}
6508    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6511class JSONExtractScalar(Binary, Func):
6512    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6513    _sql_names = ["JSON_EXTRACT_SCALAR"]
6514    is_var_len_args = True
6515
6516    @property
6517    def output_name(self) -> str:
6518        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
6516    @property
6517    def output_name(self) -> str:
6518        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):
6521class JSONBExtract(Binary, Func):
6522    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6525class JSONBExtractScalar(Binary, Func):
6526    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6529class JSONFormat(Func):
6530    arg_types = {"this": False, "options": False, "is_json": False}
6531    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6535class JSONArrayContains(Binary, Predicate, Func):
6536    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6539class ParseJSON(Func):
6540    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6541    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6542    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6543    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class ParseTime(Func):
6546class ParseTime(Func):
6547    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'parsetime'
class ParseDatetime(Func):
6550class ParseDatetime(Func):
6551    arg_types = {"this": True, "format": False, "zone": False}
arg_types = {'this': True, 'format': False, 'zone': False}
key = 'parsedatetime'
class Least(Func):
6554class Least(Func):
6555    arg_types = {"this": True, "expressions": False}
6556    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6559class Left(Func):
6560    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Reverse(Func):
6567class Reverse(Func):
6568    pass
key = 'reverse'
class Length(Func):
6571class Length(Func):
6572    arg_types = {"this": True, "binary": False, "encoding": False}
6573    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6576class Levenshtein(Func):
6577    arg_types = {
6578        "this": True,
6579        "expression": False,
6580        "ins_cost": False,
6581        "del_cost": False,
6582        "sub_cost": False,
6583        "max_dist": False,
6584    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6587class Ln(Func):
6588    pass
key = 'ln'
class Log(Func):
6591class Log(Func):
6592    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6595class LogicalOr(AggFunc):
6596    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6599class LogicalAnd(AggFunc):
6600    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6603class Lower(Func):
6604    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6607class Map(Func):
6608    arg_types = {"keys": False, "values": False}
6609
6610    @property
6611    def keys(self) -> t.List[Expression]:
6612        keys = self.args.get("keys")
6613        return keys.expressions if keys else []
6614
6615    @property
6616    def values(self) -> t.List[Expression]:
6617        values = self.args.get("values")
6618        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6610    @property
6611    def keys(self) -> t.List[Expression]:
6612        keys = self.args.get("keys")
6613        return keys.expressions if keys else []
values: List[Expression]
6615    @property
6616    def values(self) -> t.List[Expression]:
6617        values = self.args.get("values")
6618        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6622class ToMap(Func):
6623    pass
key = 'tomap'
class MapFromEntries(Func):
6626class MapFromEntries(Func):
6627    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6631class ScopeResolution(Expression):
6632    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6635class Stream(Expression):
6636    pass
key = 'stream'
class StarMap(Func):
6639class StarMap(Func):
6640    pass
key = 'starmap'
class VarMap(Func):
6643class VarMap(Func):
6644    arg_types = {"keys": True, "values": True}
6645    is_var_len_args = True
6646
6647    @property
6648    def keys(self) -> t.List[Expression]:
6649        return self.args["keys"].expressions
6650
6651    @property
6652    def values(self) -> t.List[Expression]:
6653        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6647    @property
6648    def keys(self) -> t.List[Expression]:
6649        return self.args["keys"].expressions
values: List[Expression]
6651    @property
6652    def values(self) -> t.List[Expression]:
6653        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6657class MatchAgainst(Func):
6658    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6661class Max(AggFunc):
6662    arg_types = {"this": True, "expressions": False}
6663    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6666class MD5(Func):
6667    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6671class MD5Digest(Func):
6672    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6675class Median(AggFunc):
6676    pass
key = 'median'
class Min(AggFunc):
6679class Min(AggFunc):
6680    arg_types = {"this": True, "expressions": False}
6681    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6684class Month(Func):
6685    pass
key = 'month'
class AddMonths(Func):
6688class AddMonths(Func):
6689    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6692class Nvl2(Func):
6693    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6696class Normalize(Func):
6697    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6700class Overlay(Func):
6701    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):
6705class Predict(Func):
6706    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6709class Pow(Binary, Func):
6710    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6713class PercentileCont(AggFunc):
6714    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6717class PercentileDisc(AggFunc):
6718    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6721class Quantile(AggFunc):
6722    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6725class ApproxQuantile(Quantile):
6726    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):
6729class Quarter(Func):
6730    pass
key = 'quarter'
class Rand(Func):
6735class Rand(Func):
6736    _sql_names = ["RAND", "RANDOM"]
6737    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6740class Randn(Func):
6741    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6744class RangeN(Func):
6745    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6748class ReadCSV(Func):
6749    _sql_names = ["READ_CSV"]
6750    is_var_len_args = True
6751    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6754class Reduce(Func):
6755    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):
6758class RegexpExtract(Func):
6759    arg_types = {
6760        "this": True,
6761        "expression": True,
6762        "position": False,
6763        "occurrence": False,
6764        "parameters": False,
6765        "group": False,
6766    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6769class RegexpExtractAll(Func):
6770    arg_types = {
6771        "this": True,
6772        "expression": True,
6773        "position": False,
6774        "occurrence": False,
6775        "parameters": False,
6776        "group": False,
6777    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6780class RegexpReplace(Func):
6781    arg_types = {
6782        "this": True,
6783        "expression": True,
6784        "replacement": False,
6785        "position": False,
6786        "occurrence": False,
6787        "modifiers": False,
6788    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6791class RegexpLike(Binary, Func):
6792    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6795class RegexpILike(Binary, Func):
6796    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6801class RegexpSplit(Func):
6802    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6805class Repeat(Func):
6806    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
6810class Replace(Func):
6811    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
6816class Round(Func):
6817    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6820class RowNumber(Func):
6821    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6824class SafeDivide(Func):
6825    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6828class SHA(Func):
6829    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6832class SHA2(Func):
6833    _sql_names = ["SHA2"]
6834    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6837class Sign(Func):
6838    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6841class SortArray(Func):
6842    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6845class Split(Func):
6846    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6850class SplitPart(Func):
6851    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6856class Substring(Func):
6857    _sql_names = ["SUBSTRING", "SUBSTR"]
6858    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
6861class SubstringIndex(Func):
6862    """
6863    SUBSTRING_INDEX(str, delim, count)
6864
6865    *count* > 0  → left slice before the *count*-th delimiter
6866    *count* < 0  → right slice after the |count|-th delimiter
6867    """
6868
6869    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):
6872class StandardHash(Func):
6873    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6876class StartsWith(Func):
6877    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6878    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
6881class EndsWith(Func):
6882    _sql_names = ["ENDS_WITH", "ENDSWITH"]
6883    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
6886class StrPosition(Func):
6887    arg_types = {
6888        "this": True,
6889        "substr": True,
6890        "position": False,
6891        "occurrence": False,
6892    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6895class StrToDate(Func):
6896    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6899class StrToTime(Func):
6900    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):
6905class StrToUnix(Func):
6906    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6911class StrToMap(Func):
6912    arg_types = {
6913        "this": True,
6914        "pair_delim": False,
6915        "key_value_delim": False,
6916        "duplicate_resolution_callback": False,
6917    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6920class NumberToStr(Func):
6921    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6924class FromBase(Func):
6925    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
6928class Space(Func):
6929    """
6930    SPACE(n) → string consisting of n blank characters
6931    """
6932
6933    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
6936class Struct(Func):
6937    arg_types = {"expressions": False}
6938    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6941class StructExtract(Func):
6942    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6947class Stuff(Func):
6948    _sql_names = ["STUFF", "INSERT"]
6949    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):
6952class Sum(AggFunc):
6953    pass
key = 'sum'
class Sqrt(Func):
6956class Sqrt(Func):
6957    pass
key = 'sqrt'
class Stddev(AggFunc):
6960class Stddev(AggFunc):
6961    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6964class StddevPop(AggFunc):
6965    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6968class StddevSamp(AggFunc):
6969    pass
key = 'stddevsamp'
class Time(Func):
6973class Time(Func):
6974    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6977class TimeToStr(Func):
6978    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):
6981class TimeToTimeStr(Func):
6982    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6985class TimeToUnix(Func):
6986    pass
key = 'timetounix'
class TimeStrToDate(Func):
6989class TimeStrToDate(Func):
6990    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6993class TimeStrToTime(Func):
6994    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6997class TimeStrToUnix(Func):
6998    pass
key = 'timestrtounix'
class Trim(Func):
7001class Trim(Func):
7002    arg_types = {
7003        "this": True,
7004        "expression": False,
7005        "position": False,
7006        "collation": False,
7007    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
7010class TsOrDsAdd(Func, TimeUnit):
7011    # return_type is used to correctly cast the arguments of this expression when transpiling it
7012    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
7013
7014    @property
7015    def return_type(self) -> DataType:
7016        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
7014    @property
7015    def return_type(self) -> DataType:
7016        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
7019class TsOrDsDiff(Func, TimeUnit):
7020    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
7023class TsOrDsToDateStr(Func):
7024    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
7027class TsOrDsToDate(Func):
7028    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
7031class TsOrDsToDatetime(Func):
7032    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
7035class TsOrDsToTime(Func):
7036    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
7039class TsOrDsToTimestamp(Func):
7040    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
7043class TsOrDiToDi(Func):
7044    pass
key = 'tsorditodi'
class Unhex(Func):
7047class Unhex(Func):
7048    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7051class Unicode(Func):
7052    pass
key = 'unicode'
class UnixDate(Func):
7056class UnixDate(Func):
7057    pass
key = 'unixdate'
class UnixToStr(Func):
7060class UnixToStr(Func):
7061    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7066class UnixToTime(Func):
7067    arg_types = {
7068        "this": True,
7069        "scale": False,
7070        "zone": False,
7071        "hours": False,
7072        "minutes": False,
7073        "format": False,
7074    }
7075
7076    SECONDS = Literal.number(0)
7077    DECIS = Literal.number(1)
7078    CENTIS = Literal.number(2)
7079    MILLIS = Literal.number(3)
7080    DECIMILLIS = Literal.number(4)
7081    CENTIMILLIS = Literal.number(5)
7082    MICROS = Literal.number(6)
7083    DECIMICROS = Literal.number(7)
7084    CENTIMICROS = Literal.number(8)
7085    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):
7088class UnixToTimeStr(Func):
7089    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7092class UnixSeconds(Func):
7093    pass
key = 'unixseconds'
class UnixMicros(Func):
7096class UnixMicros(Func):
7097    pass
key = 'unixmicros'
class UnixMillis(Func):
7100class UnixMillis(Func):
7101    pass
key = 'unixmillis'
class Uuid(Func):
7104class Uuid(Func):
7105    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7106
7107    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7110class TimestampFromParts(Func):
7111    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7112    arg_types = {
7113        "year": True,
7114        "month": True,
7115        "day": True,
7116        "hour": True,
7117        "min": True,
7118        "sec": True,
7119        "nano": False,
7120        "zone": False,
7121        "milli": False,
7122    }
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):
7125class Upper(Func):
7126    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7129class Corr(Binary, AggFunc):
7130    pass
key = 'corr'
class Variance(AggFunc):
7133class Variance(AggFunc):
7134    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7137class VariancePop(AggFunc):
7138    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7141class CovarSamp(Binary, AggFunc):
7142    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7145class CovarPop(Binary, AggFunc):
7146    pass
key = 'covarpop'
class Week(Func):
7149class Week(Func):
7150    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class WeekStart(Expression):
7153class WeekStart(Expression):
7154    pass
key = 'weekstart'
class XMLElement(Func):
7157class XMLElement(Func):
7158    _sql_names = ["XMLELEMENT"]
7159    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7162class XMLTable(Func):
7163    arg_types = {
7164        "this": True,
7165        "namespaces": False,
7166        "passing": False,
7167        "columns": False,
7168        "by_ref": False,
7169    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7172class XMLNamespace(Expression):
7173    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7177class XMLKeyValueOption(Expression):
7178    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7181class Year(Func):
7182    pass
key = 'year'
class Use(Expression):
7185class Use(Expression):
7186    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7189class Merge(DML):
7190    arg_types = {
7191        "this": True,
7192        "using": True,
7193        "on": True,
7194        "whens": True,
7195        "with": False,
7196        "returning": False,
7197    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7200class When(Expression):
7201    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):
7204class Whens(Expression):
7205    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7206
7207    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7212class NextValueFor(Func):
7213    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7218class Semicolon(Expression):
7219    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7224class TableColumn(Expression):
7225    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 '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 '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 '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'>, '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'>, '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'>, '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:
7265def maybe_parse(
7266    sql_or_expression: ExpOrStr,
7267    *,
7268    into: t.Optional[IntoType] = None,
7269    dialect: DialectType = None,
7270    prefix: t.Optional[str] = None,
7271    copy: bool = False,
7272    **opts,
7273) -> Expression:
7274    """Gracefully handle a possible string or expression.
7275
7276    Example:
7277        >>> maybe_parse("1")
7278        Literal(this=1, is_string=False)
7279        >>> maybe_parse(to_identifier("x"))
7280        Identifier(this=x, quoted=False)
7281
7282    Args:
7283        sql_or_expression: the SQL code string or an expression
7284        into: the SQLGlot Expression to parse into
7285        dialect: the dialect used to parse the input expressions (in the case that an
7286            input expression is a SQL string).
7287        prefix: a string to prefix the sql with before it gets parsed
7288            (automatically includes a space)
7289        copy: whether to copy the expression.
7290        **opts: other options to use to parse the input expressions (again, in the case
7291            that an input expression is a SQL string).
7292
7293    Returns:
7294        Expression: the parsed or given expression.
7295    """
7296    if isinstance(sql_or_expression, Expression):
7297        if copy:
7298            return sql_or_expression.copy()
7299        return sql_or_expression
7300
7301    if sql_or_expression is None:
7302        raise ParseError("SQL cannot be None")
7303
7304    import sqlglot
7305
7306    sql = str(sql_or_expression)
7307    if prefix:
7308        sql = f"{prefix} {sql}"
7309
7310    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):
7321def maybe_copy(instance, copy=True):
7322    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:
7577def union(
7578    *expressions: ExpOrStr,
7579    distinct: bool = True,
7580    dialect: DialectType = None,
7581    copy: bool = True,
7582    **opts,
7583) -> Union:
7584    """
7585    Initializes a syntax tree for the `UNION` operation.
7586
7587    Example:
7588        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7589        'SELECT * FROM foo UNION SELECT * FROM bla'
7590
7591    Args:
7592        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7593            If `Expression` instances are passed, they will be used as-is.
7594        distinct: set the DISTINCT flag if and only if this is true.
7595        dialect: the dialect used to parse the input expression.
7596        copy: whether to copy the expression.
7597        opts: other options to use to parse the input expressions.
7598
7599    Returns:
7600        The new Union instance.
7601    """
7602    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7603    return _apply_set_operation(
7604        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7605    )

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:
7608def intersect(
7609    *expressions: ExpOrStr,
7610    distinct: bool = True,
7611    dialect: DialectType = None,
7612    copy: bool = True,
7613    **opts,
7614) -> Intersect:
7615    """
7616    Initializes a syntax tree for the `INTERSECT` operation.
7617
7618    Example:
7619        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7620        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7621
7622    Args:
7623        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7624            If `Expression` instances are passed, they will be used as-is.
7625        distinct: set the DISTINCT flag if and only if this is true.
7626        dialect: the dialect used to parse the input expression.
7627        copy: whether to copy the expression.
7628        opts: other options to use to parse the input expressions.
7629
7630    Returns:
7631        The new Intersect instance.
7632    """
7633    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7634    return _apply_set_operation(
7635        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7636    )

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

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

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:
7938def and_(
7939    *expressions: t.Optional[ExpOrStr],
7940    dialect: DialectType = None,
7941    copy: bool = True,
7942    wrap: bool = True,
7943    **opts,
7944) -> Condition:
7945    """
7946    Combine multiple conditions with an AND logical operator.
7947
7948    Example:
7949        >>> and_("x=1", and_("y=1", "z=1")).sql()
7950        'x = 1 AND (y = 1 AND z = 1)'
7951
7952    Args:
7953        *expressions: the SQL code strings to parse.
7954            If an Expression instance is passed, this is used as-is.
7955        dialect: the dialect used to parse the input expression.
7956        copy: whether to copy `expressions` (only applies to Expressions).
7957        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7958            precedence issues, but can be turned off when the produced AST is too deep and
7959            causes recursion-related issues.
7960        **opts: other options to use to parse the input expressions.
7961
7962    Returns:
7963        The new condition
7964    """
7965    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:
7968def or_(
7969    *expressions: t.Optional[ExpOrStr],
7970    dialect: DialectType = None,
7971    copy: bool = True,
7972    wrap: bool = True,
7973    **opts,
7974) -> Condition:
7975    """
7976    Combine multiple conditions with an OR logical operator.
7977
7978    Example:
7979        >>> or_("x=1", or_("y=1", "z=1")).sql()
7980        'x = 1 OR (y = 1 OR z = 1)'
7981
7982    Args:
7983        *expressions: the SQL code strings to parse.
7984            If an Expression instance is passed, this is used as-is.
7985        dialect: the dialect used to parse the input expression.
7986        copy: whether to copy `expressions` (only applies to Expressions).
7987        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7988            precedence issues, but can be turned off when the produced AST is too deep and
7989            causes recursion-related issues.
7990        **opts: other options to use to parse the input expressions.
7991
7992    Returns:
7993        The new condition
7994    """
7995    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:
7998def xor(
7999    *expressions: t.Optional[ExpOrStr],
8000    dialect: DialectType = None,
8001    copy: bool = True,
8002    wrap: bool = True,
8003    **opts,
8004) -> Condition:
8005    """
8006    Combine multiple conditions with an XOR logical operator.
8007
8008    Example:
8009        >>> xor("x=1", xor("y=1", "z=1")).sql()
8010        'x = 1 XOR (y = 1 XOR z = 1)'
8011
8012    Args:
8013        *expressions: the SQL code strings to parse.
8014            If an Expression instance is passed, this is used as-is.
8015        dialect: the dialect used to parse the input expression.
8016        copy: whether to copy `expressions` (only applies to Expressions).
8017        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8018            precedence issues, but can be turned off when the produced AST is too deep and
8019            causes recursion-related issues.
8020        **opts: other options to use to parse the input expressions.
8021
8022    Returns:
8023        The new condition
8024    """
8025    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:
8028def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
8029    """
8030    Wrap a condition with a NOT operator.
8031
8032    Example:
8033        >>> not_("this_suit='black'").sql()
8034        "NOT this_suit = 'black'"
8035
8036    Args:
8037        expression: the SQL code string 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 the expression or not.
8041        **opts: other options to use to parse the input expressions.
8042
8043    Returns:
8044        The new condition.
8045    """
8046    this = condition(
8047        expression,
8048        dialect=dialect,
8049        copy=copy,
8050        **opts,
8051    )
8052    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:
8055def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
8056    """
8057    Wrap an expression in parentheses.
8058
8059    Example:
8060        >>> paren("5 + 3").sql()
8061        '(5 + 3)'
8062
8063    Args:
8064        expression: the SQL code string to parse.
8065            If an Expression instance is passed, this is used as-is.
8066        copy: whether to copy the expression or not.
8067
8068    Returns:
8069        The wrapped expression.
8070    """
8071    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):
8087def to_identifier(name, quoted=None, copy=True):
8088    """Builds an identifier.
8089
8090    Args:
8091        name: The name to turn into an identifier.
8092        quoted: Whether to force quote the identifier.
8093        copy: Whether to copy name if it's an Identifier.
8094
8095    Returns:
8096        The identifier ast node.
8097    """
8098
8099    if name is None:
8100        return None
8101
8102    if isinstance(name, Identifier):
8103        identifier = maybe_copy(name, copy)
8104    elif isinstance(name, str):
8105        identifier = Identifier(
8106            this=name,
8107            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8108        )
8109    else:
8110        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8111    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:
8114def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8115    """
8116    Parses a given string into an identifier.
8117
8118    Args:
8119        name: The name to parse into an identifier.
8120        dialect: The dialect to parse against.
8121
8122    Returns:
8123        The identifier ast node.
8124    """
8125    try:
8126        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8127    except (ParseError, TokenError):
8128        expression = to_identifier(name)
8129
8130    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:
8136def to_interval(interval: str | Literal) -> Interval:
8137    """Builds an interval expression from a string like '1 day' or '5 months'."""
8138    if isinstance(interval, Literal):
8139        if not interval.is_string:
8140            raise ValueError("Invalid interval string.")
8141
8142        interval = interval.this
8143
8144    interval = maybe_parse(f"INTERVAL {interval}")
8145    assert isinstance(interval, Interval)
8146    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:
8149def to_table(
8150    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8151) -> Table:
8152    """
8153    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8154    If a table is passed in then that table is returned.
8155
8156    Args:
8157        sql_path: a `[catalog].[schema].[table]` string.
8158        dialect: the source dialect according to which the table name will be parsed.
8159        copy: Whether to copy a table if it is passed in.
8160        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8161
8162    Returns:
8163        A table expression.
8164    """
8165    if isinstance(sql_path, Table):
8166        return maybe_copy(sql_path, copy=copy)
8167
8168    try:
8169        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8170    except ParseError:
8171        catalog, db, this = split_num_words(sql_path, ".", 3)
8172
8173        if not this:
8174            raise
8175
8176        table = table_(this, db=db, catalog=catalog)
8177
8178    for k, v in kwargs.items():
8179        table.set(k, v)
8180
8181    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:
8184def to_column(
8185    sql_path: str | Column,
8186    quoted: t.Optional[bool] = None,
8187    dialect: DialectType = None,
8188    copy: bool = True,
8189    **kwargs,
8190) -> Column:
8191    """
8192    Create a column from a `[table].[column]` sql path. Table is optional.
8193    If a column is passed in then that column is returned.
8194
8195    Args:
8196        sql_path: a `[table].[column]` string.
8197        quoted: Whether or not to force quote identifiers.
8198        dialect: the source dialect according to which the column name will be parsed.
8199        copy: Whether to copy a column if it is passed in.
8200        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8201
8202    Returns:
8203        A column expression.
8204    """
8205    if isinstance(sql_path, Column):
8206        return maybe_copy(sql_path, copy=copy)
8207
8208    try:
8209        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8210    except ParseError:
8211        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8212
8213    for k, v in kwargs.items():
8214        col.set(k, v)
8215
8216    if quoted:
8217        for i in col.find_all(Identifier):
8218            i.set("quoted", True)
8219
8220    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):
8223def alias_(
8224    expression: ExpOrStr,
8225    alias: t.Optional[str | Identifier],
8226    table: bool | t.Sequence[str | Identifier] = False,
8227    quoted: t.Optional[bool] = None,
8228    dialect: DialectType = None,
8229    copy: bool = True,
8230    **opts,
8231):
8232    """Create an Alias expression.
8233
8234    Example:
8235        >>> alias_('foo', 'bar').sql()
8236        'foo AS bar'
8237
8238        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8239        '(SELECT 1, 2) AS bar(a, b)'
8240
8241    Args:
8242        expression: the SQL code strings to parse.
8243            If an Expression instance is passed, this is used as-is.
8244        alias: the alias name to use. If the name has
8245            special characters it is quoted.
8246        table: Whether to create a table alias, can also be a list of columns.
8247        quoted: whether to quote the alias
8248        dialect: the dialect used to parse the input expression.
8249        copy: Whether to copy the expression.
8250        **opts: other options to use to parse the input expressions.
8251
8252    Returns:
8253        Alias: the aliased expression
8254    """
8255    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8256    alias = to_identifier(alias, quoted=quoted)
8257
8258    if table:
8259        table_alias = TableAlias(this=alias)
8260        exp.set("alias", table_alias)
8261
8262        if not isinstance(table, bool):
8263            for column in table:
8264                table_alias.append("columns", to_identifier(column, quoted=quoted))
8265
8266        return exp
8267
8268    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8269    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8270    # for the complete Window expression.
8271    #
8272    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8273
8274    if "alias" in exp.arg_types and not isinstance(exp, Window):
8275        exp.set("alias", alias)
8276        return exp
8277    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:
8280def subquery(
8281    expression: ExpOrStr,
8282    alias: t.Optional[Identifier | str] = None,
8283    dialect: DialectType = None,
8284    **opts,
8285) -> Select:
8286    """
8287    Build a subquery expression that's selected from.
8288
8289    Example:
8290        >>> subquery('select x from tbl', 'bar').select('x').sql()
8291        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8292
8293    Args:
8294        expression: the SQL code strings to parse.
8295            If an Expression instance is passed, this is used as-is.
8296        alias: the alias name to use.
8297        dialect: the dialect used to parse the input expression.
8298        **opts: other options to use to parse the input expressions.
8299
8300    Returns:
8301        A new Select instance with the subquery expression included.
8302    """
8303
8304    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8305    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):
8336def column(
8337    col,
8338    table=None,
8339    db=None,
8340    catalog=None,
8341    *,
8342    fields=None,
8343    quoted=None,
8344    copy=True,
8345):
8346    """
8347    Build a Column.
8348
8349    Args:
8350        col: Column name.
8351        table: Table name.
8352        db: Database name.
8353        catalog: Catalog name.
8354        fields: Additional fields using dots.
8355        quoted: Whether to force quotes on the column's identifiers.
8356        copy: Whether to copy identifiers if passed in.
8357
8358    Returns:
8359        The new Column instance.
8360    """
8361    if not isinstance(col, Star):
8362        col = to_identifier(col, quoted=quoted, copy=copy)
8363
8364    this = Column(
8365        this=col,
8366        table=to_identifier(table, quoted=quoted, copy=copy),
8367        db=to_identifier(db, quoted=quoted, copy=copy),
8368        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8369    )
8370
8371    if fields:
8372        this = Dot.build(
8373            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8374        )
8375    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:
8378def cast(
8379    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8380) -> Cast:
8381    """Cast an expression to a data type.
8382
8383    Example:
8384        >>> cast('x + 1', 'int').sql()
8385        'CAST(x + 1 AS INT)'
8386
8387    Args:
8388        expression: The expression to cast.
8389        to: The datatype to cast to.
8390        copy: Whether to copy the supplied expressions.
8391        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8392            - The expression to be cast is already a exp.Cast expression
8393            - The existing cast is to a type that is logically equivalent to new type
8394
8395            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8396            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8397            and instead just return the original expression `CAST(x as DATETIME)`.
8398
8399            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8400            mapping is applied in the target dialect generator.
8401
8402    Returns:
8403        The new Cast instance.
8404    """
8405    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8406    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8407
8408    # dont re-cast if the expression is already a cast to the correct type
8409    if isinstance(expr, Cast):
8410        from sqlglot.dialects.dialect import Dialect
8411
8412        target_dialect = Dialect.get_or_raise(dialect)
8413        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8414
8415        existing_cast_type: DataType.Type = expr.to.this
8416        new_cast_type: DataType.Type = data_type.this
8417        types_are_equivalent = type_mapping.get(
8418            existing_cast_type, existing_cast_type.value
8419        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8420
8421        if expr.is_type(data_type) or types_are_equivalent:
8422            return expr
8423
8424    expr = Cast(this=expr, to=data_type)
8425    expr.type = data_type
8426
8427    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:
8430def table_(
8431    table: Identifier | str,
8432    db: t.Optional[Identifier | str] = None,
8433    catalog: t.Optional[Identifier | str] = None,
8434    quoted: t.Optional[bool] = None,
8435    alias: t.Optional[Identifier | str] = None,
8436) -> Table:
8437    """Build a Table.
8438
8439    Args:
8440        table: Table name.
8441        db: Database name.
8442        catalog: Catalog name.
8443        quote: Whether to force quotes on the table's identifiers.
8444        alias: Table's alias.
8445
8446    Returns:
8447        The new Table instance.
8448    """
8449    return Table(
8450        this=to_identifier(table, quoted=quoted) if table else None,
8451        db=to_identifier(db, quoted=quoted) if db else None,
8452        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8453        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8454    )

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:
8457def values(
8458    values: t.Iterable[t.Tuple[t.Any, ...]],
8459    alias: t.Optional[str] = None,
8460    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8461) -> Values:
8462    """Build VALUES statement.
8463
8464    Example:
8465        >>> values([(1, '2')]).sql()
8466        "VALUES (1, '2')"
8467
8468    Args:
8469        values: values statements that will be converted to SQL
8470        alias: optional alias
8471        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8472         If either are provided then an alias is also required.
8473
8474    Returns:
8475        Values: the Values expression object
8476    """
8477    if columns and not alias:
8478        raise ValueError("Alias is required when providing columns")
8479
8480    return Values(
8481        expressions=[convert(tup) for tup in values],
8482        alias=(
8483            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8484            if columns
8485            else (TableAlias(this=to_identifier(alias)) if alias else None)
8486        ),
8487    )

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:
8490def var(name: t.Optional[ExpOrStr]) -> Var:
8491    """Build a SQL variable.
8492
8493    Example:
8494        >>> repr(var('x'))
8495        'Var(this=x)'
8496
8497        >>> repr(var(column('x', table='y')))
8498        'Var(this=x)'
8499
8500    Args:
8501        name: The name of the var or an expression who's name will become the var.
8502
8503    Returns:
8504        The new variable node.
8505    """
8506    if not name:
8507        raise ValueError("Cannot convert empty name into var.")
8508
8509    if isinstance(name, Expression):
8510        name = name.name
8511    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:
8514def rename_table(
8515    old_name: str | Table,
8516    new_name: str | Table,
8517    dialect: DialectType = None,
8518) -> Alter:
8519    """Build ALTER TABLE... RENAME... expression
8520
8521    Args:
8522        old_name: The old name of the table
8523        new_name: The new name of the table
8524        dialect: The dialect to parse the table.
8525
8526    Returns:
8527        Alter table expression
8528    """
8529    old_table = to_table(old_name, dialect=dialect)
8530    new_table = to_table(new_name, dialect=dialect)
8531    return Alter(
8532        this=old_table,
8533        kind="TABLE",
8534        actions=[
8535            AlterRename(this=new_table),
8536        ],
8537    )

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:
8540def rename_column(
8541    table_name: str | Table,
8542    old_column_name: str | Column,
8543    new_column_name: str | Column,
8544    exists: t.Optional[bool] = None,
8545    dialect: DialectType = None,
8546) -> Alter:
8547    """Build ALTER TABLE... RENAME COLUMN... expression
8548
8549    Args:
8550        table_name: Name of the table
8551        old_column: The old name of the column
8552        new_column: The new name of the column
8553        exists: Whether to add the `IF EXISTS` clause
8554        dialect: The dialect to parse the table/column.
8555
8556    Returns:
8557        Alter table expression
8558    """
8559    table = to_table(table_name, dialect=dialect)
8560    old_column = to_column(old_column_name, dialect=dialect)
8561    new_column = to_column(new_column_name, dialect=dialect)
8562    return Alter(
8563        this=table,
8564        kind="TABLE",
8565        actions=[
8566            RenameColumn(this=old_column, to=new_column, exists=exists),
8567        ],
8568    )

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

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:
8708def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8709    """Get the full name of a table as a string.
8710
8711    Args:
8712        table: Table expression node or string.
8713        dialect: The dialect to generate the table name for.
8714        identify: Determines when an identifier should be quoted. Possible values are:
8715            False (default): Never quote, except in cases where it's mandatory by the dialect.
8716            True: Always quote.
8717
8718    Examples:
8719        >>> from sqlglot import exp, parse_one
8720        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8721        'a.b.c'
8722
8723    Returns:
8724        The table name.
8725    """
8726
8727    table = maybe_parse(table, into=Table, dialect=dialect)
8728
8729    if not table:
8730        raise ValueError(f"Cannot parse {table}")
8731
8732    return ".".join(
8733        (
8734            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8735            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8736            else part.name
8737        )
8738        for part in table.parts
8739    )

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:
8742def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8743    """Returns a case normalized table name without quotes.
8744
8745    Args:
8746        table: the table to normalize
8747        dialect: the dialect to use for normalization rules
8748        copy: whether to copy the expression.
8749
8750    Examples:
8751        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8752        'A-B.c'
8753    """
8754    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8755
8756    return ".".join(
8757        p.name
8758        for p in normalize_identifiers(
8759            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8760        ).parts
8761    )

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

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:
8997def tuple_(
8998    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8999) -> Tuple:
9000    """
9001    Returns an tuple.
9002
9003    Examples:
9004        >>> tuple_(1, 'x').sql()
9005        '(1, x)'
9006
9007    Args:
9008        expressions: the expressions to add to the tuple.
9009        copy: whether to copy the argument expressions.
9010        dialect: the source dialect.
9011        kwargs: the kwargs used to instantiate the function of interest.
9012
9013    Returns:
9014        A tuple expression.
9015    """
9016    return Tuple(
9017        expressions=[
9018            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9019            for expression in expressions
9020        ]
9021    )

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:
9024def true() -> Boolean:
9025    """
9026    Returns a true Boolean expression.
9027    """
9028    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
9031def false() -> Boolean:
9032    """
9033    Returns a false Boolean expression.
9034    """
9035    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
9038def null() -> Null:
9039    """
9040    Returns a Null expression.
9041    """
9042    return Null()

Returns a Null expression.

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