Edit on GitHub

Expressions

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

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


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

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

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

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

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
108    def __init__(self, **args: t.Any):
109        self.args: t.Dict[str, t.Any] = args
110        self.parent: t.Optional[Expression] = None
111        self.arg_key: t.Optional[str] = None
112        self.index: t.Optional[int] = None
113        self.comments: t.Optional[t.List[str]] = None
114        self._type: t.Optional[DataType] = None
115        self._meta: t.Optional[t.Dict[str, t.Any]] = None
116        self._hash: t.Optional[int] = None
117
118        for arg_key, value in self.args.items():
119            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
hashable_args: Any
124    @property
125    def hashable_args(self) -> t.Any:
126        return frozenset(
127            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
128            for k, v in self.args.items()
129            if not (v is None or v is False or (type(v) is list and not v))
130        )
this: Any
138    @property
139    def this(self) -> t.Any:
140        """
141        Retrieves the argument with key "this".
142        """
143        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
159    def text(self, key) -> str:
160        """
161        Returns a textual representation of the argument corresponding to "key". This can only be used
162        for args that are strings or leaf Expression instances, such as identifiers and literals.
163        """
164        field = self.args.get(key)
165        if isinstance(field, str):
166            return field
167        if isinstance(field, (Identifier, Literal, Var)):
168            return field.this
169        if isinstance(field, (Star, Null)):
170            return field.name
171        return ""

Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expression instances, such as identifiers and literals.

is_string: bool
173    @property
174    def is_string(self) -> bool:
175        """
176        Checks whether a Literal expression is a string.
177        """
178        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
216    @property
217    def alias_column_names(self) -> t.List[str]:
218        table_alias = self.args.get("alias")
219        if not table_alias:
220            return []
221        return [c.name for c in table_alias.args.get("columns") or []]
name: str
223    @property
224    def name(self) -> str:
225        return self.text("this")
alias_or_name: str
227    @property
228    def alias_or_name(self) -> str:
229        return self.alias or self.name
output_name: str
231    @property
232    def output_name(self) -> str:
233        """
234        Name of the output column if this expression is a selection.
235
236        If the Expression has no output name, an empty string is returned.
237
238        Example:
239            >>> from sqlglot import parse_one
240            >>> parse_one("SELECT a").expressions[0].output_name
241            'a'
242            >>> parse_one("SELECT b AS c").expressions[0].output_name
243            'c'
244            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
245            ''
246        """
247        return ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
249    @property
250    def type(self) -> t.Optional[DataType]:
251        return self._type
def is_type(self, *dtypes) -> bool:
259    def is_type(self, *dtypes) -> bool:
260        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
262    def is_leaf(self) -> bool:
263        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
265    @property
266    def meta(self) -> t.Dict[str, t.Any]:
267        if self._meta is None:
268            self._meta = {}
269        return self._meta
def copy(self) -> typing_extensions.Self:
305    def copy(self) -> Self:
306        """
307        Returns a deep copy of the expression.
308        """
309        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
311    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
312        if self.comments is None:
313            self.comments = []
314
315        if comments:
316            for comment in comments:
317                _, *meta = comment.split(SQLGLOT_META)
318                if meta:
319                    for kv in "".join(meta).split(","):
320                        k, *v = kv.split("=")
321                        value = v[0].strip() if v else True
322                        self.meta[k.strip()] = to_bool(value)
323
324                if not prepend:
325                    self.comments.append(comment)
326
327            if prepend:
328                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
330    def pop_comments(self) -> t.List[str]:
331        comments = self.comments or []
332        self.comments = None
333        return comments
def append(self, arg_key: str, value: Any) -> None:
335    def append(self, arg_key: str, value: t.Any) -> None:
336        """
337        Appends value to arg_key if it's a list or sets it as a new list.
338
339        Args:
340            arg_key (str): name of the list expression arg
341            value (Any): value to append to the list
342        """
343        if type(self.args.get(arg_key)) is not list:
344            self.args[arg_key] = []
345        self._set_parent(arg_key, value)
346        values = self.args[arg_key]
347        if hasattr(value, "parent"):
348            value.index = len(values)
349        values.append(value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set( self, arg_key: str, value: Any, index: Optional[int] = None, overwrite: bool = True) -> None:
351    def set(
352        self,
353        arg_key: str,
354        value: t.Any,
355        index: t.Optional[int] = None,
356        overwrite: bool = True,
357    ) -> None:
358        """
359        Sets arg_key to value.
360
361        Args:
362            arg_key: name of the expression arg.
363            value: value to set the arg to.
364            index: if the arg is a list, this specifies what position to add the value in it.
365            overwrite: assuming an index is given, this determines whether to overwrite the
366                list entry instead of only inserting a new value (i.e., like list.insert).
367        """
368        if index is not None:
369            expressions = self.args.get(arg_key) or []
370
371            if seq_get(expressions, index) is None:
372                return
373            if value is None:
374                expressions.pop(index)
375                for v in expressions[index:]:
376                    v.index = v.index - 1
377                return
378
379            if isinstance(value, list):
380                expressions.pop(index)
381                expressions[index:index] = value
382            elif overwrite:
383                expressions[index] = value
384            else:
385                expressions.insert(index, value)
386
387            value = expressions
388        elif value is None:
389            self.args.pop(arg_key, None)
390            return
391
392        self.args[arg_key] = value
393        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
  • overwrite: assuming an index is given, this determines whether to overwrite the list entry instead of only inserting a new value (i.e., like list.insert).
depth: int
407    @property
408    def depth(self) -> int:
409        """
410        Returns the depth of this tree.
411        """
412        if self.parent:
413            return self.parent.depth + 1
414        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
416    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
417        """Yields the key and expression for all arguments, exploding list args."""
418        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
419            if type(vs) is list:
420                for v in reversed(vs) if reverse else vs:  # type: ignore
421                    if hasattr(v, "parent"):
422                        yield v
423            else:
424                if hasattr(vs, "parent"):
425                    yield vs

Yields the key and expression for all arguments, exploding list args.

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
427    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
428        """
429        Returns the first node in this tree which matches at least one of
430        the specified types.
431
432        Args:
433            expression_types: the expression type(s) to match.
434            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
435
436        Returns:
437            The node which matches the criteria or None if no such node was found.
438        """
439        return next(self.find_all(*expression_types, bfs=bfs), None)

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
441    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
442        """
443        Returns a generator object which visits all nodes in this tree and only
444        yields those that match at least one of the specified expression types.
445
446        Args:
447            expression_types: the expression type(s) to match.
448            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
449
450        Returns:
451            The generator object.
452        """
453        for expression in self.walk(bfs=bfs):
454            if isinstance(expression, expression_types):
455                yield expression

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
457    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
458        """
459        Returns a nearest parent matching expression_types.
460
461        Args:
462            expression_types: the expression type(s) to match.
463
464        Returns:
465            The parent node.
466        """
467        ancestor = self.parent
468        while ancestor and not isinstance(ancestor, expression_types):
469            ancestor = ancestor.parent
470        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

Arguments:
  • expression_types: the expression type(s) to match.
Returns:

The parent node.

parent_select: Optional[Select]
472    @property
473    def parent_select(self) -> t.Optional[Select]:
474        """
475        Returns the parent select statement.
476        """
477        return self.find_ancestor(Select)

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
493    def walk(
494        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
495    ) -> t.Iterator[Expression]:
496        """
497        Returns a generator object which visits all nodes in this tree.
498
499        Args:
500            bfs: if set to True the BFS traversal order will be applied,
501                otherwise the DFS traversal will be used instead.
502            prune: callable that returns True if the generator should stop traversing
503                this branch of the tree.
504
505        Returns:
506            the generator object.
507        """
508        if bfs:
509            yield from self.bfs(prune=prune)
510        else:
511            yield from self.dfs(prune=prune)

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs: if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune: callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
513    def dfs(
514        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
515    ) -> t.Iterator[Expression]:
516        """
517        Returns a generator object which visits all nodes in this tree in
518        the DFS (Depth-first) order.
519
520        Returns:
521            The generator object.
522        """
523        stack = [self]
524
525        while stack:
526            node = stack.pop()
527
528            yield node
529
530            if prune and prune(node):
531                continue
532
533            for v in node.iter_expressions(reverse=True):
534                stack.append(v)

Returns a generator object which visits all nodes in this tree in the DFS (Depth-first) order.

Returns:

The generator object.

def bfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
536    def bfs(
537        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
538    ) -> t.Iterator[Expression]:
539        """
540        Returns a generator object which visits all nodes in this tree in
541        the BFS (Breadth-first) order.
542
543        Returns:
544            The generator object.
545        """
546        queue = deque([self])
547
548        while queue:
549            node = queue.popleft()
550
551            yield node
552
553            if prune and prune(node):
554                continue
555
556            for v in node.iter_expressions():
557                queue.append(v)

Returns a generator object which visits all nodes in this tree in the BFS (Breadth-first) order.

Returns:

The generator object.

def unnest(self):
559    def unnest(self):
560        """
561        Returns the first non parenthesis child or self.
562        """
563        expression = self
564        while type(expression) is Paren:
565            expression = expression.this
566        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
582    def flatten(self, unnest=True):
583        """
584        Returns a generator which yields child nodes whose parents are the same class.
585
586        A AND B AND C -> [A, B, C]
587        """
588        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
589            if type(node) is not self.__class__:
590                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
598    def to_s(self) -> str:
599        """
600        Same as __repr__, but includes additional information which can be useful
601        for debugging, like empty or missing args and the AST nodes' object IDs.
602        """
603        return _to_s(self, verbose=True)

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

def sql( self, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> str:
605    def sql(self, dialect: DialectType = None, **opts) -> str:
606        """
607        Returns SQL string representation of this tree.
608
609        Args:
610            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
611            opts: other `sqlglot.generator.Generator` options.
612
613        Returns:
614            The SQL string.
615        """
616        from sqlglot.dialects import Dialect
617
618        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

Arguments:
  • dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
  • opts: other sqlglot.generator.Generator options.
Returns:

The SQL string.

def transform( self, fun: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
620    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
621        """
622        Visits all tree nodes (excluding already transformed ones)
623        and applies the given transformation function to each node.
624
625        Args:
626            fun: a function which takes a node as an argument and returns a
627                new transformed node or the same node without modifications. If the function
628                returns None, then the corresponding node will be removed from the syntax tree.
629            copy: if set to True a new tree instance is constructed, otherwise the tree is
630                modified in place.
631
632        Returns:
633            The transformed tree.
634        """
635        root = None
636        new_node = None
637
638        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
639            parent, arg_key, index = node.parent, node.arg_key, node.index
640            new_node = fun(node, *args, **kwargs)
641
642            if not root:
643                root = new_node
644            elif parent and arg_key and new_node is not node:
645                parent.set(arg_key, new_node, index)
646
647        assert root
648        return root.assert_is(Expression)

Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun: a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy: if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

def replace(self, expression):
656    def replace(self, expression):
657        """
658        Swap out this expression with a new expression.
659
660        For example::
661
662            >>> tree = Select().select("x").from_("tbl")
663            >>> tree.find(Column).replace(column("y"))
664            Column(
665              this=Identifier(this=y, quoted=False))
666            >>> tree.sql()
667            'SELECT y FROM tbl'
668
669        Args:
670            expression: new node
671
672        Returns:
673            The new expression or expressions.
674        """
675        parent = self.parent
676
677        if not parent or parent is expression:
678            return expression
679
680        key = self.arg_key
681        value = parent.args.get(key)
682
683        if type(expression) is list and isinstance(value, Expression):
684            # We are trying to replace an Expression with a list, so it's assumed that
685            # the intention was to really replace the parent of this expression.
686            value.parent.replace(expression)
687        else:
688            parent.set(key, expression, self.index)
689
690        if expression is not self:
691            self.parent = None
692            self.arg_key = None
693            self.index = None
694
695        return expression

Swap out this expression with a new expression.

For example::

>>> tree = Select().select("x").from_("tbl")
>>> tree.find(Column).replace(column("y"))
Column(
  this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
697    def pop(self: E) -> E:
698        """
699        Remove this expression from its AST.
700
701        Returns:
702            The popped expression.
703        """
704        self.replace(None)
705        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
707    def assert_is(self, type_: t.Type[E]) -> E:
708        """
709        Assert that this `Expression` is an instance of `type_`.
710
711        If it is NOT an instance of `type_`, this raises an assertion error.
712        Otherwise, this returns this expression.
713
714        Examples:
715            This is useful for type security in chained expressions:
716
717            >>> import sqlglot
718            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
719            'SELECT x, z FROM y'
720        """
721        if not isinstance(self, type_):
722            raise AssertionError(f"{self} is not {type_}.")
723        return self

Assert that this Expression is an instance of type_.

If it is NOT an instance of type_, this raises an assertion error. Otherwise, this returns this expression.

Examples:

This is useful for type security in chained expressions:

>>> import sqlglot
>>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
'SELECT x, z FROM y'
def error_messages(self, args: Optional[Sequence] = None) -> List[str]:
725    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
726        """
727        Checks if this expression is valid (e.g. all mandatory args are set).
728
729        Args:
730            args: a sequence of values that were used to instantiate a Func expression. This is used
731                to check that the provided arguments don't exceed the function argument limit.
732
733        Returns:
734            A list of error messages for all possible errors that were found.
735        """
736        errors: t.List[str] = []
737
738        for k in self.args:
739            if k not in self.arg_types:
740                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
741        for k, mandatory in self.arg_types.items():
742            v = self.args.get(k)
743            if mandatory and (v is None or (isinstance(v, list) and not v)):
744                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
745
746        if (
747            args
748            and isinstance(self, Func)
749            and len(args) > len(self.arg_types)
750            and not self.is_var_len_args
751        ):
752            errors.append(
753                f"The number of provided arguments ({len(args)}) is greater than "
754                f"the maximum number of supported arguments ({len(self.arg_types)})"
755            )
756
757        return errors

Checks if this expression is valid (e.g. all mandatory args are set).

Arguments:
  • args: a sequence of values that were used to instantiate a Func expression. This is used to check that the provided arguments don't exceed the function argument limit.
Returns:

A list of error messages for all possible errors that were found.

def dump(self):
759    def dump(self):
760        """
761        Dump this Expression to a JSON-serializable dict.
762        """
763        from sqlglot.serde import dump
764
765        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
767    @classmethod
768    def load(cls, obj):
769        """
770        Load a dict (as returned by `Expression.dump`) into an Expression instance.
771        """
772        from sqlglot.serde import load
773
774        return load(obj)

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

def and_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
776    def and_(
777        self,
778        *expressions: t.Optional[ExpOrStr],
779        dialect: DialectType = None,
780        copy: bool = True,
781        wrap: bool = True,
782        **opts,
783    ) -> Condition:
784        """
785        AND this condition with one or multiple expressions.
786
787        Example:
788            >>> condition("x=1").and_("y=1").sql()
789            'x = 1 AND y = 1'
790
791        Args:
792            *expressions: the SQL code strings to parse.
793                If an `Expression` instance is passed, it will be used as-is.
794            dialect: the dialect used to parse the input expression.
795            copy: whether to copy the involved expressions (only applies to Expressions).
796            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
797                precedence issues, but can be turned off when the produced AST is too deep and
798                causes recursion-related issues.
799            opts: other options to use to parse the input expressions.
800
801        Returns:
802            The new And condition.
803        """
804        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **opts)

AND this condition with one or multiple expressions.

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

The new And condition.

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

OR this condition with one or multiple expressions.

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

The new Or condition.

def not_(self, copy: bool = True):
836    def not_(self, copy: bool = True):
837        """
838        Wrap this condition with NOT.
839
840        Example:
841            >>> condition("x=1").not_().sql()
842            'NOT x = 1'
843
844        Args:
845            copy: whether to copy this object.
846
847        Returns:
848            The new Not instance.
849        """
850        return not_(self, copy=copy)

Wrap this condition with NOT.

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

The new Not instance.

def update_positions( self: ~E, other: Union[sqlglot.tokens.Token, Expression, NoneType] = None, **kwargs: Any) -> ~E:
852    def update_positions(
853        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
854    ) -> E:
855        """
856        Update this expression with positions from a token or other expression.
857
858        Args:
859            other: a token or expression to update this expression with.
860
861        Returns:
862            The updated expression.
863        """
864        if isinstance(other, Expression):
865            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
866        elif other is not None:
867            self.meta.update(
868                {
869                    "line": other.line,
870                    "col": other.col,
871                    "start": other.start,
872                    "end": other.end,
873                }
874            )
875        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
876        return self

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

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

The updated expression.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
878    def as_(
879        self,
880        alias: str | Identifier,
881        quoted: t.Optional[bool] = None,
882        dialect: DialectType = None,
883        copy: bool = True,
884        **opts,
885    ) -> Alias:
886        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
911    def isin(
912        self,
913        *expressions: t.Any,
914        query: t.Optional[ExpOrStr] = None,
915        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
916        copy: bool = True,
917        **opts,
918    ) -> In:
919        subquery = maybe_parse(query, copy=copy, **opts) if query else None
920        if subquery and not isinstance(subquery, Subquery):
921            subquery = subquery.subquery(copy=False)
922
923        return In(
924            this=maybe_copy(self, copy),
925            expressions=[convert(e, copy=copy) for e in expressions],
926            query=subquery,
927            unnest=(
928                Unnest(
929                    expressions=[
930                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
931                        for e in ensure_list(unnest)
932                    ]
933                )
934                if unnest
935                else None
936            ),
937        )
def between( self, low: Any, high: Any, copy: bool = True, symmetric: Optional[bool] = None, **opts) -> Between:
939    def between(
940        self,
941        low: t.Any,
942        high: t.Any,
943        copy: bool = True,
944        symmetric: t.Optional[bool] = None,
945        **opts,
946    ) -> Between:
947        between = Between(
948            this=maybe_copy(self, copy),
949            low=convert(low, copy=copy, **opts),
950            high=convert(high, copy=copy, **opts),
951        )
952        if symmetric is not None:
953            between.set("symmetric", symmetric)
954
955        return between
def is_( self, other: Union[str, Expression]) -> Is:
957    def is_(self, other: ExpOrStr) -> Is:
958        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
960    def like(self, other: ExpOrStr) -> Like:
961        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
963    def ilike(self, other: ExpOrStr) -> ILike:
964        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
966    def eq(self, other: t.Any) -> EQ:
967        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
969    def neq(self, other: t.Any) -> NEQ:
970        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
972    def rlike(self, other: ExpOrStr) -> RegexpLike:
973        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
975    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
976        div = self._binop(Div, other)
977        div.args["typed"] = typed
978        div.args["safe"] = safe
979        return div
def asc(self, nulls_first: bool = True) -> Ordered:
981    def asc(self, nulls_first: bool = True) -> Ordered:
982        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
984    def desc(self, nulls_first: bool = False) -> Ordered:
985        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
1068class Condition(Expression):
1069    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1106    def limit(
1107        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1108    ) -> Q:
1109        """
1110        Adds a LIMIT clause to this query.
1111
1112        Example:
1113            >>> select("1").union(select("1")).limit(1).sql()
1114            'SELECT 1 UNION SELECT 1 LIMIT 1'
1115
1116        Args:
1117            expression: the SQL code string to parse.
1118                This can also be an integer.
1119                If a `Limit` instance is passed, it will be used as-is.
1120                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1121            dialect: the dialect used to parse the input expression.
1122            copy: if `False`, modify this expression instance in-place.
1123            opts: other options to use to parse the input expressions.
1124
1125        Returns:
1126            A limited Select expression.
1127        """
1128        return _apply_builder(
1129            expression=expression,
1130            instance=self,
1131            arg="limit",
1132            into=Limit,
1133            prefix="LIMIT",
1134            dialect=dialect,
1135            copy=copy,
1136            into_arg="expression",
1137            **opts,
1138        )

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

Set the ORDER BY expression.

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

The modified Select expression.

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1230    def select(
1231        self: Q,
1232        *expressions: t.Optional[ExpOrStr],
1233        append: bool = True,
1234        dialect: DialectType = None,
1235        copy: bool = True,
1236        **opts,
1237    ) -> Q:
1238        """
1239        Append to or set the SELECT expressions.
1240
1241        Example:
1242            >>> Select().select("x", "y").sql()
1243            'SELECT x, y'
1244
1245        Args:
1246            *expressions: the SQL code strings to parse.
1247                If an `Expression` instance is passed, it will be used as-is.
1248            append: if `True`, add to any existing expressions.
1249                Otherwise, this resets the expressions.
1250            dialect: the dialect used to parse the input expressions.
1251            copy: if `False`, modify this expression instance in-place.
1252            opts: other options to use to parse the input expressions.
1253
1254        Returns:
1255            The modified Query expression.
1256        """
1257        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

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

The modified Query expression.

def where( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1259    def where(
1260        self: Q,
1261        *expressions: t.Optional[ExpOrStr],
1262        append: bool = True,
1263        dialect: DialectType = None,
1264        copy: bool = True,
1265        **opts,
1266    ) -> Q:
1267        """
1268        Append to or set the WHERE expressions.
1269
1270        Examples:
1271            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1272            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1273
1274        Args:
1275            *expressions: the SQL code strings to parse.
1276                If an `Expression` instance is passed, it will be used as-is.
1277                Multiple expressions are combined with an AND operator.
1278            append: if `True`, AND the new expressions to any existing expression.
1279                Otherwise, this resets the expression.
1280            dialect: the dialect used to parse the input expressions.
1281            copy: if `False`, modify this expression instance in-place.
1282            opts: other options to use to parse the input expressions.
1283
1284        Returns:
1285            The modified expression.
1286        """
1287        return _apply_conjunction_builder(
1288            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1289            instance=self,
1290            arg="where",
1291            append=append,
1292            into=Where,
1293            dialect=dialect,
1294            copy=copy,
1295            **opts,
1296        )

Append to or set the WHERE expressions.

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

The modified expression.

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

Append to or set the common table expressions.

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

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Union:
1347    def union(
1348        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1349    ) -> Union:
1350        """
1351        Builds a UNION expression.
1352
1353        Example:
1354            >>> import sqlglot
1355            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1356            'SELECT * FROM foo UNION SELECT * FROM bla'
1357
1358        Args:
1359            expressions: the SQL code strings.
1360                If `Expression` instances are passed, they will be used as-is.
1361            distinct: set the DISTINCT flag if and only if this is true.
1362            dialect: the dialect used to parse the input expression.
1363            opts: other options to use to parse the input expressions.
1364
1365        Returns:
1366            The new Union expression.
1367        """
1368        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

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

The new Union expression.

def intersect( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Intersect:
1370    def intersect(
1371        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1372    ) -> Intersect:
1373        """
1374        Builds an INTERSECT expression.
1375
1376        Example:
1377            >>> import sqlglot
1378            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1379            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1380
1381        Args:
1382            expressions: the SQL code strings.
1383                If `Expression` instances are passed, they will be used as-is.
1384            distinct: set the DISTINCT flag if and only if this is true.
1385            dialect: the dialect used to parse the input expression.
1386            opts: other options to use to parse the input expressions.
1387
1388        Returns:
1389            The new Intersect expression.
1390        """
1391        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

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

The new Intersect expression.

def except_( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Except:
1393    def except_(
1394        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1395    ) -> Except:
1396        """
1397        Builds an EXCEPT expression.
1398
1399        Example:
1400            >>> import sqlglot
1401            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1402            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1403
1404        Args:
1405            expressions: the SQL code strings.
1406                If `Expression` instance are passed, they will be used as-is.
1407            distinct: set the DISTINCT flag if and only if this is true.
1408            dialect: the dialect used to parse the input expression.
1409            opts: other options to use to parse the input expressions.
1410
1411        Returns:
1412            The new Except expression.
1413        """
1414        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

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

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1417class UDTF(DerivedTable):
1418    @property
1419    def selects(self) -> t.List[Expression]:
1420        alias = self.args.get("alias")
1421        return alias.columns if alias else []
selects: List[Expression]
1418    @property
1419    def selects(self) -> t.List[Expression]:
1420        alias = self.args.get("alias")
1421        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1424class Cache(Expression):
1425    arg_types = {
1426        "this": True,
1427        "lazy": False,
1428        "options": False,
1429        "expression": False,
1430    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1433class Uncache(Expression):
1434    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1437class Refresh(Expression):
1438    pass
key = 'refresh'
class DDL(Expression):
1441class DDL(Expression):
1442    @property
1443    def ctes(self) -> t.List[CTE]:
1444        """Returns a list of all the CTEs attached to this statement."""
1445        with_ = self.args.get("with")
1446        return with_.expressions if with_ else []
1447
1448    @property
1449    def selects(self) -> t.List[Expression]:
1450        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1451        return self.expression.selects if isinstance(self.expression, Query) else []
1452
1453    @property
1454    def named_selects(self) -> t.List[str]:
1455        """
1456        If this statement contains a query (e.g. a CTAS), this returns the output
1457        names of the query's projections.
1458        """
1459        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1442    @property
1443    def ctes(self) -> t.List[CTE]:
1444        """Returns a list of all the CTEs attached to this statement."""
1445        with_ = self.args.get("with")
1446        return with_.expressions if with_ else []

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

selects: List[Expression]
1448    @property
1449    def selects(self) -> t.List[Expression]:
1450        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1451        return self.expression.selects if isinstance(self.expression, Query) else []

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

named_selects: List[str]
1453    @property
1454    def named_selects(self) -> t.List[str]:
1455        """
1456        If this statement contains a query (e.g. a CTAS), this returns the output
1457        names of the query's projections.
1458        """
1459        return self.expression.named_selects if isinstance(self.expression, Query) else []

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

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

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):
1499class Create(DDL):
1500    arg_types = {
1501        "with": False,
1502        "this": True,
1503        "kind": True,
1504        "expression": False,
1505        "exists": False,
1506        "properties": False,
1507        "replace": False,
1508        "refresh": False,
1509        "unique": False,
1510        "indexes": False,
1511        "no_schema_binding": False,
1512        "begin": False,
1513        "end": False,
1514        "clone": False,
1515        "concurrently": False,
1516        "clustered": False,
1517    }
1518
1519    @property
1520    def kind(self) -> t.Optional[str]:
1521        kind = self.args.get("kind")
1522        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]
1519    @property
1520    def kind(self) -> t.Optional[str]:
1521        kind = self.args.get("kind")
1522        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1525class SequenceProperties(Expression):
1526    arg_types = {
1527        "increment": False,
1528        "minvalue": False,
1529        "maxvalue": False,
1530        "cache": False,
1531        "start": False,
1532        "owned": False,
1533        "options": False,
1534    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1537class TruncateTable(Expression):
1538    arg_types = {
1539        "expressions": True,
1540        "is_database": False,
1541        "exists": False,
1542        "only": False,
1543        "cluster": False,
1544        "identity": False,
1545        "option": False,
1546        "partition": False,
1547    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1553class Clone(Expression):
1554    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1557class Describe(Expression):
1558    arg_types = {
1559        "this": True,
1560        "style": False,
1561        "kind": False,
1562        "expressions": False,
1563        "partition": False,
1564        "format": False,
1565    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1569class Attach(Expression):
1570    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1574class Detach(Expression):
1575    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1579class Summarize(Expression):
1580    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1583class Kill(Expression):
1584    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1587class Pragma(Expression):
1588    pass
key = 'pragma'
class Declare(Expression):
1591class Declare(Expression):
1592    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1595class DeclareItem(Expression):
1596    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
class Set(Expression):
1599class Set(Expression):
1600    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1603class Heredoc(Expression):
1604    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1607class SetItem(Expression):
1608    arg_types = {
1609        "this": False,
1610        "expressions": False,
1611        "kind": False,
1612        "collate": False,  # MySQL SET NAMES statement
1613        "global": False,
1614    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1617class Show(Expression):
1618    arg_types = {
1619        "this": True,
1620        "history": False,
1621        "terse": False,
1622        "target": False,
1623        "offset": False,
1624        "starts_with": False,
1625        "limit": False,
1626        "from": False,
1627        "like": False,
1628        "where": False,
1629        "db": False,
1630        "scope": False,
1631        "scope_kind": False,
1632        "full": False,
1633        "mutex": False,
1634        "query": False,
1635        "channel": False,
1636        "global": False,
1637        "log": False,
1638        "position": False,
1639        "types": False,
1640        "privileges": False,
1641    }
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):
1644class UserDefinedFunction(Expression):
1645    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1648class CharacterSet(Expression):
1649    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1652class RecursiveWithSearch(Expression):
1653    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):
1656class With(Expression):
1657    arg_types = {"expressions": True, "recursive": False, "search": False}
1658
1659    @property
1660    def recursive(self) -> bool:
1661        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1659    @property
1660    def recursive(self) -> bool:
1661        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1664class WithinGroup(Expression):
1665    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1670class CTE(DerivedTable):
1671    arg_types = {
1672        "this": True,
1673        "alias": True,
1674        "scalar": False,
1675        "materialized": False,
1676    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1679class ProjectionDef(Expression):
1680    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1683class TableAlias(Expression):
1684    arg_types = {"this": False, "columns": False, "column_only": False}
1685
1686    @property
1687    def columns(self):
1688        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False, 'column_only': False}
columns
1686    @property
1687    def columns(self):
1688        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1691class BitString(Condition):
1692    pass
key = 'bitstring'
class HexString(Condition):
1695class HexString(Condition):
1696    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1699class ByteString(Condition):
1700    pass
key = 'bytestring'
class RawString(Condition):
1703class RawString(Condition):
1704    pass
key = 'rawstring'
class UnicodeString(Condition):
1707class UnicodeString(Condition):
1708    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1711class Column(Condition):
1712    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1713
1714    @property
1715    def table(self) -> str:
1716        return self.text("table")
1717
1718    @property
1719    def db(self) -> str:
1720        return self.text("db")
1721
1722    @property
1723    def catalog(self) -> str:
1724        return self.text("catalog")
1725
1726    @property
1727    def output_name(self) -> str:
1728        return self.name
1729
1730    @property
1731    def parts(self) -> t.List[Identifier]:
1732        """Return the parts of a column in order catalog, db, table, name."""
1733        return [
1734            t.cast(Identifier, self.args[part])
1735            for part in ("catalog", "db", "table", "this")
1736            if self.args.get(part)
1737        ]
1738
1739    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1740        """Converts the column into a dot expression."""
1741        parts = self.parts
1742        parent = self.parent
1743
1744        if include_dots:
1745            while isinstance(parent, Dot):
1746                parts.append(parent.expression)
1747                parent = parent.parent
1748
1749        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
1714    @property
1715    def table(self) -> str:
1716        return self.text("table")
db: str
1718    @property
1719    def db(self) -> str:
1720        return self.text("db")
catalog: str
1722    @property
1723    def catalog(self) -> str:
1724        return self.text("catalog")
output_name: str
1726    @property
1727    def output_name(self) -> str:
1728        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]
1730    @property
1731    def parts(self) -> t.List[Identifier]:
1732        """Return the parts of a column in order catalog, db, table, name."""
1733        return [
1734            t.cast(Identifier, self.args[part])
1735            for part in ("catalog", "db", "table", "this")
1736            if self.args.get(part)
1737        ]

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

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

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1752class ColumnPosition(Expression):
1753    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1756class ColumnDef(Expression):
1757    arg_types = {
1758        "this": True,
1759        "kind": False,
1760        "constraints": False,
1761        "exists": False,
1762        "position": False,
1763        "default": False,
1764        "output": False,
1765    }
1766
1767    @property
1768    def constraints(self) -> t.List[ColumnConstraint]:
1769        return self.args.get("constraints") or []
1770
1771    @property
1772    def kind(self) -> t.Optional[DataType]:
1773        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1767    @property
1768    def constraints(self) -> t.List[ColumnConstraint]:
1769        return self.args.get("constraints") or []
kind: Optional[DataType]
1771    @property
1772    def kind(self) -> t.Optional[DataType]:
1773        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1776class AlterColumn(Expression):
1777    arg_types = {
1778        "this": True,
1779        "dtype": False,
1780        "collate": False,
1781        "using": False,
1782        "default": False,
1783        "drop": False,
1784        "comment": False,
1785        "allow_null": False,
1786        "visible": False,
1787    }
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):
1791class AlterIndex(Expression):
1792    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1796class AlterDistStyle(Expression):
1797    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1800class AlterSortKey(Expression):
1801    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1804class AlterSet(Expression):
1805    arg_types = {
1806        "expressions": False,
1807        "option": False,
1808        "tablespace": False,
1809        "access_method": False,
1810        "file_format": False,
1811        "copy_options": False,
1812        "tag": False,
1813        "location": False,
1814        "serde": False,
1815    }
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):
1818class RenameColumn(Expression):
1819    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1822class AlterRename(Expression):
1823    pass
key = 'alterrename'
class SwapTable(Expression):
1826class SwapTable(Expression):
1827    pass
key = 'swaptable'
class Comment(Expression):
1830class Comment(Expression):
1831    arg_types = {
1832        "this": True,
1833        "kind": True,
1834        "expression": True,
1835        "exists": False,
1836        "materialized": False,
1837    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1840class Comprehension(Expression):
1841    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):
1845class MergeTreeTTLAction(Expression):
1846    arg_types = {
1847        "this": True,
1848        "delete": False,
1849        "recompress": False,
1850        "to_disk": False,
1851        "to_volume": False,
1852    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1856class MergeTreeTTL(Expression):
1857    arg_types = {
1858        "expressions": True,
1859        "where": False,
1860        "group": False,
1861        "aggregates": False,
1862    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1866class IndexConstraintOption(Expression):
1867    arg_types = {
1868        "key_block_size": False,
1869        "using": False,
1870        "parser": False,
1871        "comment": False,
1872        "visible": False,
1873        "engine_attr": False,
1874        "secondary_engine_attr": False,
1875    }
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):
1878class ColumnConstraint(Expression):
1879    arg_types = {"this": False, "kind": True}
1880
1881    @property
1882    def kind(self) -> ColumnConstraintKind:
1883        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1881    @property
1882    def kind(self) -> ColumnConstraintKind:
1883        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1886class ColumnConstraintKind(Expression):
1887    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1890class AutoIncrementColumnConstraint(ColumnConstraintKind):
1891    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1894class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1895    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1898class CaseSpecificColumnConstraint(ColumnConstraintKind):
1899    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1902class CharacterSetColumnConstraint(ColumnConstraintKind):
1903    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1906class CheckColumnConstraint(ColumnConstraintKind):
1907    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1910class ClusteredColumnConstraint(ColumnConstraintKind):
1911    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1914class CollateColumnConstraint(ColumnConstraintKind):
1915    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1918class CommentColumnConstraint(ColumnConstraintKind):
1919    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1922class CompressColumnConstraint(ColumnConstraintKind):
1923    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1926class DateFormatColumnConstraint(ColumnConstraintKind):
1927    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1930class DefaultColumnConstraint(ColumnConstraintKind):
1931    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1934class EncodeColumnConstraint(ColumnConstraintKind):
1935    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1939class ExcludeColumnConstraint(ColumnConstraintKind):
1940    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1943class EphemeralColumnConstraint(ColumnConstraintKind):
1944    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1947class WithOperator(Expression):
1948    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1951class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1952    # this: True -> ALWAYS, this: False -> BY DEFAULT
1953    arg_types = {
1954        "this": False,
1955        "expression": False,
1956        "on_null": False,
1957        "start": False,
1958        "increment": False,
1959        "minvalue": False,
1960        "maxvalue": False,
1961        "cycle": False,
1962        "order": False,
1963    }
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):
1966class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1967    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1972class IndexColumnConstraint(ColumnConstraintKind):
1973    arg_types = {
1974        "this": False,
1975        "expressions": False,
1976        "kind": False,
1977        "index_type": False,
1978        "options": False,
1979        "expression": False,  # Clickhouse
1980        "granularity": False,
1981    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1984class InlineLengthColumnConstraint(ColumnConstraintKind):
1985    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1988class NonClusteredColumnConstraint(ColumnConstraintKind):
1989    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1992class NotForReplicationColumnConstraint(ColumnConstraintKind):
1993    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1997class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1998    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
2001class NotNullColumnConstraint(ColumnConstraintKind):
2002    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
2006class OnUpdateColumnConstraint(ColumnConstraintKind):
2007    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2010class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2011    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2014class TitleColumnConstraint(ColumnConstraintKind):
2015    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2018class UniqueColumnConstraint(ColumnConstraintKind):
2019    arg_types = {
2020        "this": False,
2021        "index_type": False,
2022        "on_conflict": False,
2023        "nulls": False,
2024        "options": False,
2025    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2028class UppercaseColumnConstraint(ColumnConstraintKind):
2029    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2033class WatermarkColumnConstraint(Expression):
2034    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2037class PathColumnConstraint(ColumnConstraintKind):
2038    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2042class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2043    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2048class ComputedColumnConstraint(ColumnConstraintKind):
2049    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2052class Constraint(Expression):
2053    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2056class Delete(DML):
2057    arg_types = {
2058        "with": False,
2059        "this": False,
2060        "using": False,
2061        "where": False,
2062        "returning": False,
2063        "limit": False,
2064        "tables": False,  # Multiple-Table Syntax (MySQL)
2065        "cluster": False,  # Clickhouse
2066    }
2067
2068    def delete(
2069        self,
2070        table: ExpOrStr,
2071        dialect: DialectType = None,
2072        copy: bool = True,
2073        **opts,
2074    ) -> Delete:
2075        """
2076        Create a DELETE expression or replace the table on an existing DELETE expression.
2077
2078        Example:
2079            >>> delete("tbl").sql()
2080            'DELETE FROM tbl'
2081
2082        Args:
2083            table: the table from which to delete.
2084            dialect: the dialect used to parse the input expression.
2085            copy: if `False`, modify this expression instance in-place.
2086            opts: other options to use to parse the input expressions.
2087
2088        Returns:
2089            Delete: the modified expression.
2090        """
2091        return _apply_builder(
2092            expression=table,
2093            instance=self,
2094            arg="this",
2095            dialect=dialect,
2096            into=Table,
2097            copy=copy,
2098            **opts,
2099        )
2100
2101    def where(
2102        self,
2103        *expressions: t.Optional[ExpOrStr],
2104        append: bool = True,
2105        dialect: DialectType = None,
2106        copy: bool = True,
2107        **opts,
2108    ) -> Delete:
2109        """
2110        Append to or set the WHERE expressions.
2111
2112        Example:
2113            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2114            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2115
2116        Args:
2117            *expressions: the SQL code strings to parse.
2118                If an `Expression` instance is passed, it will be used as-is.
2119                Multiple expressions are combined with an AND operator.
2120            append: if `True`, AND the new expressions to any existing expression.
2121                Otherwise, this resets the expression.
2122            dialect: the dialect used to parse the input expressions.
2123            copy: if `False`, modify this expression instance in-place.
2124            opts: other options to use to parse the input expressions.
2125
2126        Returns:
2127            Delete: the modified expression.
2128        """
2129        return _apply_conjunction_builder(
2130            *expressions,
2131            instance=self,
2132            arg="where",
2133            append=append,
2134            into=Where,
2135            dialect=dialect,
2136            copy=copy,
2137            **opts,
2138        )
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:
2068    def delete(
2069        self,
2070        table: ExpOrStr,
2071        dialect: DialectType = None,
2072        copy: bool = True,
2073        **opts,
2074    ) -> Delete:
2075        """
2076        Create a DELETE expression or replace the table on an existing DELETE expression.
2077
2078        Example:
2079            >>> delete("tbl").sql()
2080            'DELETE FROM tbl'
2081
2082        Args:
2083            table: the table from which to delete.
2084            dialect: the dialect used to parse the input expression.
2085            copy: if `False`, modify this expression instance in-place.
2086            opts: other options to use to parse the input expressions.
2087
2088        Returns:
2089            Delete: the modified expression.
2090        """
2091        return _apply_builder(
2092            expression=table,
2093            instance=self,
2094            arg="this",
2095            dialect=dialect,
2096            into=Table,
2097            copy=copy,
2098            **opts,
2099        )

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

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

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):
2383class ConditionalInsert(Expression):
2384    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2387class MultitableInserts(Expression):
2388    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2391class OnConflict(Expression):
2392    arg_types = {
2393        "duplicate": False,
2394        "expressions": False,
2395        "action": False,
2396        "conflict_keys": False,
2397        "constraint": False,
2398        "where": False,
2399    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2402class OnCondition(Expression):
2403    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2406class Returning(Expression):
2407    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2411class Introducer(Expression):
2412    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2416class National(Expression):
2417    pass
key = 'national'
class LoadData(Expression):
2420class LoadData(Expression):
2421    arg_types = {
2422        "this": True,
2423        "local": False,
2424        "overwrite": False,
2425        "inpath": True,
2426        "partition": False,
2427        "input_format": False,
2428        "serde": False,
2429    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2432class Partition(Expression):
2433    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2436class PartitionRange(Expression):
2437    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
class PartitionId(Expression):
2441class PartitionId(Expression):
2442    pass
key = 'partitionid'
class Fetch(Expression):
2445class Fetch(Expression):
2446    arg_types = {
2447        "direction": False,
2448        "count": False,
2449        "limit_options": False,
2450    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2453class Grant(Expression):
2454    arg_types = {
2455        "privileges": True,
2456        "kind": False,
2457        "securable": True,
2458        "principals": True,
2459        "grant_option": False,
2460    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2463class Group(Expression):
2464    arg_types = {
2465        "expressions": False,
2466        "grouping_sets": False,
2467        "cube": False,
2468        "rollup": False,
2469        "totals": False,
2470        "all": False,
2471    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2474class Cube(Expression):
2475    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2478class Rollup(Expression):
2479    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2482class GroupingSets(Expression):
2483    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2486class Lambda(Expression):
2487    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2490class Limit(Expression):
2491    arg_types = {
2492        "this": False,
2493        "expression": True,
2494        "offset": False,
2495        "limit_options": False,
2496        "expressions": False,
2497    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2500class LimitOptions(Expression):
2501    arg_types = {
2502        "percent": False,
2503        "rows": False,
2504        "with_ties": False,
2505    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2508class Literal(Condition):
2509    arg_types = {"this": True, "is_string": True}
2510
2511    @property
2512    def hashable_args(self) -> t.Any:
2513        return (self.this, self.args.get("is_string"))
2514
2515    @classmethod
2516    def number(cls, number) -> Literal:
2517        return cls(this=str(number), is_string=False)
2518
2519    @classmethod
2520    def string(cls, string) -> Literal:
2521        return cls(this=str(string), is_string=True)
2522
2523    @property
2524    def output_name(self) -> str:
2525        return self.name
2526
2527    def to_py(self) -> int | str | Decimal:
2528        if self.is_number:
2529            try:
2530                return int(self.this)
2531            except ValueError:
2532                return Decimal(self.this)
2533        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2511    @property
2512    def hashable_args(self) -> t.Any:
2513        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2515    @classmethod
2516    def number(cls, number) -> Literal:
2517        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2519    @classmethod
2520    def string(cls, string) -> Literal:
2521        return cls(this=str(string), is_string=True)
output_name: str
2523    @property
2524    def output_name(self) -> str:
2525        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:
2527    def to_py(self) -> int | str | Decimal:
2528        if self.is_number:
2529            try:
2530                return int(self.this)
2531            except ValueError:
2532                return Decimal(self.this)
2533        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2536class Join(Expression):
2537    arg_types = {
2538        "this": True,
2539        "on": False,
2540        "side": False,
2541        "kind": False,
2542        "using": False,
2543        "method": False,
2544        "global": False,
2545        "hint": False,
2546        "match_condition": False,  # Snowflake
2547        "expressions": False,
2548        "pivots": False,
2549    }
2550
2551    @property
2552    def method(self) -> str:
2553        return self.text("method").upper()
2554
2555    @property
2556    def kind(self) -> str:
2557        return self.text("kind").upper()
2558
2559    @property
2560    def side(self) -> str:
2561        return self.text("side").upper()
2562
2563    @property
2564    def hint(self) -> str:
2565        return self.text("hint").upper()
2566
2567    @property
2568    def alias_or_name(self) -> str:
2569        return self.this.alias_or_name
2570
2571    @property
2572    def is_semi_or_anti_join(self) -> bool:
2573        return self.kind in ("SEMI", "ANTI")
2574
2575    def on(
2576        self,
2577        *expressions: t.Optional[ExpOrStr],
2578        append: bool = True,
2579        dialect: DialectType = None,
2580        copy: bool = True,
2581        **opts,
2582    ) -> Join:
2583        """
2584        Append to or set the ON expressions.
2585
2586        Example:
2587            >>> import sqlglot
2588            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2589            'JOIN x ON y = 1'
2590
2591        Args:
2592            *expressions: the SQL code strings to parse.
2593                If an `Expression` instance is passed, it will be used as-is.
2594                Multiple expressions are combined with an AND operator.
2595            append: if `True`, AND the new expressions to any existing expression.
2596                Otherwise, this resets the expression.
2597            dialect: the dialect used to parse the input expressions.
2598            copy: if `False`, modify this expression instance in-place.
2599            opts: other options to use to parse the input expressions.
2600
2601        Returns:
2602            The modified Join expression.
2603        """
2604        join = _apply_conjunction_builder(
2605            *expressions,
2606            instance=self,
2607            arg="on",
2608            append=append,
2609            dialect=dialect,
2610            copy=copy,
2611            **opts,
2612        )
2613
2614        if join.kind == "CROSS":
2615            join.set("kind", None)
2616
2617        return join
2618
2619    def using(
2620        self,
2621        *expressions: t.Optional[ExpOrStr],
2622        append: bool = True,
2623        dialect: DialectType = None,
2624        copy: bool = True,
2625        **opts,
2626    ) -> Join:
2627        """
2628        Append to or set the USING expressions.
2629
2630        Example:
2631            >>> import sqlglot
2632            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2633            'JOIN x USING (foo, bla)'
2634
2635        Args:
2636            *expressions: the SQL code strings to parse.
2637                If an `Expression` instance is passed, it will be used as-is.
2638            append: if `True`, concatenate the new expressions to the existing "using" list.
2639                Otherwise, this resets the expression.
2640            dialect: the dialect used to parse the input expressions.
2641            copy: if `False`, modify this expression instance in-place.
2642            opts: other options to use to parse the input expressions.
2643
2644        Returns:
2645            The modified Join expression.
2646        """
2647        join = _apply_list_builder(
2648            *expressions,
2649            instance=self,
2650            arg="using",
2651            append=append,
2652            dialect=dialect,
2653            copy=copy,
2654            **opts,
2655        )
2656
2657        if join.kind == "CROSS":
2658            join.set("kind", None)
2659
2660        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
2551    @property
2552    def method(self) -> str:
2553        return self.text("method").upper()
kind: str
2555    @property
2556    def kind(self) -> str:
2557        return self.text("kind").upper()
side: str
2559    @property
2560    def side(self) -> str:
2561        return self.text("side").upper()
hint: str
2563    @property
2564    def hint(self) -> str:
2565        return self.text("hint").upper()
alias_or_name: str
2567    @property
2568    def alias_or_name(self) -> str:
2569        return self.this.alias_or_name
is_semi_or_anti_join: bool
2571    @property
2572    def is_semi_or_anti_join(self) -> bool:
2573        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:
2575    def on(
2576        self,
2577        *expressions: t.Optional[ExpOrStr],
2578        append: bool = True,
2579        dialect: DialectType = None,
2580        copy: bool = True,
2581        **opts,
2582    ) -> Join:
2583        """
2584        Append to or set the ON expressions.
2585
2586        Example:
2587            >>> import sqlglot
2588            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2589            'JOIN x ON y = 1'
2590
2591        Args:
2592            *expressions: the SQL code strings to parse.
2593                If an `Expression` instance is passed, it will be used as-is.
2594                Multiple expressions are combined with an AND operator.
2595            append: if `True`, AND the new expressions to any existing expression.
2596                Otherwise, this resets the expression.
2597            dialect: the dialect used to parse the input expressions.
2598            copy: if `False`, modify this expression instance in-place.
2599            opts: other options to use to parse the input expressions.
2600
2601        Returns:
2602            The modified Join expression.
2603        """
2604        join = _apply_conjunction_builder(
2605            *expressions,
2606            instance=self,
2607            arg="on",
2608            append=append,
2609            dialect=dialect,
2610            copy=copy,
2611            **opts,
2612        )
2613
2614        if join.kind == "CROSS":
2615            join.set("kind", None)
2616
2617        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:
2619    def using(
2620        self,
2621        *expressions: t.Optional[ExpOrStr],
2622        append: bool = True,
2623        dialect: DialectType = None,
2624        copy: bool = True,
2625        **opts,
2626    ) -> Join:
2627        """
2628        Append to or set the USING expressions.
2629
2630        Example:
2631            >>> import sqlglot
2632            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2633            'JOIN x USING (foo, bla)'
2634
2635        Args:
2636            *expressions: the SQL code strings to parse.
2637                If an `Expression` instance is passed, it will be used as-is.
2638            append: if `True`, concatenate the new expressions to the existing "using" list.
2639                Otherwise, this resets the expression.
2640            dialect: the dialect used to parse the input expressions.
2641            copy: if `False`, modify this expression instance in-place.
2642            opts: other options to use to parse the input expressions.
2643
2644        Returns:
2645            The modified Join expression.
2646        """
2647        join = _apply_list_builder(
2648            *expressions,
2649            instance=self,
2650            arg="using",
2651            append=append,
2652            dialect=dialect,
2653            copy=copy,
2654            **opts,
2655        )
2656
2657        if join.kind == "CROSS":
2658            join.set("kind", None)
2659
2660        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):
2663class Lateral(UDTF):
2664    arg_types = {
2665        "this": True,
2666        "view": False,
2667        "outer": False,
2668        "alias": False,
2669        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2670        "ordinality": False,
2671    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2676class TableFromRows(UDTF):
2677    arg_types = {
2678        "this": True,
2679        "alias": False,
2680        "joins": False,
2681        "pivots": False,
2682        "sample": False,
2683    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2686class MatchRecognizeMeasure(Expression):
2687    arg_types = {
2688        "this": True,
2689        "window_frame": False,
2690    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2693class MatchRecognize(Expression):
2694    arg_types = {
2695        "partition_by": False,
2696        "order": False,
2697        "measures": False,
2698        "rows": False,
2699        "after": False,
2700        "pattern": False,
2701        "define": False,
2702        "alias": False,
2703    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2708class Final(Expression):
2709    pass
key = 'final'
class Offset(Expression):
2712class Offset(Expression):
2713    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2716class Order(Expression):
2717    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2721class WithFill(Expression):
2722    arg_types = {
2723        "from": False,
2724        "to": False,
2725        "step": False,
2726        "interpolate": False,
2727    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2732class Cluster(Order):
2733    pass
key = 'cluster'
class Distribute(Order):
2736class Distribute(Order):
2737    pass
key = 'distribute'
class Sort(Order):
2740class Sort(Order):
2741    pass
key = 'sort'
class Ordered(Expression):
2744class Ordered(Expression):
2745    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2746
2747    @property
2748    def name(self) -> str:
2749        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2747    @property
2748    def name(self) -> str:
2749        return self.this.name
key = 'ordered'
class Property(Expression):
2752class Property(Expression):
2753    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2756class GrantPrivilege(Expression):
2757    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2760class GrantPrincipal(Expression):
2761    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2764class AllowedValuesProperty(Expression):
2765    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2768class AlgorithmProperty(Property):
2769    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2772class AutoIncrementProperty(Property):
2773    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2777class AutoRefreshProperty(Property):
2778    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2781class BackupProperty(Property):
2782    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2785class BlockCompressionProperty(Property):
2786    arg_types = {
2787        "autotemp": False,
2788        "always": False,
2789        "default": False,
2790        "manual": False,
2791        "never": False,
2792    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2795class CharacterSetProperty(Property):
2796    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2799class ChecksumProperty(Property):
2800    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2803class CollateProperty(Property):
2804    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2807class CopyGrantsProperty(Property):
2808    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2811class DataBlocksizeProperty(Property):
2812    arg_types = {
2813        "size": False,
2814        "units": False,
2815        "minimum": False,
2816        "maximum": False,
2817        "default": False,
2818    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2821class DataDeletionProperty(Property):
2822    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):
2825class DefinerProperty(Property):
2826    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2829class DistKeyProperty(Property):
2830    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2835class DistributedByProperty(Property):
2836    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):
2839class DistStyleProperty(Property):
2840    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2843class DuplicateKeyProperty(Property):
2844    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2847class EngineProperty(Property):
2848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2851class HeapProperty(Property):
2852    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2855class ToTableProperty(Property):
2856    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2859class ExecuteAsProperty(Property):
2860    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2863class ExternalProperty(Property):
2864    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2867class FallbackProperty(Property):
2868    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2872class FileFormatProperty(Property):
2873    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2876class CredentialsProperty(Property):
2877    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2880class FreespaceProperty(Property):
2881    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2884class GlobalProperty(Property):
2885    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2888class IcebergProperty(Property):
2889    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2892class InheritsProperty(Property):
2893    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2896class InputModelProperty(Property):
2897    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2900class OutputModelProperty(Property):
2901    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2904class IsolatedLoadingProperty(Property):
2905    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2908class JournalProperty(Property):
2909    arg_types = {
2910        "no": False,
2911        "dual": False,
2912        "before": False,
2913        "local": False,
2914        "after": False,
2915    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2918class LanguageProperty(Property):
2919    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2922class EnviromentProperty(Property):
2923    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2927class ClusteredByProperty(Property):
2928    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2931class DictProperty(Property):
2932    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2935class DictSubProperty(Property):
2936    pass
key = 'dictsubproperty'
class DictRange(Property):
2939class DictRange(Property):
2940    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2943class DynamicProperty(Property):
2944    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2949class OnCluster(Property):
2950    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2954class EmptyProperty(Property):
2955    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2958class LikeProperty(Property):
2959    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2962class LocationProperty(Property):
2963    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2966class LockProperty(Property):
2967    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2970class LockingProperty(Property):
2971    arg_types = {
2972        "this": False,
2973        "kind": True,
2974        "for_or_in": False,
2975        "lock_type": True,
2976        "override": False,
2977    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2980class LogProperty(Property):
2981    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2984class MaterializedProperty(Property):
2985    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2988class MergeBlockRatioProperty(Property):
2989    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):
2992class NoPrimaryIndexProperty(Property):
2993    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2996class OnProperty(Property):
2997    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
3000class OnCommitProperty(Property):
3001    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3004class PartitionedByProperty(Property):
3005    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3008class PartitionedByBucket(Property):
3009    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3012class PartitionByTruncate(Property):
3013    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3017class PartitionByRangeProperty(Property):
3018    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3022class PartitionByRangePropertyDynamic(Expression):
3023    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):
3027class UniqueKeyProperty(Property):
3028    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3032class PartitionBoundSpec(Expression):
3033    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3034    arg_types = {
3035        "this": False,
3036        "expression": False,
3037        "from_expressions": False,
3038        "to_expressions": False,
3039    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3042class PartitionedOfProperty(Property):
3043    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3044    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3047class StreamingTableProperty(Property):
3048    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3051class RemoteWithConnectionModelProperty(Property):
3052    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3055class ReturnsProperty(Property):
3056    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):
3059class StrictProperty(Property):
3060    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3063class RowFormatProperty(Property):
3064    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3067class RowFormatDelimitedProperty(Property):
3068    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3069    arg_types = {
3070        "fields": False,
3071        "escaped": False,
3072        "collection_items": False,
3073        "map_keys": False,
3074        "lines": False,
3075        "null": False,
3076        "serde": False,
3077    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3080class RowFormatSerdeProperty(Property):
3081    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3085class QueryTransform(Expression):
3086    arg_types = {
3087        "expressions": True,
3088        "command_script": True,
3089        "schema": False,
3090        "row_format_before": False,
3091        "record_writer": False,
3092        "row_format_after": False,
3093        "record_reader": False,
3094    }
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):
3097class SampleProperty(Property):
3098    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3102class SecurityProperty(Property):
3103    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3106class SchemaCommentProperty(Property):
3107    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3110class SemanticView(Expression):
3111    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):
3114class SerdeProperties(Property):
3115    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3118class SetProperty(Property):
3119    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3122class SharingProperty(Property):
3123    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3126class SetConfigProperty(Property):
3127    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3130class SettingsProperty(Property):
3131    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3134class SortKeyProperty(Property):
3135    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3138class SqlReadWriteProperty(Property):
3139    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3142class SqlSecurityProperty(Property):
3143    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3146class StabilityProperty(Property):
3147    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3150class StorageHandlerProperty(Property):
3151    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3154class TemporaryProperty(Property):
3155    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3158class SecureProperty(Property):
3159    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3163class Tags(ColumnConstraintKind, Property):
3164    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3167class TransformModelProperty(Property):
3168    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3171class TransientProperty(Property):
3172    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3175class UnloggedProperty(Property):
3176    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3180class UsingTemplateProperty(Property):
3181    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3185class ViewAttributeProperty(Property):
3186    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3189class VolatileProperty(Property):
3190    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3193class WithDataProperty(Property):
3194    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3197class WithJournalTableProperty(Property):
3198    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3201class WithSchemaBindingProperty(Property):
3202    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3205class WithSystemVersioningProperty(Property):
3206    arg_types = {
3207        "on": False,
3208        "this": False,
3209        "data_consistency": False,
3210        "retention_period": False,
3211        "with": True,
3212    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3215class WithProcedureOptions(Property):
3216    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3219class EncodeProperty(Property):
3220    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3223class IncludeProperty(Property):
3224    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3227class ForceProperty(Property):
3228    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3231class Properties(Expression):
3232    arg_types = {"expressions": True}
3233
3234    NAME_TO_PROPERTY = {
3235        "ALGORITHM": AlgorithmProperty,
3236        "AUTO_INCREMENT": AutoIncrementProperty,
3237        "CHARACTER SET": CharacterSetProperty,
3238        "CLUSTERED_BY": ClusteredByProperty,
3239        "COLLATE": CollateProperty,
3240        "COMMENT": SchemaCommentProperty,
3241        "CREDENTIALS": CredentialsProperty,
3242        "DEFINER": DefinerProperty,
3243        "DISTKEY": DistKeyProperty,
3244        "DISTRIBUTED_BY": DistributedByProperty,
3245        "DISTSTYLE": DistStyleProperty,
3246        "ENGINE": EngineProperty,
3247        "EXECUTE AS": ExecuteAsProperty,
3248        "FORMAT": FileFormatProperty,
3249        "LANGUAGE": LanguageProperty,
3250        "LOCATION": LocationProperty,
3251        "LOCK": LockProperty,
3252        "PARTITIONED_BY": PartitionedByProperty,
3253        "RETURNS": ReturnsProperty,
3254        "ROW_FORMAT": RowFormatProperty,
3255        "SORTKEY": SortKeyProperty,
3256        "ENCODE": EncodeProperty,
3257        "INCLUDE": IncludeProperty,
3258    }
3259
3260    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3261
3262    # CREATE property locations
3263    # Form: schema specified
3264    #   create [POST_CREATE]
3265    #     table a [POST_NAME]
3266    #     (b int) [POST_SCHEMA]
3267    #     with ([POST_WITH])
3268    #     index (b) [POST_INDEX]
3269    #
3270    # Form: alias selection
3271    #   create [POST_CREATE]
3272    #     table a [POST_NAME]
3273    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3274    #     index (c) [POST_INDEX]
3275    class Location(AutoName):
3276        POST_CREATE = auto()
3277        POST_NAME = auto()
3278        POST_SCHEMA = auto()
3279        POST_WITH = auto()
3280        POST_ALIAS = auto()
3281        POST_EXPRESSION = auto()
3282        POST_INDEX = auto()
3283        UNSUPPORTED = auto()
3284
3285    @classmethod
3286    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3287        expressions = []
3288        for key, value in properties_dict.items():
3289            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3290            if property_cls:
3291                expressions.append(property_cls(this=convert(value)))
3292            else:
3293                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3294
3295        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:
3285    @classmethod
3286    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3287        expressions = []
3288        for key, value in properties_dict.items():
3289            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3290            if property_cls:
3291                expressions.append(property_cls(this=convert(value)))
3292            else:
3293                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3294
3295        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3275    class Location(AutoName):
3276        POST_CREATE = auto()
3277        POST_NAME = auto()
3278        POST_SCHEMA = auto()
3279        POST_WITH = auto()
3280        POST_ALIAS = auto()
3281        POST_EXPRESSION = auto()
3282        POST_INDEX = auto()
3283        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):
3298class Qualify(Expression):
3299    pass
key = 'qualify'
class InputOutputFormat(Expression):
3302class InputOutputFormat(Expression):
3303    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3307class Return(Expression):
3308    pass
key = 'return'
class Reference(Expression):
3311class Reference(Expression):
3312    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3315class Tuple(Expression):
3316    arg_types = {"expressions": False}
3317
3318    def isin(
3319        self,
3320        *expressions: t.Any,
3321        query: t.Optional[ExpOrStr] = None,
3322        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3323        copy: bool = True,
3324        **opts,
3325    ) -> In:
3326        return In(
3327            this=maybe_copy(self, copy),
3328            expressions=[convert(e, copy=copy) for e in expressions],
3329            query=maybe_parse(query, copy=copy, **opts) if query else None,
3330            unnest=(
3331                Unnest(
3332                    expressions=[
3333                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3334                        for e in ensure_list(unnest)
3335                    ]
3336                )
3337                if unnest
3338                else None
3339            ),
3340        )
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:
3318    def isin(
3319        self,
3320        *expressions: t.Any,
3321        query: t.Optional[ExpOrStr] = None,
3322        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3323        copy: bool = True,
3324        **opts,
3325    ) -> In:
3326        return In(
3327            this=maybe_copy(self, copy),
3328            expressions=[convert(e, copy=copy) for e in expressions],
3329            query=maybe_parse(query, copy=copy, **opts) if query else None,
3330            unnest=(
3331                Unnest(
3332                    expressions=[
3333                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3334                        for e in ensure_list(unnest)
3335                    ]
3336                )
3337                if unnest
3338                else None
3339            ),
3340        )
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):
3371class QueryOption(Expression):
3372    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3376class WithTableHint(Expression):
3377    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3381class IndexTableHint(Expression):
3382    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3386class HistoricalData(Expression):
3387    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3391class Put(Expression):
3392    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3396class Get(Expression):
3397    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3400class Table(Expression):
3401    arg_types = {
3402        "this": False,
3403        "alias": False,
3404        "db": False,
3405        "catalog": False,
3406        "laterals": False,
3407        "joins": False,
3408        "pivots": False,
3409        "hints": False,
3410        "system_time": False,
3411        "version": False,
3412        "format": False,
3413        "pattern": False,
3414        "ordinality": False,
3415        "when": False,
3416        "only": False,
3417        "partition": False,
3418        "changes": False,
3419        "rows_from": False,
3420        "sample": False,
3421    }
3422
3423    @property
3424    def name(self) -> str:
3425        if not self.this or isinstance(self.this, Func):
3426            return ""
3427        return self.this.name
3428
3429    @property
3430    def db(self) -> str:
3431        return self.text("db")
3432
3433    @property
3434    def catalog(self) -> str:
3435        return self.text("catalog")
3436
3437    @property
3438    def selects(self) -> t.List[Expression]:
3439        return []
3440
3441    @property
3442    def named_selects(self) -> t.List[str]:
3443        return []
3444
3445    @property
3446    def parts(self) -> t.List[Expression]:
3447        """Return the parts of a table in order catalog, db, table."""
3448        parts: t.List[Expression] = []
3449
3450        for arg in ("catalog", "db", "this"):
3451            part = self.args.get(arg)
3452
3453            if isinstance(part, Dot):
3454                parts.extend(part.flatten())
3455            elif isinstance(part, Expression):
3456                parts.append(part)
3457
3458        return parts
3459
3460    def to_column(self, copy: bool = True) -> Expression:
3461        parts = self.parts
3462        last_part = parts[-1]
3463
3464        if isinstance(last_part, Identifier):
3465            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3466        else:
3467            # This branch will be reached if a function or array is wrapped in a `Table`
3468            col = last_part
3469
3470        alias = self.args.get("alias")
3471        if alias:
3472            col = alias_(col, alias.this, copy=copy)
3473
3474        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
3423    @property
3424    def name(self) -> str:
3425        if not self.this or isinstance(self.this, Func):
3426            return ""
3427        return self.this.name
db: str
3429    @property
3430    def db(self) -> str:
3431        return self.text("db")
catalog: str
3433    @property
3434    def catalog(self) -> str:
3435        return self.text("catalog")
selects: List[Expression]
3437    @property
3438    def selects(self) -> t.List[Expression]:
3439        return []
named_selects: List[str]
3441    @property
3442    def named_selects(self) -> t.List[str]:
3443        return []
parts: List[Expression]
3445    @property
3446    def parts(self) -> t.List[Expression]:
3447        """Return the parts of a table in order catalog, db, table."""
3448        parts: t.List[Expression] = []
3449
3450        for arg in ("catalog", "db", "this"):
3451            part = self.args.get(arg)
3452
3453            if isinstance(part, Dot):
3454                parts.extend(part.flatten())
3455            elif isinstance(part, Expression):
3456                parts.append(part)
3457
3458        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3509    @property
3510    def is_star(self) -> bool:
3511        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3513    @property
3514    def selects(self) -> t.List[Expression]:
3515        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
4305    @property
4306    def selects(self) -> t.List[Expression]:
4307        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4392class Pivot(Expression):
4393    arg_types = {
4394        "this": False,
4395        "alias": False,
4396        "expressions": False,
4397        "fields": False,
4398        "unpivot": False,
4399        "using": False,
4400        "group": False,
4401        "columns": False,
4402        "include_nulls": False,
4403        "default_on_null": False,
4404        "into": False,
4405    }
4406
4407    @property
4408    def unpivot(self) -> bool:
4409        return bool(self.args.get("unpivot"))
4410
4411    @property
4412    def fields(self) -> t.List[Expression]:
4413        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
4407    @property
4408    def unpivot(self) -> bool:
4409        return bool(self.args.get("unpivot"))
fields: List[Expression]
4411    @property
4412    def fields(self) -> t.List[Expression]:
4413        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4418class UnpivotColumns(Expression):
4419    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4422class Window(Condition):
4423    arg_types = {
4424        "this": True,
4425        "partition_by": False,
4426        "order": False,
4427        "spec": False,
4428        "alias": False,
4429        "over": False,
4430        "first": False,
4431    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4434class WindowSpec(Expression):
4435    arg_types = {
4436        "kind": False,
4437        "start": False,
4438        "start_side": False,
4439        "end": False,
4440        "end_side": False,
4441        "exclude": False,
4442    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4445class PreWhere(Expression):
4446    pass
key = 'prewhere'
class Where(Expression):
4449class Where(Expression):
4450    pass
key = 'where'
class Star(Expression):
4453class Star(Expression):
4454    arg_types = {"except": False, "replace": False, "rename": False}
4455
4456    @property
4457    def name(self) -> str:
4458        return "*"
4459
4460    @property
4461    def output_name(self) -> str:
4462        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4456    @property
4457    def name(self) -> str:
4458        return "*"
output_name: str
4460    @property
4461    def output_name(self) -> str:
4462        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):
4465class Parameter(Condition):
4466    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4469class SessionParameter(Condition):
4470    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4475class Placeholder(Condition):
4476    arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
4477
4478    @property
4479    def name(self) -> str:
4480        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False, 'jdbc': False}
name: str
4478    @property
4479    def name(self) -> str:
4480        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4483class Null(Condition):
4484    arg_types: t.Dict[str, t.Any] = {}
4485
4486    @property
4487    def name(self) -> str:
4488        return "NULL"
4489
4490    def to_py(self) -> Lit[None]:
4491        return None
arg_types: Dict[str, Any] = {}
name: str
4486    @property
4487    def name(self) -> str:
4488        return "NULL"
def to_py(self) -> Literal[None]:
4490    def to_py(self) -> Lit[None]:
4491        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4494class Boolean(Condition):
4495    def to_py(self) -> bool:
4496        return self.this
def to_py(self) -> bool:
4495    def to_py(self) -> bool:
4496        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4499class DataTypeParam(Expression):
4500    arg_types = {"this": True, "expression": False}
4501
4502    @property
4503    def name(self) -> str:
4504        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4502    @property
4503    def name(self) -> str:
4504        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4509class DataType(Expression):
4510    arg_types = {
4511        "this": True,
4512        "expressions": False,
4513        "nested": False,
4514        "values": False,
4515        "prefix": False,
4516        "kind": False,
4517        "nullable": False,
4518    }
4519
4520    class Type(AutoName):
4521        ARRAY = auto()
4522        AGGREGATEFUNCTION = auto()
4523        SIMPLEAGGREGATEFUNCTION = auto()
4524        BIGDECIMAL = auto()
4525        BIGINT = auto()
4526        BIGSERIAL = auto()
4527        BINARY = auto()
4528        BIT = auto()
4529        BLOB = auto()
4530        BOOLEAN = auto()
4531        BPCHAR = auto()
4532        CHAR = auto()
4533        DATE = auto()
4534        DATE32 = auto()
4535        DATEMULTIRANGE = auto()
4536        DATERANGE = auto()
4537        DATETIME = auto()
4538        DATETIME2 = auto()
4539        DATETIME64 = auto()
4540        DECIMAL = auto()
4541        DECIMAL32 = auto()
4542        DECIMAL64 = auto()
4543        DECIMAL128 = auto()
4544        DECIMAL256 = auto()
4545        DOUBLE = auto()
4546        DYNAMIC = auto()
4547        ENUM = auto()
4548        ENUM8 = auto()
4549        ENUM16 = auto()
4550        FIXEDSTRING = auto()
4551        FLOAT = auto()
4552        GEOGRAPHY = auto()
4553        GEOGRAPHYPOINT = auto()
4554        GEOMETRY = auto()
4555        POINT = auto()
4556        RING = auto()
4557        LINESTRING = auto()
4558        MULTILINESTRING = auto()
4559        POLYGON = auto()
4560        MULTIPOLYGON = auto()
4561        HLLSKETCH = auto()
4562        HSTORE = auto()
4563        IMAGE = auto()
4564        INET = auto()
4565        INT = auto()
4566        INT128 = auto()
4567        INT256 = auto()
4568        INT4MULTIRANGE = auto()
4569        INT4RANGE = auto()
4570        INT8MULTIRANGE = auto()
4571        INT8RANGE = auto()
4572        INTERVAL = auto()
4573        IPADDRESS = auto()
4574        IPPREFIX = auto()
4575        IPV4 = auto()
4576        IPV6 = auto()
4577        JSON = auto()
4578        JSONB = auto()
4579        LIST = auto()
4580        LONGBLOB = auto()
4581        LONGTEXT = auto()
4582        LOWCARDINALITY = auto()
4583        MAP = auto()
4584        MEDIUMBLOB = auto()
4585        MEDIUMINT = auto()
4586        MEDIUMTEXT = auto()
4587        MONEY = auto()
4588        NAME = auto()
4589        NCHAR = auto()
4590        NESTED = auto()
4591        NOTHING = auto()
4592        NULL = auto()
4593        NUMMULTIRANGE = auto()
4594        NUMRANGE = auto()
4595        NVARCHAR = auto()
4596        OBJECT = auto()
4597        RANGE = auto()
4598        ROWVERSION = auto()
4599        SERIAL = auto()
4600        SET = auto()
4601        SMALLDATETIME = auto()
4602        SMALLINT = auto()
4603        SMALLMONEY = auto()
4604        SMALLSERIAL = auto()
4605        STRUCT = auto()
4606        SUPER = auto()
4607        TEXT = auto()
4608        TINYBLOB = auto()
4609        TINYTEXT = auto()
4610        TIME = auto()
4611        TIMETZ = auto()
4612        TIMESTAMP = auto()
4613        TIMESTAMPNTZ = auto()
4614        TIMESTAMPLTZ = auto()
4615        TIMESTAMPTZ = auto()
4616        TIMESTAMP_S = auto()
4617        TIMESTAMP_MS = auto()
4618        TIMESTAMP_NS = auto()
4619        TINYINT = auto()
4620        TSMULTIRANGE = auto()
4621        TSRANGE = auto()
4622        TSTZMULTIRANGE = auto()
4623        TSTZRANGE = auto()
4624        UBIGINT = auto()
4625        UINT = auto()
4626        UINT128 = auto()
4627        UINT256 = auto()
4628        UMEDIUMINT = auto()
4629        UDECIMAL = auto()
4630        UDOUBLE = auto()
4631        UNION = auto()
4632        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4633        USERDEFINED = "USER-DEFINED"
4634        USMALLINT = auto()
4635        UTINYINT = auto()
4636        UUID = auto()
4637        VARBINARY = auto()
4638        VARCHAR = auto()
4639        VARIANT = auto()
4640        VECTOR = auto()
4641        XML = auto()
4642        YEAR = auto()
4643        TDIGEST = auto()
4644
4645    STRUCT_TYPES = {
4646        Type.NESTED,
4647        Type.OBJECT,
4648        Type.STRUCT,
4649        Type.UNION,
4650    }
4651
4652    ARRAY_TYPES = {
4653        Type.ARRAY,
4654        Type.LIST,
4655    }
4656
4657    NESTED_TYPES = {
4658        *STRUCT_TYPES,
4659        *ARRAY_TYPES,
4660        Type.MAP,
4661    }
4662
4663    TEXT_TYPES = {
4664        Type.CHAR,
4665        Type.NCHAR,
4666        Type.NVARCHAR,
4667        Type.TEXT,
4668        Type.VARCHAR,
4669        Type.NAME,
4670    }
4671
4672    SIGNED_INTEGER_TYPES = {
4673        Type.BIGINT,
4674        Type.INT,
4675        Type.INT128,
4676        Type.INT256,
4677        Type.MEDIUMINT,
4678        Type.SMALLINT,
4679        Type.TINYINT,
4680    }
4681
4682    UNSIGNED_INTEGER_TYPES = {
4683        Type.UBIGINT,
4684        Type.UINT,
4685        Type.UINT128,
4686        Type.UINT256,
4687        Type.UMEDIUMINT,
4688        Type.USMALLINT,
4689        Type.UTINYINT,
4690    }
4691
4692    INTEGER_TYPES = {
4693        *SIGNED_INTEGER_TYPES,
4694        *UNSIGNED_INTEGER_TYPES,
4695        Type.BIT,
4696    }
4697
4698    FLOAT_TYPES = {
4699        Type.DOUBLE,
4700        Type.FLOAT,
4701    }
4702
4703    REAL_TYPES = {
4704        *FLOAT_TYPES,
4705        Type.BIGDECIMAL,
4706        Type.DECIMAL,
4707        Type.DECIMAL32,
4708        Type.DECIMAL64,
4709        Type.DECIMAL128,
4710        Type.DECIMAL256,
4711        Type.MONEY,
4712        Type.SMALLMONEY,
4713        Type.UDECIMAL,
4714        Type.UDOUBLE,
4715    }
4716
4717    NUMERIC_TYPES = {
4718        *INTEGER_TYPES,
4719        *REAL_TYPES,
4720    }
4721
4722    TEMPORAL_TYPES = {
4723        Type.DATE,
4724        Type.DATE32,
4725        Type.DATETIME,
4726        Type.DATETIME2,
4727        Type.DATETIME64,
4728        Type.SMALLDATETIME,
4729        Type.TIME,
4730        Type.TIMESTAMP,
4731        Type.TIMESTAMPNTZ,
4732        Type.TIMESTAMPLTZ,
4733        Type.TIMESTAMPTZ,
4734        Type.TIMESTAMP_MS,
4735        Type.TIMESTAMP_NS,
4736        Type.TIMESTAMP_S,
4737        Type.TIMETZ,
4738    }
4739
4740    @classmethod
4741    def build(
4742        cls,
4743        dtype: DATA_TYPE,
4744        dialect: DialectType = None,
4745        udt: bool = False,
4746        copy: bool = True,
4747        **kwargs,
4748    ) -> DataType:
4749        """
4750        Constructs a DataType object.
4751
4752        Args:
4753            dtype: the data type of interest.
4754            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4755            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4756                DataType, thus creating a user-defined type.
4757            copy: whether to copy the data type.
4758            kwargs: additional arguments to pass in the constructor of DataType.
4759
4760        Returns:
4761            The constructed DataType object.
4762        """
4763        from sqlglot import parse_one
4764
4765        if isinstance(dtype, str):
4766            if dtype.upper() == "UNKNOWN":
4767                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4768
4769            try:
4770                data_type_exp = parse_one(
4771                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4772                )
4773            except ParseError:
4774                if udt:
4775                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4776                raise
4777        elif isinstance(dtype, (Identifier, Dot)) and udt:
4778            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4779        elif isinstance(dtype, DataType.Type):
4780            data_type_exp = DataType(this=dtype)
4781        elif isinstance(dtype, DataType):
4782            return maybe_copy(dtype, copy)
4783        else:
4784            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4785
4786        return DataType(**{**data_type_exp.args, **kwargs})
4787
4788    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4789        """
4790        Checks whether this DataType matches one of the provided data types. Nested types or precision
4791        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4792
4793        Args:
4794            dtypes: the data types to compare this DataType to.
4795            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4796                If false, it means that NULLABLE<INT> is equivalent to INT.
4797
4798        Returns:
4799            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4800        """
4801        self_is_nullable = self.args.get("nullable")
4802        for dtype in dtypes:
4803            other_type = DataType.build(dtype, copy=False, udt=True)
4804            other_is_nullable = other_type.args.get("nullable")
4805            if (
4806                other_type.expressions
4807                or (check_nullable and (self_is_nullable or other_is_nullable))
4808                or self.this == DataType.Type.USERDEFINED
4809                or other_type.this == DataType.Type.USERDEFINED
4810            ):
4811                matches = self == other_type
4812            else:
4813                matches = self.this == other_type.this
4814
4815            if matches:
4816                return True
4817        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.UNION: 'UNION'>, <Type.OBJECT: 'OBJECT'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>, <Type.UNION: 'UNION'>, <Type.LIST: 'LIST'>}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT256: 'UINT256'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.UINT256: 'UINT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.MONEY: 'MONEY'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL: 'DECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>}
NUMERIC_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.UINT: 'UINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL: 'DECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.BIT: 'BIT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.INT: 'INT'>, <Type.UINT128: 'UINT128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT128: 'INT128'>, <Type.MONEY: 'MONEY'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.DECIMAL128: 'DECIMAL128'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME2: 'DATETIME2'>, <Type.DATETIME: 'DATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE32: 'DATE32'>}
@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:
4740    @classmethod
4741    def build(
4742        cls,
4743        dtype: DATA_TYPE,
4744        dialect: DialectType = None,
4745        udt: bool = False,
4746        copy: bool = True,
4747        **kwargs,
4748    ) -> DataType:
4749        """
4750        Constructs a DataType object.
4751
4752        Args:
4753            dtype: the data type of interest.
4754            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4755            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4756                DataType, thus creating a user-defined type.
4757            copy: whether to copy the data type.
4758            kwargs: additional arguments to pass in the constructor of DataType.
4759
4760        Returns:
4761            The constructed DataType object.
4762        """
4763        from sqlglot import parse_one
4764
4765        if isinstance(dtype, str):
4766            if dtype.upper() == "UNKNOWN":
4767                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4768
4769            try:
4770                data_type_exp = parse_one(
4771                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4772                )
4773            except ParseError:
4774                if udt:
4775                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4776                raise
4777        elif isinstance(dtype, (Identifier, Dot)) and udt:
4778            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4779        elif isinstance(dtype, DataType.Type):
4780            data_type_exp = DataType(this=dtype)
4781        elif isinstance(dtype, DataType):
4782            return maybe_copy(dtype, copy)
4783        else:
4784            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4785
4786        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:
4788    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4789        """
4790        Checks whether this DataType matches one of the provided data types. Nested types or precision
4791        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4792
4793        Args:
4794            dtypes: the data types to compare this DataType to.
4795            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4796                If false, it means that NULLABLE<INT> is equivalent to INT.
4797
4798        Returns:
4799            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4800        """
4801        self_is_nullable = self.args.get("nullable")
4802        for dtype in dtypes:
4803            other_type = DataType.build(dtype, copy=False, udt=True)
4804            other_is_nullable = other_type.args.get("nullable")
4805            if (
4806                other_type.expressions
4807                or (check_nullable and (self_is_nullable or other_is_nullable))
4808                or self.this == DataType.Type.USERDEFINED
4809                or other_type.this == DataType.Type.USERDEFINED
4810            ):
4811                matches = self == other_type
4812            else:
4813                matches = self.this == other_type.this
4814
4815            if matches:
4816                return True
4817        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):
4520    class Type(AutoName):
4521        ARRAY = auto()
4522        AGGREGATEFUNCTION = auto()
4523        SIMPLEAGGREGATEFUNCTION = auto()
4524        BIGDECIMAL = auto()
4525        BIGINT = auto()
4526        BIGSERIAL = auto()
4527        BINARY = auto()
4528        BIT = auto()
4529        BLOB = auto()
4530        BOOLEAN = auto()
4531        BPCHAR = auto()
4532        CHAR = auto()
4533        DATE = auto()
4534        DATE32 = auto()
4535        DATEMULTIRANGE = auto()
4536        DATERANGE = auto()
4537        DATETIME = auto()
4538        DATETIME2 = auto()
4539        DATETIME64 = auto()
4540        DECIMAL = auto()
4541        DECIMAL32 = auto()
4542        DECIMAL64 = auto()
4543        DECIMAL128 = auto()
4544        DECIMAL256 = auto()
4545        DOUBLE = auto()
4546        DYNAMIC = auto()
4547        ENUM = auto()
4548        ENUM8 = auto()
4549        ENUM16 = auto()
4550        FIXEDSTRING = auto()
4551        FLOAT = auto()
4552        GEOGRAPHY = auto()
4553        GEOGRAPHYPOINT = auto()
4554        GEOMETRY = auto()
4555        POINT = auto()
4556        RING = auto()
4557        LINESTRING = auto()
4558        MULTILINESTRING = auto()
4559        POLYGON = auto()
4560        MULTIPOLYGON = auto()
4561        HLLSKETCH = auto()
4562        HSTORE = auto()
4563        IMAGE = auto()
4564        INET = auto()
4565        INT = auto()
4566        INT128 = auto()
4567        INT256 = auto()
4568        INT4MULTIRANGE = auto()
4569        INT4RANGE = auto()
4570        INT8MULTIRANGE = auto()
4571        INT8RANGE = auto()
4572        INTERVAL = auto()
4573        IPADDRESS = auto()
4574        IPPREFIX = auto()
4575        IPV4 = auto()
4576        IPV6 = auto()
4577        JSON = auto()
4578        JSONB = auto()
4579        LIST = auto()
4580        LONGBLOB = auto()
4581        LONGTEXT = auto()
4582        LOWCARDINALITY = auto()
4583        MAP = auto()
4584        MEDIUMBLOB = auto()
4585        MEDIUMINT = auto()
4586        MEDIUMTEXT = auto()
4587        MONEY = auto()
4588        NAME = auto()
4589        NCHAR = auto()
4590        NESTED = auto()
4591        NOTHING = auto()
4592        NULL = auto()
4593        NUMMULTIRANGE = auto()
4594        NUMRANGE = auto()
4595        NVARCHAR = auto()
4596        OBJECT = auto()
4597        RANGE = auto()
4598        ROWVERSION = auto()
4599        SERIAL = auto()
4600        SET = auto()
4601        SMALLDATETIME = auto()
4602        SMALLINT = auto()
4603        SMALLMONEY = auto()
4604        SMALLSERIAL = auto()
4605        STRUCT = auto()
4606        SUPER = auto()
4607        TEXT = auto()
4608        TINYBLOB = auto()
4609        TINYTEXT = auto()
4610        TIME = auto()
4611        TIMETZ = auto()
4612        TIMESTAMP = auto()
4613        TIMESTAMPNTZ = auto()
4614        TIMESTAMPLTZ = auto()
4615        TIMESTAMPTZ = auto()
4616        TIMESTAMP_S = auto()
4617        TIMESTAMP_MS = auto()
4618        TIMESTAMP_NS = auto()
4619        TINYINT = auto()
4620        TSMULTIRANGE = auto()
4621        TSRANGE = auto()
4622        TSTZMULTIRANGE = auto()
4623        TSTZRANGE = auto()
4624        UBIGINT = auto()
4625        UINT = auto()
4626        UINT128 = auto()
4627        UINT256 = auto()
4628        UMEDIUMINT = auto()
4629        UDECIMAL = auto()
4630        UDOUBLE = auto()
4631        UNION = auto()
4632        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4633        USERDEFINED = "USER-DEFINED"
4634        USMALLINT = auto()
4635        UTINYINT = auto()
4636        UUID = auto()
4637        VARBINARY = auto()
4638        VARCHAR = auto()
4639        VARIANT = auto()
4640        VECTOR = auto()
4641        XML = auto()
4642        YEAR = auto()
4643        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BLOB = <Type.BLOB: 'BLOB'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME2 = <Type.DATETIME2: 'DATETIME2'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
DYNAMIC = <Type.DYNAMIC: 'DYNAMIC'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOGRAPHYPOINT = <Type.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LIST = <Type.LIST: 'LIST'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NOTHING = <Type.NOTHING: 'NOTHING'>
NULL = <Type.NULL: 'NULL'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
RANGE = <Type.RANGE: 'RANGE'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
class PseudoType(DataType):
4821class PseudoType(DataType):
4822    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4826class ObjectIdentifier(DataType):
4827    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4831class SubqueryPredicate(Predicate):
4832    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4835class All(SubqueryPredicate):
4836    pass
key = 'all'
class Any(SubqueryPredicate):
4839class Any(SubqueryPredicate):
4840    pass
key = 'any'
class Command(Expression):
4845class Command(Expression):
4846    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4849class Transaction(Expression):
4850    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4853class Commit(Expression):
4854    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4857class Rollback(Expression):
4858    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4861class Alter(Expression):
4862    arg_types = {
4863        "this": True,
4864        "kind": True,
4865        "actions": True,
4866        "exists": False,
4867        "only": False,
4868        "options": False,
4869        "cluster": False,
4870        "not_valid": False,
4871    }
4872
4873    @property
4874    def kind(self) -> t.Optional[str]:
4875        kind = self.args.get("kind")
4876        return kind and kind.upper()
4877
4878    @property
4879    def actions(self) -> t.List[Expression]:
4880        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]
4873    @property
4874    def kind(self) -> t.Optional[str]:
4875        kind = self.args.get("kind")
4876        return kind and kind.upper()
actions: List[Expression]
4878    @property
4879    def actions(self) -> t.List[Expression]:
4880        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4883class Analyze(Expression):
4884    arg_types = {
4885        "kind": False,
4886        "this": False,
4887        "options": False,
4888        "mode": False,
4889        "partition": False,
4890        "expression": False,
4891        "properties": False,
4892    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4895class AnalyzeStatistics(Expression):
4896    arg_types = {
4897        "kind": True,
4898        "option": False,
4899        "this": False,
4900        "expressions": False,
4901    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4904class AnalyzeHistogram(Expression):
4905    arg_types = {
4906        "this": True,
4907        "expressions": True,
4908        "expression": False,
4909        "update_options": False,
4910    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4913class AnalyzeSample(Expression):
4914    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4917class AnalyzeListChainedRows(Expression):
4918    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4921class AnalyzeDelete(Expression):
4922    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4925class AnalyzeWith(Expression):
4926    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4929class AnalyzeValidate(Expression):
4930    arg_types = {
4931        "kind": True,
4932        "this": False,
4933        "expression": False,
4934    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4937class AnalyzeColumns(Expression):
4938    pass
key = 'analyzecolumns'
class UsingData(Expression):
4941class UsingData(Expression):
4942    pass
key = 'usingdata'
class AddConstraint(Expression):
4945class AddConstraint(Expression):
4946    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AddPartition(Expression):
4949class AddPartition(Expression):
4950    arg_types = {"this": True, "exists": False, "location": False}
arg_types = {'this': True, 'exists': False, 'location': False}
key = 'addpartition'
class AttachOption(Expression):
4953class AttachOption(Expression):
4954    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4957class DropPartition(Expression):
4958    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4962class ReplacePartition(Expression):
4963    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4967class Binary(Condition):
4968    arg_types = {"this": True, "expression": True}
4969
4970    @property
4971    def left(self) -> Expression:
4972        return self.this
4973
4974    @property
4975    def right(self) -> Expression:
4976        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4970    @property
4971    def left(self) -> Expression:
4972        return self.this
right: Expression
4974    @property
4975    def right(self) -> Expression:
4976        return self.expression
key = 'binary'
class Add(Binary):
4979class Add(Binary):
4980    pass
key = 'add'
class Connector(Binary):
4983class Connector(Binary):
4984    pass
key = 'connector'
class BitwiseAnd(Binary):
4987class BitwiseAnd(Binary):
4988    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4991class BitwiseLeftShift(Binary):
4992    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4995class BitwiseOr(Binary):
4996    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4999class BitwiseRightShift(Binary):
5000    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
5003class BitwiseXor(Binary):
5004    pass
key = 'bitwisexor'
class Div(Binary):
5007class Div(Binary):
5008    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):
5011class Overlaps(Binary):
5012    pass
key = 'overlaps'
class Dot(Binary):
5015class Dot(Binary):
5016    @property
5017    def is_star(self) -> bool:
5018        return self.expression.is_star
5019
5020    @property
5021    def name(self) -> str:
5022        return self.expression.name
5023
5024    @property
5025    def output_name(self) -> str:
5026        return self.name
5027
5028    @classmethod
5029    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5030        """Build a Dot object with a sequence of expressions."""
5031        if len(expressions) < 2:
5032            raise ValueError("Dot requires >= 2 expressions.")
5033
5034        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5035
5036    @property
5037    def parts(self) -> t.List[Expression]:
5038        """Return the parts of a table / column in order catalog, db, table."""
5039        this, *parts = self.flatten()
5040
5041        parts.reverse()
5042
5043        for arg in COLUMN_PARTS:
5044            part = this.args.get(arg)
5045
5046            if isinstance(part, Expression):
5047                parts.append(part)
5048
5049        parts.reverse()
5050        return parts
is_star: bool
5016    @property
5017    def is_star(self) -> bool:
5018        return self.expression.is_star

Checks whether an expression is a star.

name: str
5020    @property
5021    def name(self) -> str:
5022        return self.expression.name
output_name: str
5024    @property
5025    def output_name(self) -> str:
5026        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:
5028    @classmethod
5029    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5030        """Build a Dot object with a sequence of expressions."""
5031        if len(expressions) < 2:
5032            raise ValueError("Dot requires >= 2 expressions.")
5033
5034        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]
5036    @property
5037    def parts(self) -> t.List[Expression]:
5038        """Return the parts of a table / column in order catalog, db, table."""
5039        this, *parts = self.flatten()
5040
5041        parts.reverse()
5042
5043        for arg in COLUMN_PARTS:
5044            part = this.args.get(arg)
5045
5046            if isinstance(part, Expression):
5047                parts.append(part)
5048
5049        parts.reverse()
5050        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):
5056class DPipe(Binary):
5057    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5060class EQ(Binary, Predicate):
5061    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5064class NullSafeEQ(Binary, Predicate):
5065    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5068class NullSafeNEQ(Binary, Predicate):
5069    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5073class PropertyEQ(Binary):
5074    pass
key = 'propertyeq'
class Distance(Binary):
5077class Distance(Binary):
5078    pass
key = 'distance'
class Escape(Binary):
5081class Escape(Binary):
5082    pass
key = 'escape'
class Glob(Binary, Predicate):
5085class Glob(Binary, Predicate):
5086    pass
key = 'glob'
class GT(Binary, Predicate):
5089class GT(Binary, Predicate):
5090    pass
key = 'gt'
class GTE(Binary, Predicate):
5093class GTE(Binary, Predicate):
5094    pass
key = 'gte'
class ILike(Binary, Predicate):
5097class ILike(Binary, Predicate):
5098    pass
key = 'ilike'
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 LT(Binary, Predicate):
5117class LT(Binary, Predicate):
5118    pass
key = 'lt'
class LTE(Binary, Predicate):
5121class LTE(Binary, Predicate):
5122    pass
key = 'lte'
class Mod(Binary):
5125class Mod(Binary):
5126    pass
key = 'mod'
class Mul(Binary):
5129class Mul(Binary):
5130    pass
key = 'mul'
class NEQ(Binary, Predicate):
5133class NEQ(Binary, Predicate):
5134    pass
key = 'neq'
class Operator(Binary):
5138class Operator(Binary):
5139    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5142class SimilarTo(Binary, Predicate):
5143    pass
key = 'similarto'
class Slice(Binary):
5146class Slice(Binary):
5147    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5150class Sub(Binary):
5151    pass
key = 'sub'
class Unary(Condition):
5156class Unary(Condition):
5157    pass
key = 'unary'
class BitwiseNot(Unary):
5160class BitwiseNot(Unary):
5161    pass
key = 'bitwisenot'
class Not(Unary):
5164class Not(Unary):
5165    pass
key = 'not'
class Paren(Unary):
5168class Paren(Unary):
5169    @property
5170    def output_name(self) -> str:
5171        return self.this.name
output_name: str
5169    @property
5170    def output_name(self) -> str:
5171        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):
5174class Neg(Unary):
5175    def to_py(self) -> int | Decimal:
5176        if self.is_number:
5177            return self.this.to_py() * -1
5178        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5175    def to_py(self) -> int | Decimal:
5176        if self.is_number:
5177            return self.this.to_py() * -1
5178        return super().to_py()

Returns a Python object equivalent of the SQL node.

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

Automatically converts unit arg into a var.

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

SPACE(n) → string consisting of n blank characters

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

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7150class NextValueFor(Func):
7151    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7156class Semicolon(Expression):
7157    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7162class TableColumn(Expression):
7163    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:
7203def maybe_parse(
7204    sql_or_expression: ExpOrStr,
7205    *,
7206    into: t.Optional[IntoType] = None,
7207    dialect: DialectType = None,
7208    prefix: t.Optional[str] = None,
7209    copy: bool = False,
7210    **opts,
7211) -> Expression:
7212    """Gracefully handle a possible string or expression.
7213
7214    Example:
7215        >>> maybe_parse("1")
7216        Literal(this=1, is_string=False)
7217        >>> maybe_parse(to_identifier("x"))
7218        Identifier(this=x, quoted=False)
7219
7220    Args:
7221        sql_or_expression: the SQL code string or an expression
7222        into: the SQLGlot Expression to parse into
7223        dialect: the dialect used to parse the input expressions (in the case that an
7224            input expression is a SQL string).
7225        prefix: a string to prefix the sql with before it gets parsed
7226            (automatically includes a space)
7227        copy: whether to copy the expression.
7228        **opts: other options to use to parse the input expressions (again, in the case
7229            that an input expression is a SQL string).
7230
7231    Returns:
7232        Expression: the parsed or given expression.
7233    """
7234    if isinstance(sql_or_expression, Expression):
7235        if copy:
7236            return sql_or_expression.copy()
7237        return sql_or_expression
7238
7239    if sql_or_expression is None:
7240        raise ParseError("SQL cannot be None")
7241
7242    import sqlglot
7243
7244    sql = str(sql_or_expression)
7245    if prefix:
7246        sql = f"{prefix} {sql}"
7247
7248    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):
7259def maybe_copy(instance, copy=True):
7260    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:
7515def union(
7516    *expressions: ExpOrStr,
7517    distinct: bool = True,
7518    dialect: DialectType = None,
7519    copy: bool = True,
7520    **opts,
7521) -> Union:
7522    """
7523    Initializes a syntax tree for the `UNION` operation.
7524
7525    Example:
7526        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7527        'SELECT * FROM foo UNION SELECT * FROM bla'
7528
7529    Args:
7530        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7531            If `Expression` instances are passed, they will be used as-is.
7532        distinct: set the DISTINCT flag if and only if this is true.
7533        dialect: the dialect used to parse the input expression.
7534        copy: whether to copy the expression.
7535        opts: other options to use to parse the input expressions.
7536
7537    Returns:
7538        The new Union instance.
7539    """
7540    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7541    return _apply_set_operation(
7542        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7543    )

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

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

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

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

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

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

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

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

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

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

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

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

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:
8962def true() -> Boolean:
8963    """
8964    Returns a true Boolean expression.
8965    """
8966    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8969def false() -> Boolean:
8970    """
8971    Returns a false Boolean expression.
8972    """
8973    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8976def null() -> Null:
8977    """
8978    Returns a Null expression.
8979    """
8980    return Null()

Returns a Null expression.

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