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

Logical conditions like x AND y, or simply x

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

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

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

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

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

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

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

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

Returns the query's projections.

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

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

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

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

selects: List[Expression]
1445    @property
1446    def selects(self) -> t.List[Expression]:
1447        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1448        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]
1450    @property
1451    def named_selects(self) -> t.List[str]:
1452        """
1453        If this statement contains a query (e.g. a CTAS), this returns the output
1454        names of the query's projections.
1455        """
1456        return self.expression.named_selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the output names of the query's projections.

key = 'ddl'
class DML(Expression):
1459class DML(Expression):
1460    def returning(
1461        self,
1462        expression: ExpOrStr,
1463        dialect: DialectType = None,
1464        copy: bool = True,
1465        **opts,
1466    ) -> "Self":
1467        """
1468        Set the RETURNING expression. Not supported by all dialects.
1469
1470        Example:
1471            >>> delete("tbl").returning("*", dialect="postgres").sql()
1472            'DELETE FROM tbl RETURNING *'
1473
1474        Args:
1475            expression: the SQL code strings to parse.
1476                If an `Expression` instance is passed, it will be used as-is.
1477            dialect: the dialect used to parse the input expressions.
1478            copy: if `False`, modify this expression instance in-place.
1479            opts: other options to use to parse the input expressions.
1480
1481        Returns:
1482            Delete: the modified expression.
1483        """
1484        return _apply_builder(
1485            expression=expression,
1486            instance=self,
1487            arg="returning",
1488            prefix="RETURNING",
1489            dialect=dialect,
1490            copy=copy,
1491            into=Returning,
1492            **opts,
1493        )
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:
1460    def returning(
1461        self,
1462        expression: ExpOrStr,
1463        dialect: DialectType = None,
1464        copy: bool = True,
1465        **opts,
1466    ) -> "Self":
1467        """
1468        Set the RETURNING expression. Not supported by all dialects.
1469
1470        Example:
1471            >>> delete("tbl").returning("*", dialect="postgres").sql()
1472            'DELETE FROM tbl RETURNING *'
1473
1474        Args:
1475            expression: the SQL code strings to parse.
1476                If an `Expression` instance is passed, it will be used as-is.
1477            dialect: the dialect used to parse the input expressions.
1478            copy: if `False`, modify this expression instance in-place.
1479            opts: other options to use to parse the input expressions.
1480
1481        Returns:
1482            Delete: the modified expression.
1483        """
1484        return _apply_builder(
1485            expression=expression,
1486            instance=self,
1487            arg="returning",
1488            prefix="RETURNING",
1489            dialect=dialect,
1490            copy=copy,
1491            into=Returning,
1492            **opts,
1493        )

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):
1496class Create(DDL):
1497    arg_types = {
1498        "with": False,
1499        "this": True,
1500        "kind": True,
1501        "expression": False,
1502        "exists": False,
1503        "properties": False,
1504        "replace": False,
1505        "refresh": False,
1506        "unique": False,
1507        "indexes": False,
1508        "no_schema_binding": False,
1509        "begin": False,
1510        "end": False,
1511        "clone": False,
1512        "concurrently": False,
1513        "clustered": False,
1514    }
1515
1516    @property
1517    def kind(self) -> t.Optional[str]:
1518        kind = self.args.get("kind")
1519        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]
1516    @property
1517    def kind(self) -> t.Optional[str]:
1518        kind = self.args.get("kind")
1519        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1522class SequenceProperties(Expression):
1523    arg_types = {
1524        "increment": False,
1525        "minvalue": False,
1526        "maxvalue": False,
1527        "cache": False,
1528        "start": False,
1529        "owned": False,
1530        "options": False,
1531    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1534class TruncateTable(Expression):
1535    arg_types = {
1536        "expressions": True,
1537        "is_database": False,
1538        "exists": False,
1539        "only": False,
1540        "cluster": False,
1541        "identity": False,
1542        "option": False,
1543        "partition": False,
1544    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1550class Clone(Expression):
1551    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1554class Describe(Expression):
1555    arg_types = {
1556        "this": True,
1557        "style": False,
1558        "kind": False,
1559        "expressions": False,
1560        "partition": False,
1561        "format": False,
1562    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1566class Attach(Expression):
1567    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1571class Detach(Expression):
1572    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1576class Summarize(Expression):
1577    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1580class Kill(Expression):
1581    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1584class Pragma(Expression):
1585    pass
key = 'pragma'
class Declare(Expression):
1588class Declare(Expression):
1589    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1592class DeclareItem(Expression):
1593    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
class Set(Expression):
1596class Set(Expression):
1597    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1600class Heredoc(Expression):
1601    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1604class SetItem(Expression):
1605    arg_types = {
1606        "this": False,
1607        "expressions": False,
1608        "kind": False,
1609        "collate": False,  # MySQL SET NAMES statement
1610        "global": False,
1611    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1614class Show(Expression):
1615    arg_types = {
1616        "this": True,
1617        "history": False,
1618        "terse": False,
1619        "target": False,
1620        "offset": False,
1621        "starts_with": False,
1622        "limit": False,
1623        "from": False,
1624        "like": False,
1625        "where": False,
1626        "db": False,
1627        "scope": False,
1628        "scope_kind": False,
1629        "full": False,
1630        "mutex": False,
1631        "query": False,
1632        "channel": False,
1633        "global": False,
1634        "log": False,
1635        "position": False,
1636        "types": False,
1637        "privileges": False,
1638    }
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):
1641class UserDefinedFunction(Expression):
1642    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1645class CharacterSet(Expression):
1646    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1649class RecursiveWithSearch(Expression):
1650    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):
1653class With(Expression):
1654    arg_types = {"expressions": True, "recursive": False, "search": False}
1655
1656    @property
1657    def recursive(self) -> bool:
1658        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1656    @property
1657    def recursive(self) -> bool:
1658        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1661class WithinGroup(Expression):
1662    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1667class CTE(DerivedTable):
1668    arg_types = {
1669        "this": True,
1670        "alias": True,
1671        "scalar": False,
1672        "materialized": False,
1673    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1676class ProjectionDef(Expression):
1677    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1680class TableAlias(Expression):
1681    arg_types = {"this": False, "columns": False, "column_only": False}
1682
1683    @property
1684    def columns(self):
1685        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False, 'column_only': False}
columns
1683    @property
1684    def columns(self):
1685        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1688class BitString(Condition):
1689    pass
key = 'bitstring'
class HexString(Condition):
1692class HexString(Condition):
1693    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1696class ByteString(Condition):
1697    pass
key = 'bytestring'
class RawString(Condition):
1700class RawString(Condition):
1701    pass
key = 'rawstring'
class UnicodeString(Condition):
1704class UnicodeString(Condition):
1705    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1708class Column(Condition):
1709    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1710
1711    @property
1712    def table(self) -> str:
1713        return self.text("table")
1714
1715    @property
1716    def db(self) -> str:
1717        return self.text("db")
1718
1719    @property
1720    def catalog(self) -> str:
1721        return self.text("catalog")
1722
1723    @property
1724    def output_name(self) -> str:
1725        return self.name
1726
1727    @property
1728    def parts(self) -> t.List[Identifier]:
1729        """Return the parts of a column in order catalog, db, table, name."""
1730        return [
1731            t.cast(Identifier, self.args[part])
1732            for part in ("catalog", "db", "table", "this")
1733            if self.args.get(part)
1734        ]
1735
1736    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1737        """Converts the column into a dot expression."""
1738        parts = self.parts
1739        parent = self.parent
1740
1741        if include_dots:
1742            while isinstance(parent, Dot):
1743                parts.append(parent.expression)
1744                parent = parent.parent
1745
1746        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
1711    @property
1712    def table(self) -> str:
1713        return self.text("table")
db: str
1715    @property
1716    def db(self) -> str:
1717        return self.text("db")
catalog: str
1719    @property
1720    def catalog(self) -> str:
1721        return self.text("catalog")
output_name: str
1723    @property
1724    def output_name(self) -> str:
1725        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]
1727    @property
1728    def parts(self) -> t.List[Identifier]:
1729        """Return the parts of a column in order catalog, db, table, name."""
1730        return [
1731            t.cast(Identifier, self.args[part])
1732            for part in ("catalog", "db", "table", "this")
1733            if self.args.get(part)
1734        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1736    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1737        """Converts the column into a dot expression."""
1738        parts = self.parts
1739        parent = self.parent
1740
1741        if include_dots:
1742            while isinstance(parent, Dot):
1743                parts.append(parent.expression)
1744                parent = parent.parent
1745
1746        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1749class ColumnPosition(Expression):
1750    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1753class ColumnDef(Expression):
1754    arg_types = {
1755        "this": True,
1756        "kind": False,
1757        "constraints": False,
1758        "exists": False,
1759        "position": False,
1760        "default": False,
1761        "output": False,
1762    }
1763
1764    @property
1765    def constraints(self) -> t.List[ColumnConstraint]:
1766        return self.args.get("constraints") or []
1767
1768    @property
1769    def kind(self) -> t.Optional[DataType]:
1770        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1764    @property
1765    def constraints(self) -> t.List[ColumnConstraint]:
1766        return self.args.get("constraints") or []
kind: Optional[DataType]
1768    @property
1769    def kind(self) -> t.Optional[DataType]:
1770        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1773class AlterColumn(Expression):
1774    arg_types = {
1775        "this": True,
1776        "dtype": False,
1777        "collate": False,
1778        "using": False,
1779        "default": False,
1780        "drop": False,
1781        "comment": False,
1782        "allow_null": False,
1783        "visible": False,
1784    }
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):
1788class AlterIndex(Expression):
1789    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1793class AlterDistStyle(Expression):
1794    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1797class AlterSortKey(Expression):
1798    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1801class AlterSet(Expression):
1802    arg_types = {
1803        "expressions": False,
1804        "option": False,
1805        "tablespace": False,
1806        "access_method": False,
1807        "file_format": False,
1808        "copy_options": False,
1809        "tag": False,
1810        "location": False,
1811        "serde": False,
1812    }
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):
1815class RenameColumn(Expression):
1816    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1819class AlterRename(Expression):
1820    pass
key = 'alterrename'
class SwapTable(Expression):
1823class SwapTable(Expression):
1824    pass
key = 'swaptable'
class Comment(Expression):
1827class Comment(Expression):
1828    arg_types = {
1829        "this": True,
1830        "kind": True,
1831        "expression": True,
1832        "exists": False,
1833        "materialized": False,
1834    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1837class Comprehension(Expression):
1838    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):
1842class MergeTreeTTLAction(Expression):
1843    arg_types = {
1844        "this": True,
1845        "delete": False,
1846        "recompress": False,
1847        "to_disk": False,
1848        "to_volume": False,
1849    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1853class MergeTreeTTL(Expression):
1854    arg_types = {
1855        "expressions": True,
1856        "where": False,
1857        "group": False,
1858        "aggregates": False,
1859    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1863class IndexConstraintOption(Expression):
1864    arg_types = {
1865        "key_block_size": False,
1866        "using": False,
1867        "parser": False,
1868        "comment": False,
1869        "visible": False,
1870        "engine_attr": False,
1871        "secondary_engine_attr": False,
1872    }
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):
1875class ColumnConstraint(Expression):
1876    arg_types = {"this": False, "kind": True}
1877
1878    @property
1879    def kind(self) -> ColumnConstraintKind:
1880        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1878    @property
1879    def kind(self) -> ColumnConstraintKind:
1880        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1883class ColumnConstraintKind(Expression):
1884    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1887class AutoIncrementColumnConstraint(ColumnConstraintKind):
1888    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1891class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1892    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1895class CaseSpecificColumnConstraint(ColumnConstraintKind):
1896    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1899class CharacterSetColumnConstraint(ColumnConstraintKind):
1900    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1903class CheckColumnConstraint(ColumnConstraintKind):
1904    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1907class ClusteredColumnConstraint(ColumnConstraintKind):
1908    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1911class CollateColumnConstraint(ColumnConstraintKind):
1912    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1915class CommentColumnConstraint(ColumnConstraintKind):
1916    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1919class CompressColumnConstraint(ColumnConstraintKind):
1920    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1923class DateFormatColumnConstraint(ColumnConstraintKind):
1924    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1927class DefaultColumnConstraint(ColumnConstraintKind):
1928    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1931class EncodeColumnConstraint(ColumnConstraintKind):
1932    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1936class ExcludeColumnConstraint(ColumnConstraintKind):
1937    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1940class EphemeralColumnConstraint(ColumnConstraintKind):
1941    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1944class WithOperator(Expression):
1945    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1948class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1949    # this: True -> ALWAYS, this: False -> BY DEFAULT
1950    arg_types = {
1951        "this": False,
1952        "expression": False,
1953        "on_null": False,
1954        "start": False,
1955        "increment": False,
1956        "minvalue": False,
1957        "maxvalue": False,
1958        "cycle": False,
1959        "order": False,
1960    }
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):
1963class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1964    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1969class IndexColumnConstraint(ColumnConstraintKind):
1970    arg_types = {
1971        "this": False,
1972        "expressions": False,
1973        "kind": False,
1974        "index_type": False,
1975        "options": False,
1976        "expression": False,  # Clickhouse
1977        "granularity": False,
1978    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1981class InlineLengthColumnConstraint(ColumnConstraintKind):
1982    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1985class NonClusteredColumnConstraint(ColumnConstraintKind):
1986    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1989class NotForReplicationColumnConstraint(ColumnConstraintKind):
1990    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1994class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1995    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1998class NotNullColumnConstraint(ColumnConstraintKind):
1999    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
2003class OnUpdateColumnConstraint(ColumnConstraintKind):
2004    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2007class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2008    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2011class TitleColumnConstraint(ColumnConstraintKind):
2012    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2015class UniqueColumnConstraint(ColumnConstraintKind):
2016    arg_types = {
2017        "this": False,
2018        "index_type": False,
2019        "on_conflict": False,
2020        "nulls": False,
2021        "options": False,
2022    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2025class UppercaseColumnConstraint(ColumnConstraintKind):
2026    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2030class WatermarkColumnConstraint(Expression):
2031    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2034class PathColumnConstraint(ColumnConstraintKind):
2035    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2039class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2040    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2045class ComputedColumnConstraint(ColumnConstraintKind):
2046    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2049class Constraint(Expression):
2050    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2053class Delete(DML):
2054    arg_types = {
2055        "with": False,
2056        "this": False,
2057        "using": False,
2058        "where": False,
2059        "returning": False,
2060        "limit": False,
2061        "tables": False,  # Multiple-Table Syntax (MySQL)
2062        "cluster": False,  # Clickhouse
2063    }
2064
2065    def delete(
2066        self,
2067        table: ExpOrStr,
2068        dialect: DialectType = None,
2069        copy: bool = True,
2070        **opts,
2071    ) -> Delete:
2072        """
2073        Create a DELETE expression or replace the table on an existing DELETE expression.
2074
2075        Example:
2076            >>> delete("tbl").sql()
2077            'DELETE FROM tbl'
2078
2079        Args:
2080            table: the table from which to delete.
2081            dialect: the dialect used to parse the input expression.
2082            copy: if `False`, modify this expression instance in-place.
2083            opts: other options to use to parse the input expressions.
2084
2085        Returns:
2086            Delete: the modified expression.
2087        """
2088        return _apply_builder(
2089            expression=table,
2090            instance=self,
2091            arg="this",
2092            dialect=dialect,
2093            into=Table,
2094            copy=copy,
2095            **opts,
2096        )
2097
2098    def where(
2099        self,
2100        *expressions: t.Optional[ExpOrStr],
2101        append: bool = True,
2102        dialect: DialectType = None,
2103        copy: bool = True,
2104        **opts,
2105    ) -> Delete:
2106        """
2107        Append to or set the WHERE expressions.
2108
2109        Example:
2110            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2111            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2112
2113        Args:
2114            *expressions: the SQL code strings to parse.
2115                If an `Expression` instance is passed, it will be used as-is.
2116                Multiple expressions are combined with an AND operator.
2117            append: if `True`, AND the new expressions to any existing expression.
2118                Otherwise, this resets the expression.
2119            dialect: the dialect used to parse the input expressions.
2120            copy: if `False`, modify this expression instance in-place.
2121            opts: other options to use to parse the input expressions.
2122
2123        Returns:
2124            Delete: the modified expression.
2125        """
2126        return _apply_conjunction_builder(
2127            *expressions,
2128            instance=self,
2129            arg="where",
2130            append=append,
2131            into=Where,
2132            dialect=dialect,
2133            copy=copy,
2134            **opts,
2135        )
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:
2065    def delete(
2066        self,
2067        table: ExpOrStr,
2068        dialect: DialectType = None,
2069        copy: bool = True,
2070        **opts,
2071    ) -> Delete:
2072        """
2073        Create a DELETE expression or replace the table on an existing DELETE expression.
2074
2075        Example:
2076            >>> delete("tbl").sql()
2077            'DELETE FROM tbl'
2078
2079        Args:
2080            table: the table from which to delete.
2081            dialect: the dialect used to parse the input expression.
2082            copy: if `False`, modify this expression instance in-place.
2083            opts: other options to use to parse the input expressions.
2084
2085        Returns:
2086            Delete: the modified expression.
2087        """
2088        return _apply_builder(
2089            expression=table,
2090            instance=self,
2091            arg="this",
2092            dialect=dialect,
2093            into=Table,
2094            copy=copy,
2095            **opts,
2096        )

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

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):
2138class Drop(Expression):
2139    arg_types = {
2140        "this": False,
2141        "kind": False,
2142        "expressions": False,
2143        "exists": False,
2144        "temporary": False,
2145        "materialized": False,
2146        "cascade": False,
2147        "constraints": False,
2148        "purge": False,
2149        "cluster": False,
2150        "concurrently": False,
2151    }
2152
2153    @property
2154    def kind(self) -> t.Optional[str]:
2155        kind = self.args.get("kind")
2156        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]
2153    @property
2154    def kind(self) -> t.Optional[str]:
2155        kind = self.args.get("kind")
2156        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2160class Export(Expression):
2161    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2164class Filter(Expression):
2165    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2168class Check(Expression):
2169    pass
key = 'check'
class Changes(Expression):
2172class Changes(Expression):
2173    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2177class Connect(Expression):
2178    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2181class CopyParameter(Expression):
2182    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2185class Copy(DML):
2186    arg_types = {
2187        "this": True,
2188        "kind": True,
2189        "files": True,
2190        "credentials": False,
2191        "format": False,
2192        "params": False,
2193    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2196class Credentials(Expression):
2197    arg_types = {
2198        "credentials": False,
2199        "encryption": False,
2200        "storage": False,
2201        "iam_role": False,
2202        "region": False,
2203    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2206class Prior(Expression):
2207    pass
key = 'prior'
class Directory(Expression):
2210class Directory(Expression):
2211    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2212    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2215class ForeignKey(Expression):
2216    arg_types = {
2217        "expressions": False,
2218        "reference": False,
2219        "delete": False,
2220        "update": False,
2221        "options": False,
2222    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2225class ColumnPrefix(Expression):
2226    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2229class PrimaryKey(Expression):
2230    arg_types = {"expressions": True, "options": False, "include": False}
arg_types = {'expressions': True, 'options': False, 'include': False}
key = 'primarykey'
class Into(Expression):
2235class Into(Expression):
2236    arg_types = {
2237        "this": False,
2238        "temporary": False,
2239        "unlogged": False,
2240        "bulk_collect": False,
2241        "expressions": False,
2242    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2245class From(Expression):
2246    @property
2247    def name(self) -> str:
2248        return self.this.name
2249
2250    @property
2251    def alias_or_name(self) -> str:
2252        return self.this.alias_or_name
name: str
2246    @property
2247    def name(self) -> str:
2248        return self.this.name
alias_or_name: str
2250    @property
2251    def alias_or_name(self) -> str:
2252        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2255class Having(Expression):
2256    pass
key = 'having'
class Hint(Expression):
2259class Hint(Expression):
2260    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2263class JoinHint(Expression):
2264    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2267class Identifier(Expression):
2268    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2269
2270    @property
2271    def quoted(self) -> bool:
2272        return bool(self.args.get("quoted"))
2273
2274    @property
2275    def hashable_args(self) -> t.Any:
2276        return (self.this, self.quoted)
2277
2278    @property
2279    def output_name(self) -> str:
2280        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2270    @property
2271    def quoted(self) -> bool:
2272        return bool(self.args.get("quoted"))
hashable_args: Any
2274    @property
2275    def hashable_args(self) -> t.Any:
2276        return (self.this, self.quoted)
output_name: str
2278    @property
2279    def output_name(self) -> str:
2280        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):
2284class Opclass(Expression):
2285    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2288class Index(Expression):
2289    arg_types = {
2290        "this": False,
2291        "table": False,
2292        "unique": False,
2293        "primary": False,
2294        "amp": False,  # teradata
2295        "params": False,
2296    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2299class IndexParameters(Expression):
2300    arg_types = {
2301        "using": False,
2302        "include": False,
2303        "columns": False,
2304        "with_storage": False,
2305        "partition_by": False,
2306        "tablespace": False,
2307        "where": False,
2308        "on": False,
2309    }
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):
2312class Insert(DDL, DML):
2313    arg_types = {
2314        "hint": False,
2315        "with": False,
2316        "is_function": False,
2317        "this": False,
2318        "expression": False,
2319        "conflict": False,
2320        "returning": False,
2321        "overwrite": False,
2322        "exists": False,
2323        "alternative": False,
2324        "where": False,
2325        "ignore": False,
2326        "by_name": False,
2327        "stored": False,
2328        "partition": False,
2329        "settings": False,
2330        "source": False,
2331    }
2332
2333    def with_(
2334        self,
2335        alias: ExpOrStr,
2336        as_: ExpOrStr,
2337        recursive: t.Optional[bool] = None,
2338        materialized: t.Optional[bool] = None,
2339        append: bool = True,
2340        dialect: DialectType = None,
2341        copy: bool = True,
2342        **opts,
2343    ) -> Insert:
2344        """
2345        Append to or set the common table expressions.
2346
2347        Example:
2348            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2349            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2350
2351        Args:
2352            alias: the SQL code string to parse as the table name.
2353                If an `Expression` instance is passed, this is used as-is.
2354            as_: the SQL code string to parse as the table expression.
2355                If an `Expression` instance is passed, it will be used as-is.
2356            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2357            materialized: set the MATERIALIZED part of the expression.
2358            append: if `True`, add to any existing expressions.
2359                Otherwise, this resets the expressions.
2360            dialect: the dialect used to parse the input expression.
2361            copy: if `False`, modify this expression instance in-place.
2362            opts: other options to use to parse the input expressions.
2363
2364        Returns:
2365            The modified expression.
2366        """
2367        return _apply_cte_builder(
2368            self,
2369            alias,
2370            as_,
2371            recursive=recursive,
2372            materialized=materialized,
2373            append=append,
2374            dialect=dialect,
2375            copy=copy,
2376            **opts,
2377        )
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:
2333    def with_(
2334        self,
2335        alias: ExpOrStr,
2336        as_: ExpOrStr,
2337        recursive: t.Optional[bool] = None,
2338        materialized: t.Optional[bool] = None,
2339        append: bool = True,
2340        dialect: DialectType = None,
2341        copy: bool = True,
2342        **opts,
2343    ) -> Insert:
2344        """
2345        Append to or set the common table expressions.
2346
2347        Example:
2348            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2349            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2350
2351        Args:
2352            alias: the SQL code string to parse as the table name.
2353                If an `Expression` instance is passed, this is used as-is.
2354            as_: the SQL code string to parse as the table expression.
2355                If an `Expression` instance is passed, it will be used as-is.
2356            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2357            materialized: set the MATERIALIZED part of the expression.
2358            append: if `True`, add to any existing expressions.
2359                Otherwise, this resets the expressions.
2360            dialect: the dialect used to parse the input expression.
2361            copy: if `False`, modify this expression instance in-place.
2362            opts: other options to use to parse the input expressions.
2363
2364        Returns:
2365            The modified expression.
2366        """
2367        return _apply_cte_builder(
2368            self,
2369            alias,
2370            as_,
2371            recursive=recursive,
2372            materialized=materialized,
2373            append=append,
2374            dialect=dialect,
2375            copy=copy,
2376            **opts,
2377        )

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):
2380class ConditionalInsert(Expression):
2381    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2384class MultitableInserts(Expression):
2385    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2388class OnConflict(Expression):
2389    arg_types = {
2390        "duplicate": False,
2391        "expressions": False,
2392        "action": False,
2393        "conflict_keys": False,
2394        "constraint": False,
2395        "where": False,
2396    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2399class OnCondition(Expression):
2400    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2403class Returning(Expression):
2404    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2408class Introducer(Expression):
2409    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2413class National(Expression):
2414    pass
key = 'national'
class LoadData(Expression):
2417class LoadData(Expression):
2418    arg_types = {
2419        "this": True,
2420        "local": False,
2421        "overwrite": False,
2422        "inpath": True,
2423        "partition": False,
2424        "input_format": False,
2425        "serde": False,
2426    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2429class Partition(Expression):
2430    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2433class PartitionRange(Expression):
2434    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
class PartitionId(Expression):
2438class PartitionId(Expression):
2439    pass
key = 'partitionid'
class Fetch(Expression):
2442class Fetch(Expression):
2443    arg_types = {
2444        "direction": False,
2445        "count": False,
2446        "limit_options": False,
2447    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2450class Grant(Expression):
2451    arg_types = {
2452        "privileges": True,
2453        "kind": False,
2454        "securable": True,
2455        "principals": True,
2456        "grant_option": False,
2457    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2460class Group(Expression):
2461    arg_types = {
2462        "expressions": False,
2463        "grouping_sets": False,
2464        "cube": False,
2465        "rollup": False,
2466        "totals": False,
2467        "all": False,
2468    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2471class Cube(Expression):
2472    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2475class Rollup(Expression):
2476    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2479class GroupingSets(Expression):
2480    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2483class Lambda(Expression):
2484    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2487class Limit(Expression):
2488    arg_types = {
2489        "this": False,
2490        "expression": True,
2491        "offset": False,
2492        "limit_options": False,
2493        "expressions": False,
2494    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2497class LimitOptions(Expression):
2498    arg_types = {
2499        "percent": False,
2500        "rows": False,
2501        "with_ties": False,
2502    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2505class Literal(Condition):
2506    arg_types = {"this": True, "is_string": True}
2507
2508    @property
2509    def hashable_args(self) -> t.Any:
2510        return (self.this, self.args.get("is_string"))
2511
2512    @classmethod
2513    def number(cls, number) -> Literal:
2514        return cls(this=str(number), is_string=False)
2515
2516    @classmethod
2517    def string(cls, string) -> Literal:
2518        return cls(this=str(string), is_string=True)
2519
2520    @property
2521    def output_name(self) -> str:
2522        return self.name
2523
2524    def to_py(self) -> int | str | Decimal:
2525        if self.is_number:
2526            try:
2527                return int(self.this)
2528            except ValueError:
2529                return Decimal(self.this)
2530        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2508    @property
2509    def hashable_args(self) -> t.Any:
2510        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2512    @classmethod
2513    def number(cls, number) -> Literal:
2514        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2516    @classmethod
2517    def string(cls, string) -> Literal:
2518        return cls(this=str(string), is_string=True)
output_name: str
2520    @property
2521    def output_name(self) -> str:
2522        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:
2524    def to_py(self) -> int | str | Decimal:
2525        if self.is_number:
2526            try:
2527                return int(self.this)
2528            except ValueError:
2529                return Decimal(self.this)
2530        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2533class Join(Expression):
2534    arg_types = {
2535        "this": True,
2536        "on": False,
2537        "side": False,
2538        "kind": False,
2539        "using": False,
2540        "method": False,
2541        "global": False,
2542        "hint": False,
2543        "match_condition": False,  # Snowflake
2544        "expressions": False,
2545        "pivots": False,
2546    }
2547
2548    @property
2549    def method(self) -> str:
2550        return self.text("method").upper()
2551
2552    @property
2553    def kind(self) -> str:
2554        return self.text("kind").upper()
2555
2556    @property
2557    def side(self) -> str:
2558        return self.text("side").upper()
2559
2560    @property
2561    def hint(self) -> str:
2562        return self.text("hint").upper()
2563
2564    @property
2565    def alias_or_name(self) -> str:
2566        return self.this.alias_or_name
2567
2568    @property
2569    def is_semi_or_anti_join(self) -> bool:
2570        return self.kind in ("SEMI", "ANTI")
2571
2572    def on(
2573        self,
2574        *expressions: t.Optional[ExpOrStr],
2575        append: bool = True,
2576        dialect: DialectType = None,
2577        copy: bool = True,
2578        **opts,
2579    ) -> Join:
2580        """
2581        Append to or set the ON expressions.
2582
2583        Example:
2584            >>> import sqlglot
2585            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2586            'JOIN x ON y = 1'
2587
2588        Args:
2589            *expressions: the SQL code strings to parse.
2590                If an `Expression` instance is passed, it will be used as-is.
2591                Multiple expressions are combined with an AND operator.
2592            append: if `True`, AND the new expressions to any existing expression.
2593                Otherwise, this resets the expression.
2594            dialect: the dialect used to parse the input expressions.
2595            copy: if `False`, modify this expression instance in-place.
2596            opts: other options to use to parse the input expressions.
2597
2598        Returns:
2599            The modified Join expression.
2600        """
2601        join = _apply_conjunction_builder(
2602            *expressions,
2603            instance=self,
2604            arg="on",
2605            append=append,
2606            dialect=dialect,
2607            copy=copy,
2608            **opts,
2609        )
2610
2611        if join.kind == "CROSS":
2612            join.set("kind", None)
2613
2614        return join
2615
2616    def using(
2617        self,
2618        *expressions: t.Optional[ExpOrStr],
2619        append: bool = True,
2620        dialect: DialectType = None,
2621        copy: bool = True,
2622        **opts,
2623    ) -> Join:
2624        """
2625        Append to or set the USING expressions.
2626
2627        Example:
2628            >>> import sqlglot
2629            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2630            'JOIN x USING (foo, bla)'
2631
2632        Args:
2633            *expressions: the SQL code strings to parse.
2634                If an `Expression` instance is passed, it will be used as-is.
2635            append: if `True`, concatenate the new expressions to the existing "using" list.
2636                Otherwise, this resets the expression.
2637            dialect: the dialect used to parse the input expressions.
2638            copy: if `False`, modify this expression instance in-place.
2639            opts: other options to use to parse the input expressions.
2640
2641        Returns:
2642            The modified Join expression.
2643        """
2644        join = _apply_list_builder(
2645            *expressions,
2646            instance=self,
2647            arg="using",
2648            append=append,
2649            dialect=dialect,
2650            copy=copy,
2651            **opts,
2652        )
2653
2654        if join.kind == "CROSS":
2655            join.set("kind", None)
2656
2657        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
2548    @property
2549    def method(self) -> str:
2550        return self.text("method").upper()
kind: str
2552    @property
2553    def kind(self) -> str:
2554        return self.text("kind").upper()
side: str
2556    @property
2557    def side(self) -> str:
2558        return self.text("side").upper()
hint: str
2560    @property
2561    def hint(self) -> str:
2562        return self.text("hint").upper()
alias_or_name: str
2564    @property
2565    def alias_or_name(self) -> str:
2566        return self.this.alias_or_name
is_semi_or_anti_join: bool
2568    @property
2569    def is_semi_or_anti_join(self) -> bool:
2570        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:
2572    def on(
2573        self,
2574        *expressions: t.Optional[ExpOrStr],
2575        append: bool = True,
2576        dialect: DialectType = None,
2577        copy: bool = True,
2578        **opts,
2579    ) -> Join:
2580        """
2581        Append to or set the ON expressions.
2582
2583        Example:
2584            >>> import sqlglot
2585            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2586            'JOIN x ON y = 1'
2587
2588        Args:
2589            *expressions: the SQL code strings to parse.
2590                If an `Expression` instance is passed, it will be used as-is.
2591                Multiple expressions are combined with an AND operator.
2592            append: if `True`, AND the new expressions to any existing expression.
2593                Otherwise, this resets the expression.
2594            dialect: the dialect used to parse the input expressions.
2595            copy: if `False`, modify this expression instance in-place.
2596            opts: other options to use to parse the input expressions.
2597
2598        Returns:
2599            The modified Join expression.
2600        """
2601        join = _apply_conjunction_builder(
2602            *expressions,
2603            instance=self,
2604            arg="on",
2605            append=append,
2606            dialect=dialect,
2607            copy=copy,
2608            **opts,
2609        )
2610
2611        if join.kind == "CROSS":
2612            join.set("kind", None)
2613
2614        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:
2616    def using(
2617        self,
2618        *expressions: t.Optional[ExpOrStr],
2619        append: bool = True,
2620        dialect: DialectType = None,
2621        copy: bool = True,
2622        **opts,
2623    ) -> Join:
2624        """
2625        Append to or set the USING expressions.
2626
2627        Example:
2628            >>> import sqlglot
2629            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2630            'JOIN x USING (foo, bla)'
2631
2632        Args:
2633            *expressions: the SQL code strings to parse.
2634                If an `Expression` instance is passed, it will be used as-is.
2635            append: if `True`, concatenate the new expressions to the existing "using" list.
2636                Otherwise, this resets the expression.
2637            dialect: the dialect used to parse the input expressions.
2638            copy: if `False`, modify this expression instance in-place.
2639            opts: other options to use to parse the input expressions.
2640
2641        Returns:
2642            The modified Join expression.
2643        """
2644        join = _apply_list_builder(
2645            *expressions,
2646            instance=self,
2647            arg="using",
2648            append=append,
2649            dialect=dialect,
2650            copy=copy,
2651            **opts,
2652        )
2653
2654        if join.kind == "CROSS":
2655            join.set("kind", None)
2656
2657        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):
2660class Lateral(UDTF):
2661    arg_types = {
2662        "this": True,
2663        "view": False,
2664        "outer": False,
2665        "alias": False,
2666        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2667        "ordinality": False,
2668    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2673class TableFromRows(UDTF):
2674    arg_types = {
2675        "this": True,
2676        "alias": False,
2677        "joins": False,
2678        "pivots": False,
2679        "sample": False,
2680    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2683class MatchRecognizeMeasure(Expression):
2684    arg_types = {
2685        "this": True,
2686        "window_frame": False,
2687    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2690class MatchRecognize(Expression):
2691    arg_types = {
2692        "partition_by": False,
2693        "order": False,
2694        "measures": False,
2695        "rows": False,
2696        "after": False,
2697        "pattern": False,
2698        "define": False,
2699        "alias": False,
2700    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2705class Final(Expression):
2706    pass
key = 'final'
class Offset(Expression):
2709class Offset(Expression):
2710    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2713class Order(Expression):
2714    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2718class WithFill(Expression):
2719    arg_types = {
2720        "from": False,
2721        "to": False,
2722        "step": False,
2723        "interpolate": False,
2724    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2729class Cluster(Order):
2730    pass
key = 'cluster'
class Distribute(Order):
2733class Distribute(Order):
2734    pass
key = 'distribute'
class Sort(Order):
2737class Sort(Order):
2738    pass
key = 'sort'
class Ordered(Expression):
2741class Ordered(Expression):
2742    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2743
2744    @property
2745    def name(self) -> str:
2746        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2744    @property
2745    def name(self) -> str:
2746        return self.this.name
key = 'ordered'
class Property(Expression):
2749class Property(Expression):
2750    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2753class GrantPrivilege(Expression):
2754    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2757class GrantPrincipal(Expression):
2758    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2761class AllowedValuesProperty(Expression):
2762    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2765class AlgorithmProperty(Property):
2766    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2769class AutoIncrementProperty(Property):
2770    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2774class AutoRefreshProperty(Property):
2775    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2778class BackupProperty(Property):
2779    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2782class BlockCompressionProperty(Property):
2783    arg_types = {
2784        "autotemp": False,
2785        "always": False,
2786        "default": False,
2787        "manual": False,
2788        "never": False,
2789    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2792class CharacterSetProperty(Property):
2793    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2796class ChecksumProperty(Property):
2797    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2800class CollateProperty(Property):
2801    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2804class CopyGrantsProperty(Property):
2805    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2808class DataBlocksizeProperty(Property):
2809    arg_types = {
2810        "size": False,
2811        "units": False,
2812        "minimum": False,
2813        "maximum": False,
2814        "default": False,
2815    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2818class DataDeletionProperty(Property):
2819    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):
2822class DefinerProperty(Property):
2823    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2826class DistKeyProperty(Property):
2827    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2832class DistributedByProperty(Property):
2833    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):
2836class DistStyleProperty(Property):
2837    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2840class DuplicateKeyProperty(Property):
2841    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2844class EngineProperty(Property):
2845    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2848class HeapProperty(Property):
2849    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2852class ToTableProperty(Property):
2853    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2856class ExecuteAsProperty(Property):
2857    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2860class ExternalProperty(Property):
2861    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2864class FallbackProperty(Property):
2865    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2869class FileFormatProperty(Property):
2870    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2873class CredentialsProperty(Property):
2874    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2877class FreespaceProperty(Property):
2878    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2881class GlobalProperty(Property):
2882    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2885class IcebergProperty(Property):
2886    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2889class InheritsProperty(Property):
2890    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2893class InputModelProperty(Property):
2894    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2897class OutputModelProperty(Property):
2898    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2901class IsolatedLoadingProperty(Property):
2902    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2905class JournalProperty(Property):
2906    arg_types = {
2907        "no": False,
2908        "dual": False,
2909        "before": False,
2910        "local": False,
2911        "after": False,
2912    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2915class LanguageProperty(Property):
2916    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2919class EnviromentProperty(Property):
2920    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2924class ClusteredByProperty(Property):
2925    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2928class DictProperty(Property):
2929    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2932class DictSubProperty(Property):
2933    pass
key = 'dictsubproperty'
class DictRange(Property):
2936class DictRange(Property):
2937    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2940class DynamicProperty(Property):
2941    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2946class OnCluster(Property):
2947    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2951class EmptyProperty(Property):
2952    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2955class LikeProperty(Property):
2956    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2959class LocationProperty(Property):
2960    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2963class LockProperty(Property):
2964    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2967class LockingProperty(Property):
2968    arg_types = {
2969        "this": False,
2970        "kind": True,
2971        "for_or_in": False,
2972        "lock_type": True,
2973        "override": False,
2974    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2977class LogProperty(Property):
2978    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2981class MaterializedProperty(Property):
2982    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2985class MergeBlockRatioProperty(Property):
2986    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):
2989class NoPrimaryIndexProperty(Property):
2990    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2993class OnProperty(Property):
2994    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2997class OnCommitProperty(Property):
2998    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3001class PartitionedByProperty(Property):
3002    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3005class PartitionedByBucket(Property):
3006    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3009class PartitionByTruncate(Property):
3010    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3014class PartitionByRangeProperty(Property):
3015    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3019class PartitionByRangePropertyDynamic(Expression):
3020    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):
3024class UniqueKeyProperty(Property):
3025    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3029class PartitionBoundSpec(Expression):
3030    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3031    arg_types = {
3032        "this": False,
3033        "expression": False,
3034        "from_expressions": False,
3035        "to_expressions": False,
3036    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3039class PartitionedOfProperty(Property):
3040    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3041    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3044class StreamingTableProperty(Property):
3045    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3048class RemoteWithConnectionModelProperty(Property):
3049    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3052class ReturnsProperty(Property):
3053    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):
3056class StrictProperty(Property):
3057    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3060class RowFormatProperty(Property):
3061    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3064class RowFormatDelimitedProperty(Property):
3065    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3066    arg_types = {
3067        "fields": False,
3068        "escaped": False,
3069        "collection_items": False,
3070        "map_keys": False,
3071        "lines": False,
3072        "null": False,
3073        "serde": False,
3074    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3077class RowFormatSerdeProperty(Property):
3078    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3082class QueryTransform(Expression):
3083    arg_types = {
3084        "expressions": True,
3085        "command_script": True,
3086        "schema": False,
3087        "row_format_before": False,
3088        "record_writer": False,
3089        "row_format_after": False,
3090        "record_reader": False,
3091    }
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):
3094class SampleProperty(Property):
3095    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3099class SecurityProperty(Property):
3100    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3103class SchemaCommentProperty(Property):
3104    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3107class SemanticView(Expression):
3108    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):
3111class SerdeProperties(Property):
3112    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3115class SetProperty(Property):
3116    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3119class SharingProperty(Property):
3120    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3123class SetConfigProperty(Property):
3124    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3127class SettingsProperty(Property):
3128    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3131class SortKeyProperty(Property):
3132    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3135class SqlReadWriteProperty(Property):
3136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3139class SqlSecurityProperty(Property):
3140    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3143class StabilityProperty(Property):
3144    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3147class StorageHandlerProperty(Property):
3148    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3151class TemporaryProperty(Property):
3152    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3155class SecureProperty(Property):
3156    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3160class Tags(ColumnConstraintKind, Property):
3161    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3164class TransformModelProperty(Property):
3165    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3168class TransientProperty(Property):
3169    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3172class UnloggedProperty(Property):
3173    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3177class UsingTemplateProperty(Property):
3178    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3182class ViewAttributeProperty(Property):
3183    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3186class VolatileProperty(Property):
3187    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3190class WithDataProperty(Property):
3191    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3194class WithJournalTableProperty(Property):
3195    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3198class WithSchemaBindingProperty(Property):
3199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3202class WithSystemVersioningProperty(Property):
3203    arg_types = {
3204        "on": False,
3205        "this": False,
3206        "data_consistency": False,
3207        "retention_period": False,
3208        "with": True,
3209    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3212class WithProcedureOptions(Property):
3213    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3216class EncodeProperty(Property):
3217    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3220class IncludeProperty(Property):
3221    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3224class ForceProperty(Property):
3225    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3228class Properties(Expression):
3229    arg_types = {"expressions": True}
3230
3231    NAME_TO_PROPERTY = {
3232        "ALGORITHM": AlgorithmProperty,
3233        "AUTO_INCREMENT": AutoIncrementProperty,
3234        "CHARACTER SET": CharacterSetProperty,
3235        "CLUSTERED_BY": ClusteredByProperty,
3236        "COLLATE": CollateProperty,
3237        "COMMENT": SchemaCommentProperty,
3238        "CREDENTIALS": CredentialsProperty,
3239        "DEFINER": DefinerProperty,
3240        "DISTKEY": DistKeyProperty,
3241        "DISTRIBUTED_BY": DistributedByProperty,
3242        "DISTSTYLE": DistStyleProperty,
3243        "ENGINE": EngineProperty,
3244        "EXECUTE AS": ExecuteAsProperty,
3245        "FORMAT": FileFormatProperty,
3246        "LANGUAGE": LanguageProperty,
3247        "LOCATION": LocationProperty,
3248        "LOCK": LockProperty,
3249        "PARTITIONED_BY": PartitionedByProperty,
3250        "RETURNS": ReturnsProperty,
3251        "ROW_FORMAT": RowFormatProperty,
3252        "SORTKEY": SortKeyProperty,
3253        "ENCODE": EncodeProperty,
3254        "INCLUDE": IncludeProperty,
3255    }
3256
3257    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3258
3259    # CREATE property locations
3260    # Form: schema specified
3261    #   create [POST_CREATE]
3262    #     table a [POST_NAME]
3263    #     (b int) [POST_SCHEMA]
3264    #     with ([POST_WITH])
3265    #     index (b) [POST_INDEX]
3266    #
3267    # Form: alias selection
3268    #   create [POST_CREATE]
3269    #     table a [POST_NAME]
3270    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3271    #     index (c) [POST_INDEX]
3272    class Location(AutoName):
3273        POST_CREATE = auto()
3274        POST_NAME = auto()
3275        POST_SCHEMA = auto()
3276        POST_WITH = auto()
3277        POST_ALIAS = auto()
3278        POST_EXPRESSION = auto()
3279        POST_INDEX = auto()
3280        UNSUPPORTED = auto()
3281
3282    @classmethod
3283    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3284        expressions = []
3285        for key, value in properties_dict.items():
3286            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3287            if property_cls:
3288                expressions.append(property_cls(this=convert(value)))
3289            else:
3290                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3291
3292        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:
3282    @classmethod
3283    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3284        expressions = []
3285        for key, value in properties_dict.items():
3286            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3287            if property_cls:
3288                expressions.append(property_cls(this=convert(value)))
3289            else:
3290                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3291
3292        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3272    class Location(AutoName):
3273        POST_CREATE = auto()
3274        POST_NAME = auto()
3275        POST_SCHEMA = auto()
3276        POST_WITH = auto()
3277        POST_ALIAS = auto()
3278        POST_EXPRESSION = auto()
3279        POST_INDEX = auto()
3280        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):
3295class Qualify(Expression):
3296    pass
key = 'qualify'
class InputOutputFormat(Expression):
3299class InputOutputFormat(Expression):
3300    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3304class Return(Expression):
3305    pass
key = 'return'
class Reference(Expression):
3308class Reference(Expression):
3309    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3312class Tuple(Expression):
3313    arg_types = {"expressions": False}
3314
3315    def isin(
3316        self,
3317        *expressions: t.Any,
3318        query: t.Optional[ExpOrStr] = None,
3319        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3320        copy: bool = True,
3321        **opts,
3322    ) -> In:
3323        return In(
3324            this=maybe_copy(self, copy),
3325            expressions=[convert(e, copy=copy) for e in expressions],
3326            query=maybe_parse(query, copy=copy, **opts) if query else None,
3327            unnest=(
3328                Unnest(
3329                    expressions=[
3330                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3331                        for e in ensure_list(unnest)
3332                    ]
3333                )
3334                if unnest
3335                else None
3336            ),
3337        )
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:
3315    def isin(
3316        self,
3317        *expressions: t.Any,
3318        query: t.Optional[ExpOrStr] = None,
3319        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3320        copy: bool = True,
3321        **opts,
3322    ) -> In:
3323        return In(
3324            this=maybe_copy(self, copy),
3325            expressions=[convert(e, copy=copy) for e in expressions],
3326            query=maybe_parse(query, copy=copy, **opts) if query else None,
3327            unnest=(
3328                Unnest(
3329                    expressions=[
3330                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3331                        for e in ensure_list(unnest)
3332                    ]
3333                )
3334                if unnest
3335                else None
3336            ),
3337        )
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):
3368class QueryOption(Expression):
3369    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3373class WithTableHint(Expression):
3374    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3378class IndexTableHint(Expression):
3379    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3383class HistoricalData(Expression):
3384    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3388class Put(Expression):
3389    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3393class Get(Expression):
3394    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3397class Table(Expression):
3398    arg_types = {
3399        "this": False,
3400        "alias": False,
3401        "db": False,
3402        "catalog": False,
3403        "laterals": False,
3404        "joins": False,
3405        "pivots": False,
3406        "hints": False,
3407        "system_time": False,
3408        "version": False,
3409        "format": False,
3410        "pattern": False,
3411        "ordinality": False,
3412        "when": False,
3413        "only": False,
3414        "partition": False,
3415        "changes": False,
3416        "rows_from": False,
3417        "sample": False,
3418    }
3419
3420    @property
3421    def name(self) -> str:
3422        if not self.this or isinstance(self.this, Func):
3423            return ""
3424        return self.this.name
3425
3426    @property
3427    def db(self) -> str:
3428        return self.text("db")
3429
3430    @property
3431    def catalog(self) -> str:
3432        return self.text("catalog")
3433
3434    @property
3435    def selects(self) -> t.List[Expression]:
3436        return []
3437
3438    @property
3439    def named_selects(self) -> t.List[str]:
3440        return []
3441
3442    @property
3443    def parts(self) -> t.List[Expression]:
3444        """Return the parts of a table in order catalog, db, table."""
3445        parts: t.List[Expression] = []
3446
3447        for arg in ("catalog", "db", "this"):
3448            part = self.args.get(arg)
3449
3450            if isinstance(part, Dot):
3451                parts.extend(part.flatten())
3452            elif isinstance(part, Expression):
3453                parts.append(part)
3454
3455        return parts
3456
3457    def to_column(self, copy: bool = True) -> Expression:
3458        parts = self.parts
3459        last_part = parts[-1]
3460
3461        if isinstance(last_part, Identifier):
3462            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3463        else:
3464            # This branch will be reached if a function or array is wrapped in a `Table`
3465            col = last_part
3466
3467        alias = self.args.get("alias")
3468        if alias:
3469            col = alias_(col, alias.this, copy=copy)
3470
3471        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
3420    @property
3421    def name(self) -> str:
3422        if not self.this or isinstance(self.this, Func):
3423            return ""
3424        return self.this.name
db: str
3426    @property
3427    def db(self) -> str:
3428        return self.text("db")
catalog: str
3430    @property
3431    def catalog(self) -> str:
3432        return self.text("catalog")
selects: List[Expression]
3434    @property
3435    def selects(self) -> t.List[Expression]:
3436        return []
named_selects: List[str]
3438    @property
3439    def named_selects(self) -> t.List[str]:
3440        return []
parts: List[Expression]
3442    @property
3443    def parts(self) -> t.List[Expression]:
3444        """Return the parts of a table in order catalog, db, table."""
3445        parts: t.List[Expression] = []
3446
3447        for arg in ("catalog", "db", "this"):
3448            part = self.args.get(arg)
3449
3450            if isinstance(part, Dot):
3451                parts.extend(part.flatten())
3452            elif isinstance(part, Expression):
3453                parts.append(part)
3454
3455        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3506    @property
3507    def is_star(self) -> bool:
3508        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3510    @property
3511    def selects(self) -> t.List[Expression]:
3512        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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:
3951    def select(
3952        self,
3953        *expressions: t.Optional[ExpOrStr],
3954        append: bool = True,
3955        dialect: DialectType = None,
3956        copy: bool = True,
3957        **opts,
3958    ) -> Select:
3959        return _apply_list_builder(
3960            *expressions,
3961            instance=self,
3962            arg="expressions",
3963            append=append,
3964            dialect=dialect,
3965            into=Expression,
3966            copy=copy,
3967            **opts,
3968        )

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
4302    @property
4303    def selects(self) -> t.List[Expression]:
4304        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
4325    def unwrap(self) -> Subquery:
4326        expression = self
4327        while expression.same_parent and expression.is_wrapper:
4328            expression = t.cast(Subquery, expression.parent)
4329        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:
4331    def select(
4332        self,
4333        *expressions: t.Optional[ExpOrStr],
4334        append: bool = True,
4335        dialect: DialectType = None,
4336        copy: bool = True,
4337        **opts,
4338    ) -> Subquery:
4339        this = maybe_copy(self, copy)
4340        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4341        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
4343    @property
4344    def is_wrapper(self) -> bool:
4345        """
4346        Whether this Subquery acts as a simple wrapper around another expression.
4347
4348        SELECT * FROM (((SELECT * FROM t)))
4349                      ^
4350                      This corresponds to a "wrapper" Subquery node
4351        """
4352        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
4354    @property
4355    def is_star(self) -> bool:
4356        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4358    @property
4359    def output_name(self) -> str:
4360        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):
4363class TableSample(Expression):
4364    arg_types = {
4365        "expressions": False,
4366        "method": False,
4367        "bucket_numerator": False,
4368        "bucket_denominator": False,
4369        "bucket_field": False,
4370        "percent": False,
4371        "rows": False,
4372        "size": False,
4373        "seed": False,
4374    }
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):
4377class Tag(Expression):
4378    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4379
4380    arg_types = {
4381        "this": False,
4382        "prefix": False,
4383        "postfix": False,
4384    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4389class Pivot(Expression):
4390    arg_types = {
4391        "this": False,
4392        "alias": False,
4393        "expressions": False,
4394        "fields": False,
4395        "unpivot": False,
4396        "using": False,
4397        "group": False,
4398        "columns": False,
4399        "include_nulls": False,
4400        "default_on_null": False,
4401        "into": False,
4402    }
4403
4404    @property
4405    def unpivot(self) -> bool:
4406        return bool(self.args.get("unpivot"))
4407
4408    @property
4409    def fields(self) -> t.List[Expression]:
4410        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
4404    @property
4405    def unpivot(self) -> bool:
4406        return bool(self.args.get("unpivot"))
fields: List[Expression]
4408    @property
4409    def fields(self) -> t.List[Expression]:
4410        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4415class UnpivotColumns(Expression):
4416    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4419class Window(Condition):
4420    arg_types = {
4421        "this": True,
4422        "partition_by": False,
4423        "order": False,
4424        "spec": False,
4425        "alias": False,
4426        "over": False,
4427        "first": False,
4428    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4431class WindowSpec(Expression):
4432    arg_types = {
4433        "kind": False,
4434        "start": False,
4435        "start_side": False,
4436        "end": False,
4437        "end_side": False,
4438        "exclude": False,
4439    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4442class PreWhere(Expression):
4443    pass
key = 'prewhere'
class Where(Expression):
4446class Where(Expression):
4447    pass
key = 'where'
class Star(Expression):
4450class Star(Expression):
4451    arg_types = {"except": False, "replace": False, "rename": False}
4452
4453    @property
4454    def name(self) -> str:
4455        return "*"
4456
4457    @property
4458    def output_name(self) -> str:
4459        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4453    @property
4454    def name(self) -> str:
4455        return "*"
output_name: str
4457    @property
4458    def output_name(self) -> str:
4459        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):
4462class Parameter(Condition):
4463    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4466class SessionParameter(Condition):
4467    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4472class Placeholder(Condition):
4473    arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
4474
4475    @property
4476    def name(self) -> str:
4477        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False, 'jdbc': False}
name: str
4475    @property
4476    def name(self) -> str:
4477        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4480class Null(Condition):
4481    arg_types: t.Dict[str, t.Any] = {}
4482
4483    @property
4484    def name(self) -> str:
4485        return "NULL"
4486
4487    def to_py(self) -> Lit[None]:
4488        return None
arg_types: Dict[str, Any] = {}
name: str
4483    @property
4484    def name(self) -> str:
4485        return "NULL"
def to_py(self) -> Literal[None]:
4487    def to_py(self) -> Lit[None]:
4488        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4491class Boolean(Condition):
4492    def to_py(self) -> bool:
4493        return self.this
def to_py(self) -> bool:
4492    def to_py(self) -> bool:
4493        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
5016    @property
5017    def name(self) -> str:
5018        return self.expression.name
output_name: str
5020    @property
5021    def output_name(self) -> str:
5022        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:
5024    @classmethod
5025    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5026        """Build a Dot object with a sequence of expressions."""
5027        if len(expressions) < 2:
5028            raise ValueError("Dot requires >= 2 expressions.")
5029
5030        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]
5032    @property
5033    def parts(self) -> t.List[Expression]:
5034        """Return the parts of a table / column in order catalog, db, table."""
5035        this, *parts = self.flatten()
5036
5037        parts.reverse()
5038
5039        for arg in COLUMN_PARTS:
5040            part = this.args.get(arg)
5041
5042            if isinstance(part, Expression):
5043                parts.append(part)
5044
5045        parts.reverse()
5046        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):
5052class DPipe(Binary):
5053    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5056class EQ(Binary, Predicate):
5057    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5060class NullSafeEQ(Binary, Predicate):
5061    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5064class NullSafeNEQ(Binary, Predicate):
5065    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5069class PropertyEQ(Binary):
5070    pass
key = 'propertyeq'
class Distance(Binary):
5073class Distance(Binary):
5074    pass
key = 'distance'
class Escape(Binary):
5077class Escape(Binary):
5078    pass
key = 'escape'
class Glob(Binary, Predicate):
5081class Glob(Binary, Predicate):
5082    pass
key = 'glob'
class GT(Binary, Predicate):
5085class GT(Binary, Predicate):
5086    pass
key = 'gt'
class GTE(Binary, Predicate):
5089class GTE(Binary, Predicate):
5090    pass
key = 'gte'
class ILike(Binary, Predicate):
5093class ILike(Binary, Predicate):
5094    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
5097class ILikeAny(Binary, Predicate):
5098    pass
key = 'ilikeany'
class IntDiv(Binary):
5101class IntDiv(Binary):
5102    pass
key = 'intdiv'
class Is(Binary, Predicate):
5105class Is(Binary, Predicate):
5106    pass
key = 'is'
class Kwarg(Binary):
5109class Kwarg(Binary):
5110    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5113class Like(Binary, Predicate):
5114    pass
key = 'like'
class LikeAny(Binary, Predicate):
5117class LikeAny(Binary, Predicate):
5118    pass
key = 'likeany'
class LT(Binary, Predicate):
5121class LT(Binary, Predicate):
5122    pass
key = 'lt'
class LTE(Binary, Predicate):
5125class LTE(Binary, Predicate):
5126    pass
key = 'lte'
class Mod(Binary):
5129class Mod(Binary):
5130    pass
key = 'mod'
class Mul(Binary):
5133class Mul(Binary):
5134    pass
key = 'mul'
class NEQ(Binary, Predicate):
5137class NEQ(Binary, Predicate):
5138    pass
key = 'neq'
class Operator(Binary):
5142class Operator(Binary):
5143    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5146class SimilarTo(Binary, Predicate):
5147    pass
key = 'similarto'
class Slice(Binary):
5150class Slice(Binary):
5151    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5154class Sub(Binary):
5155    pass
key = 'sub'
class Unary(Condition):
5160class Unary(Condition):
5161    pass
key = 'unary'
class BitwiseNot(Unary):
5164class BitwiseNot(Unary):
5165    pass
key = 'bitwisenot'
class Not(Unary):
5168class Not(Unary):
5169    pass
key = 'not'
class Paren(Unary):
5172class Paren(Unary):
5173    @property
5174    def output_name(self) -> str:
5175        return self.this.name
output_name: str
5173    @property
5174    def output_name(self) -> str:
5175        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):
5178class Neg(Unary):
5179    def to_py(self) -> int | Decimal:
5180        if self.is_number:
5181            return self.this.to_py() * -1
5182        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5179    def to_py(self) -> int | Decimal:
5180        if self.is_number:
5181            return self.this.to_py() * -1
5182        return super().to_py()

Returns a Python object equivalent of the SQL node.

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

Automatically converts unit arg into a var.

TimeUnit(**args)
5298    def __init__(self, **args):
5299        unit = args.get("unit")
5300        if isinstance(unit, self.VAR_LIKE):
5301            args["unit"] = Var(
5302                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5303            )
5304        elif isinstance(unit, Week):
5305            unit.set("this", Var(this=unit.this.name.upper()))
5306
5307        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]
5309    @property
5310    def unit(self) -> t.Optional[Var | IntervalSpan]:
5311        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5314class IntervalOp(TimeUnit):
5315    arg_types = {"unit": False, "expression": True}
5316
5317    def interval(self):
5318        return Interval(
5319            this=self.expression.copy(),
5320            unit=self.unit.copy() if self.unit else None,
5321        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5317    def interval(self):
5318        return Interval(
5319            this=self.expression.copy(),
5320            unit=self.unit.copy() if self.unit else None,
5321        )
key = 'intervalop'
class IntervalSpan(DataType):
5327class IntervalSpan(DataType):
5328    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5331class Interval(TimeUnit):
5332    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5335class IgnoreNulls(Expression):
5336    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5339class RespectNulls(Expression):
5340    pass
key = 'respectnulls'
class HavingMax(Expression):
5344class HavingMax(Expression):
5345    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5349class Func(Condition):
5350    """
5351    The base class for all function expressions.
5352
5353    Attributes:
5354        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5355            treated as a variable length argument and the argument's value will be stored as a list.
5356        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5357            function expression. These values are used to map this node to a name during parsing as
5358            well as to provide the function's name during SQL string generation. By default the SQL
5359            name is set to the expression's class name transformed to snake case.
5360    """
5361
5362    is_var_len_args = False
5363
5364    @classmethod
5365    def from_arg_list(cls, args):
5366        if cls.is_var_len_args:
5367            all_arg_keys = list(cls.arg_types)
5368            # If this function supports variable length argument treat the last argument as such.
5369            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5370            num_non_var = len(non_var_len_arg_keys)
5371
5372            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5373            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5374        else:
5375            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5376
5377        return cls(**args_dict)
5378
5379    @classmethod
5380    def sql_names(cls):
5381        if cls is Func:
5382            raise NotImplementedError(
5383                "SQL name is only supported by concrete function implementations"
5384            )
5385        if "_sql_names" not in cls.__dict__:
5386            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5387        return cls._sql_names
5388
5389    @classmethod
5390    def sql_name(cls):
5391        sql_names = cls.sql_names()
5392        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5393        return sql_names[0]
5394
5395    @classmethod
5396    def default_parser_mappings(cls):
5397        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):
5364    @classmethod
5365    def from_arg_list(cls, args):
5366        if cls.is_var_len_args:
5367            all_arg_keys = list(cls.arg_types)
5368            # If this function supports variable length argument treat the last argument as such.
5369            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5370            num_non_var = len(non_var_len_arg_keys)
5371
5372            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5373            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5374        else:
5375            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5376
5377        return cls(**args_dict)
@classmethod
def sql_names(cls):
5379    @classmethod
5380    def sql_names(cls):
5381        if cls is Func:
5382            raise NotImplementedError(
5383                "SQL name is only supported by concrete function implementations"
5384            )
5385        if "_sql_names" not in cls.__dict__:
5386            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5387        return cls._sql_names
@classmethod
def sql_name(cls):
5389    @classmethod
5390    def sql_name(cls):
5391        sql_names = cls.sql_names()
5392        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5393        return sql_names[0]
@classmethod
def default_parser_mappings(cls):
5395    @classmethod
5396    def default_parser_mappings(cls):
5397        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5400class Typeof(Func):
5401    pass
key = 'typeof'
class AggFunc(Func):
5404class AggFunc(Func):
5405    pass
key = 'aggfunc'
class BitwiseAndAgg(AggFunc):
5408class BitwiseAndAgg(AggFunc):
5409    _sql_names = ["BIT_AND"]
key = 'bitwiseandagg'
class BitwiseOrAgg(AggFunc):
5412class BitwiseOrAgg(AggFunc):
5413    _sql_names = ["BIT_OR"]
key = 'bitwiseoragg'
class BitwiseXorAgg(AggFunc):
5416class BitwiseXorAgg(AggFunc):
5417    _sql_names = ["BIT_XOR"]
key = 'bitwisexoragg'
class BitwiseCountAgg(AggFunc):
5420class BitwiseCountAgg(AggFunc):
5421    _sql_names = ["BIT_COUNT"]
key = 'bitwisecountagg'
class ArrayRemove(Func):
5424class ArrayRemove(Func):
5425    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5428class ParameterizedAgg(AggFunc):
5429    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5432class Abs(Func):
5433    pass
key = 'abs'
class ArgMax(AggFunc):
5436class ArgMax(AggFunc):
5437    arg_types = {"this": True, "expression": True, "count": False}
5438    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5441class ArgMin(AggFunc):
5442    arg_types = {"this": True, "expression": True, "count": False}
5443    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5446class ApproxTopK(AggFunc):
5447    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5450class Flatten(Func):
5451    pass
key = 'flatten'
class Transform(Func):
5455class Transform(Func):
5456    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5459class Anonymous(Func):
5460    arg_types = {"this": True, "expressions": False}
5461    is_var_len_args = True
5462
5463    @property
5464    def name(self) -> str:
5465        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
5463    @property
5464    def name(self) -> str:
5465        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5468class AnonymousAggFunc(AggFunc):
5469    arg_types = {"this": True, "expressions": False}
5470    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5474class CombinedAggFunc(AnonymousAggFunc):
5475    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5478class CombinedParameterizedAgg(ParameterizedAgg):
5479    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5484class Hll(AggFunc):
5485    arg_types = {"this": True, "expressions": False}
5486    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5489class ApproxDistinct(AggFunc):
5490    arg_types = {"this": True, "accuracy": False}
5491    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5494class Apply(Func):
5495    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5498class Array(Func):
5499    arg_types = {"expressions": False, "bracket_notation": False}
5500    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5503class Ascii(Func):
5504    pass
key = 'ascii'
class ToArray(Func):
5508class ToArray(Func):
5509    pass
key = 'toarray'
class List(Func):
5513class List(Func):
5514    arg_types = {"expressions": False}
5515    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5519class Pad(Func):
5520    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):
5525class ToChar(Func):
5526    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5531class ToNumber(Func):
5532    arg_types = {
5533        "this": True,
5534        "format": False,
5535        "nlsparam": False,
5536        "precision": False,
5537        "scale": False,
5538    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5542class ToDouble(Func):
5543    arg_types = {
5544        "this": True,
5545        "format": False,
5546    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5549class Columns(Func):
5550    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5554class Convert(Func):
5555    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5559class ConvertToCharset(Func):
5560    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5563class ConvertTimezone(Func):
5564    arg_types = {
5565        "source_tz": False,
5566        "target_tz": True,
5567        "timestamp": True,
5568        "options": False,
5569    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class GenerateSeries(Func):
5572class GenerateSeries(Func):
5573    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):
5579class ExplodingGenerateSeries(GenerateSeries):
5580    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5583class ArrayAgg(AggFunc):
5584    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5587class ArrayUniqueAgg(AggFunc):
5588    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5591class ArrayAll(Func):
5592    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5596class ArrayAny(Func):
5597    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5600class ArrayConcat(Func):
5601    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5602    arg_types = {"this": True, "expressions": False}
5603    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5606class ArrayConcatAgg(AggFunc):
5607    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5610class ArrayConstructCompact(Func):
5611    arg_types = {"expressions": True}
5612    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5615class ArrayContains(Binary, Func):
5616    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5619class ArrayContainsAll(Binary, Func):
5620    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5623class ArrayFilter(Func):
5624    arg_types = {"this": True, "expression": True}
5625    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5628class ArrayFirst(Func):
5629    pass
key = 'arrayfirst'
class ArrayLast(Func):
5632class ArrayLast(Func):
5633    pass
key = 'arraylast'
class ArrayReverse(Func):
5636class ArrayReverse(Func):
5637    pass
key = 'arrayreverse'
class ArraySlice(Func):
5640class ArraySlice(Func):
5641    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):
5644class ArrayToString(Func):
5645    arg_types = {"this": True, "expression": True, "null": False}
5646    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5649class ArrayIntersect(Func):
5650    arg_types = {"expressions": True}
5651    is_var_len_args = True
5652    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5655class StPoint(Func):
5656    arg_types = {"this": True, "expression": True, "null": False}
5657    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5660class StDistance(Func):
5661    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5665class String(Func):
5666    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5669class StringToArray(Func):
5670    arg_types = {"this": True, "expression": False, "null": False}
5671    _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):
5674class ArrayOverlaps(Binary, Func):
5675    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5678class ArraySize(Func):
5679    arg_types = {"this": True, "expression": False}
5680    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5683class ArraySort(Func):
5684    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5687class ArraySum(Func):
5688    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5691class ArrayUnionAgg(AggFunc):
5692    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5695class Avg(AggFunc):
5696    pass
key = 'avg'
class AnyValue(AggFunc):
5699class AnyValue(AggFunc):
5700    pass
key = 'anyvalue'
class Lag(AggFunc):
5703class Lag(AggFunc):
5704    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5707class Lead(AggFunc):
5708    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5713class First(AggFunc):
5714    pass
key = 'first'
class Last(AggFunc):
5717class Last(AggFunc):
5718    pass
key = 'last'
class FirstValue(AggFunc):
5721class FirstValue(AggFunc):
5722    pass
key = 'firstvalue'
class LastValue(AggFunc):
5725class LastValue(AggFunc):
5726    pass
key = 'lastvalue'
class NthValue(AggFunc):
5729class NthValue(AggFunc):
5730    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5733class Case(Func):
5734    arg_types = {"this": False, "ifs": True, "default": False}
5735
5736    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5737        instance = maybe_copy(self, copy)
5738        instance.append(
5739            "ifs",
5740            If(
5741                this=maybe_parse(condition, copy=copy, **opts),
5742                true=maybe_parse(then, copy=copy, **opts),
5743            ),
5744        )
5745        return instance
5746
5747    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5748        instance = maybe_copy(self, copy)
5749        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5750        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:
5736    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5737        instance = maybe_copy(self, copy)
5738        instance.append(
5739            "ifs",
5740            If(
5741                this=maybe_parse(condition, copy=copy, **opts),
5742                true=maybe_parse(then, copy=copy, **opts),
5743            ),
5744        )
5745        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5747    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5748        instance = maybe_copy(self, copy)
5749        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5750        return instance
key = 'case'
class Cast(Func):
5753class Cast(Func):
5754    arg_types = {
5755        "this": True,
5756        "to": True,
5757        "format": False,
5758        "safe": False,
5759        "action": False,
5760        "default": False,
5761    }
5762
5763    @property
5764    def name(self) -> str:
5765        return self.this.name
5766
5767    @property
5768    def to(self) -> DataType:
5769        return self.args["to"]
5770
5771    @property
5772    def output_name(self) -> str:
5773        return self.name
5774
5775    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5776        """
5777        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5778        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5779        array<int> != array<float>.
5780
5781        Args:
5782            dtypes: the data types to compare this Cast's DataType to.
5783
5784        Returns:
5785            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5786        """
5787        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5763    @property
5764    def name(self) -> str:
5765        return self.this.name
to: DataType
5767    @property
5768    def to(self) -> DataType:
5769        return self.args["to"]
output_name: str
5771    @property
5772    def output_name(self) -> str:
5773        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:
5775    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5776        """
5777        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5778        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5779        array<int> != array<float>.
5780
5781        Args:
5782            dtypes: the data types to compare this Cast's DataType to.
5783
5784        Returns:
5785            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5786        """
5787        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):
5790class TryCast(Cast):
5791    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):
5795class JSONCast(Cast):
5796    pass
key = 'jsoncast'
class Try(Func):
5799class Try(Func):
5800    pass
key = 'try'
class CastToStrType(Func):
5803class CastToStrType(Func):
5804    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
5808class TranslateCharacters(Expression):
5809    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
5812class Collate(Binary, Func):
5813    pass
key = 'collate'
class Ceil(Func):
5816class Ceil(Func):
5817    arg_types = {"this": True, "decimals": False, "to": False}
5818    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5821class Coalesce(Func):
5822    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
5823    is_var_len_args = True
5824    _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):
5827class Chr(Func):
5828    arg_types = {"expressions": True, "charset": False}
5829    is_var_len_args = True
5830    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5833class Concat(Func):
5834    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5835    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5838class ConcatWs(Concat):
5839    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5842class Contains(Func):
5843    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5847class ConnectByRoot(Func):
5848    pass
key = 'connectbyroot'
class Count(AggFunc):
5851class Count(AggFunc):
5852    arg_types = {"this": False, "expressions": False, "big_int": False}
5853    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5856class CountIf(AggFunc):
5857    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5861class Cbrt(Func):
5862    pass
key = 'cbrt'
class CurrentDate(Func):
5865class CurrentDate(Func):
5866    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5869class CurrentDatetime(Func):
5870    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5873class CurrentTime(Func):
5874    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5877class CurrentTimestamp(Func):
5878    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
5881class CurrentTimestampLTZ(Func):
5882    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
5885class CurrentSchema(Func):
5886    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5889class CurrentUser(Func):
5890    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5893class DateAdd(Func, IntervalOp):
5894    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5897class DateBin(Func, IntervalOp):
5898    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):
5901class DateSub(Func, IntervalOp):
5902    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5905class DateDiff(Func, TimeUnit):
5906    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5907    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):
5910class DateTrunc(Func):
5911    arg_types = {"unit": True, "this": True, "zone": False}
5912
5913    def __init__(self, **args):
5914        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5915        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5916        unabbreviate = args.pop("unabbreviate", True)
5917
5918        unit = args.get("unit")
5919        if isinstance(unit, TimeUnit.VAR_LIKE):
5920            unit_name = unit.name.upper()
5921            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5922                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5923
5924            args["unit"] = Literal.string(unit_name)
5925
5926        super().__init__(**args)
5927
5928    @property
5929    def unit(self) -> Expression:
5930        return self.args["unit"]
DateTrunc(**args)
5913    def __init__(self, **args):
5914        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5915        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5916        unabbreviate = args.pop("unabbreviate", True)
5917
5918        unit = args.get("unit")
5919        if isinstance(unit, TimeUnit.VAR_LIKE):
5920            unit_name = unit.name.upper()
5921            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5922                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5923
5924            args["unit"] = Literal.string(unit_name)
5925
5926        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5928    @property
5929    def unit(self) -> Expression:
5930        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5935class Datetime(Func):
5936    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5939class DatetimeAdd(Func, IntervalOp):
5940    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5943class DatetimeSub(Func, IntervalOp):
5944    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5947class DatetimeDiff(Func, TimeUnit):
5948    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5951class DatetimeTrunc(Func, TimeUnit):
5952    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5955class DayOfWeek(Func):
5956    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5961class DayOfWeekIso(Func):
5962    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5965class DayOfMonth(Func):
5966    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5969class DayOfYear(Func):
5970    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5973class ToDays(Func):
5974    pass
key = 'todays'
class WeekOfYear(Func):
5977class WeekOfYear(Func):
5978    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5981class MonthsBetween(Func):
5982    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5985class MakeInterval(Func):
5986    arg_types = {
5987        "year": False,
5988        "month": False,
5989        "day": False,
5990        "hour": False,
5991        "minute": False,
5992        "second": False,
5993    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5996class LastDay(Func, TimeUnit):
5997    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5998    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
6001class Extract(Func):
6002    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6005class Exists(Func, SubqueryPredicate):
6006    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6009class Timestamp(Func):
6010    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6013class TimestampAdd(Func, TimeUnit):
6014    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6017class TimestampSub(Func, TimeUnit):
6018    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6021class TimestampDiff(Func, TimeUnit):
6022    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6023    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6026class TimestampTrunc(Func, TimeUnit):
6027    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6030class TimeAdd(Func, TimeUnit):
6031    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6034class TimeSub(Func, TimeUnit):
6035    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6038class TimeDiff(Func, TimeUnit):
6039    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6042class TimeTrunc(Func, TimeUnit):
6043    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6046class DateFromParts(Func):
6047    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6048    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6051class TimeFromParts(Func):
6052    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6053    arg_types = {
6054        "hour": True,
6055        "min": True,
6056        "sec": True,
6057        "nano": False,
6058        "fractions": False,
6059        "precision": False,
6060    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6063class DateStrToDate(Func):
6064    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6067class DateToDateStr(Func):
6068    pass
key = 'datetodatestr'
class DateToDi(Func):
6071class DateToDi(Func):
6072    pass
key = 'datetodi'
class Date(Func):
6076class Date(Func):
6077    arg_types = {"this": False, "zone": False, "expressions": False}
6078    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6081class Day(Func):
6082    pass
key = 'day'
class Decode(Func):
6085class Decode(Func):
6086    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6089class DecodeCase(Func):
6090    arg_types = {"expressions": True}
6091    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DiToDate(Func):
6094class DiToDate(Func):
6095    pass
key = 'ditodate'
class Encode(Func):
6098class Encode(Func):
6099    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6102class Exp(Func):
6103    pass
key = 'exp'
class Explode(Func, UDTF):
6107class Explode(Func, UDTF):
6108    arg_types = {"this": True, "expressions": False}
6109    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6113class Inline(Func):
6114    pass
key = 'inline'
class ExplodeOuter(Explode):
6117class ExplodeOuter(Explode):
6118    pass
key = 'explodeouter'
class Posexplode(Explode):
6121class Posexplode(Explode):
6122    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6125class PosexplodeOuter(Posexplode, ExplodeOuter):
6126    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6129class PositionalColumn(Expression):
6130    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6133class Unnest(Func, UDTF):
6134    arg_types = {
6135        "expressions": True,
6136        "alias": False,
6137        "offset": False,
6138        "explode_array": False,
6139    }
6140
6141    @property
6142    def selects(self) -> t.List[Expression]:
6143        columns = super().selects
6144        offset = self.args.get("offset")
6145        if offset:
6146            columns = columns + [to_identifier("offset") if offset is True else offset]
6147        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6141    @property
6142    def selects(self) -> t.List[Expression]:
6143        columns = super().selects
6144        offset = self.args.get("offset")
6145        if offset:
6146            columns = columns + [to_identifier("offset") if offset is True else offset]
6147        return columns
key = 'unnest'
class Floor(Func):
6150class Floor(Func):
6151    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
6154class FromBase64(Func):
6155    pass
key = 'frombase64'
class FeaturesAtTime(Func):
6158class FeaturesAtTime(Func):
6159    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):
6162class ToBase64(Func):
6163    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
6167class FromISO8601Timestamp(Func):
6168    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6171class GapFill(Func):
6172    arg_types = {
6173        "this": True,
6174        "ts_column": True,
6175        "bucket_width": True,
6176        "partitioning_columns": False,
6177        "value_columns": False,
6178        "origin": False,
6179        "ignore_nulls": False,
6180    }
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):
6184class GenerateDateArray(Func):
6185    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6189class GenerateTimestampArray(Func):
6190    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
6193class Greatest(Func):
6194    arg_types = {"this": True, "expressions": False}
6195    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6200class OverflowTruncateBehavior(Expression):
6201    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6204class GroupConcat(AggFunc):
6205    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6208class Hex(Func):
6209    pass
key = 'hex'
class LowerHex(Hex):
6212class LowerHex(Hex):
6213    pass
key = 'lowerhex'
class And(Connector, Func):
6216class And(Connector, Func):
6217    pass
key = 'and'
class Or(Connector, Func):
6220class Or(Connector, Func):
6221    pass
key = 'or'
class Xor(Connector, Func):
6224class Xor(Connector, Func):
6225    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6228class If(Func):
6229    arg_types = {"this": True, "true": True, "false": False}
6230    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6233class Nullif(Func):
6234    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6237class Initcap(Func):
6238    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6241class IsAscii(Func):
6242    pass
key = 'isascii'
class IsNan(Func):
6245class IsNan(Func):
6246    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6250class Int64(Func):
6251    pass
key = 'int64'
class IsInf(Func):
6254class IsInf(Func):
6255    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6259class JSON(Expression):
6260    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6263class JSONPath(Expression):
6264    arg_types = {"expressions": True, "escape": False}
6265
6266    @property
6267    def output_name(self) -> str:
6268        last_segment = self.expressions[-1].this
6269        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6266    @property
6267    def output_name(self) -> str:
6268        last_segment = self.expressions[-1].this
6269        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):
6272class JSONPathPart(Expression):
6273    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6276class JSONPathFilter(JSONPathPart):
6277    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6280class JSONPathKey(JSONPathPart):
6281    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6284class JSONPathRecursive(JSONPathPart):
6285    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6288class JSONPathRoot(JSONPathPart):
6289    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6292class JSONPathScript(JSONPathPart):
6293    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6296class JSONPathSlice(JSONPathPart):
6297    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6300class JSONPathSelector(JSONPathPart):
6301    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6304class JSONPathSubscript(JSONPathPart):
6305    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6308class JSONPathUnion(JSONPathPart):
6309    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6312class JSONPathWildcard(JSONPathPart):
6313    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6316class FormatJson(Expression):
6317    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6320class JSONKeyValue(Expression):
6321    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6324class JSONObject(Func):
6325    arg_types = {
6326        "expressions": False,
6327        "null_handling": False,
6328        "unique_keys": False,
6329        "return_type": False,
6330        "encoding": False,
6331    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6334class JSONObjectAgg(AggFunc):
6335    arg_types = {
6336        "expressions": False,
6337        "null_handling": False,
6338        "unique_keys": False,
6339        "return_type": False,
6340        "encoding": False,
6341    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6345class JSONBObjectAgg(AggFunc):
6346    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6350class JSONArray(Func):
6351    arg_types = {
6352        "expressions": False,
6353        "null_handling": False,
6354        "return_type": False,
6355        "strict": False,
6356    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6360class JSONArrayAgg(Func):
6361    arg_types = {
6362        "this": True,
6363        "order": False,
6364        "null_handling": False,
6365        "return_type": False,
6366        "strict": False,
6367    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6370class JSONExists(Func):
6371    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):
6376class JSONColumnDef(Expression):
6377    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):
6380class JSONSchema(Expression):
6381    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6385class JSONValue(Expression):
6386    arg_types = {
6387        "this": True,
6388        "path": True,
6389        "returning": False,
6390        "on_condition": False,
6391    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6394class JSONValueArray(Func):
6395    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6399class JSONTable(Func):
6400    arg_types = {
6401        "this": True,
6402        "schema": True,
6403        "path": False,
6404        "error_handling": False,
6405        "empty_handling": False,
6406    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6411class JSONType(Func):
6412    arg_types = {"this": True, "expression": False}
6413    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6417class ObjectInsert(Func):
6418    arg_types = {
6419        "this": True,
6420        "key": True,
6421        "value": True,
6422        "update_flag": False,
6423    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6426class OpenJSONColumnDef(Expression):
6427    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):
6430class OpenJSON(Func):
6431    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6434class JSONBContains(Binary, Func):
6435    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6438class JSONBExists(Func):
6439    arg_types = {"this": True, "path": True}
6440    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6443class JSONExtract(Binary, Func):
6444    arg_types = {
6445        "this": True,
6446        "expression": True,
6447        "only_json_types": False,
6448        "expressions": False,
6449        "variant_extract": False,
6450        "json_query": False,
6451        "option": False,
6452        "quote": False,
6453        "on_condition": False,
6454        "requires_json": False,
6455    }
6456    _sql_names = ["JSON_EXTRACT"]
6457    is_var_len_args = True
6458
6459    @property
6460    def output_name(self) -> str:
6461        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
6459    @property
6460    def output_name(self) -> str:
6461        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):
6465class JSONExtractQuote(Expression):
6466    arg_types = {
6467        "option": True,
6468        "scalar": False,
6469    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6472class JSONExtractArray(Func):
6473    arg_types = {"this": True, "expression": False}
6474    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6477class JSONExtractScalar(Binary, Func):
6478    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6479    _sql_names = ["JSON_EXTRACT_SCALAR"]
6480    is_var_len_args = True
6481
6482    @property
6483    def output_name(self) -> str:
6484        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
6482    @property
6483    def output_name(self) -> str:
6484        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):
6487class JSONBExtract(Binary, Func):
6488    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6491class JSONBExtractScalar(Binary, Func):
6492    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6495class JSONFormat(Func):
6496    arg_types = {"this": False, "options": False, "is_json": False}
6497    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6501class JSONArrayContains(Binary, Predicate, Func):
6502    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6505class ParseJSON(Func):
6506    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6507    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6508    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6509    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6512class Least(Func):
6513    arg_types = {"this": True, "expressions": False}
6514    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6517class Left(Func):
6518    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6525class Length(Func):
6526    arg_types = {"this": True, "binary": False, "encoding": False}
6527    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6530class Levenshtein(Func):
6531    arg_types = {
6532        "this": True,
6533        "expression": False,
6534        "ins_cost": False,
6535        "del_cost": False,
6536        "sub_cost": False,
6537        "max_dist": False,
6538    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6541class Ln(Func):
6542    pass
key = 'ln'
class Log(Func):
6545class Log(Func):
6546    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6549class LogicalOr(AggFunc):
6550    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6553class LogicalAnd(AggFunc):
6554    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6557class Lower(Func):
6558    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6561class Map(Func):
6562    arg_types = {"keys": False, "values": False}
6563
6564    @property
6565    def keys(self) -> t.List[Expression]:
6566        keys = self.args.get("keys")
6567        return keys.expressions if keys else []
6568
6569    @property
6570    def values(self) -> t.List[Expression]:
6571        values = self.args.get("values")
6572        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6564    @property
6565    def keys(self) -> t.List[Expression]:
6566        keys = self.args.get("keys")
6567        return keys.expressions if keys else []
values: List[Expression]
6569    @property
6570    def values(self) -> t.List[Expression]:
6571        values = self.args.get("values")
6572        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6576class ToMap(Func):
6577    pass
key = 'tomap'
class MapFromEntries(Func):
6580class MapFromEntries(Func):
6581    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6585class ScopeResolution(Expression):
6586    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6589class Stream(Expression):
6590    pass
key = 'stream'
class StarMap(Func):
6593class StarMap(Func):
6594    pass
key = 'starmap'
class VarMap(Func):
6597class VarMap(Func):
6598    arg_types = {"keys": True, "values": True}
6599    is_var_len_args = True
6600
6601    @property
6602    def keys(self) -> t.List[Expression]:
6603        return self.args["keys"].expressions
6604
6605    @property
6606    def values(self) -> t.List[Expression]:
6607        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6601    @property
6602    def keys(self) -> t.List[Expression]:
6603        return self.args["keys"].expressions
values: List[Expression]
6605    @property
6606    def values(self) -> t.List[Expression]:
6607        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6611class MatchAgainst(Func):
6612    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6615class Max(AggFunc):
6616    arg_types = {"this": True, "expressions": False}
6617    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6620class MD5(Func):
6621    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6625class MD5Digest(Func):
6626    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6629class Median(AggFunc):
6630    pass
key = 'median'
class Min(AggFunc):
6633class Min(AggFunc):
6634    arg_types = {"this": True, "expressions": False}
6635    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6638class Month(Func):
6639    pass
key = 'month'
class AddMonths(Func):
6642class AddMonths(Func):
6643    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6646class Nvl2(Func):
6647    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6650class Normalize(Func):
6651    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6654class Overlay(Func):
6655    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):
6659class Predict(Func):
6660    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6663class Pow(Binary, Func):
6664    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6667class PercentileCont(AggFunc):
6668    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6671class PercentileDisc(AggFunc):
6672    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6675class Quantile(AggFunc):
6676    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6679class ApproxQuantile(Quantile):
6680    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):
6683class Quarter(Func):
6684    pass
key = 'quarter'
class Rand(Func):
6689class Rand(Func):
6690    _sql_names = ["RAND", "RANDOM"]
6691    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6694class Randn(Func):
6695    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6698class RangeN(Func):
6699    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6702class ReadCSV(Func):
6703    _sql_names = ["READ_CSV"]
6704    is_var_len_args = True
6705    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6708class Reduce(Func):
6709    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):
6712class RegexpExtract(Func):
6713    arg_types = {
6714        "this": True,
6715        "expression": True,
6716        "position": False,
6717        "occurrence": False,
6718        "parameters": False,
6719        "group": False,
6720    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6723class RegexpExtractAll(Func):
6724    arg_types = {
6725        "this": True,
6726        "expression": True,
6727        "position": False,
6728        "occurrence": False,
6729        "parameters": False,
6730        "group": False,
6731    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6734class RegexpReplace(Func):
6735    arg_types = {
6736        "this": True,
6737        "expression": True,
6738        "replacement": False,
6739        "position": False,
6740        "occurrence": False,
6741        "modifiers": False,
6742    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6745class RegexpLike(Binary, Func):
6746    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6749class RegexpILike(Binary, Func):
6750    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6755class RegexpSplit(Func):
6756    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6759class Repeat(Func):
6760    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
6764class Replace(Func):
6765    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
6770class Round(Func):
6771    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6774class RowNumber(Func):
6775    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6778class SafeDivide(Func):
6779    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6782class SHA(Func):
6783    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6786class SHA2(Func):
6787    _sql_names = ["SHA2"]
6788    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6791class Sign(Func):
6792    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6795class SortArray(Func):
6796    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6799class Split(Func):
6800    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6804class SplitPart(Func):
6805    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6810class Substring(Func):
6811    _sql_names = ["SUBSTRING", "SUBSTR"]
6812    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
6815class SubstringIndex(Func):
6816    """
6817    SUBSTRING_INDEX(str, delim, count)
6818
6819    *count* > 0  → left slice before the *count*-th delimiter
6820    *count* < 0  → right slice after the |count|-th delimiter
6821    """
6822
6823    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):
6826class StandardHash(Func):
6827    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6830class StartsWith(Func):
6831    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6832    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
6835class EndsWith(Func):
6836    _sql_names = ["ENDS_WITH", "ENDSWITH"]
6837    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
6840class StrPosition(Func):
6841    arg_types = {
6842        "this": True,
6843        "substr": True,
6844        "position": False,
6845        "occurrence": False,
6846    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6849class StrToDate(Func):
6850    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6853class StrToTime(Func):
6854    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):
6859class StrToUnix(Func):
6860    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6865class StrToMap(Func):
6866    arg_types = {
6867        "this": True,
6868        "pair_delim": False,
6869        "key_value_delim": False,
6870        "duplicate_resolution_callback": False,
6871    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6874class NumberToStr(Func):
6875    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6878class FromBase(Func):
6879    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
6882class Space(Func):
6883    """
6884    SPACE(n) → string consisting of n blank characters
6885    """
6886
6887    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
6890class Struct(Func):
6891    arg_types = {"expressions": False}
6892    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6895class StructExtract(Func):
6896    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6901class Stuff(Func):
6902    _sql_names = ["STUFF", "INSERT"]
6903    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):
6906class Sum(AggFunc):
6907    pass
key = 'sum'
class Sqrt(Func):
6910class Sqrt(Func):
6911    pass
key = 'sqrt'
class Stddev(AggFunc):
6914class Stddev(AggFunc):
6915    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6918class StddevPop(AggFunc):
6919    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6922class StddevSamp(AggFunc):
6923    pass
key = 'stddevsamp'
class Time(Func):
6927class Time(Func):
6928    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6931class TimeToStr(Func):
6932    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):
6935class TimeToTimeStr(Func):
6936    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6939class TimeToUnix(Func):
6940    pass
key = 'timetounix'
class TimeStrToDate(Func):
6943class TimeStrToDate(Func):
6944    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6947class TimeStrToTime(Func):
6948    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6951class TimeStrToUnix(Func):
6952    pass
key = 'timestrtounix'
class Trim(Func):
6955class Trim(Func):
6956    arg_types = {
6957        "this": True,
6958        "expression": False,
6959        "position": False,
6960        "collation": False,
6961    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6964class TsOrDsAdd(Func, TimeUnit):
6965    # return_type is used to correctly cast the arguments of this expression when transpiling it
6966    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6967
6968    @property
6969    def return_type(self) -> DataType:
6970        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
6968    @property
6969    def return_type(self) -> DataType:
6970        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6973class TsOrDsDiff(Func, TimeUnit):
6974    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6977class TsOrDsToDateStr(Func):
6978    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6981class TsOrDsToDate(Func):
6982    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6985class TsOrDsToDatetime(Func):
6986    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6989class TsOrDsToTime(Func):
6990    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6993class TsOrDsToTimestamp(Func):
6994    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6997class TsOrDiToDi(Func):
6998    pass
key = 'tsorditodi'
class Unhex(Func):
7001class Unhex(Func):
7002    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7005class Unicode(Func):
7006    pass
key = 'unicode'
class UnixDate(Func):
7010class UnixDate(Func):
7011    pass
key = 'unixdate'
class UnixToStr(Func):
7014class UnixToStr(Func):
7015    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7020class UnixToTime(Func):
7021    arg_types = {
7022        "this": True,
7023        "scale": False,
7024        "zone": False,
7025        "hours": False,
7026        "minutes": False,
7027        "format": False,
7028    }
7029
7030    SECONDS = Literal.number(0)
7031    DECIS = Literal.number(1)
7032    CENTIS = Literal.number(2)
7033    MILLIS = Literal.number(3)
7034    DECIMILLIS = Literal.number(4)
7035    CENTIMILLIS = Literal.number(5)
7036    MICROS = Literal.number(6)
7037    DECIMICROS = Literal.number(7)
7038    CENTIMICROS = Literal.number(8)
7039    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):
7042class UnixToTimeStr(Func):
7043    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7046class UnixSeconds(Func):
7047    pass
key = 'unixseconds'
class Uuid(Func):
7050class Uuid(Func):
7051    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7052
7053    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7056class TimestampFromParts(Func):
7057    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7058    arg_types = {
7059        "year": True,
7060        "month": True,
7061        "day": True,
7062        "hour": True,
7063        "min": True,
7064        "sec": True,
7065        "nano": False,
7066        "zone": False,
7067        "milli": False,
7068    }
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):
7071class Upper(Func):
7072    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7075class Corr(Binary, AggFunc):
7076    pass
key = 'corr'
class Variance(AggFunc):
7079class Variance(AggFunc):
7080    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7083class VariancePop(AggFunc):
7084    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7087class CovarSamp(Binary, AggFunc):
7088    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7091class CovarPop(Binary, AggFunc):
7092    pass
key = 'covarpop'
class Week(Func):
7095class Week(Func):
7096    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
7099class XMLElement(Func):
7100    _sql_names = ["XMLELEMENT"]
7101    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7104class XMLTable(Func):
7105    arg_types = {
7106        "this": True,
7107        "namespaces": False,
7108        "passing": False,
7109        "columns": False,
7110        "by_ref": False,
7111    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7114class XMLNamespace(Expression):
7115    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7119class XMLKeyValueOption(Expression):
7120    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7123class Year(Func):
7124    pass
key = 'year'
class Use(Expression):
7127class Use(Expression):
7128    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7131class Merge(DML):
7132    arg_types = {
7133        "this": True,
7134        "using": True,
7135        "on": True,
7136        "whens": True,
7137        "with": False,
7138        "returning": False,
7139    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7142class When(Expression):
7143    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):
7146class Whens(Expression):
7147    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7148
7149    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7154class NextValueFor(Func):
7155    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7160class Semicolon(Expression):
7161    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7166class TableColumn(Expression):
7167    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 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class '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 '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 '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 '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 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Replace'>, <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 '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'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, '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_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'>, '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'>, '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_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_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'>, '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_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:
7207def maybe_parse(
7208    sql_or_expression: ExpOrStr,
7209    *,
7210    into: t.Optional[IntoType] = None,
7211    dialect: DialectType = None,
7212    prefix: t.Optional[str] = None,
7213    copy: bool = False,
7214    **opts,
7215) -> Expression:
7216    """Gracefully handle a possible string or expression.
7217
7218    Example:
7219        >>> maybe_parse("1")
7220        Literal(this=1, is_string=False)
7221        >>> maybe_parse(to_identifier("x"))
7222        Identifier(this=x, quoted=False)
7223
7224    Args:
7225        sql_or_expression: the SQL code string or an expression
7226        into: the SQLGlot Expression to parse into
7227        dialect: the dialect used to parse the input expressions (in the case that an
7228            input expression is a SQL string).
7229        prefix: a string to prefix the sql with before it gets parsed
7230            (automatically includes a space)
7231        copy: whether to copy the expression.
7232        **opts: other options to use to parse the input expressions (again, in the case
7233            that an input expression is a SQL string).
7234
7235    Returns:
7236        Expression: the parsed or given expression.
7237    """
7238    if isinstance(sql_or_expression, Expression):
7239        if copy:
7240            return sql_or_expression.copy()
7241        return sql_or_expression
7242
7243    if sql_or_expression is None:
7244        raise ParseError("SQL cannot be None")
7245
7246    import sqlglot
7247
7248    sql = str(sql_or_expression)
7249    if prefix:
7250        sql = f"{prefix} {sql}"
7251
7252    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):
7263def maybe_copy(instance, copy=True):
7264    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:
7519def union(
7520    *expressions: ExpOrStr,
7521    distinct: bool = True,
7522    dialect: DialectType = None,
7523    copy: bool = True,
7524    **opts,
7525) -> Union:
7526    """
7527    Initializes a syntax tree for the `UNION` operation.
7528
7529    Example:
7530        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7531        'SELECT * FROM foo UNION SELECT * FROM bla'
7532
7533    Args:
7534        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7535            If `Expression` instances are passed, they will be used as-is.
7536        distinct: set the DISTINCT flag if and only if this is true.
7537        dialect: the dialect used to parse the input expression.
7538        copy: whether to copy the expression.
7539        opts: other options to use to parse the input expressions.
7540
7541    Returns:
7542        The new Union instance.
7543    """
7544    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7545    return _apply_set_operation(
7546        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7547    )

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:
7550def intersect(
7551    *expressions: ExpOrStr,
7552    distinct: bool = True,
7553    dialect: DialectType = None,
7554    copy: bool = True,
7555    **opts,
7556) -> Intersect:
7557    """
7558    Initializes a syntax tree for the `INTERSECT` operation.
7559
7560    Example:
7561        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7562        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7563
7564    Args:
7565        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7566            If `Expression` instances are passed, they will be used as-is.
7567        distinct: set the DISTINCT flag if and only if this is true.
7568        dialect: the dialect used to parse the input expression.
7569        copy: whether to copy the expression.
7570        opts: other options to use to parse the input expressions.
7571
7572    Returns:
7573        The new Intersect instance.
7574    """
7575    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7576    return _apply_set_operation(
7577        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7578    )

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:
7581def except_(
7582    *expressions: ExpOrStr,
7583    distinct: bool = True,
7584    dialect: DialectType = None,
7585    copy: bool = True,
7586    **opts,
7587) -> Except:
7588    """
7589    Initializes a syntax tree for the `EXCEPT` operation.
7590
7591    Example:
7592        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7593        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7594
7595    Args:
7596        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7597            If `Expression` instances are passed, they will be used as-is.
7598        distinct: set the DISTINCT flag if and only if this is true.
7599        dialect: the dialect used to parse the input expression.
7600        copy: whether to copy the expression.
7601        opts: other options to use to parse the input expressions.
7602
7603    Returns:
7604        The new Except instance.
7605    """
7606    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7607    return _apply_set_operation(
7608        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7609    )

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:
7612def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7613    """
7614    Initializes a syntax tree from one or multiple SELECT expressions.
7615
7616    Example:
7617        >>> select("col1", "col2").from_("tbl").sql()
7618        'SELECT col1, col2 FROM tbl'
7619
7620    Args:
7621        *expressions: the SQL code string to parse as the expressions of a
7622            SELECT statement. If an Expression instance is passed, this is used as-is.
7623        dialect: the dialect used to parse the input expressions (in the case that an
7624            input expression is a SQL string).
7625        **opts: other options to use to parse the input expressions (again, in the case
7626            that an input expression is a SQL string).
7627
7628    Returns:
7629        Select: the syntax tree for the SELECT statement.
7630    """
7631    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:
7634def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7635    """
7636    Initializes a syntax tree from a FROM expression.
7637
7638    Example:
7639        >>> from_("tbl").select("col1", "col2").sql()
7640        'SELECT col1, col2 FROM tbl'
7641
7642    Args:
7643        *expression: the SQL code string to parse as the FROM expressions of a
7644            SELECT statement. If an Expression instance is passed, this is used as-is.
7645        dialect: the dialect used to parse the input expression (in the case that the
7646            input expression is a SQL string).
7647        **opts: other options to use to parse the input expressions (again, in the case
7648            that the input expression is a SQL string).
7649
7650    Returns:
7651        Select: the syntax tree for the SELECT statement.
7652    """
7653    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:
7656def update(
7657    table: str | Table,
7658    properties: t.Optional[dict] = None,
7659    where: t.Optional[ExpOrStr] = None,
7660    from_: t.Optional[ExpOrStr] = None,
7661    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7662    dialect: DialectType = None,
7663    **opts,
7664) -> Update:
7665    """
7666    Creates an update statement.
7667
7668    Example:
7669        >>> 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()
7670        "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"
7671
7672    Args:
7673        properties: dictionary of properties to SET which are
7674            auto converted to sql objects eg None -> NULL
7675        where: sql conditional parsed into a WHERE statement
7676        from_: sql statement parsed into a FROM statement
7677        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7678        dialect: the dialect used to parse the input expressions.
7679        **opts: other options to use to parse the input expressions.
7680
7681    Returns:
7682        Update: the syntax tree for the UPDATE statement.
7683    """
7684    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7685    if properties:
7686        update_expr.set(
7687            "expressions",
7688            [
7689                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7690                for k, v in properties.items()
7691            ],
7692        )
7693    if from_:
7694        update_expr.set(
7695            "from",
7696            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7697        )
7698    if isinstance(where, Condition):
7699        where = Where(this=where)
7700    if where:
7701        update_expr.set(
7702            "where",
7703            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7704        )
7705    if with_:
7706        cte_list = [
7707            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7708            for alias, qry in with_.items()
7709        ]
7710        update_expr.set(
7711            "with",
7712            With(expressions=cte_list),
7713        )
7714    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:
7717def delete(
7718    table: ExpOrStr,
7719    where: t.Optional[ExpOrStr] = None,
7720    returning: t.Optional[ExpOrStr] = None,
7721    dialect: DialectType = None,
7722    **opts,
7723) -> Delete:
7724    """
7725    Builds a delete statement.
7726
7727    Example:
7728        >>> delete("my_table", where="id > 1").sql()
7729        'DELETE FROM my_table WHERE id > 1'
7730
7731    Args:
7732        where: sql conditional parsed into a WHERE statement
7733        returning: sql conditional parsed into a RETURNING statement
7734        dialect: the dialect used to parse the input expressions.
7735        **opts: other options to use to parse the input expressions.
7736
7737    Returns:
7738        Delete: the syntax tree for the DELETE statement.
7739    """
7740    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7741    if where:
7742        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7743    if returning:
7744        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7745    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:
7748def insert(
7749    expression: ExpOrStr,
7750    into: ExpOrStr,
7751    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7752    overwrite: t.Optional[bool] = None,
7753    returning: t.Optional[ExpOrStr] = None,
7754    dialect: DialectType = None,
7755    copy: bool = True,
7756    **opts,
7757) -> Insert:
7758    """
7759    Builds an INSERT statement.
7760
7761    Example:
7762        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7763        'INSERT INTO tbl VALUES (1, 2, 3)'
7764
7765    Args:
7766        expression: the sql string or expression of the INSERT statement
7767        into: the tbl to insert data to.
7768        columns: optionally the table's column names.
7769        overwrite: whether to INSERT OVERWRITE or not.
7770        returning: sql conditional parsed into a RETURNING statement
7771        dialect: the dialect used to parse the input expressions.
7772        copy: whether to copy the expression.
7773        **opts: other options to use to parse the input expressions.
7774
7775    Returns:
7776        Insert: the syntax tree for the INSERT statement.
7777    """
7778    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7779    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7780
7781    if columns:
7782        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7783
7784    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7785
7786    if returning:
7787        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7788
7789    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:
7792def merge(
7793    *when_exprs: ExpOrStr,
7794    into: ExpOrStr,
7795    using: ExpOrStr,
7796    on: ExpOrStr,
7797    returning: t.Optional[ExpOrStr] = None,
7798    dialect: DialectType = None,
7799    copy: bool = True,
7800    **opts,
7801) -> Merge:
7802    """
7803    Builds a MERGE statement.
7804
7805    Example:
7806        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7807        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7808        ...       into="my_table",
7809        ...       using="source_table",
7810        ...       on="my_table.id = source_table.id").sql()
7811        '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)'
7812
7813    Args:
7814        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7815        into: The target table to merge data into.
7816        using: The source table to merge data from.
7817        on: The join condition for the merge.
7818        returning: The columns to return from the merge.
7819        dialect: The dialect used to parse the input expressions.
7820        copy: Whether to copy the expression.
7821        **opts: Other options to use to parse the input expressions.
7822
7823    Returns:
7824        Merge: The syntax tree for the MERGE statement.
7825    """
7826    expressions: t.List[Expression] = []
7827    for when_expr in when_exprs:
7828        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7829        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7830
7831    merge = Merge(
7832        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7833        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7834        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7835        whens=Whens(expressions=expressions),
7836    )
7837    if returning:
7838        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7839
7840    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:
7843def condition(
7844    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7845) -> Condition:
7846    """
7847    Initialize a logical condition expression.
7848
7849    Example:
7850        >>> condition("x=1").sql()
7851        'x = 1'
7852
7853        This is helpful for composing larger logical syntax trees:
7854        >>> where = condition("x=1")
7855        >>> where = where.and_("y=1")
7856        >>> Select().from_("tbl").select("*").where(where).sql()
7857        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7858
7859    Args:
7860        *expression: the SQL code string to parse.
7861            If an Expression instance is passed, this is used as-is.
7862        dialect: the dialect used to parse the input expression (in the case that the
7863            input expression is a SQL string).
7864        copy: Whether to copy `expression` (only applies to expressions).
7865        **opts: other options to use to parse the input expressions (again, in the case
7866            that the input expression is a SQL string).
7867
7868    Returns:
7869        The new Condition instance
7870    """
7871    return maybe_parse(
7872        expression,
7873        into=Condition,
7874        dialect=dialect,
7875        copy=copy,
7876        **opts,
7877    )

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:
7880def and_(
7881    *expressions: t.Optional[ExpOrStr],
7882    dialect: DialectType = None,
7883    copy: bool = True,
7884    wrap: bool = True,
7885    **opts,
7886) -> Condition:
7887    """
7888    Combine multiple conditions with an AND logical operator.
7889
7890    Example:
7891        >>> and_("x=1", and_("y=1", "z=1")).sql()
7892        'x = 1 AND (y = 1 AND z = 1)'
7893
7894    Args:
7895        *expressions: the SQL code strings to parse.
7896            If an Expression instance is passed, this is used as-is.
7897        dialect: the dialect used to parse the input expression.
7898        copy: whether to copy `expressions` (only applies to Expressions).
7899        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7900            precedence issues, but can be turned off when the produced AST is too deep and
7901            causes recursion-related issues.
7902        **opts: other options to use to parse the input expressions.
7903
7904    Returns:
7905        The new condition
7906    """
7907    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:
7910def or_(
7911    *expressions: t.Optional[ExpOrStr],
7912    dialect: DialectType = None,
7913    copy: bool = True,
7914    wrap: bool = True,
7915    **opts,
7916) -> Condition:
7917    """
7918    Combine multiple conditions with an OR logical operator.
7919
7920    Example:
7921        >>> or_("x=1", or_("y=1", "z=1")).sql()
7922        'x = 1 OR (y = 1 OR z = 1)'
7923
7924    Args:
7925        *expressions: the SQL code strings to parse.
7926            If an Expression instance is passed, this is used as-is.
7927        dialect: the dialect used to parse the input expression.
7928        copy: whether to copy `expressions` (only applies to Expressions).
7929        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7930            precedence issues, but can be turned off when the produced AST is too deep and
7931            causes recursion-related issues.
7932        **opts: other options to use to parse the input expressions.
7933
7934    Returns:
7935        The new condition
7936    """
7937    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:
7940def xor(
7941    *expressions: t.Optional[ExpOrStr],
7942    dialect: DialectType = None,
7943    copy: bool = True,
7944    wrap: bool = True,
7945    **opts,
7946) -> Condition:
7947    """
7948    Combine multiple conditions with an XOR logical operator.
7949
7950    Example:
7951        >>> xor("x=1", xor("y=1", "z=1")).sql()
7952        'x = 1 XOR (y = 1 XOR z = 1)'
7953
7954    Args:
7955        *expressions: the SQL code strings to parse.
7956            If an Expression instance is passed, this is used as-is.
7957        dialect: the dialect used to parse the input expression.
7958        copy: whether to copy `expressions` (only applies to Expressions).
7959        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7960            precedence issues, but can be turned off when the produced AST is too deep and
7961            causes recursion-related issues.
7962        **opts: other options to use to parse the input expressions.
7963
7964    Returns:
7965        The new condition
7966    """
7967    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:
7970def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7971    """
7972    Wrap a condition with a NOT operator.
7973
7974    Example:
7975        >>> not_("this_suit='black'").sql()
7976        "NOT this_suit = 'black'"
7977
7978    Args:
7979        expression: the SQL code string to parse.
7980            If an Expression instance is passed, this is used as-is.
7981        dialect: the dialect used to parse the input expression.
7982        copy: whether to copy the expression or not.
7983        **opts: other options to use to parse the input expressions.
7984
7985    Returns:
7986        The new condition.
7987    """
7988    this = condition(
7989        expression,
7990        dialect=dialect,
7991        copy=copy,
7992        **opts,
7993    )
7994    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:
7997def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7998    """
7999    Wrap an expression in parentheses.
8000
8001    Example:
8002        >>> paren("5 + 3").sql()
8003        '(5 + 3)'
8004
8005    Args:
8006        expression: the SQL code string to parse.
8007            If an Expression instance is passed, this is used as-is.
8008        copy: whether to copy the expression or not.
8009
8010    Returns:
8011        The wrapped expression.
8012    """
8013    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):
8029def to_identifier(name, quoted=None, copy=True):
8030    """Builds an identifier.
8031
8032    Args:
8033        name: The name to turn into an identifier.
8034        quoted: Whether to force quote the identifier.
8035        copy: Whether to copy name if it's an Identifier.
8036
8037    Returns:
8038        The identifier ast node.
8039    """
8040
8041    if name is None:
8042        return None
8043
8044    if isinstance(name, Identifier):
8045        identifier = maybe_copy(name, copy)
8046    elif isinstance(name, str):
8047        identifier = Identifier(
8048            this=name,
8049            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8050        )
8051    else:
8052        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8053    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:
8056def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8057    """
8058    Parses a given string into an identifier.
8059
8060    Args:
8061        name: The name to parse into an identifier.
8062        dialect: The dialect to parse against.
8063
8064    Returns:
8065        The identifier ast node.
8066    """
8067    try:
8068        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8069    except (ParseError, TokenError):
8070        expression = to_identifier(name)
8071
8072    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:
8078def to_interval(interval: str | Literal) -> Interval:
8079    """Builds an interval expression from a string like '1 day' or '5 months'."""
8080    if isinstance(interval, Literal):
8081        if not interval.is_string:
8082            raise ValueError("Invalid interval string.")
8083
8084        interval = interval.this
8085
8086    interval = maybe_parse(f"INTERVAL {interval}")
8087    assert isinstance(interval, Interval)
8088    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:
8091def to_table(
8092    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8093) -> Table:
8094    """
8095    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8096    If a table is passed in then that table is returned.
8097
8098    Args:
8099        sql_path: a `[catalog].[schema].[table]` string.
8100        dialect: the source dialect according to which the table name will be parsed.
8101        copy: Whether to copy a table if it is passed in.
8102        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8103
8104    Returns:
8105        A table expression.
8106    """
8107    if isinstance(sql_path, Table):
8108        return maybe_copy(sql_path, copy=copy)
8109
8110    try:
8111        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8112    except ParseError:
8113        catalog, db, this = split_num_words(sql_path, ".", 3)
8114
8115        if not this:
8116            raise
8117
8118        table = table_(this, db=db, catalog=catalog)
8119
8120    for k, v in kwargs.items():
8121        table.set(k, v)
8122
8123    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:
8126def to_column(
8127    sql_path: str | Column,
8128    quoted: t.Optional[bool] = None,
8129    dialect: DialectType = None,
8130    copy: bool = True,
8131    **kwargs,
8132) -> Column:
8133    """
8134    Create a column from a `[table].[column]` sql path. Table is optional.
8135    If a column is passed in then that column is returned.
8136
8137    Args:
8138        sql_path: a `[table].[column]` string.
8139        quoted: Whether or not to force quote identifiers.
8140        dialect: the source dialect according to which the column name will be parsed.
8141        copy: Whether to copy a column if it is passed in.
8142        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8143
8144    Returns:
8145        A column expression.
8146    """
8147    if isinstance(sql_path, Column):
8148        return maybe_copy(sql_path, copy=copy)
8149
8150    try:
8151        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8152    except ParseError:
8153        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8154
8155    for k, v in kwargs.items():
8156        col.set(k, v)
8157
8158    if quoted:
8159        for i in col.find_all(Identifier):
8160            i.set("quoted", True)
8161
8162    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):
8165def alias_(
8166    expression: ExpOrStr,
8167    alias: t.Optional[str | Identifier],
8168    table: bool | t.Sequence[str | Identifier] = False,
8169    quoted: t.Optional[bool] = None,
8170    dialect: DialectType = None,
8171    copy: bool = True,
8172    **opts,
8173):
8174    """Create an Alias expression.
8175
8176    Example:
8177        >>> alias_('foo', 'bar').sql()
8178        'foo AS bar'
8179
8180        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8181        '(SELECT 1, 2) AS bar(a, b)'
8182
8183    Args:
8184        expression: the SQL code strings to parse.
8185            If an Expression instance is passed, this is used as-is.
8186        alias: the alias name to use. If the name has
8187            special characters it is quoted.
8188        table: Whether to create a table alias, can also be a list of columns.
8189        quoted: whether to quote the alias
8190        dialect: the dialect used to parse the input expression.
8191        copy: Whether to copy the expression.
8192        **opts: other options to use to parse the input expressions.
8193
8194    Returns:
8195        Alias: the aliased expression
8196    """
8197    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8198    alias = to_identifier(alias, quoted=quoted)
8199
8200    if table:
8201        table_alias = TableAlias(this=alias)
8202        exp.set("alias", table_alias)
8203
8204        if not isinstance(table, bool):
8205            for column in table:
8206                table_alias.append("columns", to_identifier(column, quoted=quoted))
8207
8208        return exp
8209
8210    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8211    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8212    # for the complete Window expression.
8213    #
8214    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8215
8216    if "alias" in exp.arg_types and not isinstance(exp, Window):
8217        exp.set("alias", alias)
8218        return exp
8219    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:
8222def subquery(
8223    expression: ExpOrStr,
8224    alias: t.Optional[Identifier | str] = None,
8225    dialect: DialectType = None,
8226    **opts,
8227) -> Select:
8228    """
8229    Build a subquery expression that's selected from.
8230
8231    Example:
8232        >>> subquery('select x from tbl', 'bar').select('x').sql()
8233        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8234
8235    Args:
8236        expression: the SQL code strings to parse.
8237            If an Expression instance is passed, this is used as-is.
8238        alias: the alias name to use.
8239        dialect: the dialect used to parse the input expression.
8240        **opts: other options to use to parse the input expressions.
8241
8242    Returns:
8243        A new Select instance with the subquery expression included.
8244    """
8245
8246    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8247    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):
8278def column(
8279    col,
8280    table=None,
8281    db=None,
8282    catalog=None,
8283    *,
8284    fields=None,
8285    quoted=None,
8286    copy=True,
8287):
8288    """
8289    Build a Column.
8290
8291    Args:
8292        col: Column name.
8293        table: Table name.
8294        db: Database name.
8295        catalog: Catalog name.
8296        fields: Additional fields using dots.
8297        quoted: Whether to force quotes on the column's identifiers.
8298        copy: Whether to copy identifiers if passed in.
8299
8300    Returns:
8301        The new Column instance.
8302    """
8303    if not isinstance(col, Star):
8304        col = to_identifier(col, quoted=quoted, copy=copy)
8305
8306    this = Column(
8307        this=col,
8308        table=to_identifier(table, quoted=quoted, copy=copy),
8309        db=to_identifier(db, quoted=quoted, copy=copy),
8310        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8311    )
8312
8313    if fields:
8314        this = Dot.build(
8315            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8316        )
8317    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:
8320def cast(
8321    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8322) -> Cast:
8323    """Cast an expression to a data type.
8324
8325    Example:
8326        >>> cast('x + 1', 'int').sql()
8327        'CAST(x + 1 AS INT)'
8328
8329    Args:
8330        expression: The expression to cast.
8331        to: The datatype to cast to.
8332        copy: Whether to copy the supplied expressions.
8333        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8334            - The expression to be cast is already a exp.Cast expression
8335            - The existing cast is to a type that is logically equivalent to new type
8336
8337            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8338            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8339            and instead just return the original expression `CAST(x as DATETIME)`.
8340
8341            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8342            mapping is applied in the target dialect generator.
8343
8344    Returns:
8345        The new Cast instance.
8346    """
8347    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8348    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8349
8350    # dont re-cast if the expression is already a cast to the correct type
8351    if isinstance(expr, Cast):
8352        from sqlglot.dialects.dialect import Dialect
8353
8354        target_dialect = Dialect.get_or_raise(dialect)
8355        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8356
8357        existing_cast_type: DataType.Type = expr.to.this
8358        new_cast_type: DataType.Type = data_type.this
8359        types_are_equivalent = type_mapping.get(
8360            existing_cast_type, existing_cast_type.value
8361        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8362
8363        if expr.is_type(data_type) or types_are_equivalent:
8364            return expr
8365
8366    expr = Cast(this=expr, to=data_type)
8367    expr.type = data_type
8368
8369    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:
8372def table_(
8373    table: Identifier | str,
8374    db: t.Optional[Identifier | str] = None,
8375    catalog: t.Optional[Identifier | str] = None,
8376    quoted: t.Optional[bool] = None,
8377    alias: t.Optional[Identifier | str] = None,
8378) -> Table:
8379    """Build a Table.
8380
8381    Args:
8382        table: Table name.
8383        db: Database name.
8384        catalog: Catalog name.
8385        quote: Whether to force quotes on the table's identifiers.
8386        alias: Table's alias.
8387
8388    Returns:
8389        The new Table instance.
8390    """
8391    return Table(
8392        this=to_identifier(table, quoted=quoted) if table else None,
8393        db=to_identifier(db, quoted=quoted) if db else None,
8394        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8395        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8396    )

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:
8399def values(
8400    values: t.Iterable[t.Tuple[t.Any, ...]],
8401    alias: t.Optional[str] = None,
8402    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8403) -> Values:
8404    """Build VALUES statement.
8405
8406    Example:
8407        >>> values([(1, '2')]).sql()
8408        "VALUES (1, '2')"
8409
8410    Args:
8411        values: values statements that will be converted to SQL
8412        alias: optional alias
8413        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8414         If either are provided then an alias is also required.
8415
8416    Returns:
8417        Values: the Values expression object
8418    """
8419    if columns and not alias:
8420        raise ValueError("Alias is required when providing columns")
8421
8422    return Values(
8423        expressions=[convert(tup) for tup in values],
8424        alias=(
8425            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8426            if columns
8427            else (TableAlias(this=to_identifier(alias)) if alias else None)
8428        ),
8429    )

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:
8432def var(name: t.Optional[ExpOrStr]) -> Var:
8433    """Build a SQL variable.
8434
8435    Example:
8436        >>> repr(var('x'))
8437        'Var(this=x)'
8438
8439        >>> repr(var(column('x', table='y')))
8440        'Var(this=x)'
8441
8442    Args:
8443        name: The name of the var or an expression who's name will become the var.
8444
8445    Returns:
8446        The new variable node.
8447    """
8448    if not name:
8449        raise ValueError("Cannot convert empty name into var.")
8450
8451    if isinstance(name, Expression):
8452        name = name.name
8453    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:
8456def rename_table(
8457    old_name: str | Table,
8458    new_name: str | Table,
8459    dialect: DialectType = None,
8460) -> Alter:
8461    """Build ALTER TABLE... RENAME... expression
8462
8463    Args:
8464        old_name: The old name of the table
8465        new_name: The new name of the table
8466        dialect: The dialect to parse the table.
8467
8468    Returns:
8469        Alter table expression
8470    """
8471    old_table = to_table(old_name, dialect=dialect)
8472    new_table = to_table(new_name, dialect=dialect)
8473    return Alter(
8474        this=old_table,
8475        kind="TABLE",
8476        actions=[
8477            AlterRename(this=new_table),
8478        ],
8479    )

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:
8482def rename_column(
8483    table_name: str | Table,
8484    old_column_name: str | Column,
8485    new_column_name: str | Column,
8486    exists: t.Optional[bool] = None,
8487    dialect: DialectType = None,
8488) -> Alter:
8489    """Build ALTER TABLE... RENAME COLUMN... expression
8490
8491    Args:
8492        table_name: Name of the table
8493        old_column: The old name of the column
8494        new_column: The new name of the column
8495        exists: Whether to add the `IF EXISTS` clause
8496        dialect: The dialect to parse the table/column.
8497
8498    Returns:
8499        Alter table expression
8500    """
8501    table = to_table(table_name, dialect=dialect)
8502    old_column = to_column(old_column_name, dialect=dialect)
8503    new_column = to_column(new_column_name, dialect=dialect)
8504    return Alter(
8505        this=table,
8506        kind="TABLE",
8507        actions=[
8508            RenameColumn(this=old_column, to=new_column, exists=exists),
8509        ],
8510    )

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:
8513def convert(value: t.Any, copy: bool = False) -> Expression:
8514    """Convert a python value into an expression object.
8515
8516    Raises an error if a conversion is not possible.
8517
8518    Args:
8519        value: A python object.
8520        copy: Whether to copy `value` (only applies to Expressions and collections).
8521
8522    Returns:
8523        The equivalent expression object.
8524    """
8525    if isinstance(value, Expression):
8526        return maybe_copy(value, copy)
8527    if isinstance(value, str):
8528        return Literal.string(value)
8529    if isinstance(value, bool):
8530        return Boolean(this=value)
8531    if value is None or (isinstance(value, float) and math.isnan(value)):
8532        return null()
8533    if isinstance(value, numbers.Number):
8534        return Literal.number(value)
8535    if isinstance(value, bytes):
8536        return HexString(this=value.hex())
8537    if isinstance(value, datetime.datetime):
8538        datetime_literal = Literal.string(value.isoformat(sep=" "))
8539
8540        tz = None
8541        if value.tzinfo:
8542            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8543            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8544            tz = Literal.string(str(value.tzinfo))
8545
8546        return TimeStrToTime(this=datetime_literal, zone=tz)
8547    if isinstance(value, datetime.date):
8548        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8549        return DateStrToDate(this=date_literal)
8550    if isinstance(value, datetime.time):
8551        time_literal = Literal.string(value.isoformat())
8552        return TsOrDsToTime(this=time_literal)
8553    if isinstance(value, tuple):
8554        if hasattr(value, "_fields"):
8555            return Struct(
8556                expressions=[
8557                    PropertyEQ(
8558                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8559                    )
8560                    for k in value._fields
8561                ]
8562            )
8563        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8564    if isinstance(value, list):
8565        return Array(expressions=[convert(v, copy=copy) for v in value])
8566    if isinstance(value, dict):
8567        return Map(
8568            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8569            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8570        )
8571    if hasattr(value, "__dict__"):
8572        return Struct(
8573            expressions=[
8574                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8575                for k, v in value.__dict__.items()
8576            ]
8577        )
8578    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:
8581def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8582    """
8583    Replace children of an expression with the result of a lambda fun(child) -> exp.
8584    """
8585    for k, v in tuple(expression.args.items()):
8586        is_list_arg = type(v) is list
8587
8588        child_nodes = v if is_list_arg else [v]
8589        new_child_nodes = []
8590
8591        for cn in child_nodes:
8592            if isinstance(cn, Expression):
8593                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8594                    new_child_nodes.append(child_node)
8595            else:
8596                new_child_nodes.append(cn)
8597
8598        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:
8601def replace_tree(
8602    expression: Expression,
8603    fun: t.Callable,
8604    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8605) -> Expression:
8606    """
8607    Replace an entire tree with the result of function calls on each node.
8608
8609    This will be traversed in reverse dfs, so leaves first.
8610    If new nodes are created as a result of function calls, they will also be traversed.
8611    """
8612    stack = list(expression.dfs(prune=prune))
8613
8614    while stack:
8615        node = stack.pop()
8616        new_node = fun(node)
8617
8618        if new_node is not node:
8619            node.replace(new_node)
8620
8621            if isinstance(new_node, Expression):
8622                stack.append(new_node)
8623
8624    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]:
8627def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8628    """
8629    Return all table names referenced through columns in an expression.
8630
8631    Example:
8632        >>> import sqlglot
8633        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8634        ['a', 'c']
8635
8636    Args:
8637        expression: expression to find table names.
8638        exclude: a table name to exclude
8639
8640    Returns:
8641        A list of unique names.
8642    """
8643    return {
8644        table
8645        for table in (column.table for column in expression.find_all(Column))
8646        if table and table != exclude
8647    }

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:
8650def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8651    """Get the full name of a table as a string.
8652
8653    Args:
8654        table: Table expression node or string.
8655        dialect: The dialect to generate the table name for.
8656        identify: Determines when an identifier should be quoted. Possible values are:
8657            False (default): Never quote, except in cases where it's mandatory by the dialect.
8658            True: Always quote.
8659
8660    Examples:
8661        >>> from sqlglot import exp, parse_one
8662        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8663        'a.b.c'
8664
8665    Returns:
8666        The table name.
8667    """
8668
8669    table = maybe_parse(table, into=Table, dialect=dialect)
8670
8671    if not table:
8672        raise ValueError(f"Cannot parse {table}")
8673
8674    return ".".join(
8675        (
8676            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8677            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8678            else part.name
8679        )
8680        for part in table.parts
8681    )

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:
8684def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8685    """Returns a case normalized table name without quotes.
8686
8687    Args:
8688        table: the table to normalize
8689        dialect: the dialect to use for normalization rules
8690        copy: whether to copy the expression.
8691
8692    Examples:
8693        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8694        'A-B.c'
8695    """
8696    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8697
8698    return ".".join(
8699        p.name
8700        for p in normalize_identifiers(
8701            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8702        ).parts
8703    )

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:
8706def replace_tables(
8707    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8708) -> E:
8709    """Replace all tables in expression according to the mapping.
8710
8711    Args:
8712        expression: expression node to be transformed and replaced.
8713        mapping: mapping of table names.
8714        dialect: the dialect of the mapping table
8715        copy: whether to copy the expression.
8716
8717    Examples:
8718        >>> from sqlglot import exp, parse_one
8719        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8720        'SELECT * FROM c /* a.b */'
8721
8722    Returns:
8723        The mapped expression.
8724    """
8725
8726    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8727
8728    def _replace_tables(node: Expression) -> Expression:
8729        if isinstance(node, Table) and node.meta.get("replace") is not False:
8730            original = normalize_table_name(node, dialect=dialect)
8731            new_name = mapping.get(original)
8732
8733            if new_name:
8734                table = to_table(
8735                    new_name,
8736                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8737                    dialect=dialect,
8738                )
8739                table.add_comments([original])
8740                return table
8741        return node
8742
8743    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:
8746def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8747    """Replace placeholders in an expression.
8748
8749    Args:
8750        expression: expression node to be transformed and replaced.
8751        args: positional names that will substitute unnamed placeholders in the given order.
8752        kwargs: keyword arguments that will substitute named placeholders.
8753
8754    Examples:
8755        >>> from sqlglot import exp, parse_one
8756        >>> replace_placeholders(
8757        ...     parse_one("select * from :tbl where ? = ?"),
8758        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8759        ... ).sql()
8760        "SELECT * FROM foo WHERE str_col = 'b'"
8761
8762    Returns:
8763        The mapped expression.
8764    """
8765
8766    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8767        if isinstance(node, Placeholder):
8768            if node.this:
8769                new_name = kwargs.get(node.this)
8770                if new_name is not None:
8771                    return convert(new_name)
8772            else:
8773                try:
8774                    return convert(next(args))
8775                except StopIteration:
8776                    pass
8777        return node
8778
8779    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:
8782def expand(
8783    expression: Expression,
8784    sources: t.Dict[str, Query | t.Callable[[], Query]],
8785    dialect: DialectType = None,
8786    copy: bool = True,
8787) -> Expression:
8788    """Transforms an expression by expanding all referenced sources into subqueries.
8789
8790    Examples:
8791        >>> from sqlglot import parse_one
8792        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8793        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8794
8795        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8796        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8797
8798    Args:
8799        expression: The expression to expand.
8800        sources: A dict of name to query or a callable that provides a query on demand.
8801        dialect: The dialect of the sources dict or the callable.
8802        copy: Whether to copy the expression during transformation. Defaults to True.
8803
8804    Returns:
8805        The transformed expression.
8806    """
8807    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8808
8809    def _expand(node: Expression):
8810        if isinstance(node, Table):
8811            name = normalize_table_name(node, dialect=dialect)
8812            source = normalized_sources.get(name)
8813
8814            if source:
8815                # Create a subquery with the same alias (or table name if no alias)
8816                parsed_source = source() if callable(source) else source
8817                subquery = parsed_source.subquery(node.alias or name)
8818                subquery.comments = [f"source: {name}"]
8819
8820                # Continue expanding within the subquery
8821                return subquery.transform(_expand, copy=False)
8822
8823        return node
8824
8825    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:
8828def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8829    """
8830    Returns a Func expression.
8831
8832    Examples:
8833        >>> func("abs", 5).sql()
8834        'ABS(5)'
8835
8836        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8837        'CAST(5 AS DOUBLE)'
8838
8839    Args:
8840        name: the name of the function to build.
8841        args: the args used to instantiate the function of interest.
8842        copy: whether to copy the argument expressions.
8843        dialect: the source dialect.
8844        kwargs: the kwargs used to instantiate the function of interest.
8845
8846    Note:
8847        The arguments `args` and `kwargs` are mutually exclusive.
8848
8849    Returns:
8850        An instance of the function of interest, or an anonymous function, if `name` doesn't
8851        correspond to an existing `sqlglot.expressions.Func` class.
8852    """
8853    if args and kwargs:
8854        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8855
8856    from sqlglot.dialects.dialect import Dialect
8857
8858    dialect = Dialect.get_or_raise(dialect)
8859
8860    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8861    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8862
8863    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8864    if constructor:
8865        if converted:
8866            if "dialect" in constructor.__code__.co_varnames:
8867                function = constructor(converted, dialect=dialect)
8868            else:
8869                function = constructor(converted)
8870        elif constructor.__name__ == "from_arg_list":
8871            function = constructor.__self__(**kwargs)  # type: ignore
8872        else:
8873            constructor = FUNCTION_BY_NAME.get(name.upper())
8874            if constructor:
8875                function = constructor(**kwargs)
8876            else:
8877                raise ValueError(
8878                    f"Unable to convert '{name}' into a Func. Either manually construct "
8879                    "the Func expression of interest or parse the function call."
8880                )
8881    else:
8882        kwargs = kwargs or {"expressions": converted}
8883        function = Anonymous(this=name, **kwargs)
8884
8885    for error_message in function.error_messages(converted):
8886        raise ValueError(error_message)
8887
8888    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:
8891def case(
8892    expression: t.Optional[ExpOrStr] = None,
8893    **opts,
8894) -> Case:
8895    """
8896    Initialize a CASE statement.
8897
8898    Example:
8899        case().when("a = 1", "foo").else_("bar")
8900
8901    Args:
8902        expression: Optionally, the input expression (not all dialects support this)
8903        **opts: Extra keyword arguments for parsing `expression`
8904    """
8905    if expression is not None:
8906        this = maybe_parse(expression, **opts)
8907    else:
8908        this = None
8909    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:
8912def array(
8913    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8914) -> Array:
8915    """
8916    Returns an array.
8917
8918    Examples:
8919        >>> array(1, 'x').sql()
8920        'ARRAY(1, x)'
8921
8922    Args:
8923        expressions: the expressions to add to the array.
8924        copy: whether to copy the argument expressions.
8925        dialect: the source dialect.
8926        kwargs: the kwargs used to instantiate the function of interest.
8927
8928    Returns:
8929        An array expression.
8930    """
8931    return Array(
8932        expressions=[
8933            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8934            for expression in expressions
8935        ]
8936    )

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:
8939def tuple_(
8940    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8941) -> Tuple:
8942    """
8943    Returns an tuple.
8944
8945    Examples:
8946        >>> tuple_(1, 'x').sql()
8947        '(1, x)'
8948
8949    Args:
8950        expressions: the expressions to add to the tuple.
8951        copy: whether to copy the argument expressions.
8952        dialect: the source dialect.
8953        kwargs: the kwargs used to instantiate the function of interest.
8954
8955    Returns:
8956        A tuple expression.
8957    """
8958    return Tuple(
8959        expressions=[
8960            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8961            for expression in expressions
8962        ]
8963    )

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:
8966def true() -> Boolean:
8967    """
8968    Returns a true Boolean expression.
8969    """
8970    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8973def false() -> Boolean:
8974    """
8975    Returns a false Boolean expression.
8976    """
8977    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8980def null() -> Null:
8981    """
8982    Returns a Null expression.
8983    """
8984    return Null()

Returns a Null expression.

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