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

Retrieves the argument with key "this".

expression: Any
139    @property
140    def expression(self) -> t.Any:
141        """
142        Retrieves the argument with key "expression".
143        """
144        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
146    @property
147    def expressions(self) -> t.List[t.Any]:
148        """
149        Retrieves the argument with key "expressions".
150        """
151        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

is_number: bool
174    @property
175    def is_number(self) -> bool:
176        """
177        Checks whether a Literal expression is a number.
178        """
179        return (isinstance(self, Literal) and not self.args["is_string"]) or (
180            isinstance(self, Neg) and self.this.is_number
181        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
183    def to_py(self) -> t.Any:
184        """
185        Returns a Python object equivalent of the SQL node.
186        """
187        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
189    @property
190    def is_int(self) -> bool:
191        """
192        Checks whether an expression is an integer.
193        """
194        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
196    @property
197    def is_star(self) -> bool:
198        """Checks whether an expression is a star."""
199        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
201    @property
202    def alias(self) -> str:
203        """
204        Returns the alias of the expression, or an empty string if it's not aliased.
205        """
206        if isinstance(self.args.get("alias"), TableAlias):
207            return self.args["alias"].name
208        return self.text("alias")

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

alias_column_names: List[str]
210    @property
211    def alias_column_names(self) -> t.List[str]:
212        table_alias = self.args.get("alias")
213        if not table_alias:
214            return []
215        return [c.name for c in table_alias.args.get("columns") or []]
name: str
217    @property
218    def name(self) -> str:
219        return self.text("this")
alias_or_name: str
221    @property
222    def alias_or_name(self) -> str:
223        return self.alias or self.name
output_name: str
225    @property
226    def output_name(self) -> str:
227        """
228        Name of the output column if this expression is a selection.
229
230        If the Expression has no output name, an empty string is returned.
231
232        Example:
233            >>> from sqlglot import parse_one
234            >>> parse_one("SELECT a").expressions[0].output_name
235            'a'
236            >>> parse_one("SELECT b AS c").expressions[0].output_name
237            'c'
238            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
239            ''
240        """
241        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]
243    @property
244    def type(self) -> t.Optional[DataType]:
245        return self._type
def is_type(self, *dtypes) -> bool:
253    def is_type(self, *dtypes) -> bool:
254        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
256    def is_leaf(self) -> bool:
257        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
259    @property
260    def meta(self) -> t.Dict[str, t.Any]:
261        if self._meta is None:
262            self._meta = {}
263        return self._meta
def copy(self):
299    def copy(self):
300        """
301        Returns a deep copy of the expression.
302        """
303        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]] = None) -> None:
305    def add_comments(self, comments: t.Optional[t.List[str]] = None) -> None:
306        if self.comments is None:
307            self.comments = []
308
309        if comments:
310            for comment in comments:
311                _, *meta = comment.split(SQLGLOT_META)
312                if meta:
313                    for kv in "".join(meta).split(","):
314                        k, *v = kv.split("=")
315                        value = v[0].strip() if v else True
316                        self.meta[k.strip()] = value
317                self.comments.append(comment)
def pop_comments(self) -> List[str]:
319    def pop_comments(self) -> t.List[str]:
320        comments = self.comments or []
321        self.comments = None
322        return comments
def append(self, arg_key: str, value: Any) -> None:
324    def append(self, arg_key: str, value: t.Any) -> None:
325        """
326        Appends value to arg_key if it's a list or sets it as a new list.
327
328        Args:
329            arg_key (str): name of the list expression arg
330            value (Any): value to append to the list
331        """
332        if type(self.args.get(arg_key)) is not list:
333            self.args[arg_key] = []
334        self._set_parent(arg_key, value)
335        values = self.args[arg_key]
336        if hasattr(value, "parent"):
337            value.index = len(values)
338        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) -> None:
340    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
341        """
342        Sets arg_key to value.
343
344        Args:
345            arg_key: name of the expression arg.
346            value: value to set the arg to.
347            index: if the arg is a list, this specifies what position to add the value in it.
348        """
349        if index is not None:
350            expressions = self.args.get(arg_key) or []
351
352            if seq_get(expressions, index) is None:
353                return
354            if value is None:
355                expressions.pop(index)
356                for v in expressions[index:]:
357                    v.index = v.index - 1
358                return
359
360            if isinstance(value, list):
361                expressions.pop(index)
362                expressions[index:index] = value
363            else:
364                expressions[index] = value
365
366            value = expressions
367        elif value is None:
368            self.args.pop(arg_key, None)
369            return
370
371        self.args[arg_key] = value
372        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.
depth: int
386    @property
387    def depth(self) -> int:
388        """
389        Returns the depth of this tree.
390        """
391        if self.parent:
392            return self.parent.depth + 1
393        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
395    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
396        """Yields the key and expression for all arguments, exploding list args."""
397        # remove tuple when python 3.7 is deprecated
398        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
399            if type(vs) is list:
400                for v in reversed(vs) if reverse else vs:
401                    if hasattr(v, "parent"):
402                        yield v
403            else:
404                if hasattr(vs, "parent"):
405                    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]:
407    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
408        """
409        Returns the first node in this tree which matches at least one of
410        the specified types.
411
412        Args:
413            expression_types: the expression type(s) to match.
414            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
415
416        Returns:
417            The node which matches the criteria or None if no such node was found.
418        """
419        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]:
421    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
422        """
423        Returns a generator object which visits all nodes in this tree and only
424        yields those that match at least one of the specified expression types.
425
426        Args:
427            expression_types: the expression type(s) to match.
428            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
429
430        Returns:
431            The generator object.
432        """
433        for expression in self.walk(bfs=bfs):
434            if isinstance(expression, expression_types):
435                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]:
437    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
438        """
439        Returns a nearest parent matching expression_types.
440
441        Args:
442            expression_types: the expression type(s) to match.
443
444        Returns:
445            The parent node.
446        """
447        ancestor = self.parent
448        while ancestor and not isinstance(ancestor, expression_types):
449            ancestor = ancestor.parent
450        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]
452    @property
453    def parent_select(self) -> t.Optional[Select]:
454        """
455        Returns the parent select statement.
456        """
457        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
459    @property
460    def same_parent(self) -> bool:
461        """Returns if the parent is the same class as itself."""
462        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
464    def root(self) -> Expression:
465        """
466        Returns the root expression of this tree.
467        """
468        expression = self
469        while expression.parent:
470            expression = expression.parent
471        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
473    def walk(
474        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
475    ) -> t.Iterator[Expression]:
476        """
477        Returns a generator object which visits all nodes in this tree.
478
479        Args:
480            bfs: if set to True the BFS traversal order will be applied,
481                otherwise the DFS traversal will be used instead.
482            prune: callable that returns True if the generator should stop traversing
483                this branch of the tree.
484
485        Returns:
486            the generator object.
487        """
488        if bfs:
489            yield from self.bfs(prune=prune)
490        else:
491            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]:
493    def dfs(
494        self, 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 in
498        the DFS (Depth-first) order.
499
500        Returns:
501            The generator object.
502        """
503        stack = [self]
504
505        while stack:
506            node = stack.pop()
507
508            yield node
509
510            if prune and prune(node):
511                continue
512
513            for v in node.iter_expressions(reverse=True):
514                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]:
516    def bfs(
517        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
518    ) -> t.Iterator[Expression]:
519        """
520        Returns a generator object which visits all nodes in this tree in
521        the BFS (Breadth-first) order.
522
523        Returns:
524            The generator object.
525        """
526        queue = deque([self])
527
528        while queue:
529            node = queue.popleft()
530
531            yield node
532
533            if prune and prune(node):
534                continue
535
536            for v in node.iter_expressions():
537                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):
539    def unnest(self):
540        """
541        Returns the first non parenthesis child or self.
542        """
543        expression = self
544        while type(expression) is Paren:
545            expression = expression.this
546        return expression

Returns the first non parenthesis child or self.

def unalias(self):
548    def unalias(self):
549        """
550        Returns the inner expression if this is an Alias.
551        """
552        if isinstance(self, Alias):
553            return self.this
554        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
556    def unnest_operands(self):
557        """
558        Returns unnested operands as a tuple.
559        """
560        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
747    @classmethod
748    def load(cls, obj):
749        """
750        Load a dict (as returned by `Expression.dump`) into an Expression instance.
751        """
752        from sqlglot.serde import load
753
754        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
756    def and_(
757        self,
758        *expressions: t.Optional[ExpOrStr],
759        dialect: DialectType = None,
760        copy: bool = True,
761        **opts,
762    ) -> Condition:
763        """
764        AND this condition with one or multiple expressions.
765
766        Example:
767            >>> condition("x=1").and_("y=1").sql()
768            'x = 1 AND y = 1'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expression` instance is passed, it will be used as-is.
773            dialect: the dialect used to parse the input expression.
774            copy: whether to copy the involved expressions (only applies to Expressions).
775            opts: other options to use to parse the input expressions.
776
777        Returns:
778            The new And condition.
779        """
780        return and_(self, *expressions, dialect=dialect, copy=copy, **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).
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
782    def or_(
783        self,
784        *expressions: t.Optional[ExpOrStr],
785        dialect: DialectType = None,
786        copy: bool = True,
787        **opts,
788    ) -> Condition:
789        """
790        OR this condition with one or multiple expressions.
791
792        Example:
793            >>> condition("x=1").or_("y=1").sql()
794            'x = 1 OR y = 1'
795
796        Args:
797            *expressions: the SQL code strings to parse.
798                If an `Expression` instance is passed, it will be used as-is.
799            dialect: the dialect used to parse the input expression.
800            copy: whether to copy the involved expressions (only applies to Expressions).
801            opts: other options to use to parse the input expressions.
802
803        Returns:
804            The new Or condition.
805        """
806        return or_(self, *expressions, dialect=dialect, copy=copy, **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).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
808    def not_(self, copy: bool = True):
809        """
810        Wrap this condition with NOT.
811
812        Example:
813            >>> condition("x=1").not_().sql()
814            'NOT x = 1'
815
816        Args:
817            copy: whether to copy this object.
818
819        Returns:
820            The new Not instance.
821        """
822        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 as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
824    def as_(
825        self,
826        alias: str | Identifier,
827        quoted: t.Optional[bool] = None,
828        dialect: DialectType = None,
829        copy: bool = True,
830        **opts,
831    ) -> Alias:
832        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:
857    def isin(
858        self,
859        *expressions: t.Any,
860        query: t.Optional[ExpOrStr] = None,
861        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
862        copy: bool = True,
863        **opts,
864    ) -> In:
865        subquery = maybe_parse(query, copy=copy, **opts) if query else None
866        if subquery and not isinstance(subquery, Subquery):
867            subquery = subquery.subquery(copy=False)
868
869        return In(
870            this=maybe_copy(self, copy),
871            expressions=[convert(e, copy=copy) for e in expressions],
872            query=subquery,
873            unnest=(
874                Unnest(
875                    expressions=[
876                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
877                        for e in ensure_list(unnest)
878                    ]
879                )
880                if unnest
881                else None
882            ),
883        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
885    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
886        return Between(
887            this=maybe_copy(self, copy),
888            low=convert(low, copy=copy, **opts),
889            high=convert(high, copy=copy, **opts),
890        )
def is_( self, other: Union[str, Expression]) -> Is:
892    def is_(self, other: ExpOrStr) -> Is:
893        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
895    def like(self, other: ExpOrStr) -> Like:
896        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
898    def ilike(self, other: ExpOrStr) -> ILike:
899        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
901    def eq(self, other: t.Any) -> EQ:
902        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
904    def neq(self, other: t.Any) -> NEQ:
905        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
907    def rlike(self, other: ExpOrStr) -> RegexpLike:
908        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
910    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
911        div = self._binop(Div, other)
912        div.args["typed"] = typed
913        div.args["safe"] = safe
914        return div
def asc(self, nulls_first: bool = True) -> Ordered:
916    def asc(self, nulls_first: bool = True) -> Ordered:
917        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
919    def desc(self, nulls_first: bool = False) -> Ordered:
920        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):
1003class Condition(Expression):
1004    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
1011class DerivedTable(Expression):
1012    @property
1013    def selects(self) -> t.List[Expression]:
1014        return self.this.selects if isinstance(self.this, Query) else []
1015
1016    @property
1017    def named_selects(self) -> t.List[str]:
1018        return [select.output_name for select in self.selects]
selects: List[Expression]
1012    @property
1013    def selects(self) -> t.List[Expression]:
1014        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1016    @property
1017    def named_selects(self) -> t.List[str]:
1018        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1021class Query(Expression):
1022    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1023        """
1024        Returns a `Subquery` that wraps around this query.
1025
1026        Example:
1027            >>> subquery = Select().select("x").from_("tbl").subquery()
1028            >>> Select().select("x").from_(subquery).sql()
1029            'SELECT x FROM (SELECT x FROM tbl)'
1030
1031        Args:
1032            alias: an optional alias for the subquery.
1033            copy: if `False`, modify this expression instance in-place.
1034        """
1035        instance = maybe_copy(self, copy)
1036        if not isinstance(alias, Expression):
1037            alias = TableAlias(this=to_identifier(alias)) if alias else None
1038
1039        return Subquery(this=instance, alias=alias)
1040
1041    def limit(
1042        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1043    ) -> Q:
1044        """
1045        Adds a LIMIT clause to this query.
1046
1047        Example:
1048            >>> select("1").union(select("1")).limit(1).sql()
1049            'SELECT 1 UNION SELECT 1 LIMIT 1'
1050
1051        Args:
1052            expression: the SQL code string to parse.
1053                This can also be an integer.
1054                If a `Limit` instance is passed, it will be used as-is.
1055                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1056            dialect: the dialect used to parse the input expression.
1057            copy: if `False`, modify this expression instance in-place.
1058            opts: other options to use to parse the input expressions.
1059
1060        Returns:
1061            A limited Select expression.
1062        """
1063        return _apply_builder(
1064            expression=expression,
1065            instance=self,
1066            arg="limit",
1067            into=Limit,
1068            prefix="LIMIT",
1069            dialect=dialect,
1070            copy=copy,
1071            into_arg="expression",
1072            **opts,
1073        )
1074
1075    def offset(
1076        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1077    ) -> Q:
1078        """
1079        Set the OFFSET expression.
1080
1081        Example:
1082            >>> Select().from_("tbl").select("x").offset(10).sql()
1083            'SELECT x FROM tbl OFFSET 10'
1084
1085        Args:
1086            expression: the SQL code string to parse.
1087                This can also be an integer.
1088                If a `Offset` instance is passed, this is used as-is.
1089                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1090            dialect: the dialect used to parse the input expression.
1091            copy: if `False`, modify this expression instance in-place.
1092            opts: other options to use to parse the input expressions.
1093
1094        Returns:
1095            The modified Select expression.
1096        """
1097        return _apply_builder(
1098            expression=expression,
1099            instance=self,
1100            arg="offset",
1101            into=Offset,
1102            prefix="OFFSET",
1103            dialect=dialect,
1104            copy=copy,
1105            into_arg="expression",
1106            **opts,
1107        )
1108
1109    def order_by(
1110        self: Q,
1111        *expressions: t.Optional[ExpOrStr],
1112        append: bool = True,
1113        dialect: DialectType = None,
1114        copy: bool = True,
1115        **opts,
1116    ) -> Q:
1117        """
1118        Set the ORDER BY expression.
1119
1120        Example:
1121            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1122            'SELECT x FROM tbl ORDER BY x DESC'
1123
1124        Args:
1125            *expressions: the SQL code strings to parse.
1126                If a `Group` instance is passed, this is used as-is.
1127                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1128            append: if `True`, add to any existing expressions.
1129                Otherwise, this flattens all the `Order` expression into a single expression.
1130            dialect: the dialect used to parse the input expression.
1131            copy: if `False`, modify this expression instance in-place.
1132            opts: other options to use to parse the input expressions.
1133
1134        Returns:
1135            The modified Select expression.
1136        """
1137        return _apply_child_list_builder(
1138            *expressions,
1139            instance=self,
1140            arg="order",
1141            append=append,
1142            copy=copy,
1143            prefix="ORDER BY",
1144            into=Order,
1145            dialect=dialect,
1146            **opts,
1147        )
1148
1149    @property
1150    def ctes(self) -> t.List[CTE]:
1151        """Returns a list of all the CTEs attached to this query."""
1152        with_ = self.args.get("with")
1153        return with_.expressions if with_ else []
1154
1155    @property
1156    def selects(self) -> t.List[Expression]:
1157        """Returns the query's projections."""
1158        raise NotImplementedError("Query objects must implement `selects`")
1159
1160    @property
1161    def named_selects(self) -> t.List[str]:
1162        """Returns the output names of the query's projections."""
1163        raise NotImplementedError("Query objects must implement `named_selects`")
1164
1165    def select(
1166        self: Q,
1167        *expressions: t.Optional[ExpOrStr],
1168        append: bool = True,
1169        dialect: DialectType = None,
1170        copy: bool = True,
1171        **opts,
1172    ) -> Q:
1173        """
1174        Append to or set the SELECT expressions.
1175
1176        Example:
1177            >>> Select().select("x", "y").sql()
1178            'SELECT x, y'
1179
1180        Args:
1181            *expressions: the SQL code strings to parse.
1182                If an `Expression` instance is passed, it will be used as-is.
1183            append: if `True`, add to any existing expressions.
1184                Otherwise, this resets the expressions.
1185            dialect: the dialect used to parse the input expressions.
1186            copy: if `False`, modify this expression instance in-place.
1187            opts: other options to use to parse the input expressions.
1188
1189        Returns:
1190            The modified Query expression.
1191        """
1192        raise NotImplementedError("Query objects must implement `select`")
1193
1194    def with_(
1195        self: Q,
1196        alias: ExpOrStr,
1197        as_: ExpOrStr,
1198        recursive: t.Optional[bool] = None,
1199        append: bool = True,
1200        dialect: DialectType = None,
1201        copy: bool = True,
1202        **opts,
1203    ) -> Q:
1204        """
1205        Append to or set the common table expressions.
1206
1207        Example:
1208            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1209            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1210
1211        Args:
1212            alias: the SQL code string to parse as the table name.
1213                If an `Expression` instance is passed, this is used as-is.
1214            as_: the SQL code string to parse as the table expression.
1215                If an `Expression` instance is passed, it will be used as-is.
1216            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1217            append: if `True`, add to any existing expressions.
1218                Otherwise, this resets the expressions.
1219            dialect: the dialect used to parse the input expression.
1220            copy: if `False`, modify this expression instance in-place.
1221            opts: other options to use to parse the input expressions.
1222
1223        Returns:
1224            The modified expression.
1225        """
1226        return _apply_cte_builder(
1227            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1228        )
1229
1230    def union(
1231        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1232    ) -> Union:
1233        """
1234        Builds a UNION expression.
1235
1236        Example:
1237            >>> import sqlglot
1238            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1239            'SELECT * FROM foo UNION SELECT * FROM bla'
1240
1241        Args:
1242            expression: the SQL code string.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            distinct: set the DISTINCT flag if and only if this is true.
1245            dialect: the dialect used to parse the input expression.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The new Union expression.
1250        """
1251        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1252
1253    def intersect(
1254        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1255    ) -> Intersect:
1256        """
1257        Builds an INTERSECT expression.
1258
1259        Example:
1260            >>> import sqlglot
1261            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1262            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1263
1264        Args:
1265            expression: the SQL code string.
1266                If an `Expression` instance is passed, it will be used as-is.
1267            distinct: set the DISTINCT flag if and only if this is true.
1268            dialect: the dialect used to parse the input expression.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The new Intersect expression.
1273        """
1274        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1275
1276    def except_(
1277        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1278    ) -> Except:
1279        """
1280        Builds an EXCEPT expression.
1281
1282        Example:
1283            >>> import sqlglot
1284            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1285            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1286
1287        Args:
1288            expression: the SQL code string.
1289                If an `Expression` instance is passed, it will be used as-is.
1290            distinct: set the DISTINCT flag if and only if this is true.
1291            dialect: the dialect used to parse the input expression.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The new Except expression.
1296        """
1297        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1022    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1023        """
1024        Returns a `Subquery` that wraps around this query.
1025
1026        Example:
1027            >>> subquery = Select().select("x").from_("tbl").subquery()
1028            >>> Select().select("x").from_(subquery).sql()
1029            'SELECT x FROM (SELECT x FROM tbl)'
1030
1031        Args:
1032            alias: an optional alias for the subquery.
1033            copy: if `False`, modify this expression instance in-place.
1034        """
1035        instance = maybe_copy(self, copy)
1036        if not isinstance(alias, Expression):
1037            alias = TableAlias(this=to_identifier(alias)) if alias else None
1038
1039        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1041    def limit(
1042        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1043    ) -> Q:
1044        """
1045        Adds a LIMIT clause to this query.
1046
1047        Example:
1048            >>> select("1").union(select("1")).limit(1).sql()
1049            'SELECT 1 UNION SELECT 1 LIMIT 1'
1050
1051        Args:
1052            expression: the SQL code string to parse.
1053                This can also be an integer.
1054                If a `Limit` instance is passed, it will be used as-is.
1055                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1056            dialect: the dialect used to parse the input expression.
1057            copy: if `False`, modify this expression instance in-place.
1058            opts: other options to use to parse the input expressions.
1059
1060        Returns:
1061            A limited Select expression.
1062        """
1063        return _apply_builder(
1064            expression=expression,
1065            instance=self,
1066            arg="limit",
1067            into=Limit,
1068            prefix="LIMIT",
1069            dialect=dialect,
1070            copy=copy,
1071            into_arg="expression",
1072            **opts,
1073        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1075    def offset(
1076        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1077    ) -> Q:
1078        """
1079        Set the OFFSET expression.
1080
1081        Example:
1082            >>> Select().from_("tbl").select("x").offset(10).sql()
1083            'SELECT x FROM tbl OFFSET 10'
1084
1085        Args:
1086            expression: the SQL code string to parse.
1087                This can also be an integer.
1088                If a `Offset` instance is passed, this is used as-is.
1089                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1090            dialect: the dialect used to parse the input expression.
1091            copy: if `False`, modify this expression instance in-place.
1092            opts: other options to use to parse the input expressions.
1093
1094        Returns:
1095            The modified Select expression.
1096        """
1097        return _apply_builder(
1098            expression=expression,
1099            instance=self,
1100            arg="offset",
1101            into=Offset,
1102            prefix="OFFSET",
1103            dialect=dialect,
1104            copy=copy,
1105            into_arg="expression",
1106            **opts,
1107        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1109    def order_by(
1110        self: Q,
1111        *expressions: t.Optional[ExpOrStr],
1112        append: bool = True,
1113        dialect: DialectType = None,
1114        copy: bool = True,
1115        **opts,
1116    ) -> Q:
1117        """
1118        Set the ORDER BY expression.
1119
1120        Example:
1121            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1122            'SELECT x FROM tbl ORDER BY x DESC'
1123
1124        Args:
1125            *expressions: the SQL code strings to parse.
1126                If a `Group` instance is passed, this is used as-is.
1127                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1128            append: if `True`, add to any existing expressions.
1129                Otherwise, this flattens all the `Order` expression into a single expression.
1130            dialect: the dialect used to parse the input expression.
1131            copy: if `False`, modify this expression instance in-place.
1132            opts: other options to use to parse the input expressions.
1133
1134        Returns:
1135            The modified Select expression.
1136        """
1137        return _apply_child_list_builder(
1138            *expressions,
1139            instance=self,
1140            arg="order",
1141            append=append,
1142            copy=copy,
1143            prefix="ORDER BY",
1144            into=Order,
1145            dialect=dialect,
1146            **opts,
1147        )

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

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

selects: List[Expression]
1155    @property
1156    def selects(self) -> t.List[Expression]:
1157        """Returns the query's projections."""
1158        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1160    @property
1161    def named_selects(self) -> t.List[str]:
1162        """Returns the output names of the query's projections."""
1163        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1165    def select(
1166        self: Q,
1167        *expressions: t.Optional[ExpOrStr],
1168        append: bool = True,
1169        dialect: DialectType = None,
1170        copy: bool = True,
1171        **opts,
1172    ) -> Q:
1173        """
1174        Append to or set the SELECT expressions.
1175
1176        Example:
1177            >>> Select().select("x", "y").sql()
1178            'SELECT x, y'
1179
1180        Args:
1181            *expressions: the SQL code strings to parse.
1182                If an `Expression` instance is passed, it will be used as-is.
1183            append: if `True`, add to any existing expressions.
1184                Otherwise, this resets the expressions.
1185            dialect: the dialect used to parse the input expressions.
1186            copy: if `False`, modify this expression instance in-place.
1187            opts: other options to use to parse the input expressions.
1188
1189        Returns:
1190            The modified Query expression.
1191        """
1192        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 with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1194    def with_(
1195        self: Q,
1196        alias: ExpOrStr,
1197        as_: ExpOrStr,
1198        recursive: t.Optional[bool] = None,
1199        append: bool = True,
1200        dialect: DialectType = None,
1201        copy: bool = True,
1202        **opts,
1203    ) -> Q:
1204        """
1205        Append to or set the common table expressions.
1206
1207        Example:
1208            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1209            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1210
1211        Args:
1212            alias: the SQL code string to parse as the table name.
1213                If an `Expression` instance is passed, this is used as-is.
1214            as_: the SQL code string to parse as the table expression.
1215                If an `Expression` instance is passed, it will be used as-is.
1216            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1217            append: if `True`, add to any existing expressions.
1218                Otherwise, this resets the expressions.
1219            dialect: the dialect used to parse the input expression.
1220            copy: if `False`, modify this expression instance in-place.
1221            opts: other options to use to parse the input expressions.
1222
1223        Returns:
1224            The modified expression.
1225        """
1226        return _apply_cte_builder(
1227            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1228        )

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.
  • 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.

def union( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1230    def union(
1231        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1232    ) -> Union:
1233        """
1234        Builds a UNION expression.
1235
1236        Example:
1237            >>> import sqlglot
1238            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1239            'SELECT * FROM foo UNION SELECT * FROM bla'
1240
1241        Args:
1242            expression: the SQL code string.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            distinct: set the DISTINCT flag if and only if this is true.
1245            dialect: the dialect used to parse the input expression.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The new Union expression.
1250        """
1251        return union(left=self, right=expression, 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:
  • expression: the SQL code string. If an Expression instance is passed, it 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, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1253    def intersect(
1254        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1255    ) -> Intersect:
1256        """
1257        Builds an INTERSECT expression.
1258
1259        Example:
1260            >>> import sqlglot
1261            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1262            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1263
1264        Args:
1265            expression: the SQL code string.
1266                If an `Expression` instance is passed, it will be used as-is.
1267            distinct: set the DISTINCT flag if and only if this is true.
1268            dialect: the dialect used to parse the input expression.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The new Intersect expression.
1273        """
1274        return intersect(left=self, right=expression, 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:
  • expression: the SQL code string. If an Expression instance is passed, it 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, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1276    def except_(
1277        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1278    ) -> Except:
1279        """
1280        Builds an EXCEPT expression.
1281
1282        Example:
1283            >>> import sqlglot
1284            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1285            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1286
1287        Args:
1288            expression: the SQL code string.
1289                If an `Expression` instance is passed, it will be used as-is.
1290            distinct: set the DISTINCT flag if and only if this is true.
1291            dialect: the dialect used to parse the input expression.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The new Except expression.
1296        """
1297        return except_(left=self, right=expression, 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:
  • expression: the SQL code string. If an Expression instance is passed, it 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):
1300class UDTF(DerivedTable):
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
selects: List[Expression]
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1307class Cache(Expression):
1308    arg_types = {
1309        "this": True,
1310        "lazy": False,
1311        "options": False,
1312        "expression": False,
1313    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1316class Uncache(Expression):
1317    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1320class Refresh(Expression):
1321    pass
key = 'refresh'
class DDL(Expression):
1324class DDL(Expression):
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []
1330
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        return self.expression.selects if isinstance(self.expression, Query) else []
1335
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []

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

selects: List[Expression]
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        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]
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        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):
1345class DML(Expression):
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> DML:
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )

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):
1382class Create(DDL):
1383    arg_types = {
1384        "with": False,
1385        "this": True,
1386        "kind": True,
1387        "expression": False,
1388        "exists": False,
1389        "properties": False,
1390        "replace": False,
1391        "unique": False,
1392        "indexes": False,
1393        "no_schema_binding": False,
1394        "begin": False,
1395        "end": False,
1396        "clone": False,
1397        "concurrently": False,
1398        "clustered": False,
1399    }
1400
1401    @property
1402    def kind(self) -> t.Optional[str]:
1403        kind = self.args.get("kind")
1404        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False, 'concurrently': False, 'clustered': False}
kind: Optional[str]
1401    @property
1402    def kind(self) -> t.Optional[str]:
1403        kind = self.args.get("kind")
1404        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1407class SequenceProperties(Expression):
1408    arg_types = {
1409        "increment": False,
1410        "minvalue": False,
1411        "maxvalue": False,
1412        "cache": False,
1413        "start": False,
1414        "owned": False,
1415        "options": False,
1416    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1419class TruncateTable(Expression):
1420    arg_types = {
1421        "expressions": True,
1422        "is_database": False,
1423        "exists": False,
1424        "only": False,
1425        "cluster": False,
1426        "identity": False,
1427        "option": False,
1428        "partition": False,
1429    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1435class Clone(Expression):
1436    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1439class Describe(Expression):
1440    arg_types = {"this": True, "style": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False}
key = 'describe'
class Summarize(Expression):
1444class Summarize(Expression):
1445    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1448class Kill(Expression):
1449    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1452class Pragma(Expression):
1453    pass
key = 'pragma'
class Declare(Expression):
1456class Declare(Expression):
1457    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1460class DeclareItem(Expression):
1461    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1464class Set(Expression):
1465    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1468class Heredoc(Expression):
1469    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1472class SetItem(Expression):
1473    arg_types = {
1474        "this": False,
1475        "expressions": False,
1476        "kind": False,
1477        "collate": False,  # MySQL SET NAMES statement
1478        "global": False,
1479    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1482class Show(Expression):
1483    arg_types = {
1484        "this": True,
1485        "history": False,
1486        "terse": False,
1487        "target": False,
1488        "offset": False,
1489        "starts_with": False,
1490        "limit": False,
1491        "from": False,
1492        "like": False,
1493        "where": False,
1494        "db": False,
1495        "scope": False,
1496        "scope_kind": False,
1497        "full": False,
1498        "mutex": False,
1499        "query": False,
1500        "channel": False,
1501        "global": False,
1502        "log": False,
1503        "position": False,
1504        "types": False,
1505    }
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}
key = 'show'
class UserDefinedFunction(Expression):
1508class UserDefinedFunction(Expression):
1509    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1512class CharacterSet(Expression):
1513    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1516class With(Expression):
1517    arg_types = {"expressions": True, "recursive": False}
1518
1519    @property
1520    def recursive(self) -> bool:
1521        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1519    @property
1520    def recursive(self) -> bool:
1521        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1524class WithinGroup(Expression):
1525    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1530class CTE(DerivedTable):
1531    arg_types = {
1532        "this": True,
1533        "alias": True,
1534        "scalar": False,
1535        "materialized": False,
1536    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1539class ProjectionDef(Expression):
1540    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1543class TableAlias(Expression):
1544    arg_types = {"this": False, "columns": False}
1545
1546    @property
1547    def columns(self):
1548        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1546    @property
1547    def columns(self):
1548        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1551class BitString(Condition):
1552    pass
key = 'bitstring'
class HexString(Condition):
1555class HexString(Condition):
1556    pass
key = 'hexstring'
class ByteString(Condition):
1559class ByteString(Condition):
1560    pass
key = 'bytestring'
class RawString(Condition):
1563class RawString(Condition):
1564    pass
key = 'rawstring'
class UnicodeString(Condition):
1567class UnicodeString(Condition):
1568    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1571class Column(Condition):
1572    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1573
1574    @property
1575    def table(self) -> str:
1576        return self.text("table")
1577
1578    @property
1579    def db(self) -> str:
1580        return self.text("db")
1581
1582    @property
1583    def catalog(self) -> str:
1584        return self.text("catalog")
1585
1586    @property
1587    def output_name(self) -> str:
1588        return self.name
1589
1590    @property
1591    def parts(self) -> t.List[Identifier]:
1592        """Return the parts of a column in order catalog, db, table, name."""
1593        return [
1594            t.cast(Identifier, self.args[part])
1595            for part in ("catalog", "db", "table", "this")
1596            if self.args.get(part)
1597        ]
1598
1599    def to_dot(self) -> Dot | Identifier:
1600        """Converts the column into a dot expression."""
1601        parts = self.parts
1602        parent = self.parent
1603
1604        while parent:
1605            if isinstance(parent, Dot):
1606                parts.append(parent.expression)
1607            parent = parent.parent
1608
1609        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
1574    @property
1575    def table(self) -> str:
1576        return self.text("table")
db: str
1578    @property
1579    def db(self) -> str:
1580        return self.text("db")
catalog: str
1582    @property
1583    def catalog(self) -> str:
1584        return self.text("catalog")
output_name: str
1586    @property
1587    def output_name(self) -> str:
1588        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]
1590    @property
1591    def parts(self) -> t.List[Identifier]:
1592        """Return the parts of a column in order catalog, db, table, name."""
1593        return [
1594            t.cast(Identifier, self.args[part])
1595            for part in ("catalog", "db", "table", "this")
1596            if self.args.get(part)
1597        ]

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

def to_dot(self) -> Dot | Identifier:
1599    def to_dot(self) -> Dot | Identifier:
1600        """Converts the column into a dot expression."""
1601        parts = self.parts
1602        parent = self.parent
1603
1604        while parent:
1605            if isinstance(parent, Dot):
1606                parts.append(parent.expression)
1607            parent = parent.parent
1608
1609        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1612class ColumnPosition(Expression):
1613    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1616class ColumnDef(Expression):
1617    arg_types = {
1618        "this": True,
1619        "kind": False,
1620        "constraints": False,
1621        "exists": False,
1622        "position": False,
1623    }
1624
1625    @property
1626    def constraints(self) -> t.List[ColumnConstraint]:
1627        return self.args.get("constraints") or []
1628
1629    @property
1630    def kind(self) -> t.Optional[DataType]:
1631        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1625    @property
1626    def constraints(self) -> t.List[ColumnConstraint]:
1627        return self.args.get("constraints") or []
kind: Optional[DataType]
1629    @property
1630    def kind(self) -> t.Optional[DataType]:
1631        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1634class AlterColumn(Expression):
1635    arg_types = {
1636        "this": True,
1637        "dtype": False,
1638        "collate": False,
1639        "using": False,
1640        "default": False,
1641        "drop": False,
1642        "comment": False,
1643        "allow_null": False,
1644    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1648class AlterDistStyle(Expression):
1649    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1652class AlterSortKey(Expression):
1653    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1656class AlterSet(Expression):
1657    arg_types = {
1658        "expressions": False,
1659        "option": False,
1660        "tablespace": False,
1661        "access_method": False,
1662        "file_format": False,
1663        "copy_options": False,
1664        "tag": False,
1665        "location": False,
1666        "serde": False,
1667    }
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):
1670class RenameColumn(Expression):
1671    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1674class RenameTable(Expression):
1675    pass
key = 'renametable'
class SwapTable(Expression):
1678class SwapTable(Expression):
1679    pass
key = 'swaptable'
class Comment(Expression):
1682class Comment(Expression):
1683    arg_types = {
1684        "this": True,
1685        "kind": True,
1686        "expression": True,
1687        "exists": False,
1688        "materialized": False,
1689    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1692class Comprehension(Expression):
1693    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):
1697class MergeTreeTTLAction(Expression):
1698    arg_types = {
1699        "this": True,
1700        "delete": False,
1701        "recompress": False,
1702        "to_disk": False,
1703        "to_volume": False,
1704    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1708class MergeTreeTTL(Expression):
1709    arg_types = {
1710        "expressions": True,
1711        "where": False,
1712        "group": False,
1713        "aggregates": False,
1714    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1718class IndexConstraintOption(Expression):
1719    arg_types = {
1720        "key_block_size": False,
1721        "using": False,
1722        "parser": False,
1723        "comment": False,
1724        "visible": False,
1725        "engine_attr": False,
1726        "secondary_engine_attr": False,
1727    }
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):
1730class ColumnConstraint(Expression):
1731    arg_types = {"this": False, "kind": True}
1732
1733    @property
1734    def kind(self) -> ColumnConstraintKind:
1735        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1733    @property
1734    def kind(self) -> ColumnConstraintKind:
1735        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1738class ColumnConstraintKind(Expression):
1739    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1742class AutoIncrementColumnConstraint(ColumnConstraintKind):
1743    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1746class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1747    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1750class CaseSpecificColumnConstraint(ColumnConstraintKind):
1751    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1754class CharacterSetColumnConstraint(ColumnConstraintKind):
1755    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1758class CheckColumnConstraint(ColumnConstraintKind):
1759    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1762class ClusteredColumnConstraint(ColumnConstraintKind):
1763    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1766class CollateColumnConstraint(ColumnConstraintKind):
1767    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1770class CommentColumnConstraint(ColumnConstraintKind):
1771    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1774class CompressColumnConstraint(ColumnConstraintKind):
1775    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1778class DateFormatColumnConstraint(ColumnConstraintKind):
1779    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1782class DefaultColumnConstraint(ColumnConstraintKind):
1783    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1786class EncodeColumnConstraint(ColumnConstraintKind):
1787    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1791class ExcludeColumnConstraint(ColumnConstraintKind):
1792    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1795class EphemeralColumnConstraint(ColumnConstraintKind):
1796    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1799class WithOperator(Expression):
1800    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1803class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1804    # this: True -> ALWAYS, this: False -> BY DEFAULT
1805    arg_types = {
1806        "this": False,
1807        "expression": False,
1808        "on_null": False,
1809        "start": False,
1810        "increment": False,
1811        "minvalue": False,
1812        "maxvalue": False,
1813        "cycle": False,
1814    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1817class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1818    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1823class IndexColumnConstraint(ColumnConstraintKind):
1824    arg_types = {
1825        "this": False,
1826        "expressions": False,
1827        "kind": False,
1828        "index_type": False,
1829        "options": False,
1830        "expression": False,  # Clickhouse
1831        "granularity": False,
1832    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1835class InlineLengthColumnConstraint(ColumnConstraintKind):
1836    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1839class NonClusteredColumnConstraint(ColumnConstraintKind):
1840    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1843class NotForReplicationColumnConstraint(ColumnConstraintKind):
1844    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1848class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1849    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1852class NotNullColumnConstraint(ColumnConstraintKind):
1853    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1857class OnUpdateColumnConstraint(ColumnConstraintKind):
1858    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1862class TagColumnConstraint(ColumnConstraintKind):
1863    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1867class TransformColumnConstraint(ColumnConstraintKind):
1868    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1871class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1872    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1875class TitleColumnConstraint(ColumnConstraintKind):
1876    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1879class UniqueColumnConstraint(ColumnConstraintKind):
1880    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1883class UppercaseColumnConstraint(ColumnConstraintKind):
1884    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1887class PathColumnConstraint(ColumnConstraintKind):
1888    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1892class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1893    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1898class ComputedColumnConstraint(ColumnConstraintKind):
1899    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1902class Constraint(Expression):
1903    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1906class Delete(DML):
1907    arg_types = {
1908        "with": False,
1909        "this": False,
1910        "using": False,
1911        "where": False,
1912        "returning": False,
1913        "limit": False,
1914        "tables": False,  # Multiple-Table Syntax (MySQL)
1915    }
1916
1917    def delete(
1918        self,
1919        table: ExpOrStr,
1920        dialect: DialectType = None,
1921        copy: bool = True,
1922        **opts,
1923    ) -> Delete:
1924        """
1925        Create a DELETE expression or replace the table on an existing DELETE expression.
1926
1927        Example:
1928            >>> delete("tbl").sql()
1929            'DELETE FROM tbl'
1930
1931        Args:
1932            table: the table from which to delete.
1933            dialect: the dialect used to parse the input expression.
1934            copy: if `False`, modify this expression instance in-place.
1935            opts: other options to use to parse the input expressions.
1936
1937        Returns:
1938            Delete: the modified expression.
1939        """
1940        return _apply_builder(
1941            expression=table,
1942            instance=self,
1943            arg="this",
1944            dialect=dialect,
1945            into=Table,
1946            copy=copy,
1947            **opts,
1948        )
1949
1950    def where(
1951        self,
1952        *expressions: t.Optional[ExpOrStr],
1953        append: bool = True,
1954        dialect: DialectType = None,
1955        copy: bool = True,
1956        **opts,
1957    ) -> Delete:
1958        """
1959        Append to or set the WHERE expressions.
1960
1961        Example:
1962            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1963            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1964
1965        Args:
1966            *expressions: the SQL code strings to parse.
1967                If an `Expression` instance is passed, it will be used as-is.
1968                Multiple expressions are combined with an AND operator.
1969            append: if `True`, AND the new expressions to any existing expression.
1970                Otherwise, this resets the expression.
1971            dialect: the dialect used to parse the input expressions.
1972            copy: if `False`, modify this expression instance in-place.
1973            opts: other options to use to parse the input expressions.
1974
1975        Returns:
1976            Delete: the modified expression.
1977        """
1978        return _apply_conjunction_builder(
1979            *expressions,
1980            instance=self,
1981            arg="where",
1982            append=append,
1983            into=Where,
1984            dialect=dialect,
1985            copy=copy,
1986            **opts,
1987        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1917    def delete(
1918        self,
1919        table: ExpOrStr,
1920        dialect: DialectType = None,
1921        copy: bool = True,
1922        **opts,
1923    ) -> Delete:
1924        """
1925        Create a DELETE expression or replace the table on an existing DELETE expression.
1926
1927        Example:
1928            >>> delete("tbl").sql()
1929            'DELETE FROM tbl'
1930
1931        Args:
1932            table: the table from which to delete.
1933            dialect: the dialect used to parse the input expression.
1934            copy: if `False`, modify this expression instance in-place.
1935            opts: other options to use to parse the input expressions.
1936
1937        Returns:
1938            Delete: the modified expression.
1939        """
1940        return _apply_builder(
1941            expression=table,
1942            instance=self,
1943            arg="this",
1944            dialect=dialect,
1945            into=Table,
1946            copy=copy,
1947            **opts,
1948        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1950    def where(
1951        self,
1952        *expressions: t.Optional[ExpOrStr],
1953        append: bool = True,
1954        dialect: DialectType = None,
1955        copy: bool = True,
1956        **opts,
1957    ) -> Delete:
1958        """
1959        Append to or set the WHERE expressions.
1960
1961        Example:
1962            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1963            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1964
1965        Args:
1966            *expressions: the SQL code strings to parse.
1967                If an `Expression` instance is passed, it will be used as-is.
1968                Multiple expressions are combined with an AND operator.
1969            append: if `True`, AND the new expressions to any existing expression.
1970                Otherwise, this resets the expression.
1971            dialect: the dialect used to parse the input expressions.
1972            copy: if `False`, modify this expression instance in-place.
1973            opts: other options to use to parse the input expressions.
1974
1975        Returns:
1976            Delete: the modified expression.
1977        """
1978        return _apply_conjunction_builder(
1979            *expressions,
1980            instance=self,
1981            arg="where",
1982            append=append,
1983            into=Where,
1984            dialect=dialect,
1985            copy=copy,
1986            **opts,
1987        )

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):
1990class Drop(Expression):
1991    arg_types = {
1992        "this": False,
1993        "kind": False,
1994        "expressions": False,
1995        "exists": False,
1996        "temporary": False,
1997        "materialized": False,
1998        "cascade": False,
1999        "constraints": False,
2000        "purge": False,
2001        "cluster": False,
2002    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
key = 'drop'
class Filter(Expression):
2005class Filter(Expression):
2006    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2009class Check(Expression):
2010    pass
key = 'check'
class Changes(Expression):
2013class Changes(Expression):
2014    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2018class Connect(Expression):
2019    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2022class CopyParameter(Expression):
2023    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2026class Copy(DML):
2027    arg_types = {
2028        "this": True,
2029        "kind": True,
2030        "files": True,
2031        "credentials": False,
2032        "format": False,
2033        "params": False,
2034    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2037class Credentials(Expression):
2038    arg_types = {
2039        "credentials": False,
2040        "encryption": False,
2041        "storage": False,
2042        "iam_role": False,
2043        "region": False,
2044    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2047class Prior(Expression):
2048    pass
key = 'prior'
class Directory(Expression):
2051class Directory(Expression):
2052    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2053    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2056class ForeignKey(Expression):
2057    arg_types = {
2058        "expressions": True,
2059        "reference": False,
2060        "delete": False,
2061        "update": False,
2062    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2065class ColumnPrefix(Expression):
2066    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2069class PrimaryKey(Expression):
2070    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2075class Into(Expression):
2076    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2079class From(Expression):
2080    @property
2081    def name(self) -> str:
2082        return self.this.name
2083
2084    @property
2085    def alias_or_name(self) -> str:
2086        return self.this.alias_or_name
name: str
2080    @property
2081    def name(self) -> str:
2082        return self.this.name
alias_or_name: str
2084    @property
2085    def alias_or_name(self) -> str:
2086        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2089class Having(Expression):
2090    pass
key = 'having'
class Hint(Expression):
2093class Hint(Expression):
2094    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2097class JoinHint(Expression):
2098    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2101class Identifier(Expression):
2102    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2103
2104    @property
2105    def quoted(self) -> bool:
2106        return bool(self.args.get("quoted"))
2107
2108    @property
2109    def hashable_args(self) -> t.Any:
2110        return (self.this, self.quoted)
2111
2112    @property
2113    def output_name(self) -> str:
2114        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2104    @property
2105    def quoted(self) -> bool:
2106        return bool(self.args.get("quoted"))
hashable_args: Any
2108    @property
2109    def hashable_args(self) -> t.Any:
2110        return (self.this, self.quoted)
output_name: str
2112    @property
2113    def output_name(self) -> str:
2114        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):
2118class Opclass(Expression):
2119    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2122class Index(Expression):
2123    arg_types = {
2124        "this": False,
2125        "table": False,
2126        "unique": False,
2127        "primary": False,
2128        "amp": False,  # teradata
2129        "params": False,
2130    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2133class IndexParameters(Expression):
2134    arg_types = {
2135        "using": False,
2136        "include": False,
2137        "columns": False,
2138        "with_storage": False,
2139        "partition_by": False,
2140        "tablespace": False,
2141        "where": False,
2142        "on": False,
2143    }
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):
2146class Insert(DDL, DML):
2147    arg_types = {
2148        "hint": False,
2149        "with": False,
2150        "is_function": False,
2151        "this": False,
2152        "expression": False,
2153        "conflict": False,
2154        "returning": False,
2155        "overwrite": False,
2156        "exists": False,
2157        "alternative": False,
2158        "where": False,
2159        "ignore": False,
2160        "by_name": False,
2161        "stored": False,
2162    }
2163
2164    def with_(
2165        self,
2166        alias: ExpOrStr,
2167        as_: ExpOrStr,
2168        recursive: t.Optional[bool] = None,
2169        append: bool = True,
2170        dialect: DialectType = None,
2171        copy: bool = True,
2172        **opts,
2173    ) -> Insert:
2174        """
2175        Append to or set the common table expressions.
2176
2177        Example:
2178            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2179            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2180
2181        Args:
2182            alias: the SQL code string to parse as the table name.
2183                If an `Expression` instance is passed, this is used as-is.
2184            as_: the SQL code string to parse as the table expression.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2187            append: if `True`, add to any existing expressions.
2188                Otherwise, this resets the expressions.
2189            dialect: the dialect used to parse the input expression.
2190            copy: if `False`, modify this expression instance in-place.
2191            opts: other options to use to parse the input expressions.
2192
2193        Returns:
2194            The modified expression.
2195        """
2196        return _apply_cte_builder(
2197            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2198        )
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}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2164    def with_(
2165        self,
2166        alias: ExpOrStr,
2167        as_: ExpOrStr,
2168        recursive: t.Optional[bool] = None,
2169        append: bool = True,
2170        dialect: DialectType = None,
2171        copy: bool = True,
2172        **opts,
2173    ) -> Insert:
2174        """
2175        Append to or set the common table expressions.
2176
2177        Example:
2178            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2179            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2180
2181        Args:
2182            alias: the SQL code string to parse as the table name.
2183                If an `Expression` instance is passed, this is used as-is.
2184            as_: the SQL code string to parse as the table expression.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2187            append: if `True`, add to any existing expressions.
2188                Otherwise, this resets the expressions.
2189            dialect: the dialect used to parse the input expression.
2190            copy: if `False`, modify this expression instance in-place.
2191            opts: other options to use to parse the input expressions.
2192
2193        Returns:
2194            The modified expression.
2195        """
2196        return _apply_cte_builder(
2197            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2198        )

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.
  • 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 OnConflict(Expression):
2201class OnConflict(Expression):
2202    arg_types = {
2203        "duplicate": False,
2204        "expressions": False,
2205        "action": False,
2206        "conflict_keys": False,
2207        "constraint": False,
2208    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2211class Returning(Expression):
2212    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2216class Introducer(Expression):
2217    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2221class National(Expression):
2222    pass
key = 'national'
class LoadData(Expression):
2225class LoadData(Expression):
2226    arg_types = {
2227        "this": True,
2228        "local": False,
2229        "overwrite": False,
2230        "inpath": True,
2231        "partition": False,
2232        "input_format": False,
2233        "serde": False,
2234    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2237class Partition(Expression):
2238    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2241class PartitionRange(Expression):
2242    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2246class PartitionId(Expression):
2247    pass
key = 'partitionid'
class Fetch(Expression):
2250class Fetch(Expression):
2251    arg_types = {
2252        "direction": False,
2253        "count": False,
2254        "percent": False,
2255        "with_ties": False,
2256    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2259class Group(Expression):
2260    arg_types = {
2261        "expressions": False,
2262        "grouping_sets": False,
2263        "cube": False,
2264        "rollup": False,
2265        "totals": False,
2266        "all": False,
2267    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2270class Lambda(Expression):
2271    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2274class Limit(Expression):
2275    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2278class Literal(Condition):
2279    arg_types = {"this": True, "is_string": True}
2280
2281    @property
2282    def hashable_args(self) -> t.Any:
2283        return (self.this, self.args.get("is_string"))
2284
2285    @classmethod
2286    def number(cls, number) -> Literal:
2287        return cls(this=str(number), is_string=False)
2288
2289    @classmethod
2290    def string(cls, string) -> Literal:
2291        return cls(this=str(string), is_string=True)
2292
2293    @property
2294    def output_name(self) -> str:
2295        return self.name
2296
2297    def to_py(self) -> int | str | Decimal:
2298        if self.is_number:
2299            try:
2300                return int(self.this)
2301            except ValueError:
2302                return Decimal(self.this)
2303        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2281    @property
2282    def hashable_args(self) -> t.Any:
2283        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2285    @classmethod
2286    def number(cls, number) -> Literal:
2287        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2289    @classmethod
2290    def string(cls, string) -> Literal:
2291        return cls(this=str(string), is_string=True)
output_name: str
2293    @property
2294    def output_name(self) -> str:
2295        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:
2297    def to_py(self) -> int | str | Decimal:
2298        if self.is_number:
2299            try:
2300                return int(self.this)
2301            except ValueError:
2302                return Decimal(self.this)
2303        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2306class Join(Expression):
2307    arg_types = {
2308        "this": True,
2309        "on": False,
2310        "side": False,
2311        "kind": False,
2312        "using": False,
2313        "method": False,
2314        "global": False,
2315        "hint": False,
2316        "match_condition": False,  # Snowflake
2317    }
2318
2319    @property
2320    def method(self) -> str:
2321        return self.text("method").upper()
2322
2323    @property
2324    def kind(self) -> str:
2325        return self.text("kind").upper()
2326
2327    @property
2328    def side(self) -> str:
2329        return self.text("side").upper()
2330
2331    @property
2332    def hint(self) -> str:
2333        return self.text("hint").upper()
2334
2335    @property
2336    def alias_or_name(self) -> str:
2337        return self.this.alias_or_name
2338
2339    def on(
2340        self,
2341        *expressions: t.Optional[ExpOrStr],
2342        append: bool = True,
2343        dialect: DialectType = None,
2344        copy: bool = True,
2345        **opts,
2346    ) -> Join:
2347        """
2348        Append to or set the ON expressions.
2349
2350        Example:
2351            >>> import sqlglot
2352            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2353            'JOIN x ON y = 1'
2354
2355        Args:
2356            *expressions: the SQL code strings to parse.
2357                If an `Expression` instance is passed, it will be used as-is.
2358                Multiple expressions are combined with an AND operator.
2359            append: if `True`, AND the new expressions to any existing expression.
2360                Otherwise, this resets the expression.
2361            dialect: the dialect used to parse the input expressions.
2362            copy: if `False`, modify this expression instance in-place.
2363            opts: other options to use to parse the input expressions.
2364
2365        Returns:
2366            The modified Join expression.
2367        """
2368        join = _apply_conjunction_builder(
2369            *expressions,
2370            instance=self,
2371            arg="on",
2372            append=append,
2373            dialect=dialect,
2374            copy=copy,
2375            **opts,
2376        )
2377
2378        if join.kind == "CROSS":
2379            join.set("kind", None)
2380
2381        return join
2382
2383    def using(
2384        self,
2385        *expressions: t.Optional[ExpOrStr],
2386        append: bool = True,
2387        dialect: DialectType = None,
2388        copy: bool = True,
2389        **opts,
2390    ) -> Join:
2391        """
2392        Append to or set the USING expressions.
2393
2394        Example:
2395            >>> import sqlglot
2396            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2397            'JOIN x USING (foo, bla)'
2398
2399        Args:
2400            *expressions: the SQL code strings to parse.
2401                If an `Expression` instance is passed, it will be used as-is.
2402            append: if `True`, concatenate the new expressions to the existing "using" list.
2403                Otherwise, this resets the expression.
2404            dialect: the dialect used to parse the input expressions.
2405            copy: if `False`, modify this expression instance in-place.
2406            opts: other options to use to parse the input expressions.
2407
2408        Returns:
2409            The modified Join expression.
2410        """
2411        join = _apply_list_builder(
2412            *expressions,
2413            instance=self,
2414            arg="using",
2415            append=append,
2416            dialect=dialect,
2417            copy=copy,
2418            **opts,
2419        )
2420
2421        if join.kind == "CROSS":
2422            join.set("kind", None)
2423
2424        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False}
method: str
2319    @property
2320    def method(self) -> str:
2321        return self.text("method").upper()
kind: str
2323    @property
2324    def kind(self) -> str:
2325        return self.text("kind").upper()
side: str
2327    @property
2328    def side(self) -> str:
2329        return self.text("side").upper()
hint: str
2331    @property
2332    def hint(self) -> str:
2333        return self.text("hint").upper()
alias_or_name: str
2335    @property
2336    def alias_or_name(self) -> str:
2337        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2339    def on(
2340        self,
2341        *expressions: t.Optional[ExpOrStr],
2342        append: bool = True,
2343        dialect: DialectType = None,
2344        copy: bool = True,
2345        **opts,
2346    ) -> Join:
2347        """
2348        Append to or set the ON expressions.
2349
2350        Example:
2351            >>> import sqlglot
2352            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2353            'JOIN x ON y = 1'
2354
2355        Args:
2356            *expressions: the SQL code strings to parse.
2357                If an `Expression` instance is passed, it will be used as-is.
2358                Multiple expressions are combined with an AND operator.
2359            append: if `True`, AND the new expressions to any existing expression.
2360                Otherwise, this resets the expression.
2361            dialect: the dialect used to parse the input expressions.
2362            copy: if `False`, modify this expression instance in-place.
2363            opts: other options to use to parse the input expressions.
2364
2365        Returns:
2366            The modified Join expression.
2367        """
2368        join = _apply_conjunction_builder(
2369            *expressions,
2370            instance=self,
2371            arg="on",
2372            append=append,
2373            dialect=dialect,
2374            copy=copy,
2375            **opts,
2376        )
2377
2378        if join.kind == "CROSS":
2379            join.set("kind", None)
2380
2381        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2383    def using(
2384        self,
2385        *expressions: t.Optional[ExpOrStr],
2386        append: bool = True,
2387        dialect: DialectType = None,
2388        copy: bool = True,
2389        **opts,
2390    ) -> Join:
2391        """
2392        Append to or set the USING expressions.
2393
2394        Example:
2395            >>> import sqlglot
2396            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2397            'JOIN x USING (foo, bla)'
2398
2399        Args:
2400            *expressions: the SQL code strings to parse.
2401                If an `Expression` instance is passed, it will be used as-is.
2402            append: if `True`, concatenate the new expressions to the existing "using" list.
2403                Otherwise, this resets the expression.
2404            dialect: the dialect used to parse the input expressions.
2405            copy: if `False`, modify this expression instance in-place.
2406            opts: other options to use to parse the input expressions.
2407
2408        Returns:
2409            The modified Join expression.
2410        """
2411        join = _apply_list_builder(
2412            *expressions,
2413            instance=self,
2414            arg="using",
2415            append=append,
2416            dialect=dialect,
2417            copy=copy,
2418            **opts,
2419        )
2420
2421        if join.kind == "CROSS":
2422            join.set("kind", None)
2423
2424        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):
2427class Lateral(UDTF):
2428    arg_types = {
2429        "this": True,
2430        "view": False,
2431        "outer": False,
2432        "alias": False,
2433        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2434    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2437class MatchRecognizeMeasure(Expression):
2438    arg_types = {
2439        "this": True,
2440        "window_frame": False,
2441    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2444class MatchRecognize(Expression):
2445    arg_types = {
2446        "partition_by": False,
2447        "order": False,
2448        "measures": False,
2449        "rows": False,
2450        "after": False,
2451        "pattern": False,
2452        "define": False,
2453        "alias": False,
2454    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2459class Final(Expression):
2460    pass
key = 'final'
class Offset(Expression):
2463class Offset(Expression):
2464    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2467class Order(Expression):
2468    arg_types = {
2469        "this": False,
2470        "expressions": True,
2471        "interpolate": False,
2472        "siblings": False,
2473    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2477class WithFill(Expression):
2478    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2483class Cluster(Order):
2484    pass
key = 'cluster'
class Distribute(Order):
2487class Distribute(Order):
2488    pass
key = 'distribute'
class Sort(Order):
2491class Sort(Order):
2492    pass
key = 'sort'
class Ordered(Expression):
2495class Ordered(Expression):
2496    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2499class Property(Expression):
2500    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2503class AllowedValuesProperty(Expression):
2504    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2507class AlgorithmProperty(Property):
2508    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2511class AutoIncrementProperty(Property):
2512    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2516class AutoRefreshProperty(Property):
2517    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2520class BackupProperty(Property):
2521    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2524class BlockCompressionProperty(Property):
2525    arg_types = {
2526        "autotemp": False,
2527        "always": False,
2528        "default": False,
2529        "manual": False,
2530        "never": False,
2531    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2534class CharacterSetProperty(Property):
2535    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2538class ChecksumProperty(Property):
2539    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2542class CollateProperty(Property):
2543    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2546class CopyGrantsProperty(Property):
2547    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2550class DataBlocksizeProperty(Property):
2551    arg_types = {
2552        "size": False,
2553        "units": False,
2554        "minimum": False,
2555        "maximum": False,
2556        "default": False,
2557    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2560class DataDeletionProperty(Property):
2561    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):
2564class DefinerProperty(Property):
2565    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2568class DistKeyProperty(Property):
2569    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2572class DistStyleProperty(Property):
2573    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2576class EngineProperty(Property):
2577    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2580class HeapProperty(Property):
2581    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2584class ToTableProperty(Property):
2585    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2588class ExecuteAsProperty(Property):
2589    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2592class ExternalProperty(Property):
2593    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2596class FallbackProperty(Property):
2597    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2600class FileFormatProperty(Property):
2601    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2604class FreespaceProperty(Property):
2605    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2608class GlobalProperty(Property):
2609    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2612class IcebergProperty(Property):
2613    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2616class InheritsProperty(Property):
2617    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2620class InputModelProperty(Property):
2621    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2624class OutputModelProperty(Property):
2625    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2628class IsolatedLoadingProperty(Property):
2629    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2632class JournalProperty(Property):
2633    arg_types = {
2634        "no": False,
2635        "dual": False,
2636        "before": False,
2637        "local": False,
2638        "after": False,
2639    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2642class LanguageProperty(Property):
2643    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2647class ClusteredByProperty(Property):
2648    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2651class DictProperty(Property):
2652    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2655class DictSubProperty(Property):
2656    pass
key = 'dictsubproperty'
class DictRange(Property):
2659class DictRange(Property):
2660    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2663class DynamicProperty(Property):
2664    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2669class OnCluster(Property):
2670    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2673class LikeProperty(Property):
2674    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2677class LocationProperty(Property):
2678    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2681class LockProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2685class LockingProperty(Property):
2686    arg_types = {
2687        "this": False,
2688        "kind": True,
2689        "for_or_in": False,
2690        "lock_type": True,
2691        "override": False,
2692    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2695class LogProperty(Property):
2696    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2699class MaterializedProperty(Property):
2700    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2703class MergeBlockRatioProperty(Property):
2704    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):
2707class NoPrimaryIndexProperty(Property):
2708    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2711class OnProperty(Property):
2712    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2715class OnCommitProperty(Property):
2716    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2719class PartitionedByProperty(Property):
2720    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2724class PartitionBoundSpec(Expression):
2725    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2726    arg_types = {
2727        "this": False,
2728        "expression": False,
2729        "from_expressions": False,
2730        "to_expressions": False,
2731    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2734class PartitionedOfProperty(Property):
2735    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2736    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2739class RemoteWithConnectionModelProperty(Property):
2740    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2743class ReturnsProperty(Property):
2744    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):
2747class StrictProperty(Property):
2748    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2751class RowFormatProperty(Property):
2752    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2755class RowFormatDelimitedProperty(Property):
2756    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2757    arg_types = {
2758        "fields": False,
2759        "escaped": False,
2760        "collection_items": False,
2761        "map_keys": False,
2762        "lines": False,
2763        "null": False,
2764        "serde": False,
2765    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2768class RowFormatSerdeProperty(Property):
2769    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2773class QueryTransform(Expression):
2774    arg_types = {
2775        "expressions": True,
2776        "command_script": True,
2777        "schema": False,
2778        "row_format_before": False,
2779        "record_writer": False,
2780        "row_format_after": False,
2781        "record_reader": False,
2782    }
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):
2785class SampleProperty(Property):
2786    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2789class SchemaCommentProperty(Property):
2790    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2793class SerdeProperties(Property):
2794    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2797class SetProperty(Property):
2798    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2801class SharingProperty(Property):
2802    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2805class SetConfigProperty(Property):
2806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2809class SettingsProperty(Property):
2810    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2813class SortKeyProperty(Property):
2814    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2817class SqlReadWriteProperty(Property):
2818    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2821class SqlSecurityProperty(Property):
2822    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2825class StabilityProperty(Property):
2826    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2829class TemporaryProperty(Property):
2830    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2833class SecureProperty(Property):
2834    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2837class TransformModelProperty(Property):
2838    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2841class TransientProperty(Property):
2842    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2845class UnloggedProperty(Property):
2846    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2850class ViewAttributeProperty(Property):
2851    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2854class VolatileProperty(Property):
2855    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2858class WithDataProperty(Property):
2859    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2862class WithJournalTableProperty(Property):
2863    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2866class WithSchemaBindingProperty(Property):
2867    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2870class WithSystemVersioningProperty(Property):
2871    arg_types = {
2872        "on": False,
2873        "this": False,
2874        "data_consistency": False,
2875        "retention_period": False,
2876        "with": True,
2877    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2880class Properties(Expression):
2881    arg_types = {"expressions": True}
2882
2883    NAME_TO_PROPERTY = {
2884        "ALGORITHM": AlgorithmProperty,
2885        "AUTO_INCREMENT": AutoIncrementProperty,
2886        "CHARACTER SET": CharacterSetProperty,
2887        "CLUSTERED_BY": ClusteredByProperty,
2888        "COLLATE": CollateProperty,
2889        "COMMENT": SchemaCommentProperty,
2890        "DEFINER": DefinerProperty,
2891        "DISTKEY": DistKeyProperty,
2892        "DISTSTYLE": DistStyleProperty,
2893        "ENGINE": EngineProperty,
2894        "EXECUTE AS": ExecuteAsProperty,
2895        "FORMAT": FileFormatProperty,
2896        "LANGUAGE": LanguageProperty,
2897        "LOCATION": LocationProperty,
2898        "LOCK": LockProperty,
2899        "PARTITIONED_BY": PartitionedByProperty,
2900        "RETURNS": ReturnsProperty,
2901        "ROW_FORMAT": RowFormatProperty,
2902        "SORTKEY": SortKeyProperty,
2903    }
2904
2905    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2906
2907    # CREATE property locations
2908    # Form: schema specified
2909    #   create [POST_CREATE]
2910    #     table a [POST_NAME]
2911    #     (b int) [POST_SCHEMA]
2912    #     with ([POST_WITH])
2913    #     index (b) [POST_INDEX]
2914    #
2915    # Form: alias selection
2916    #   create [POST_CREATE]
2917    #     table a [POST_NAME]
2918    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2919    #     index (c) [POST_INDEX]
2920    class Location(AutoName):
2921        POST_CREATE = auto()
2922        POST_NAME = auto()
2923        POST_SCHEMA = auto()
2924        POST_WITH = auto()
2925        POST_ALIAS = auto()
2926        POST_EXPRESSION = auto()
2927        POST_INDEX = auto()
2928        UNSUPPORTED = auto()
2929
2930    @classmethod
2931    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2932        expressions = []
2933        for key, value in properties_dict.items():
2934            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2935            if property_cls:
2936                expressions.append(property_cls(this=convert(value)))
2937            else:
2938                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2939
2940        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'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, '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'>}
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 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <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'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2930    @classmethod
2931    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2932        expressions = []
2933        for key, value in properties_dict.items():
2934            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2935            if property_cls:
2936                expressions.append(property_cls(this=convert(value)))
2937            else:
2938                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2939
2940        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2920    class Location(AutoName):
2921        POST_CREATE = auto()
2922        POST_NAME = auto()
2923        POST_SCHEMA = auto()
2924        POST_WITH = auto()
2925        POST_ALIAS = auto()
2926        POST_EXPRESSION = auto()
2927        POST_INDEX = auto()
2928        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'>
Inherited Members
enum.Enum
name
value
class Qualify(Expression):
2943class Qualify(Expression):
2944    pass
key = 'qualify'
class InputOutputFormat(Expression):
2947class InputOutputFormat(Expression):
2948    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2952class Return(Expression):
2953    pass
key = 'return'
class Reference(Expression):
2956class Reference(Expression):
2957    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2960class Tuple(Expression):
2961    arg_types = {"expressions": False}
2962
2963    def isin(
2964        self,
2965        *expressions: t.Any,
2966        query: t.Optional[ExpOrStr] = None,
2967        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2968        copy: bool = True,
2969        **opts,
2970    ) -> In:
2971        return In(
2972            this=maybe_copy(self, copy),
2973            expressions=[convert(e, copy=copy) for e in expressions],
2974            query=maybe_parse(query, copy=copy, **opts) if query else None,
2975            unnest=(
2976                Unnest(
2977                    expressions=[
2978                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2979                        for e in ensure_list(unnest)
2980                    ]
2981                )
2982                if unnest
2983                else None
2984            ),
2985        )
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:
2963    def isin(
2964        self,
2965        *expressions: t.Any,
2966        query: t.Optional[ExpOrStr] = None,
2967        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2968        copy: bool = True,
2969        **opts,
2970    ) -> In:
2971        return In(
2972            this=maybe_copy(self, copy),
2973            expressions=[convert(e, copy=copy) for e in expressions],
2974            query=maybe_parse(query, copy=copy, **opts) if query else None,
2975            unnest=(
2976                Unnest(
2977                    expressions=[
2978                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2979                        for e in ensure_list(unnest)
2980                    ]
2981                )
2982                if unnest
2983                else None
2984            ),
2985        )
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):
3016class QueryOption(Expression):
3017    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3021class WithTableHint(Expression):
3022    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3026class IndexTableHint(Expression):
3027    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3031class HistoricalData(Expression):
3032    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3035class Table(Expression):
3036    arg_types = {
3037        "this": False,
3038        "alias": False,
3039        "db": False,
3040        "catalog": False,
3041        "laterals": False,
3042        "joins": False,
3043        "pivots": False,
3044        "hints": False,
3045        "system_time": False,
3046        "version": False,
3047        "format": False,
3048        "pattern": False,
3049        "ordinality": False,
3050        "when": False,
3051        "only": False,
3052        "partition": False,
3053        "changes": False,
3054        "rows_from": False,
3055    }
3056
3057    @property
3058    def name(self) -> str:
3059        if isinstance(self.this, Func):
3060            return ""
3061        return self.this.name
3062
3063    @property
3064    def db(self) -> str:
3065        return self.text("db")
3066
3067    @property
3068    def catalog(self) -> str:
3069        return self.text("catalog")
3070
3071    @property
3072    def selects(self) -> t.List[Expression]:
3073        return []
3074
3075    @property
3076    def named_selects(self) -> t.List[str]:
3077        return []
3078
3079    @property
3080    def parts(self) -> t.List[Expression]:
3081        """Return the parts of a table in order catalog, db, table."""
3082        parts: t.List[Expression] = []
3083
3084        for arg in ("catalog", "db", "this"):
3085            part = self.args.get(arg)
3086
3087            if isinstance(part, Dot):
3088                parts.extend(part.flatten())
3089            elif isinstance(part, Expression):
3090                parts.append(part)
3091
3092        return parts
3093
3094    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3095        parts = self.parts
3096        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3097        alias = self.args.get("alias")
3098        if alias:
3099            col = alias_(col, alias.this, copy=copy)
3100        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}
name: str
3057    @property
3058    def name(self) -> str:
3059        if isinstance(self.this, Func):
3060            return ""
3061        return self.this.name
db: str
3063    @property
3064    def db(self) -> str:
3065        return self.text("db")
catalog: str
3067    @property
3068    def catalog(self) -> str:
3069        return self.text("catalog")
selects: List[Expression]
3071    @property
3072    def selects(self) -> t.List[Expression]:
3073        return []
named_selects: List[str]
3075    @property
3076    def named_selects(self) -> t.List[str]:
3077        return []
parts: List[Expression]
3079    @property
3080    def parts(self) -> t.List[Expression]:
3081        """Return the parts of a table in order catalog, db, table."""
3082        parts: t.List[Expression] = []
3083
3084        for arg in ("catalog", "db", "this"):
3085            part = self.args.get(arg)
3086
3087            if isinstance(part, Dot):
3088                parts.extend(part.flatten())
3089            elif isinstance(part, Expression):
3090                parts.append(part)
3091
3092        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3094    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3095        parts = self.parts
3096        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3097        alias = self.args.get("alias")
3098        if alias:
3099            col = alias_(col, alias.this, copy=copy)
3100        return col
key = 'table'
class SetOperation(Query):
3103class SetOperation(Query):
3104    arg_types = {
3105        "with": False,
3106        "this": True,
3107        "expression": True,
3108        "distinct": False,
3109        "by_name": False,
3110        **QUERY_MODIFIERS,
3111    }
3112
3113    def select(
3114        self: S,
3115        *expressions: t.Optional[ExpOrStr],
3116        append: bool = True,
3117        dialect: DialectType = None,
3118        copy: bool = True,
3119        **opts,
3120    ) -> S:
3121        this = maybe_copy(self, copy)
3122        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3123        this.expression.unnest().select(
3124            *expressions, append=append, dialect=dialect, copy=False, **opts
3125        )
3126        return this
3127
3128    @property
3129    def named_selects(self) -> t.List[str]:
3130        return self.this.unnest().named_selects
3131
3132    @property
3133    def is_star(self) -> bool:
3134        return self.this.is_star or self.expression.is_star
3135
3136    @property
3137    def selects(self) -> t.List[Expression]:
3138        return self.this.unnest().selects
3139
3140    @property
3141    def left(self) -> Expression:
3142        return self.this
3143
3144    @property
3145    def right(self) -> Expression:
3146        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3113    def select(
3114        self: S,
3115        *expressions: t.Optional[ExpOrStr],
3116        append: bool = True,
3117        dialect: DialectType = None,
3118        copy: bool = True,
3119        **opts,
3120    ) -> S:
3121        this = maybe_copy(self, copy)
3122        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3123        this.expression.unnest().select(
3124            *expressions, append=append, dialect=dialect, copy=False, **opts
3125        )
3126        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]
3128    @property
3129    def named_selects(self) -> t.List[str]:
3130        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3132    @property
3133    def is_star(self) -> bool:
3134        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3136    @property
3137    def selects(self) -> t.List[Expression]:
3138        return self.this.unnest().selects

Returns the query's projections.

left: Expression
3140    @property
3141    def left(self) -> Expression:
3142        return self.this
right: Expression
3144    @property
3145    def right(self) -> Expression:
3146        return self.expression
key = 'setoperation'
class Union(SetOperation):
3149class Union(SetOperation):
3150    pass
key = 'union'
class Except(SetOperation):
3153class Except(SetOperation):
3154    pass
key = 'except'
class Intersect(SetOperation):
3157class Intersect(SetOperation):
3158    pass
key = 'intersect'
class Update(Expression):
3161class Update(Expression):
3162    arg_types = {
3163        "with": False,
3164        "this": False,
3165        "expressions": True,
3166        "from": False,
3167        "where": False,
3168        "returning": False,
3169        "order": False,
3170        "limit": False,
3171    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
3174class Values(UDTF):
3175    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3178class Var(Expression):
3179    pass
key = 'var'
class Version(Expression):
3182class Version(Expression):
3183    """
3184    Time travel, iceberg, bigquery etc
3185    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3186    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3187    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3188    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3189    this is either TIMESTAMP or VERSION
3190    kind is ("AS OF", "BETWEEN")
3191    """
3192
3193    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3196class Schema(Expression):
3197    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3202class Lock(Expression):
3203    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3206class Select(Query):
3207    arg_types = {
3208        "with": False,
3209        "kind": False,
3210        "expressions": False,
3211        "hint": False,
3212        "distinct": False,
3213        "into": False,
3214        "from": False,
3215        **QUERY_MODIFIERS,
3216    }
3217
3218    def from_(
3219        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3220    ) -> Select:
3221        """
3222        Set the FROM expression.
3223
3224        Example:
3225            >>> Select().from_("tbl").select("x").sql()
3226            'SELECT x FROM tbl'
3227
3228        Args:
3229            expression : the SQL code strings to parse.
3230                If a `From` instance is passed, this is used as-is.
3231                If another `Expression` instance is passed, it will be wrapped in a `From`.
3232            dialect: the dialect used to parse the input expression.
3233            copy: if `False`, modify this expression instance in-place.
3234            opts: other options to use to parse the input expressions.
3235
3236        Returns:
3237            The modified Select expression.
3238        """
3239        return _apply_builder(
3240            expression=expression,
3241            instance=self,
3242            arg="from",
3243            into=From,
3244            prefix="FROM",
3245            dialect=dialect,
3246            copy=copy,
3247            **opts,
3248        )
3249
3250    def group_by(
3251        self,
3252        *expressions: t.Optional[ExpOrStr],
3253        append: bool = True,
3254        dialect: DialectType = None,
3255        copy: bool = True,
3256        **opts,
3257    ) -> Select:
3258        """
3259        Set the GROUP BY expression.
3260
3261        Example:
3262            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3263            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3264
3265        Args:
3266            *expressions: the SQL code strings to parse.
3267                If a `Group` instance is passed, this is used as-is.
3268                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3269                If nothing is passed in then a group by is not applied to the expression
3270            append: if `True`, add to any existing expressions.
3271                Otherwise, this flattens all the `Group` expression into a single expression.
3272            dialect: the dialect used to parse the input expression.
3273            copy: if `False`, modify this expression instance in-place.
3274            opts: other options to use to parse the input expressions.
3275
3276        Returns:
3277            The modified Select expression.
3278        """
3279        if not expressions:
3280            return self if not copy else self.copy()
3281
3282        return _apply_child_list_builder(
3283            *expressions,
3284            instance=self,
3285            arg="group",
3286            append=append,
3287            copy=copy,
3288            prefix="GROUP BY",
3289            into=Group,
3290            dialect=dialect,
3291            **opts,
3292        )
3293
3294    def sort_by(
3295        self,
3296        *expressions: t.Optional[ExpOrStr],
3297        append: bool = True,
3298        dialect: DialectType = None,
3299        copy: bool = True,
3300        **opts,
3301    ) -> Select:
3302        """
3303        Set the SORT BY expression.
3304
3305        Example:
3306            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3307            'SELECT x FROM tbl SORT BY x DESC'
3308
3309        Args:
3310            *expressions: the SQL code strings to parse.
3311                If a `Group` instance is passed, this is used as-is.
3312                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3313            append: if `True`, add to any existing expressions.
3314                Otherwise, this flattens all the `Order` expression into a single expression.
3315            dialect: the dialect used to parse the input expression.
3316            copy: if `False`, modify this expression instance in-place.
3317            opts: other options to use to parse the input expressions.
3318
3319        Returns:
3320            The modified Select expression.
3321        """
3322        return _apply_child_list_builder(
3323            *expressions,
3324            instance=self,
3325            arg="sort",
3326            append=append,
3327            copy=copy,
3328            prefix="SORT BY",
3329            into=Sort,
3330            dialect=dialect,
3331            **opts,
3332        )
3333
3334    def cluster_by(
3335        self,
3336        *expressions: t.Optional[ExpOrStr],
3337        append: bool = True,
3338        dialect: DialectType = None,
3339        copy: bool = True,
3340        **opts,
3341    ) -> Select:
3342        """
3343        Set the CLUSTER BY expression.
3344
3345        Example:
3346            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3347            'SELECT x FROM tbl CLUSTER BY x DESC'
3348
3349        Args:
3350            *expressions: the SQL code strings to parse.
3351                If a `Group` instance is passed, this is used as-is.
3352                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3353            append: if `True`, add to any existing expressions.
3354                Otherwise, this flattens all the `Order` expression into a single expression.
3355            dialect: the dialect used to parse the input expression.
3356            copy: if `False`, modify this expression instance in-place.
3357            opts: other options to use to parse the input expressions.
3358
3359        Returns:
3360            The modified Select expression.
3361        """
3362        return _apply_child_list_builder(
3363            *expressions,
3364            instance=self,
3365            arg="cluster",
3366            append=append,
3367            copy=copy,
3368            prefix="CLUSTER BY",
3369            into=Cluster,
3370            dialect=dialect,
3371            **opts,
3372        )
3373
3374    def select(
3375        self,
3376        *expressions: t.Optional[ExpOrStr],
3377        append: bool = True,
3378        dialect: DialectType = None,
3379        copy: bool = True,
3380        **opts,
3381    ) -> Select:
3382        return _apply_list_builder(
3383            *expressions,
3384            instance=self,
3385            arg="expressions",
3386            append=append,
3387            dialect=dialect,
3388            into=Expression,
3389            copy=copy,
3390            **opts,
3391        )
3392
3393    def lateral(
3394        self,
3395        *expressions: t.Optional[ExpOrStr],
3396        append: bool = True,
3397        dialect: DialectType = None,
3398        copy: bool = True,
3399        **opts,
3400    ) -> Select:
3401        """
3402        Append to or set the LATERAL expressions.
3403
3404        Example:
3405            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3406            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3407
3408        Args:
3409            *expressions: the SQL code strings to parse.
3410                If an `Expression` instance is passed, it will be used as-is.
3411            append: if `True`, add to any existing expressions.
3412                Otherwise, this resets the expressions.
3413            dialect: the dialect used to parse the input expressions.
3414            copy: if `False`, modify this expression instance in-place.
3415            opts: other options to use to parse the input expressions.
3416
3417        Returns:
3418            The modified Select expression.
3419        """
3420        return _apply_list_builder(
3421            *expressions,
3422            instance=self,
3423            arg="laterals",
3424            append=append,
3425            into=Lateral,
3426            prefix="LATERAL VIEW",
3427            dialect=dialect,
3428            copy=copy,
3429            **opts,
3430        )
3431
3432    def join(
3433        self,
3434        expression: ExpOrStr,
3435        on: t.Optional[ExpOrStr] = None,
3436        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3437        append: bool = True,
3438        join_type: t.Optional[str] = None,
3439        join_alias: t.Optional[Identifier | str] = None,
3440        dialect: DialectType = None,
3441        copy: bool = True,
3442        **opts,
3443    ) -> Select:
3444        """
3445        Append to or set the JOIN expressions.
3446
3447        Example:
3448            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3449            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3450
3451            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3452            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3453
3454            Use `join_type` to change the type of join:
3455
3456            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3457            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3458
3459        Args:
3460            expression: the SQL code string to parse.
3461                If an `Expression` instance is passed, it will be used as-is.
3462            on: optionally specify the join "on" criteria as a SQL string.
3463                If an `Expression` instance is passed, it will be used as-is.
3464            using: optionally specify the join "using" criteria as a SQL string.
3465                If an `Expression` instance is passed, it will be used as-is.
3466            append: if `True`, add to any existing expressions.
3467                Otherwise, this resets the expressions.
3468            join_type: if set, alter the parsed join type.
3469            join_alias: an optional alias for the joined source.
3470            dialect: the dialect used to parse the input expressions.
3471            copy: if `False`, modify this expression instance in-place.
3472            opts: other options to use to parse the input expressions.
3473
3474        Returns:
3475            Select: the modified expression.
3476        """
3477        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3478
3479        try:
3480            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3481        except ParseError:
3482            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3483
3484        join = expression if isinstance(expression, Join) else Join(this=expression)
3485
3486        if isinstance(join.this, Select):
3487            join.this.replace(join.this.subquery())
3488
3489        if join_type:
3490            method: t.Optional[Token]
3491            side: t.Optional[Token]
3492            kind: t.Optional[Token]
3493
3494            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3495
3496            if method:
3497                join.set("method", method.text)
3498            if side:
3499                join.set("side", side.text)
3500            if kind:
3501                join.set("kind", kind.text)
3502
3503        if on:
3504            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3505            join.set("on", on)
3506
3507        if using:
3508            join = _apply_list_builder(
3509                *ensure_list(using),
3510                instance=join,
3511                arg="using",
3512                append=append,
3513                copy=copy,
3514                into=Identifier,
3515                **opts,
3516            )
3517
3518        if join_alias:
3519            join.set("this", alias_(join.this, join_alias, table=True))
3520
3521        return _apply_list_builder(
3522            join,
3523            instance=self,
3524            arg="joins",
3525            append=append,
3526            copy=copy,
3527            **opts,
3528        )
3529
3530    def where(
3531        self,
3532        *expressions: t.Optional[ExpOrStr],
3533        append: bool = True,
3534        dialect: DialectType = None,
3535        copy: bool = True,
3536        **opts,
3537    ) -> Select:
3538        """
3539        Append to or set the WHERE expressions.
3540
3541        Example:
3542            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3543            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3544
3545        Args:
3546            *expressions: the SQL code strings to parse.
3547                If an `Expression` instance is passed, it will be used as-is.
3548                Multiple expressions are combined with an AND operator.
3549            append: if `True`, AND the new expressions to any existing expression.
3550                Otherwise, this resets the expression.
3551            dialect: the dialect used to parse the input expressions.
3552            copy: if `False`, modify this expression instance in-place.
3553            opts: other options to use to parse the input expressions.
3554
3555        Returns:
3556            Select: the modified expression.
3557        """
3558        return _apply_conjunction_builder(
3559            *expressions,
3560            instance=self,
3561            arg="where",
3562            append=append,
3563            into=Where,
3564            dialect=dialect,
3565            copy=copy,
3566            **opts,
3567        )
3568
3569    def having(
3570        self,
3571        *expressions: t.Optional[ExpOrStr],
3572        append: bool = True,
3573        dialect: DialectType = None,
3574        copy: bool = True,
3575        **opts,
3576    ) -> Select:
3577        """
3578        Append to or set the HAVING expressions.
3579
3580        Example:
3581            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3582            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3583
3584        Args:
3585            *expressions: the SQL code strings to parse.
3586                If an `Expression` instance is passed, it will be used as-is.
3587                Multiple expressions are combined with an AND operator.
3588            append: if `True`, AND the new expressions to any existing expression.
3589                Otherwise, this resets the expression.
3590            dialect: the dialect used to parse the input expressions.
3591            copy: if `False`, modify this expression instance in-place.
3592            opts: other options to use to parse the input expressions.
3593
3594        Returns:
3595            The modified Select expression.
3596        """
3597        return _apply_conjunction_builder(
3598            *expressions,
3599            instance=self,
3600            arg="having",
3601            append=append,
3602            into=Having,
3603            dialect=dialect,
3604            copy=copy,
3605            **opts,
3606        )
3607
3608    def window(
3609        self,
3610        *expressions: t.Optional[ExpOrStr],
3611        append: bool = True,
3612        dialect: DialectType = None,
3613        copy: bool = True,
3614        **opts,
3615    ) -> Select:
3616        return _apply_list_builder(
3617            *expressions,
3618            instance=self,
3619            arg="windows",
3620            append=append,
3621            into=Window,
3622            dialect=dialect,
3623            copy=copy,
3624            **opts,
3625        )
3626
3627    def qualify(
3628        self,
3629        *expressions: t.Optional[ExpOrStr],
3630        append: bool = True,
3631        dialect: DialectType = None,
3632        copy: bool = True,
3633        **opts,
3634    ) -> Select:
3635        return _apply_conjunction_builder(
3636            *expressions,
3637            instance=self,
3638            arg="qualify",
3639            append=append,
3640            into=Qualify,
3641            dialect=dialect,
3642            copy=copy,
3643            **opts,
3644        )
3645
3646    def distinct(
3647        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3648    ) -> Select:
3649        """
3650        Set the OFFSET expression.
3651
3652        Example:
3653            >>> Select().from_("tbl").select("x").distinct().sql()
3654            'SELECT DISTINCT x FROM tbl'
3655
3656        Args:
3657            ons: the expressions to distinct on
3658            distinct: whether the Select should be distinct
3659            copy: if `False`, modify this expression instance in-place.
3660
3661        Returns:
3662            Select: the modified expression.
3663        """
3664        instance = maybe_copy(self, copy)
3665        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3666        instance.set("distinct", Distinct(on=on) if distinct else None)
3667        return instance
3668
3669    def ctas(
3670        self,
3671        table: ExpOrStr,
3672        properties: t.Optional[t.Dict] = None,
3673        dialect: DialectType = None,
3674        copy: bool = True,
3675        **opts,
3676    ) -> Create:
3677        """
3678        Convert this expression to a CREATE TABLE AS statement.
3679
3680        Example:
3681            >>> Select().select("*").from_("tbl").ctas("x").sql()
3682            'CREATE TABLE x AS SELECT * FROM tbl'
3683
3684        Args:
3685            table: the SQL code string to parse as the table name.
3686                If another `Expression` instance is passed, it will be used as-is.
3687            properties: an optional mapping of table properties
3688            dialect: the dialect used to parse the input table.
3689            copy: if `False`, modify this expression instance in-place.
3690            opts: other options to use to parse the input table.
3691
3692        Returns:
3693            The new Create expression.
3694        """
3695        instance = maybe_copy(self, copy)
3696        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3697
3698        properties_expression = None
3699        if properties:
3700            properties_expression = Properties.from_dict(properties)
3701
3702        return Create(
3703            this=table_expression,
3704            kind="TABLE",
3705            expression=instance,
3706            properties=properties_expression,
3707        )
3708
3709    def lock(self, update: bool = True, copy: bool = True) -> Select:
3710        """
3711        Set the locking read mode for this expression.
3712
3713        Examples:
3714            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3715            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3716
3717            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3718            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3719
3720        Args:
3721            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3722            copy: if `False`, modify this expression instance in-place.
3723
3724        Returns:
3725            The modified expression.
3726        """
3727        inst = maybe_copy(self, copy)
3728        inst.set("locks", [Lock(update=update)])
3729
3730        return inst
3731
3732    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3733        """
3734        Set hints for this expression.
3735
3736        Examples:
3737            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3738            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3739
3740        Args:
3741            hints: The SQL code strings to parse as the hints.
3742                If an `Expression` instance is passed, it will be used as-is.
3743            dialect: The dialect used to parse the hints.
3744            copy: If `False`, modify this expression instance in-place.
3745
3746        Returns:
3747            The modified expression.
3748        """
3749        inst = maybe_copy(self, copy)
3750        inst.set(
3751            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3752        )
3753
3754        return inst
3755
3756    @property
3757    def named_selects(self) -> t.List[str]:
3758        return [e.output_name for e in self.expressions if e.alias_or_name]
3759
3760    @property
3761    def is_star(self) -> bool:
3762        return any(expression.is_star for expression in self.expressions)
3763
3764    @property
3765    def selects(self) -> t.List[Expression]:
3766        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3218    def from_(
3219        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3220    ) -> Select:
3221        """
3222        Set the FROM expression.
3223
3224        Example:
3225            >>> Select().from_("tbl").select("x").sql()
3226            'SELECT x FROM tbl'
3227
3228        Args:
3229            expression : the SQL code strings to parse.
3230                If a `From` instance is passed, this is used as-is.
3231                If another `Expression` instance is passed, it will be wrapped in a `From`.
3232            dialect: the dialect used to parse the input expression.
3233            copy: if `False`, modify this expression instance in-place.
3234            opts: other options to use to parse the input expressions.
3235
3236        Returns:
3237            The modified Select expression.
3238        """
3239        return _apply_builder(
3240            expression=expression,
3241            instance=self,
3242            arg="from",
3243            into=From,
3244            prefix="FROM",
3245            dialect=dialect,
3246            copy=copy,
3247            **opts,
3248        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3250    def group_by(
3251        self,
3252        *expressions: t.Optional[ExpOrStr],
3253        append: bool = True,
3254        dialect: DialectType = None,
3255        copy: bool = True,
3256        **opts,
3257    ) -> Select:
3258        """
3259        Set the GROUP BY expression.
3260
3261        Example:
3262            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3263            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3264
3265        Args:
3266            *expressions: the SQL code strings to parse.
3267                If a `Group` instance is passed, this is used as-is.
3268                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3269                If nothing is passed in then a group by is not applied to the expression
3270            append: if `True`, add to any existing expressions.
3271                Otherwise, this flattens all the `Group` expression into a single expression.
3272            dialect: the dialect used to parse the input expression.
3273            copy: if `False`, modify this expression instance in-place.
3274            opts: other options to use to parse the input expressions.
3275
3276        Returns:
3277            The modified Select expression.
3278        """
3279        if not expressions:
3280            return self if not copy else self.copy()
3281
3282        return _apply_child_list_builder(
3283            *expressions,
3284            instance=self,
3285            arg="group",
3286            append=append,
3287            copy=copy,
3288            prefix="GROUP BY",
3289            into=Group,
3290            dialect=dialect,
3291            **opts,
3292        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3294    def sort_by(
3295        self,
3296        *expressions: t.Optional[ExpOrStr],
3297        append: bool = True,
3298        dialect: DialectType = None,
3299        copy: bool = True,
3300        **opts,
3301    ) -> Select:
3302        """
3303        Set the SORT BY expression.
3304
3305        Example:
3306            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3307            'SELECT x FROM tbl SORT BY x DESC'
3308
3309        Args:
3310            *expressions: the SQL code strings to parse.
3311                If a `Group` instance is passed, this is used as-is.
3312                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3313            append: if `True`, add to any existing expressions.
3314                Otherwise, this flattens all the `Order` expression into a single expression.
3315            dialect: the dialect used to parse the input expression.
3316            copy: if `False`, modify this expression instance in-place.
3317            opts: other options to use to parse the input expressions.
3318
3319        Returns:
3320            The modified Select expression.
3321        """
3322        return _apply_child_list_builder(
3323            *expressions,
3324            instance=self,
3325            arg="sort",
3326            append=append,
3327            copy=copy,
3328            prefix="SORT BY",
3329            into=Sort,
3330            dialect=dialect,
3331            **opts,
3332        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3334    def cluster_by(
3335        self,
3336        *expressions: t.Optional[ExpOrStr],
3337        append: bool = True,
3338        dialect: DialectType = None,
3339        copy: bool = True,
3340        **opts,
3341    ) -> Select:
3342        """
3343        Set the CLUSTER BY expression.
3344
3345        Example:
3346            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3347            'SELECT x FROM tbl CLUSTER BY x DESC'
3348
3349        Args:
3350            *expressions: the SQL code strings to parse.
3351                If a `Group` instance is passed, this is used as-is.
3352                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3353            append: if `True`, add to any existing expressions.
3354                Otherwise, this flattens all the `Order` expression into a single expression.
3355            dialect: the dialect used to parse the input expression.
3356            copy: if `False`, modify this expression instance in-place.
3357            opts: other options to use to parse the input expressions.
3358
3359        Returns:
3360            The modified Select expression.
3361        """
3362        return _apply_child_list_builder(
3363            *expressions,
3364            instance=self,
3365            arg="cluster",
3366            append=append,
3367            copy=copy,
3368            prefix="CLUSTER BY",
3369            into=Cluster,
3370            dialect=dialect,
3371            **opts,
3372        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3374    def select(
3375        self,
3376        *expressions: t.Optional[ExpOrStr],
3377        append: bool = True,
3378        dialect: DialectType = None,
3379        copy: bool = True,
3380        **opts,
3381    ) -> Select:
3382        return _apply_list_builder(
3383            *expressions,
3384            instance=self,
3385            arg="expressions",
3386            append=append,
3387            dialect=dialect,
3388            into=Expression,
3389            copy=copy,
3390            **opts,
3391        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3393    def lateral(
3394        self,
3395        *expressions: t.Optional[ExpOrStr],
3396        append: bool = True,
3397        dialect: DialectType = None,
3398        copy: bool = True,
3399        **opts,
3400    ) -> Select:
3401        """
3402        Append to or set the LATERAL expressions.
3403
3404        Example:
3405            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3406            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3407
3408        Args:
3409            *expressions: the SQL code strings to parse.
3410                If an `Expression` instance is passed, it will be used as-is.
3411            append: if `True`, add to any existing expressions.
3412                Otherwise, this resets the expressions.
3413            dialect: the dialect used to parse the input expressions.
3414            copy: if `False`, modify this expression instance in-place.
3415            opts: other options to use to parse the input expressions.
3416
3417        Returns:
3418            The modified Select expression.
3419        """
3420        return _apply_list_builder(
3421            *expressions,
3422            instance=self,
3423            arg="laterals",
3424            append=append,
3425            into=Lateral,
3426            prefix="LATERAL VIEW",
3427            dialect=dialect,
3428            copy=copy,
3429            **opts,
3430        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3432    def join(
3433        self,
3434        expression: ExpOrStr,
3435        on: t.Optional[ExpOrStr] = None,
3436        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3437        append: bool = True,
3438        join_type: t.Optional[str] = None,
3439        join_alias: t.Optional[Identifier | str] = None,
3440        dialect: DialectType = None,
3441        copy: bool = True,
3442        **opts,
3443    ) -> Select:
3444        """
3445        Append to or set the JOIN expressions.
3446
3447        Example:
3448            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3449            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3450
3451            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3452            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3453
3454            Use `join_type` to change the type of join:
3455
3456            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3457            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3458
3459        Args:
3460            expression: the SQL code string to parse.
3461                If an `Expression` instance is passed, it will be used as-is.
3462            on: optionally specify the join "on" criteria as a SQL string.
3463                If an `Expression` instance is passed, it will be used as-is.
3464            using: optionally specify the join "using" criteria as a SQL string.
3465                If an `Expression` instance is passed, it will be used as-is.
3466            append: if `True`, add to any existing expressions.
3467                Otherwise, this resets the expressions.
3468            join_type: if set, alter the parsed join type.
3469            join_alias: an optional alias for the joined source.
3470            dialect: the dialect used to parse the input expressions.
3471            copy: if `False`, modify this expression instance in-place.
3472            opts: other options to use to parse the input expressions.
3473
3474        Returns:
3475            Select: the modified expression.
3476        """
3477        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3478
3479        try:
3480            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3481        except ParseError:
3482            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3483
3484        join = expression if isinstance(expression, Join) else Join(this=expression)
3485
3486        if isinstance(join.this, Select):
3487            join.this.replace(join.this.subquery())
3488
3489        if join_type:
3490            method: t.Optional[Token]
3491            side: t.Optional[Token]
3492            kind: t.Optional[Token]
3493
3494            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3495
3496            if method:
3497                join.set("method", method.text)
3498            if side:
3499                join.set("side", side.text)
3500            if kind:
3501                join.set("kind", kind.text)
3502
3503        if on:
3504            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3505            join.set("on", on)
3506
3507        if using:
3508            join = _apply_list_builder(
3509                *ensure_list(using),
3510                instance=join,
3511                arg="using",
3512                append=append,
3513                copy=copy,
3514                into=Identifier,
3515                **opts,
3516            )
3517
3518        if join_alias:
3519            join.set("this", alias_(join.this, join_alias, table=True))
3520
3521        return _apply_list_builder(
3522            join,
3523            instance=self,
3524            arg="joins",
3525            append=append,
3526            copy=copy,
3527            **opts,
3528        )

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 where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3530    def where(
3531        self,
3532        *expressions: t.Optional[ExpOrStr],
3533        append: bool = True,
3534        dialect: DialectType = None,
3535        copy: bool = True,
3536        **opts,
3537    ) -> Select:
3538        """
3539        Append to or set the WHERE expressions.
3540
3541        Example:
3542            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3543            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3544
3545        Args:
3546            *expressions: the SQL code strings to parse.
3547                If an `Expression` instance is passed, it will be used as-is.
3548                Multiple expressions are combined with an AND operator.
3549            append: if `True`, AND the new expressions to any existing expression.
3550                Otherwise, this resets the expression.
3551            dialect: the dialect used to parse the input expressions.
3552            copy: if `False`, modify this expression instance in-place.
3553            opts: other options to use to parse the input expressions.
3554
3555        Returns:
3556            Select: the modified expression.
3557        """
3558        return _apply_conjunction_builder(
3559            *expressions,
3560            instance=self,
3561            arg="where",
3562            append=append,
3563            into=Where,
3564            dialect=dialect,
3565            copy=copy,
3566            **opts,
3567        )

Append to or set the WHERE expressions.

Example:
>>> 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:

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3569    def having(
3570        self,
3571        *expressions: t.Optional[ExpOrStr],
3572        append: bool = True,
3573        dialect: DialectType = None,
3574        copy: bool = True,
3575        **opts,
3576    ) -> Select:
3577        """
3578        Append to or set the HAVING expressions.
3579
3580        Example:
3581            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3582            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3583
3584        Args:
3585            *expressions: the SQL code strings to parse.
3586                If an `Expression` instance is passed, it will be used as-is.
3587                Multiple expressions are combined with an AND operator.
3588            append: if `True`, AND the new expressions to any existing expression.
3589                Otherwise, this resets the expression.
3590            dialect: the dialect used to parse the input expressions.
3591            copy: if `False`, modify this expression instance in-place.
3592            opts: other options to use to parse the input expressions.
3593
3594        Returns:
3595            The modified Select expression.
3596        """
3597        return _apply_conjunction_builder(
3598            *expressions,
3599            instance=self,
3600            arg="having",
3601            append=append,
3602            into=Having,
3603            dialect=dialect,
3604            copy=copy,
3605            **opts,
3606        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3608    def window(
3609        self,
3610        *expressions: t.Optional[ExpOrStr],
3611        append: bool = True,
3612        dialect: DialectType = None,
3613        copy: bool = True,
3614        **opts,
3615    ) -> Select:
3616        return _apply_list_builder(
3617            *expressions,
3618            instance=self,
3619            arg="windows",
3620            append=append,
3621            into=Window,
3622            dialect=dialect,
3623            copy=copy,
3624            **opts,
3625        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3627    def qualify(
3628        self,
3629        *expressions: t.Optional[ExpOrStr],
3630        append: bool = True,
3631        dialect: DialectType = None,
3632        copy: bool = True,
3633        **opts,
3634    ) -> Select:
3635        return _apply_conjunction_builder(
3636            *expressions,
3637            instance=self,
3638            arg="qualify",
3639            append=append,
3640            into=Qualify,
3641            dialect=dialect,
3642            copy=copy,
3643            **opts,
3644        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3646    def distinct(
3647        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3648    ) -> Select:
3649        """
3650        Set the OFFSET expression.
3651
3652        Example:
3653            >>> Select().from_("tbl").select("x").distinct().sql()
3654            'SELECT DISTINCT x FROM tbl'
3655
3656        Args:
3657            ons: the expressions to distinct on
3658            distinct: whether the Select should be distinct
3659            copy: if `False`, modify this expression instance in-place.
3660
3661        Returns:
3662            Select: the modified expression.
3663        """
3664        instance = maybe_copy(self, copy)
3665        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3666        instance.set("distinct", Distinct(on=on) if distinct else None)
3667        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
3669    def ctas(
3670        self,
3671        table: ExpOrStr,
3672        properties: t.Optional[t.Dict] = None,
3673        dialect: DialectType = None,
3674        copy: bool = True,
3675        **opts,
3676    ) -> Create:
3677        """
3678        Convert this expression to a CREATE TABLE AS statement.
3679
3680        Example:
3681            >>> Select().select("*").from_("tbl").ctas("x").sql()
3682            'CREATE TABLE x AS SELECT * FROM tbl'
3683
3684        Args:
3685            table: the SQL code string to parse as the table name.
3686                If another `Expression` instance is passed, it will be used as-is.
3687            properties: an optional mapping of table properties
3688            dialect: the dialect used to parse the input table.
3689            copy: if `False`, modify this expression instance in-place.
3690            opts: other options to use to parse the input table.
3691
3692        Returns:
3693            The new Create expression.
3694        """
3695        instance = maybe_copy(self, copy)
3696        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3697
3698        properties_expression = None
3699        if properties:
3700            properties_expression = Properties.from_dict(properties)
3701
3702        return Create(
3703            this=table_expression,
3704            kind="TABLE",
3705            expression=instance,
3706            properties=properties_expression,
3707        )

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:
3709    def lock(self, update: bool = True, copy: bool = True) -> Select:
3710        """
3711        Set the locking read mode for this expression.
3712
3713        Examples:
3714            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3715            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3716
3717            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3718            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3719
3720        Args:
3721            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3722            copy: if `False`, modify this expression instance in-place.
3723
3724        Returns:
3725            The modified expression.
3726        """
3727        inst = maybe_copy(self, copy)
3728        inst.set("locks", [Lock(update=update)])
3729
3730        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
3732    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3733        """
3734        Set hints for this expression.
3735
3736        Examples:
3737            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3738            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3739
3740        Args:
3741            hints: The SQL code strings to parse as the hints.
3742                If an `Expression` instance is passed, it will be used as-is.
3743            dialect: The dialect used to parse the hints.
3744            copy: If `False`, modify this expression instance in-place.
3745
3746        Returns:
3747            The modified expression.
3748        """
3749        inst = maybe_copy(self, copy)
3750        inst.set(
3751            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3752        )
3753
3754        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]
3756    @property
3757    def named_selects(self) -> t.List[str]:
3758        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
3760    @property
3761    def is_star(self) -> bool:
3762        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3764    @property
3765    def selects(self) -> t.List[Expression]:
3766        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
3772class Subquery(DerivedTable, Query):
3773    arg_types = {
3774        "this": True,
3775        "alias": False,
3776        "with": False,
3777        **QUERY_MODIFIERS,
3778    }
3779
3780    def unnest(self):
3781        """Returns the first non subquery."""
3782        expression = self
3783        while isinstance(expression, Subquery):
3784            expression = expression.this
3785        return expression
3786
3787    def unwrap(self) -> Subquery:
3788        expression = self
3789        while expression.same_parent and expression.is_wrapper:
3790            expression = t.cast(Subquery, expression.parent)
3791        return expression
3792
3793    def select(
3794        self,
3795        *expressions: t.Optional[ExpOrStr],
3796        append: bool = True,
3797        dialect: DialectType = None,
3798        copy: bool = True,
3799        **opts,
3800    ) -> Subquery:
3801        this = maybe_copy(self, copy)
3802        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3803        return this
3804
3805    @property
3806    def is_wrapper(self) -> bool:
3807        """
3808        Whether this Subquery acts as a simple wrapper around another expression.
3809
3810        SELECT * FROM (((SELECT * FROM t)))
3811                      ^
3812                      This corresponds to a "wrapper" Subquery node
3813        """
3814        return all(v is None for k, v in self.args.items() if k != "this")
3815
3816    @property
3817    def is_star(self) -> bool:
3818        return self.this.is_star
3819
3820    @property
3821    def output_name(self) -> str:
3822        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):
3780    def unnest(self):
3781        """Returns the first non subquery."""
3782        expression = self
3783        while isinstance(expression, Subquery):
3784            expression = expression.this
3785        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3787    def unwrap(self) -> Subquery:
3788        expression = self
3789        while expression.same_parent and expression.is_wrapper:
3790            expression = t.cast(Subquery, expression.parent)
3791        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
3793    def select(
3794        self,
3795        *expressions: t.Optional[ExpOrStr],
3796        append: bool = True,
3797        dialect: DialectType = None,
3798        copy: bool = True,
3799        **opts,
3800    ) -> Subquery:
3801        this = maybe_copy(self, copy)
3802        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3803        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
3805    @property
3806    def is_wrapper(self) -> bool:
3807        """
3808        Whether this Subquery acts as a simple wrapper around another expression.
3809
3810        SELECT * FROM (((SELECT * FROM t)))
3811                      ^
3812                      This corresponds to a "wrapper" Subquery node
3813        """
3814        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
3816    @property
3817    def is_star(self) -> bool:
3818        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3820    @property
3821    def output_name(self) -> str:
3822        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):
3825class TableSample(Expression):
3826    arg_types = {
3827        "this": False,
3828        "expressions": False,
3829        "method": False,
3830        "bucket_numerator": False,
3831        "bucket_denominator": False,
3832        "bucket_field": False,
3833        "percent": False,
3834        "rows": False,
3835        "size": False,
3836        "seed": False,
3837    }
arg_types = {'this': False, '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):
3840class Tag(Expression):
3841    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3842
3843    arg_types = {
3844        "this": False,
3845        "prefix": False,
3846        "postfix": False,
3847    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3852class Pivot(Expression):
3853    arg_types = {
3854        "this": False,
3855        "alias": False,
3856        "expressions": False,
3857        "field": False,
3858        "unpivot": False,
3859        "using": False,
3860        "group": False,
3861        "columns": False,
3862        "include_nulls": False,
3863        "default_on_null": False,
3864    }
3865
3866    @property
3867    def unpivot(self) -> bool:
3868        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False}
unpivot: bool
3866    @property
3867    def unpivot(self) -> bool:
3868        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3871class Window(Condition):
3872    arg_types = {
3873        "this": True,
3874        "partition_by": False,
3875        "order": False,
3876        "spec": False,
3877        "alias": False,
3878        "over": False,
3879        "first": False,
3880    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3883class WindowSpec(Expression):
3884    arg_types = {
3885        "kind": False,
3886        "start": False,
3887        "start_side": False,
3888        "end": False,
3889        "end_side": False,
3890    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3893class PreWhere(Expression):
3894    pass
key = 'prewhere'
class Where(Expression):
3897class Where(Expression):
3898    pass
key = 'where'
class Star(Expression):
3901class Star(Expression):
3902    arg_types = {"except": False, "replace": False, "rename": False}
3903
3904    @property
3905    def name(self) -> str:
3906        return "*"
3907
3908    @property
3909    def output_name(self) -> str:
3910        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3904    @property
3905    def name(self) -> str:
3906        return "*"
output_name: str
3908    @property
3909    def output_name(self) -> str:
3910        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):
3913class Parameter(Condition):
3914    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3917class SessionParameter(Condition):
3918    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3921class Placeholder(Condition):
3922    arg_types = {"this": False, "kind": False}
3923
3924    @property
3925    def name(self) -> str:
3926        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3924    @property
3925    def name(self) -> str:
3926        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3929class Null(Condition):
3930    arg_types: t.Dict[str, t.Any] = {}
3931
3932    @property
3933    def name(self) -> str:
3934        return "NULL"
3935
3936    def to_py(self) -> Lit[None]:
3937        return None
arg_types: Dict[str, Any] = {}
name: str
3932    @property
3933    def name(self) -> str:
3934        return "NULL"
def to_py(self) -> Literal[None]:
3936    def to_py(self) -> Lit[None]:
3937        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3940class Boolean(Condition):
3941    def to_py(self) -> bool:
3942        return self.this
def to_py(self) -> bool:
3941    def to_py(self) -> bool:
3942        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
3945class DataTypeParam(Expression):
3946    arg_types = {"this": True, "expression": False}
3947
3948    @property
3949    def name(self) -> str:
3950        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3948    @property
3949    def name(self) -> str:
3950        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3953class DataType(Expression):
3954    arg_types = {
3955        "this": True,
3956        "expressions": False,
3957        "nested": False,
3958        "values": False,
3959        "prefix": False,
3960        "kind": False,
3961    }
3962
3963    class Type(AutoName):
3964        ARRAY = auto()
3965        AGGREGATEFUNCTION = auto()
3966        SIMPLEAGGREGATEFUNCTION = auto()
3967        BIGDECIMAL = auto()
3968        BIGINT = auto()
3969        BIGSERIAL = auto()
3970        BINARY = auto()
3971        BIT = auto()
3972        BOOLEAN = auto()
3973        BPCHAR = auto()
3974        CHAR = auto()
3975        DATE = auto()
3976        DATE32 = auto()
3977        DATEMULTIRANGE = auto()
3978        DATERANGE = auto()
3979        DATETIME = auto()
3980        DATETIME64 = auto()
3981        DECIMAL = auto()
3982        DOUBLE = auto()
3983        ENUM = auto()
3984        ENUM8 = auto()
3985        ENUM16 = auto()
3986        FIXEDSTRING = auto()
3987        FLOAT = auto()
3988        GEOGRAPHY = auto()
3989        GEOMETRY = auto()
3990        HLLSKETCH = auto()
3991        HSTORE = auto()
3992        IMAGE = auto()
3993        INET = auto()
3994        INT = auto()
3995        INT128 = auto()
3996        INT256 = auto()
3997        INT4MULTIRANGE = auto()
3998        INT4RANGE = auto()
3999        INT8MULTIRANGE = auto()
4000        INT8RANGE = auto()
4001        INTERVAL = auto()
4002        IPADDRESS = auto()
4003        IPPREFIX = auto()
4004        IPV4 = auto()
4005        IPV6 = auto()
4006        JSON = auto()
4007        JSONB = auto()
4008        LIST = auto()
4009        LONGBLOB = auto()
4010        LONGTEXT = auto()
4011        LOWCARDINALITY = auto()
4012        MAP = auto()
4013        MEDIUMBLOB = auto()
4014        MEDIUMINT = auto()
4015        MEDIUMTEXT = auto()
4016        MONEY = auto()
4017        NAME = auto()
4018        NCHAR = auto()
4019        NESTED = auto()
4020        NULL = auto()
4021        NULLABLE = auto()
4022        NUMMULTIRANGE = auto()
4023        NUMRANGE = auto()
4024        NVARCHAR = auto()
4025        OBJECT = auto()
4026        ROWVERSION = auto()
4027        SERIAL = auto()
4028        SET = auto()
4029        SMALLINT = auto()
4030        SMALLMONEY = auto()
4031        SMALLSERIAL = auto()
4032        STRUCT = auto()
4033        SUPER = auto()
4034        TEXT = auto()
4035        TINYBLOB = auto()
4036        TINYTEXT = auto()
4037        TIME = auto()
4038        TIMETZ = auto()
4039        TIMESTAMP = auto()
4040        TIMESTAMPNTZ = auto()
4041        TIMESTAMPLTZ = auto()
4042        TIMESTAMPTZ = auto()
4043        TIMESTAMP_S = auto()
4044        TIMESTAMP_MS = auto()
4045        TIMESTAMP_NS = auto()
4046        TINYINT = auto()
4047        TSMULTIRANGE = auto()
4048        TSRANGE = auto()
4049        TSTZMULTIRANGE = auto()
4050        TSTZRANGE = auto()
4051        UBIGINT = auto()
4052        UINT = auto()
4053        UINT128 = auto()
4054        UINT256 = auto()
4055        UMEDIUMINT = auto()
4056        UDECIMAL = auto()
4057        UNIQUEIDENTIFIER = auto()
4058        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4059        USERDEFINED = "USER-DEFINED"
4060        USMALLINT = auto()
4061        UTINYINT = auto()
4062        UUID = auto()
4063        VARBINARY = auto()
4064        VARCHAR = auto()
4065        VARIANT = auto()
4066        VECTOR = auto()
4067        XML = auto()
4068        YEAR = auto()
4069        TDIGEST = auto()
4070
4071    STRUCT_TYPES = {
4072        Type.NESTED,
4073        Type.OBJECT,
4074        Type.STRUCT,
4075    }
4076
4077    NESTED_TYPES = {
4078        *STRUCT_TYPES,
4079        Type.ARRAY,
4080        Type.MAP,
4081    }
4082
4083    TEXT_TYPES = {
4084        Type.CHAR,
4085        Type.NCHAR,
4086        Type.NVARCHAR,
4087        Type.TEXT,
4088        Type.VARCHAR,
4089        Type.NAME,
4090    }
4091
4092    SIGNED_INTEGER_TYPES = {
4093        Type.BIGINT,
4094        Type.INT,
4095        Type.INT128,
4096        Type.INT256,
4097        Type.MEDIUMINT,
4098        Type.SMALLINT,
4099        Type.TINYINT,
4100    }
4101
4102    UNSIGNED_INTEGER_TYPES = {
4103        Type.UBIGINT,
4104        Type.UINT,
4105        Type.UINT128,
4106        Type.UINT256,
4107        Type.UMEDIUMINT,
4108        Type.USMALLINT,
4109        Type.UTINYINT,
4110    }
4111
4112    INTEGER_TYPES = {
4113        *SIGNED_INTEGER_TYPES,
4114        *UNSIGNED_INTEGER_TYPES,
4115        Type.BIT,
4116    }
4117
4118    FLOAT_TYPES = {
4119        Type.DOUBLE,
4120        Type.FLOAT,
4121    }
4122
4123    REAL_TYPES = {
4124        *FLOAT_TYPES,
4125        Type.BIGDECIMAL,
4126        Type.DECIMAL,
4127        Type.MONEY,
4128        Type.SMALLMONEY,
4129        Type.UDECIMAL,
4130    }
4131
4132    NUMERIC_TYPES = {
4133        *INTEGER_TYPES,
4134        *REAL_TYPES,
4135    }
4136
4137    TEMPORAL_TYPES = {
4138        Type.DATE,
4139        Type.DATE32,
4140        Type.DATETIME,
4141        Type.DATETIME64,
4142        Type.TIME,
4143        Type.TIMESTAMP,
4144        Type.TIMESTAMPNTZ,
4145        Type.TIMESTAMPLTZ,
4146        Type.TIMESTAMPTZ,
4147        Type.TIMESTAMP_MS,
4148        Type.TIMESTAMP_NS,
4149        Type.TIMESTAMP_S,
4150        Type.TIMETZ,
4151    }
4152
4153    @classmethod
4154    def build(
4155        cls,
4156        dtype: DATA_TYPE,
4157        dialect: DialectType = None,
4158        udt: bool = False,
4159        copy: bool = True,
4160        **kwargs,
4161    ) -> DataType:
4162        """
4163        Constructs a DataType object.
4164
4165        Args:
4166            dtype: the data type of interest.
4167            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4168            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4169                DataType, thus creating a user-defined type.
4170            copy: whether to copy the data type.
4171            kwargs: additional arguments to pass in the constructor of DataType.
4172
4173        Returns:
4174            The constructed DataType object.
4175        """
4176        from sqlglot import parse_one
4177
4178        if isinstance(dtype, str):
4179            if dtype.upper() == "UNKNOWN":
4180                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4181
4182            try:
4183                data_type_exp = parse_one(
4184                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4185                )
4186            except ParseError:
4187                if udt:
4188                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4189                raise
4190        elif isinstance(dtype, DataType.Type):
4191            data_type_exp = DataType(this=dtype)
4192        elif isinstance(dtype, DataType):
4193            return maybe_copy(dtype, copy)
4194        else:
4195            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4196
4197        return DataType(**{**data_type_exp.args, **kwargs})
4198
4199    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4200        """
4201        Checks whether this DataType matches one of the provided data types. Nested types or precision
4202        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4203
4204        Args:
4205            dtypes: the data types to compare this DataType to.
4206
4207        Returns:
4208            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4209        """
4210        for dtype in dtypes:
4211            other = DataType.build(dtype, copy=False, udt=True)
4212
4213            if (
4214                other.expressions
4215                or self.this == DataType.Type.USERDEFINED
4216                or other.this == DataType.Type.USERDEFINED
4217            ):
4218                matches = self == other
4219            else:
4220                matches = self.this == other.this
4221
4222            if matches:
4223                return True
4224        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>}
NESTED_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.MAP: 'MAP'>}
TEXT_TYPES = {<Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
INTEGER_TYPES = {<Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT: 'UINT'>, <Type.BIT: 'BIT'>, <Type.UINT256: 'UINT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT128: 'INT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.UDECIMAL: 'UDECIMAL'>}
NUMERIC_TYPES = {<Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT: 'INT'>, <Type.BIT: 'BIT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIME: 'TIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4153    @classmethod
4154    def build(
4155        cls,
4156        dtype: DATA_TYPE,
4157        dialect: DialectType = None,
4158        udt: bool = False,
4159        copy: bool = True,
4160        **kwargs,
4161    ) -> DataType:
4162        """
4163        Constructs a DataType object.
4164
4165        Args:
4166            dtype: the data type of interest.
4167            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4168            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4169                DataType, thus creating a user-defined type.
4170            copy: whether to copy the data type.
4171            kwargs: additional arguments to pass in the constructor of DataType.
4172
4173        Returns:
4174            The constructed DataType object.
4175        """
4176        from sqlglot import parse_one
4177
4178        if isinstance(dtype, str):
4179            if dtype.upper() == "UNKNOWN":
4180                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4181
4182            try:
4183                data_type_exp = parse_one(
4184                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4185                )
4186            except ParseError:
4187                if udt:
4188                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4189                raise
4190        elif isinstance(dtype, DataType.Type):
4191            data_type_exp = DataType(this=dtype)
4192        elif isinstance(dtype, DataType):
4193            return maybe_copy(dtype, copy)
4194        else:
4195            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4196
4197        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, DataType, DataType.Type]) -> bool:
4199    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4200        """
4201        Checks whether this DataType matches one of the provided data types. Nested types or precision
4202        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4203
4204        Args:
4205            dtypes: the data types to compare this DataType to.
4206
4207        Returns:
4208            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4209        """
4210        for dtype in dtypes:
4211            other = DataType.build(dtype, copy=False, udt=True)
4212
4213            if (
4214                other.expressions
4215                or self.this == DataType.Type.USERDEFINED
4216                or other.this == DataType.Type.USERDEFINED
4217            ):
4218                matches = self == other
4219            else:
4220                matches = self.this == other.this
4221
4222            if matches:
4223                return True
4224        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.
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):
3963    class Type(AutoName):
3964        ARRAY = auto()
3965        AGGREGATEFUNCTION = auto()
3966        SIMPLEAGGREGATEFUNCTION = auto()
3967        BIGDECIMAL = auto()
3968        BIGINT = auto()
3969        BIGSERIAL = auto()
3970        BINARY = auto()
3971        BIT = auto()
3972        BOOLEAN = auto()
3973        BPCHAR = auto()
3974        CHAR = auto()
3975        DATE = auto()
3976        DATE32 = auto()
3977        DATEMULTIRANGE = auto()
3978        DATERANGE = auto()
3979        DATETIME = auto()
3980        DATETIME64 = auto()
3981        DECIMAL = auto()
3982        DOUBLE = auto()
3983        ENUM = auto()
3984        ENUM8 = auto()
3985        ENUM16 = auto()
3986        FIXEDSTRING = auto()
3987        FLOAT = auto()
3988        GEOGRAPHY = auto()
3989        GEOMETRY = auto()
3990        HLLSKETCH = auto()
3991        HSTORE = auto()
3992        IMAGE = auto()
3993        INET = auto()
3994        INT = auto()
3995        INT128 = auto()
3996        INT256 = auto()
3997        INT4MULTIRANGE = auto()
3998        INT4RANGE = auto()
3999        INT8MULTIRANGE = auto()
4000        INT8RANGE = auto()
4001        INTERVAL = auto()
4002        IPADDRESS = auto()
4003        IPPREFIX = auto()
4004        IPV4 = auto()
4005        IPV6 = auto()
4006        JSON = auto()
4007        JSONB = auto()
4008        LIST = auto()
4009        LONGBLOB = auto()
4010        LONGTEXT = auto()
4011        LOWCARDINALITY = auto()
4012        MAP = auto()
4013        MEDIUMBLOB = auto()
4014        MEDIUMINT = auto()
4015        MEDIUMTEXT = auto()
4016        MONEY = auto()
4017        NAME = auto()
4018        NCHAR = auto()
4019        NESTED = auto()
4020        NULL = auto()
4021        NULLABLE = auto()
4022        NUMMULTIRANGE = auto()
4023        NUMRANGE = auto()
4024        NVARCHAR = auto()
4025        OBJECT = auto()
4026        ROWVERSION = auto()
4027        SERIAL = auto()
4028        SET = auto()
4029        SMALLINT = auto()
4030        SMALLMONEY = auto()
4031        SMALLSERIAL = auto()
4032        STRUCT = auto()
4033        SUPER = auto()
4034        TEXT = auto()
4035        TINYBLOB = auto()
4036        TINYTEXT = auto()
4037        TIME = auto()
4038        TIMETZ = auto()
4039        TIMESTAMP = auto()
4040        TIMESTAMPNTZ = auto()
4041        TIMESTAMPLTZ = auto()
4042        TIMESTAMPTZ = auto()
4043        TIMESTAMP_S = auto()
4044        TIMESTAMP_MS = auto()
4045        TIMESTAMP_NS = auto()
4046        TINYINT = auto()
4047        TSMULTIRANGE = auto()
4048        TSRANGE = auto()
4049        TSTZMULTIRANGE = auto()
4050        TSTZRANGE = auto()
4051        UBIGINT = auto()
4052        UINT = auto()
4053        UINT128 = auto()
4054        UINT256 = auto()
4055        UMEDIUMINT = auto()
4056        UDECIMAL = auto()
4057        UNIQUEIDENTIFIER = auto()
4058        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4059        USERDEFINED = "USER-DEFINED"
4060        USMALLINT = auto()
4061        UTINYINT = auto()
4062        UUID = auto()
4063        VARBINARY = auto()
4064        VARCHAR = auto()
4065        VARIANT = auto()
4066        VECTOR = auto()
4067        XML = auto()
4068        YEAR = auto()
4069        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'>
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'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
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'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
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'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
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'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4231class PseudoType(DataType):
4232    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4236class ObjectIdentifier(DataType):
4237    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4241class SubqueryPredicate(Predicate):
4242    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4245class All(SubqueryPredicate):
4246    pass
key = 'all'
class Any(SubqueryPredicate):
4249class Any(SubqueryPredicate):
4250    pass
key = 'any'
class Exists(SubqueryPredicate):
4253class Exists(SubqueryPredicate):
4254    pass
key = 'exists'
class Command(Expression):
4259class Command(Expression):
4260    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4263class Transaction(Expression):
4264    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4267class Commit(Expression):
4268    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4271class Rollback(Expression):
4272    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4275class AlterTable(Expression):
4276    arg_types = {
4277        "this": True,
4278        "actions": True,
4279        "exists": False,
4280        "only": False,
4281        "options": False,
4282        "cluster": False,
4283    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4286class AddConstraint(Expression):
4287    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4290class DropPartition(Expression):
4291    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4295class ReplacePartition(Expression):
4296    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4300class Binary(Condition):
4301    arg_types = {"this": True, "expression": True}
4302
4303    @property
4304    def left(self) -> Expression:
4305        return self.this
4306
4307    @property
4308    def right(self) -> Expression:
4309        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4303    @property
4304    def left(self) -> Expression:
4305        return self.this
right: Expression
4307    @property
4308    def right(self) -> Expression:
4309        return self.expression
key = 'binary'
class Add(Binary):
4312class Add(Binary):
4313    pass
key = 'add'
class Connector(Binary):
4316class Connector(Binary):
4317    pass
key = 'connector'
class And(Connector):
4320class And(Connector):
4321    pass
key = 'and'
class Or(Connector):
4324class Or(Connector):
4325    pass
key = 'or'
class BitwiseAnd(Binary):
4328class BitwiseAnd(Binary):
4329    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4332class BitwiseLeftShift(Binary):
4333    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4336class BitwiseOr(Binary):
4337    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4340class BitwiseRightShift(Binary):
4341    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4344class BitwiseXor(Binary):
4345    pass
key = 'bitwisexor'
class Div(Binary):
4348class Div(Binary):
4349    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):
4352class Overlaps(Binary):
4353    pass
key = 'overlaps'
class Dot(Binary):
4356class Dot(Binary):
4357    @property
4358    def is_star(self) -> bool:
4359        return self.expression.is_star
4360
4361    @property
4362    def name(self) -> str:
4363        return self.expression.name
4364
4365    @property
4366    def output_name(self) -> str:
4367        return self.name
4368
4369    @classmethod
4370    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4371        """Build a Dot object with a sequence of expressions."""
4372        if len(expressions) < 2:
4373            raise ValueError("Dot requires >= 2 expressions.")
4374
4375        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4376
4377    @property
4378    def parts(self) -> t.List[Expression]:
4379        """Return the parts of a table / column in order catalog, db, table."""
4380        this, *parts = self.flatten()
4381
4382        parts.reverse()
4383
4384        for arg in COLUMN_PARTS:
4385            part = this.args.get(arg)
4386
4387            if isinstance(part, Expression):
4388                parts.append(part)
4389
4390        parts.reverse()
4391        return parts
is_star: bool
4357    @property
4358    def is_star(self) -> bool:
4359        return self.expression.is_star

Checks whether an expression is a star.

name: str
4361    @property
4362    def name(self) -> str:
4363        return self.expression.name
output_name: str
4365    @property
4366    def output_name(self) -> str:
4367        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:
4369    @classmethod
4370    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4371        """Build a Dot object with a sequence of expressions."""
4372        if len(expressions) < 2:
4373            raise ValueError("Dot requires >= 2 expressions.")
4374
4375        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]
4377    @property
4378    def parts(self) -> t.List[Expression]:
4379        """Return the parts of a table / column in order catalog, db, table."""
4380        this, *parts = self.flatten()
4381
4382        parts.reverse()
4383
4384        for arg in COLUMN_PARTS:
4385            part = this.args.get(arg)
4386
4387            if isinstance(part, Expression):
4388                parts.append(part)
4389
4390        parts.reverse()
4391        return parts

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

key = 'dot'
class DPipe(Binary):
4394class DPipe(Binary):
4395    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4398class EQ(Binary, Predicate):
4399    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4402class NullSafeEQ(Binary, Predicate):
4403    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4406class NullSafeNEQ(Binary, Predicate):
4407    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4411class PropertyEQ(Binary):
4412    pass
key = 'propertyeq'
class Distance(Binary):
4415class Distance(Binary):
4416    pass
key = 'distance'
class Escape(Binary):
4419class Escape(Binary):
4420    pass
key = 'escape'
class Glob(Binary, Predicate):
4423class Glob(Binary, Predicate):
4424    pass
key = 'glob'
class GT(Binary, Predicate):
4427class GT(Binary, Predicate):
4428    pass
key = 'gt'
class GTE(Binary, Predicate):
4431class GTE(Binary, Predicate):
4432    pass
key = 'gte'
class ILike(Binary, Predicate):
4435class ILike(Binary, Predicate):
4436    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4439class ILikeAny(Binary, Predicate):
4440    pass
key = 'ilikeany'
class IntDiv(Binary):
4443class IntDiv(Binary):
4444    pass
key = 'intdiv'
class Is(Binary, Predicate):
4447class Is(Binary, Predicate):
4448    pass
key = 'is'
class Kwarg(Binary):
4451class Kwarg(Binary):
4452    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4455class Like(Binary, Predicate):
4456    pass
key = 'like'
class LikeAny(Binary, Predicate):
4459class LikeAny(Binary, Predicate):
4460    pass
key = 'likeany'
class LT(Binary, Predicate):
4463class LT(Binary, Predicate):
4464    pass
key = 'lt'
class LTE(Binary, Predicate):
4467class LTE(Binary, Predicate):
4468    pass
key = 'lte'
class Mod(Binary):
4471class Mod(Binary):
4472    pass
key = 'mod'
class Mul(Binary):
4475class Mul(Binary):
4476    pass
key = 'mul'
class NEQ(Binary, Predicate):
4479class NEQ(Binary, Predicate):
4480    pass
key = 'neq'
class Operator(Binary):
4484class Operator(Binary):
4485    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4488class SimilarTo(Binary, Predicate):
4489    pass
key = 'similarto'
class Slice(Binary):
4492class Slice(Binary):
4493    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4496class Sub(Binary):
4497    pass
key = 'sub'
class Unary(Condition):
4502class Unary(Condition):
4503    pass
key = 'unary'
class BitwiseNot(Unary):
4506class BitwiseNot(Unary):
4507    pass
key = 'bitwisenot'
class Not(Unary):
4510class Not(Unary):
4511    pass
key = 'not'
class Paren(Unary):
4514class Paren(Unary):
4515    @property
4516    def output_name(self) -> str:
4517        return self.this.name
output_name: str
4515    @property
4516    def output_name(self) -> str:
4517        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):
4520class Neg(Unary):
4521    def to_py(self) -> int | Decimal:
4522        if self.is_number:
4523            return self.this.to_py() * -1
4524        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4521    def to_py(self) -> int | Decimal:
4522        if self.is_number:
4523            return self.this.to_py() * -1
4524        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4527class Alias(Expression):
4528    arg_types = {"this": True, "alias": False}
4529
4530    @property
4531    def output_name(self) -> str:
4532        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4530    @property
4531    def output_name(self) -> str:
4532        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):
4537class PivotAlias(Alias):
4538    pass
key = 'pivotalias'
class PivotAny(Expression):
4543class PivotAny(Expression):
4544    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4547class Aliases(Expression):
4548    arg_types = {"this": True, "expressions": True}
4549
4550    @property
4551    def aliases(self):
4552        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4550    @property
4551    def aliases(self):
4552        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4556class AtIndex(Expression):
4557    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4560class AtTimeZone(Expression):
4561    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4564class FromTimeZone(Expression):
4565    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4568class Between(Predicate):
4569    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4572class Bracket(Condition):
4573    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4574    arg_types = {
4575        "this": True,
4576        "expressions": True,
4577        "offset": False,
4578        "safe": False,
4579        "returns_list_for_maps": False,
4580    }
4581
4582    @property
4583    def output_name(self) -> str:
4584        if len(self.expressions) == 1:
4585            return self.expressions[0].output_name
4586
4587        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4582    @property
4583    def output_name(self) -> str:
4584        if len(self.expressions) == 1:
4585            return self.expressions[0].output_name
4586
4587        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):
4590class Distinct(Expression):
4591    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4594class In(Predicate):
4595    arg_types = {
4596        "this": True,
4597        "expressions": False,
4598        "query": False,
4599        "unnest": False,
4600        "field": False,
4601        "is_global": False,
4602    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4606class ForIn(Expression):
4607    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4610class TimeUnit(Expression):
4611    """Automatically converts unit arg into a var."""
4612
4613    arg_types = {"unit": False}
4614
4615    UNABBREVIATED_UNIT_NAME = {
4616        "D": "DAY",
4617        "H": "HOUR",
4618        "M": "MINUTE",
4619        "MS": "MILLISECOND",
4620        "NS": "NANOSECOND",
4621        "Q": "QUARTER",
4622        "S": "SECOND",
4623        "US": "MICROSECOND",
4624        "W": "WEEK",
4625        "Y": "YEAR",
4626    }
4627
4628    VAR_LIKE = (Column, Literal, Var)
4629
4630    def __init__(self, **args):
4631        unit = args.get("unit")
4632        if isinstance(unit, self.VAR_LIKE):
4633            args["unit"] = Var(
4634                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4635            )
4636        elif isinstance(unit, Week):
4637            unit.set("this", Var(this=unit.this.name.upper()))
4638
4639        super().__init__(**args)
4640
4641    @property
4642    def unit(self) -> t.Optional[Var | IntervalSpan]:
4643        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4630    def __init__(self, **args):
4631        unit = args.get("unit")
4632        if isinstance(unit, self.VAR_LIKE):
4633            args["unit"] = Var(
4634                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4635            )
4636        elif isinstance(unit, Week):
4637            unit.set("this", Var(this=unit.this.name.upper()))
4638
4639        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]
4641    @property
4642    def unit(self) -> t.Optional[Var | IntervalSpan]:
4643        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4646class IntervalOp(TimeUnit):
4647    arg_types = {"unit": True, "expression": True}
4648
4649    def interval(self):
4650        return Interval(
4651            this=self.expression.copy(),
4652            unit=self.unit.copy(),
4653        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4649    def interval(self):
4650        return Interval(
4651            this=self.expression.copy(),
4652            unit=self.unit.copy(),
4653        )
key = 'intervalop'
class IntervalSpan(DataType):
4659class IntervalSpan(DataType):
4660    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4663class Interval(TimeUnit):
4664    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4667class IgnoreNulls(Expression):
4668    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4671class RespectNulls(Expression):
4672    pass
key = 'respectnulls'
class HavingMax(Expression):
4676class HavingMax(Expression):
4677    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4681class Func(Condition):
4682    """
4683    The base class for all function expressions.
4684
4685    Attributes:
4686        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4687            treated as a variable length argument and the argument's value will be stored as a list.
4688        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4689            function expression. These values are used to map this node to a name during parsing as
4690            well as to provide the function's name during SQL string generation. By default the SQL
4691            name is set to the expression's class name transformed to snake case.
4692    """
4693
4694    is_var_len_args = False
4695
4696    @classmethod
4697    def from_arg_list(cls, args):
4698        if cls.is_var_len_args:
4699            all_arg_keys = list(cls.arg_types)
4700            # If this function supports variable length argument treat the last argument as such.
4701            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4702            num_non_var = len(non_var_len_arg_keys)
4703
4704            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4705            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4706        else:
4707            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4708
4709        return cls(**args_dict)
4710
4711    @classmethod
4712    def sql_names(cls):
4713        if cls is Func:
4714            raise NotImplementedError(
4715                "SQL name is only supported by concrete function implementations"
4716            )
4717        if "_sql_names" not in cls.__dict__:
4718            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4719        return cls._sql_names
4720
4721    @classmethod
4722    def sql_name(cls):
4723        return cls.sql_names()[0]
4724
4725    @classmethod
4726    def default_parser_mappings(cls):
4727        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):
4696    @classmethod
4697    def from_arg_list(cls, args):
4698        if cls.is_var_len_args:
4699            all_arg_keys = list(cls.arg_types)
4700            # If this function supports variable length argument treat the last argument as such.
4701            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4702            num_non_var = len(non_var_len_arg_keys)
4703
4704            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4705            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4706        else:
4707            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4708
4709        return cls(**args_dict)
@classmethod
def sql_names(cls):
4711    @classmethod
4712    def sql_names(cls):
4713        if cls is Func:
4714            raise NotImplementedError(
4715                "SQL name is only supported by concrete function implementations"
4716            )
4717        if "_sql_names" not in cls.__dict__:
4718            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4719        return cls._sql_names
@classmethod
def sql_name(cls):
4721    @classmethod
4722    def sql_name(cls):
4723        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4725    @classmethod
4726    def default_parser_mappings(cls):
4727        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4730class AggFunc(Func):
4731    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4734class ParameterizedAgg(AggFunc):
4735    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4738class Abs(Func):
4739    pass
key = 'abs'
class ArgMax(AggFunc):
4742class ArgMax(AggFunc):
4743    arg_types = {"this": True, "expression": True, "count": False}
4744    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4747class ArgMin(AggFunc):
4748    arg_types = {"this": True, "expression": True, "count": False}
4749    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4752class ApproxTopK(AggFunc):
4753    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4756class Flatten(Func):
4757    pass
key = 'flatten'
class Transform(Func):
4761class Transform(Func):
4762    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4765class Anonymous(Func):
4766    arg_types = {"this": True, "expressions": False}
4767    is_var_len_args = True
4768
4769    @property
4770    def name(self) -> str:
4771        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
4769    @property
4770    def name(self) -> str:
4771        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4774class AnonymousAggFunc(AggFunc):
4775    arg_types = {"this": True, "expressions": False}
4776    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4780class CombinedAggFunc(AnonymousAggFunc):
4781    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4784class CombinedParameterizedAgg(ParameterizedAgg):
4785    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
4790class Hll(AggFunc):
4791    arg_types = {"this": True, "expressions": False}
4792    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4795class ApproxDistinct(AggFunc):
4796    arg_types = {"this": True, "accuracy": False}
4797    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4800class Array(Func):
4801    arg_types = {"expressions": False, "bracket_notation": False}
4802    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4806class ToArray(Func):
4807    pass
key = 'toarray'
class List(Func):
4811class List(Func):
4812    arg_types = {"expressions": False}
4813    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4817class Pad(Func):
4818    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):
4823class ToChar(Func):
4824    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4829class ToNumber(Func):
4830    arg_types = {
4831        "this": True,
4832        "format": False,
4833        "nlsparam": False,
4834        "precision": False,
4835        "scale": False,
4836    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4840class Convert(Func):
4841    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4844class GenerateSeries(Func):
4845    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):
4851class ExplodingGenerateSeries(GenerateSeries):
4852    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4855class ArrayAgg(AggFunc):
4856    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4859class ArrayUniqueAgg(AggFunc):
4860    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4863class ArrayAll(Func):
4864    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4868class ArrayAny(Func):
4869    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4872class ArrayConcat(Func):
4873    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4874    arg_types = {"this": True, "expressions": False}
4875    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4878class ArrayConstructCompact(Func):
4879    arg_types = {"expressions": True}
4880    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4883class ArrayContains(Binary, Func):
4884    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4887class ArrayContainsAll(Binary, Func):
4888    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4891class ArrayFilter(Func):
4892    arg_types = {"this": True, "expression": True}
4893    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4896class ArrayToString(Func):
4897    arg_types = {"this": True, "expression": True, "null": False}
4898    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4901class StringToArray(Func):
4902    arg_types = {"this": True, "expression": True, "null": False}
4903    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4906class ArrayOverlaps(Binary, Func):
4907    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4910class ArraySize(Func):
4911    arg_types = {"this": True, "expression": False}
4912    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4915class ArraySort(Func):
4916    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4919class ArraySum(Func):
4920    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4923class ArrayUnionAgg(AggFunc):
4924    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4927class Avg(AggFunc):
4928    pass
key = 'avg'
class AnyValue(AggFunc):
4931class AnyValue(AggFunc):
4932    pass
key = 'anyvalue'
class Lag(AggFunc):
4935class Lag(AggFunc):
4936    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4939class Lead(AggFunc):
4940    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4945class First(AggFunc):
4946    pass
key = 'first'
class Last(AggFunc):
4949class Last(AggFunc):
4950    pass
key = 'last'
class FirstValue(AggFunc):
4953class FirstValue(AggFunc):
4954    pass
key = 'firstvalue'
class LastValue(AggFunc):
4957class LastValue(AggFunc):
4958    pass
key = 'lastvalue'
class NthValue(AggFunc):
4961class NthValue(AggFunc):
4962    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4965class Case(Func):
4966    arg_types = {"this": False, "ifs": True, "default": False}
4967
4968    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4969        instance = maybe_copy(self, copy)
4970        instance.append(
4971            "ifs",
4972            If(
4973                this=maybe_parse(condition, copy=copy, **opts),
4974                true=maybe_parse(then, copy=copy, **opts),
4975            ),
4976        )
4977        return instance
4978
4979    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4980        instance = maybe_copy(self, copy)
4981        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4982        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:
4968    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4969        instance = maybe_copy(self, copy)
4970        instance.append(
4971            "ifs",
4972            If(
4973                this=maybe_parse(condition, copy=copy, **opts),
4974                true=maybe_parse(then, copy=copy, **opts),
4975            ),
4976        )
4977        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4979    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4980        instance = maybe_copy(self, copy)
4981        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4982        return instance
key = 'case'
class Cast(Func):
4985class Cast(Func):
4986    arg_types = {
4987        "this": True,
4988        "to": True,
4989        "format": False,
4990        "safe": False,
4991        "action": False,
4992    }
4993
4994    @property
4995    def name(self) -> str:
4996        return self.this.name
4997
4998    @property
4999    def to(self) -> DataType:
5000        return self.args["to"]
5001
5002    @property
5003    def output_name(self) -> str:
5004        return self.name
5005
5006    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5007        """
5008        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5009        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5010        array<int> != array<float>.
5011
5012        Args:
5013            dtypes: the data types to compare this Cast's DataType to.
5014
5015        Returns:
5016            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5017        """
5018        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4994    @property
4995    def name(self) -> str:
4996        return self.this.name
to: DataType
4998    @property
4999    def to(self) -> DataType:
5000        return self.args["to"]
output_name: str
5002    @property
5003    def output_name(self) -> str:
5004        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, DataType, DataType.Type]) -> bool:
5006    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5007        """
5008        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5009        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5010        array<int> != array<float>.
5011
5012        Args:
5013            dtypes: the data types to compare this Cast's DataType to.
5014
5015        Returns:
5016            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5017        """
5018        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):
5021class TryCast(Cast):
5022    pass
key = 'trycast'
class Try(Func):
5025class Try(Func):
5026    pass
key = 'try'
class CastToStrType(Func):
5029class CastToStrType(Func):
5030    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5033class Collate(Binary, Func):
5034    pass
key = 'collate'
class Ceil(Func):
5037class Ceil(Func):
5038    arg_types = {"this": True, "decimals": False}
5039    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5042class Coalesce(Func):
5043    arg_types = {"this": True, "expressions": False}
5044    is_var_len_args = True
5045    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5048class Chr(Func):
5049    arg_types = {"this": True, "charset": False, "expressions": False}
5050    is_var_len_args = True
5051    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5054class Concat(Func):
5055    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5056    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5059class ConcatWs(Concat):
5060    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5064class ConnectByRoot(Func):
5065    pass
key = 'connectbyroot'
class Count(AggFunc):
5068class Count(AggFunc):
5069    arg_types = {"this": False, "expressions": False}
5070    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5073class CountIf(AggFunc):
5074    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5078class Cbrt(Func):
5079    pass
key = 'cbrt'
class CurrentDate(Func):
5082class CurrentDate(Func):
5083    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5086class CurrentDatetime(Func):
5087    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5090class CurrentTime(Func):
5091    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5094class CurrentTimestamp(Func):
5095    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5098class CurrentUser(Func):
5099    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5102class DateAdd(Func, IntervalOp):
5103    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5106class DateSub(Func, IntervalOp):
5107    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5110class DateDiff(Func, TimeUnit):
5111    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5112    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5115class DateTrunc(Func):
5116    arg_types = {"unit": True, "this": True, "zone": False}
5117
5118    def __init__(self, **args):
5119        unit = args.get("unit")
5120        if isinstance(unit, TimeUnit.VAR_LIKE):
5121            args["unit"] = Literal.string(
5122                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5123            )
5124        elif isinstance(unit, Week):
5125            unit.set("this", Literal.string(unit.this.name.upper()))
5126
5127        super().__init__(**args)
5128
5129    @property
5130    def unit(self) -> Expression:
5131        return self.args["unit"]
DateTrunc(**args)
5118    def __init__(self, **args):
5119        unit = args.get("unit")
5120        if isinstance(unit, TimeUnit.VAR_LIKE):
5121            args["unit"] = Literal.string(
5122                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5123            )
5124        elif isinstance(unit, Week):
5125            unit.set("this", Literal.string(unit.this.name.upper()))
5126
5127        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5129    @property
5130    def unit(self) -> Expression:
5131        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5136class Datetime(Func):
5137    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5140class DatetimeAdd(Func, IntervalOp):
5141    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5144class DatetimeSub(Func, IntervalOp):
5145    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5148class DatetimeDiff(Func, TimeUnit):
5149    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5152class DatetimeTrunc(Func, TimeUnit):
5153    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5156class DayOfWeek(Func):
5157    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5160class DayOfMonth(Func):
5161    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5164class DayOfYear(Func):
5165    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5168class ToDays(Func):
5169    pass
key = 'todays'
class WeekOfYear(Func):
5172class WeekOfYear(Func):
5173    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5176class MonthsBetween(Func):
5177    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5180class LastDay(Func, TimeUnit):
5181    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5182    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5185class Extract(Func):
5186    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5189class Timestamp(Func):
5190    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5193class TimestampAdd(Func, TimeUnit):
5194    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5197class TimestampSub(Func, TimeUnit):
5198    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5201class TimestampDiff(Func, TimeUnit):
5202    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5203    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5206class TimestampTrunc(Func, TimeUnit):
5207    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5210class TimeAdd(Func, TimeUnit):
5211    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5214class TimeSub(Func, TimeUnit):
5215    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5218class TimeDiff(Func, TimeUnit):
5219    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5222class TimeTrunc(Func, TimeUnit):
5223    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5226class DateFromParts(Func):
5227    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5228    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5231class TimeFromParts(Func):
5232    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5233    arg_types = {
5234        "hour": True,
5235        "min": True,
5236        "sec": True,
5237        "nano": False,
5238        "fractions": False,
5239        "precision": False,
5240    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5243class DateStrToDate(Func):
5244    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5247class DateToDateStr(Func):
5248    pass
key = 'datetodatestr'
class DateToDi(Func):
5251class DateToDi(Func):
5252    pass
key = 'datetodi'
class Date(Func):
5256class Date(Func):
5257    arg_types = {"this": False, "zone": False, "expressions": False}
5258    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5261class Day(Func):
5262    pass
key = 'day'
class Decode(Func):
5265class Decode(Func):
5266    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5269class DiToDate(Func):
5270    pass
key = 'ditodate'
class Encode(Func):
5273class Encode(Func):
5274    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5277class Exp(Func):
5278    pass
key = 'exp'
class Explode(Func):
5282class Explode(Func):
5283    arg_types = {"this": True, "expressions": False}
5284    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5287class ExplodeOuter(Explode):
5288    pass
key = 'explodeouter'
class Posexplode(Explode):
5291class Posexplode(Explode):
5292    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5295class PosexplodeOuter(Posexplode, ExplodeOuter):
5296    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5299class Unnest(Func, UDTF):
5300    arg_types = {
5301        "expressions": True,
5302        "alias": False,
5303        "offset": False,
5304    }
5305
5306    @property
5307    def selects(self) -> t.List[Expression]:
5308        columns = super().selects
5309        offset = self.args.get("offset")
5310        if offset:
5311            columns = columns + [to_identifier("offset") if offset is True else offset]
5312        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5306    @property
5307    def selects(self) -> t.List[Expression]:
5308        columns = super().selects
5309        offset = self.args.get("offset")
5310        if offset:
5311            columns = columns + [to_identifier("offset") if offset is True else offset]
5312        return columns
key = 'unnest'
class Floor(Func):
5315class Floor(Func):
5316    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5319class FromBase64(Func):
5320    pass
key = 'frombase64'
class ToBase64(Func):
5323class ToBase64(Func):
5324    pass
key = 'tobase64'
class GapFill(Func):
5327class GapFill(Func):
5328    arg_types = {
5329        "this": True,
5330        "ts_column": True,
5331        "bucket_width": True,
5332        "partitioning_columns": False,
5333        "value_columns": False,
5334        "origin": False,
5335        "ignore_nulls": False,
5336    }
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):
5339class GenerateDateArray(Func):
5340    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5343class Greatest(Func):
5344    arg_types = {"this": True, "expressions": False}
5345    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5348class GroupConcat(AggFunc):
5349    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5352class Hex(Func):
5353    pass
key = 'hex'
class LowerHex(Hex):
5356class LowerHex(Hex):
5357    pass
key = 'lowerhex'
class Xor(Connector, Func):
5360class Xor(Connector, Func):
5361    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5364class If(Func):
5365    arg_types = {"this": True, "true": True, "false": False}
5366    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5369class Nullif(Func):
5370    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5373class Initcap(Func):
5374    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5377class IsNan(Func):
5378    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5381class IsInf(Func):
5382    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5385class JSONPath(Expression):
5386    arg_types = {"expressions": True}
5387
5388    @property
5389    def output_name(self) -> str:
5390        last_segment = self.expressions[-1].this
5391        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5388    @property
5389    def output_name(self) -> str:
5390        last_segment = self.expressions[-1].this
5391        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):
5394class JSONPathPart(Expression):
5395    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5398class JSONPathFilter(JSONPathPart):
5399    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5402class JSONPathKey(JSONPathPart):
5403    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5406class JSONPathRecursive(JSONPathPart):
5407    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5410class JSONPathRoot(JSONPathPart):
5411    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5414class JSONPathScript(JSONPathPart):
5415    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5418class JSONPathSlice(JSONPathPart):
5419    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5422class JSONPathSelector(JSONPathPart):
5423    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5426class JSONPathSubscript(JSONPathPart):
5427    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5430class JSONPathUnion(JSONPathPart):
5431    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5434class JSONPathWildcard(JSONPathPart):
5435    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5438class FormatJson(Expression):
5439    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5442class JSONKeyValue(Expression):
5443    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5446class JSONObject(Func):
5447    arg_types = {
5448        "expressions": False,
5449        "null_handling": False,
5450        "unique_keys": False,
5451        "return_type": False,
5452        "encoding": False,
5453    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5456class JSONObjectAgg(AggFunc):
5457    arg_types = {
5458        "expressions": False,
5459        "null_handling": False,
5460        "unique_keys": False,
5461        "return_type": False,
5462        "encoding": False,
5463    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5467class JSONArray(Func):
5468    arg_types = {
5469        "expressions": True,
5470        "null_handling": False,
5471        "return_type": False,
5472        "strict": False,
5473    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5477class JSONArrayAgg(Func):
5478    arg_types = {
5479        "this": True,
5480        "order": False,
5481        "null_handling": False,
5482        "return_type": False,
5483        "strict": False,
5484    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5489class JSONColumnDef(Expression):
5490    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):
5493class JSONSchema(Expression):
5494    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5498class JSONTable(Func):
5499    arg_types = {
5500        "this": True,
5501        "schema": True,
5502        "path": False,
5503        "error_handling": False,
5504        "empty_handling": False,
5505    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5509class ObjectInsert(Func):
5510    arg_types = {
5511        "this": True,
5512        "key": True,
5513        "value": True,
5514        "update_flag": False,
5515    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5518class OpenJSONColumnDef(Expression):
5519    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):
5522class OpenJSON(Func):
5523    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5526class JSONBContains(Binary, Func):
5527    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5530class JSONExtract(Binary, Func):
5531    arg_types = {
5532        "this": True,
5533        "expression": True,
5534        "only_json_types": False,
5535        "expressions": False,
5536        "variant_extract": False,
5537    }
5538    _sql_names = ["JSON_EXTRACT"]
5539    is_var_len_args = True
5540
5541    @property
5542    def output_name(self) -> str:
5543        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}
is_var_len_args = True
output_name: str
5541    @property
5542    def output_name(self) -> str:
5543        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 JSONExtractScalar(Binary, Func):
5546class JSONExtractScalar(Binary, Func):
5547    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5548    _sql_names = ["JSON_EXTRACT_SCALAR"]
5549    is_var_len_args = True
5550
5551    @property
5552    def output_name(self) -> str:
5553        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
5551    @property
5552    def output_name(self) -> str:
5553        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):
5556class JSONBExtract(Binary, Func):
5557    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5560class JSONBExtractScalar(Binary, Func):
5561    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5564class JSONFormat(Func):
5565    arg_types = {"this": False, "options": False}
5566    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5570class JSONArrayContains(Binary, Predicate, Func):
5571    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5574class ParseJSON(Func):
5575    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5576    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5577    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5578    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5581class Least(Func):
5582    arg_types = {"this": True, "expressions": False}
5583    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5586class Left(Func):
5587    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5594class Length(Func):
5595    arg_types = {"this": True, "binary": False}
5596    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5599class Levenshtein(Func):
5600    arg_types = {
5601        "this": True,
5602        "expression": False,
5603        "ins_cost": False,
5604        "del_cost": False,
5605        "sub_cost": False,
5606    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5609class Ln(Func):
5610    pass
key = 'ln'
class Log(Func):
5613class Log(Func):
5614    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5617class LogicalOr(AggFunc):
5618    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5621class LogicalAnd(AggFunc):
5622    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5625class Lower(Func):
5626    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5629class Map(Func):
5630    arg_types = {"keys": False, "values": False}
5631
5632    @property
5633    def keys(self) -> t.List[Expression]:
5634        keys = self.args.get("keys")
5635        return keys.expressions if keys else []
5636
5637    @property
5638    def values(self) -> t.List[Expression]:
5639        values = self.args.get("values")
5640        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5632    @property
5633    def keys(self) -> t.List[Expression]:
5634        keys = self.args.get("keys")
5635        return keys.expressions if keys else []
values: List[Expression]
5637    @property
5638    def values(self) -> t.List[Expression]:
5639        values = self.args.get("values")
5640        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5644class ToMap(Func):
5645    pass
key = 'tomap'
class MapFromEntries(Func):
5648class MapFromEntries(Func):
5649    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5653class ScopeResolution(Expression):
5654    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class StarMap(Func):
5657class StarMap(Func):
5658    pass
key = 'starmap'
class VarMap(Func):
5661class VarMap(Func):
5662    arg_types = {"keys": True, "values": True}
5663    is_var_len_args = True
5664
5665    @property
5666    def keys(self) -> t.List[Expression]:
5667        return self.args["keys"].expressions
5668
5669    @property
5670    def values(self) -> t.List[Expression]:
5671        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5665    @property
5666    def keys(self) -> t.List[Expression]:
5667        return self.args["keys"].expressions
values: List[Expression]
5669    @property
5670    def values(self) -> t.List[Expression]:
5671        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5675class MatchAgainst(Func):
5676    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5679class Max(AggFunc):
5680    arg_types = {"this": True, "expressions": False}
5681    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5684class MD5(Func):
5685    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5689class MD5Digest(Func):
5690    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5693class Min(AggFunc):
5694    arg_types = {"this": True, "expressions": False}
5695    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5698class Month(Func):
5699    pass
key = 'month'
class AddMonths(Func):
5702class AddMonths(Func):
5703    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5706class Nvl2(Func):
5707    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5711class Predict(Func):
5712    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5715class Pow(Binary, Func):
5716    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5719class PercentileCont(AggFunc):
5720    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5723class PercentileDisc(AggFunc):
5724    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5727class Quantile(AggFunc):
5728    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5731class ApproxQuantile(Quantile):
5732    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):
5735class Quarter(Func):
5736    pass
key = 'quarter'
class Rand(Func):
5741class Rand(Func):
5742    _sql_names = ["RAND", "RANDOM"]
5743    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5746class Randn(Func):
5747    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5750class RangeN(Func):
5751    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5754class ReadCSV(Func):
5755    _sql_names = ["READ_CSV"]
5756    is_var_len_args = True
5757    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5760class Reduce(Func):
5761    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):
5764class RegexpExtract(Func):
5765    arg_types = {
5766        "this": True,
5767        "expression": True,
5768        "position": False,
5769        "occurrence": False,
5770        "parameters": False,
5771        "group": False,
5772    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5775class RegexpReplace(Func):
5776    arg_types = {
5777        "this": True,
5778        "expression": True,
5779        "replacement": False,
5780        "position": False,
5781        "occurrence": False,
5782        "modifiers": False,
5783    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5786class RegexpLike(Binary, Func):
5787    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5790class RegexpILike(Binary, Func):
5791    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5796class RegexpSplit(Func):
5797    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5800class Repeat(Func):
5801    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5806class Round(Func):
5807    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5810class RowNumber(Func):
5811    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5814class SafeDivide(Func):
5815    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5818class SHA(Func):
5819    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5822class SHA2(Func):
5823    _sql_names = ["SHA2"]
5824    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5827class Sign(Func):
5828    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5831class SortArray(Func):
5832    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5835class Split(Func):
5836    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5841class Substring(Func):
5842    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5845class StandardHash(Func):
5846    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5849class StartsWith(Func):
5850    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5851    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5854class StrPosition(Func):
5855    arg_types = {
5856        "this": True,
5857        "substr": True,
5858        "position": False,
5859        "instance": False,
5860    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5863class StrToDate(Func):
5864    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5867class StrToTime(Func):
5868    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):
5873class StrToUnix(Func):
5874    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5879class StrToMap(Func):
5880    arg_types = {
5881        "this": True,
5882        "pair_delim": False,
5883        "key_value_delim": False,
5884        "duplicate_resolution_callback": False,
5885    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5888class NumberToStr(Func):
5889    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5892class FromBase(Func):
5893    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5896class Struct(Func):
5897    arg_types = {"expressions": False}
5898    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5901class StructExtract(Func):
5902    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5907class Stuff(Func):
5908    _sql_names = ["STUFF", "INSERT"]
5909    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):
5912class Sum(AggFunc):
5913    pass
key = 'sum'
class Sqrt(Func):
5916class Sqrt(Func):
5917    pass
key = 'sqrt'
class Stddev(AggFunc):
5920class Stddev(AggFunc):
5921    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
5924class StddevPop(AggFunc):
5925    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5928class StddevSamp(AggFunc):
5929    pass
key = 'stddevsamp'
class Time(Func):
5933class Time(Func):
5934    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5937class TimeToStr(Func):
5938    arg_types = {"this": True, "format": True, "culture": False, "timezone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'timezone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5941class TimeToTimeStr(Func):
5942    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5945class TimeToUnix(Func):
5946    pass
key = 'timetounix'
class TimeStrToDate(Func):
5949class TimeStrToDate(Func):
5950    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5953class TimeStrToTime(Func):
5954    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5957class TimeStrToUnix(Func):
5958    pass
key = 'timestrtounix'
class Trim(Func):
5961class Trim(Func):
5962    arg_types = {
5963        "this": True,
5964        "expression": False,
5965        "position": False,
5966        "collation": False,
5967    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5970class TsOrDsAdd(Func, TimeUnit):
5971    # return_type is used to correctly cast the arguments of this expression when transpiling it
5972    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5973
5974    @property
5975    def return_type(self) -> DataType:
5976        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
5974    @property
5975    def return_type(self) -> DataType:
5976        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5979class TsOrDsDiff(Func, TimeUnit):
5980    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5983class TsOrDsToDateStr(Func):
5984    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5987class TsOrDsToDate(Func):
5988    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5991class TsOrDsToTime(Func):
5992    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5995class TsOrDsToTimestamp(Func):
5996    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5999class TsOrDiToDi(Func):
6000    pass
key = 'tsorditodi'
class Unhex(Func):
6003class Unhex(Func):
6004    pass
key = 'unhex'
class UnixDate(Func):
6008class UnixDate(Func):
6009    pass
key = 'unixdate'
class UnixToStr(Func):
6012class UnixToStr(Func):
6013    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6018class UnixToTime(Func):
6019    arg_types = {
6020        "this": True,
6021        "scale": False,
6022        "zone": False,
6023        "hours": False,
6024        "minutes": False,
6025        "format": False,
6026    }
6027
6028    SECONDS = Literal.number(0)
6029    DECIS = Literal.number(1)
6030    CENTIS = Literal.number(2)
6031    MILLIS = Literal.number(3)
6032    DECIMILLIS = Literal.number(4)
6033    CENTIMILLIS = Literal.number(5)
6034    MICROS = Literal.number(6)
6035    DECIMICROS = Literal.number(7)
6036    CENTIMICROS = Literal.number(8)
6037    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):
6040class UnixToTimeStr(Func):
6041    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6044class TimestampFromParts(Func):
6045    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6046    arg_types = {
6047        "year": True,
6048        "month": True,
6049        "day": True,
6050        "hour": True,
6051        "min": True,
6052        "sec": True,
6053        "nano": False,
6054        "zone": False,
6055        "milli": False,
6056    }
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):
6059class Upper(Func):
6060    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6063class Corr(Binary, AggFunc):
6064    pass
key = 'corr'
class Variance(AggFunc):
6067class Variance(AggFunc):
6068    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6071class VariancePop(AggFunc):
6072    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6075class CovarSamp(Binary, AggFunc):
6076    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6079class CovarPop(Binary, AggFunc):
6080    pass
key = 'covarpop'
class Week(Func):
6083class Week(Func):
6084    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6087class XMLTable(Func):
6088    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
arg_types = {'this': True, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class Year(Func):
6091class Year(Func):
6092    pass
key = 'year'
class Use(Expression):
6095class Use(Expression):
6096    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6099class Merge(Expression):
6100    arg_types = {
6101        "this": True,
6102        "using": True,
6103        "on": True,
6104        "expressions": True,
6105        "with": False,
6106    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6109class When(Func):
6110    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class NextValueFor(Func):
6115class NextValueFor(Func):
6116    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6121class Semicolon(Expression):
6122    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <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 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <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 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <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 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <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 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, '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_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_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, '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'>, 'AVG': <class 'Avg'>, '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'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, '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_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, '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'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, '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_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, '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'>, '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'>, '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'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, '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'>, '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_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, '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'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, '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_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, '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_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_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, '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'>, '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'>, 'WHEN': <class 'When'>, '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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6162def maybe_parse(
6163    sql_or_expression: ExpOrStr,
6164    *,
6165    into: t.Optional[IntoType] = None,
6166    dialect: DialectType = None,
6167    prefix: t.Optional[str] = None,
6168    copy: bool = False,
6169    **opts,
6170) -> Expression:
6171    """Gracefully handle a possible string or expression.
6172
6173    Example:
6174        >>> maybe_parse("1")
6175        Literal(this=1, is_string=False)
6176        >>> maybe_parse(to_identifier("x"))
6177        Identifier(this=x, quoted=False)
6178
6179    Args:
6180        sql_or_expression: the SQL code string or an expression
6181        into: the SQLGlot Expression to parse into
6182        dialect: the dialect used to parse the input expressions (in the case that an
6183            input expression is a SQL string).
6184        prefix: a string to prefix the sql with before it gets parsed
6185            (automatically includes a space)
6186        copy: whether to copy the expression.
6187        **opts: other options to use to parse the input expressions (again, in the case
6188            that an input expression is a SQL string).
6189
6190    Returns:
6191        Expression: the parsed or given expression.
6192    """
6193    if isinstance(sql_or_expression, Expression):
6194        if copy:
6195            return sql_or_expression.copy()
6196        return sql_or_expression
6197
6198    if sql_or_expression is None:
6199        raise ParseError("SQL cannot be None")
6200
6201    import sqlglot
6202
6203    sql = str(sql_or_expression)
6204    if prefix:
6205        sql = f"{prefix} {sql}"
6206
6207    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):
6218def maybe_copy(instance, copy=True):
6219    return instance.copy() if copy and instance else instance
def union( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
6439def union(
6440    left: ExpOrStr,
6441    right: ExpOrStr,
6442    distinct: bool = True,
6443    dialect: DialectType = None,
6444    copy: bool = True,
6445    **opts,
6446) -> Union:
6447    """
6448    Initializes a syntax tree from one UNION expression.
6449
6450    Example:
6451        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6452        'SELECT * FROM foo UNION SELECT * FROM bla'
6453
6454    Args:
6455        left: the SQL code string corresponding to the left-hand side.
6456            If an `Expression` instance is passed, it will be used as-is.
6457        right: the SQL code string corresponding to the right-hand side.
6458            If an `Expression` instance is passed, it will be used as-is.
6459        distinct: set the DISTINCT flag if and only if this is true.
6460        dialect: the dialect used to parse the input expression.
6461        copy: whether to copy the expression.
6462        opts: other options to use to parse the input expressions.
6463
6464    Returns:
6465        The new Union instance.
6466    """
6467    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6468    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6469
6470    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
6473def intersect(
6474    left: ExpOrStr,
6475    right: ExpOrStr,
6476    distinct: bool = True,
6477    dialect: DialectType = None,
6478    copy: bool = True,
6479    **opts,
6480) -> Intersect:
6481    """
6482    Initializes a syntax tree from one INTERSECT expression.
6483
6484    Example:
6485        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6486        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6487
6488    Args:
6489        left: the SQL code string corresponding to the left-hand side.
6490            If an `Expression` instance is passed, it will be used as-is.
6491        right: the SQL code string corresponding to the right-hand side.
6492            If an `Expression` instance is passed, it will be used as-is.
6493        distinct: set the DISTINCT flag if and only if this is true.
6494        dialect: the dialect used to parse the input expression.
6495        copy: whether to copy the expression.
6496        opts: other options to use to parse the input expressions.
6497
6498    Returns:
6499        The new Intersect instance.
6500    """
6501    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6502    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6503
6504    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
6507def except_(
6508    left: ExpOrStr,
6509    right: ExpOrStr,
6510    distinct: bool = True,
6511    dialect: DialectType = None,
6512    copy: bool = True,
6513    **opts,
6514) -> Except:
6515    """
6516    Initializes a syntax tree from one EXCEPT expression.
6517
6518    Example:
6519        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6520        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6521
6522    Args:
6523        left: the SQL code string corresponding to the left-hand side.
6524            If an `Expression` instance is passed, it will be used as-is.
6525        right: the SQL code string corresponding to the right-hand side.
6526            If an `Expression` instance is passed, it will be used as-is.
6527        distinct: set the DISTINCT flag if and only if this is true.
6528        dialect: the dialect used to parse the input expression.
6529        copy: whether to copy the expression.
6530        opts: other options to use to parse the input expressions.
6531
6532    Returns:
6533        The new Except instance.
6534    """
6535    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6536    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6537
6538    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6541def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6542    """
6543    Initializes a syntax tree from one or multiple SELECT expressions.
6544
6545    Example:
6546        >>> select("col1", "col2").from_("tbl").sql()
6547        'SELECT col1, col2 FROM tbl'
6548
6549    Args:
6550        *expressions: the SQL code string to parse as the expressions of a
6551            SELECT statement. If an Expression instance is passed, this is used as-is.
6552        dialect: the dialect used to parse the input expressions (in the case that an
6553            input expression is a SQL string).
6554        **opts: other options to use to parse the input expressions (again, in the case
6555            that an input expression is a SQL string).
6556
6557    Returns:
6558        Select: the syntax tree for the SELECT statement.
6559    """
6560    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6563def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6564    """
6565    Initializes a syntax tree from a FROM expression.
6566
6567    Example:
6568        >>> from_("tbl").select("col1", "col2").sql()
6569        'SELECT col1, col2 FROM tbl'
6570
6571    Args:
6572        *expression: the SQL code string to parse as the FROM expressions of a
6573            SELECT statement. If an Expression instance is passed, this is used as-is.
6574        dialect: the dialect used to parse the input expression (in the case that the
6575            input expression is a SQL string).
6576        **opts: other options to use to parse the input expressions (again, in the case
6577            that the input expression is a SQL string).
6578
6579    Returns:
6580        Select: the syntax tree for the SELECT statement.
6581    """
6582    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: dict, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Update:
6585def update(
6586    table: str | Table,
6587    properties: dict,
6588    where: t.Optional[ExpOrStr] = None,
6589    from_: t.Optional[ExpOrStr] = None,
6590    dialect: DialectType = None,
6591    **opts,
6592) -> Update:
6593    """
6594    Creates an update statement.
6595
6596    Example:
6597        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6598        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6599
6600    Args:
6601        *properties: dictionary of properties to set which are
6602            auto converted to sql objects eg None -> NULL
6603        where: sql conditional parsed into a WHERE statement
6604        from_: sql statement parsed into a FROM statement
6605        dialect: the dialect used to parse the input expressions.
6606        **opts: other options to use to parse the input expressions.
6607
6608    Returns:
6609        Update: the syntax tree for the UPDATE statement.
6610    """
6611    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6612    update_expr.set(
6613        "expressions",
6614        [
6615            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6616            for k, v in properties.items()
6617        ],
6618    )
6619    if from_:
6620        update_expr.set(
6621            "from",
6622            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6623        )
6624    if isinstance(where, Condition):
6625        where = Where(this=where)
6626    if where:
6627        update_expr.set(
6628            "where",
6629            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6630        )
6631    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
"UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
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
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Delete:
6634def delete(
6635    table: ExpOrStr,
6636    where: t.Optional[ExpOrStr] = None,
6637    returning: t.Optional[ExpOrStr] = None,
6638    dialect: DialectType = None,
6639    **opts,
6640) -> Delete:
6641    """
6642    Builds a delete statement.
6643
6644    Example:
6645        >>> delete("my_table", where="id > 1").sql()
6646        'DELETE FROM my_table WHERE id > 1'
6647
6648    Args:
6649        where: sql conditional parsed into a WHERE statement
6650        returning: sql conditional parsed into a RETURNING statement
6651        dialect: the dialect used to parse the input expressions.
6652        **opts: other options to use to parse the input expressions.
6653
6654    Returns:
6655        Delete: the syntax tree for the DELETE statement.
6656    """
6657    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6658    if where:
6659        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6660    if returning:
6661        delete_expr = t.cast(
6662            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6663        )
6664    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
6667def insert(
6668    expression: ExpOrStr,
6669    into: ExpOrStr,
6670    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6671    overwrite: t.Optional[bool] = None,
6672    returning: t.Optional[ExpOrStr] = None,
6673    dialect: DialectType = None,
6674    copy: bool = True,
6675    **opts,
6676) -> Insert:
6677    """
6678    Builds an INSERT statement.
6679
6680    Example:
6681        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6682        'INSERT INTO tbl VALUES (1, 2, 3)'
6683
6684    Args:
6685        expression: the sql string or expression of the INSERT statement
6686        into: the tbl to insert data to.
6687        columns: optionally the table's column names.
6688        overwrite: whether to INSERT OVERWRITE or not.
6689        returning: sql conditional parsed into a RETURNING statement
6690        dialect: the dialect used to parse the input expressions.
6691        copy: whether to copy the expression.
6692        **opts: other options to use to parse the input expressions.
6693
6694    Returns:
6695        Insert: the syntax tree for the INSERT statement.
6696    """
6697    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6698    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6699
6700    if columns:
6701        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6702
6703    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6704
6705    if returning:
6706        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6707
6708    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 condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6711def condition(
6712    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6713) -> Condition:
6714    """
6715    Initialize a logical condition expression.
6716
6717    Example:
6718        >>> condition("x=1").sql()
6719        'x = 1'
6720
6721        This is helpful for composing larger logical syntax trees:
6722        >>> where = condition("x=1")
6723        >>> where = where.and_("y=1")
6724        >>> Select().from_("tbl").select("*").where(where).sql()
6725        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6726
6727    Args:
6728        *expression: the SQL code string to parse.
6729            If an Expression instance is passed, this is used as-is.
6730        dialect: the dialect used to parse the input expression (in the case that the
6731            input expression is a SQL string).
6732        copy: Whether to copy `expression` (only applies to expressions).
6733        **opts: other options to use to parse the input expressions (again, in the case
6734            that the input expression is a SQL string).
6735
6736    Returns:
6737        The new Condition instance
6738    """
6739    return maybe_parse(
6740        expression,
6741        into=Condition,
6742        dialect=dialect,
6743        copy=copy,
6744        **opts,
6745    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6748def and_(
6749    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6750) -> Condition:
6751    """
6752    Combine multiple conditions with an AND logical operator.
6753
6754    Example:
6755        >>> and_("x=1", and_("y=1", "z=1")).sql()
6756        'x = 1 AND (y = 1 AND z = 1)'
6757
6758    Args:
6759        *expressions: the SQL code strings to parse.
6760            If an Expression instance is passed, this is used as-is.
6761        dialect: the dialect used to parse the input expression.
6762        copy: whether to copy `expressions` (only applies to Expressions).
6763        **opts: other options to use to parse the input expressions.
6764
6765    Returns:
6766        The new condition
6767    """
6768    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **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).
  • **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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6771def or_(
6772    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6773) -> Condition:
6774    """
6775    Combine multiple conditions with an OR logical operator.
6776
6777    Example:
6778        >>> or_("x=1", or_("y=1", "z=1")).sql()
6779        'x = 1 OR (y = 1 OR z = 1)'
6780
6781    Args:
6782        *expressions: the SQL code strings to parse.
6783            If an Expression instance is passed, this is used as-is.
6784        dialect: the dialect used to parse the input expression.
6785        copy: whether to copy `expressions` (only applies to Expressions).
6786        **opts: other options to use to parse the input expressions.
6787
6788    Returns:
6789        The new condition
6790    """
6791    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **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).
  • **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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6794def xor(
6795    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6796) -> Condition:
6797    """
6798    Combine multiple conditions with an XOR logical operator.
6799
6800    Example:
6801        >>> xor("x=1", xor("y=1", "z=1")).sql()
6802        'x = 1 XOR (y = 1 XOR z = 1)'
6803
6804    Args:
6805        *expressions: the SQL code strings to parse.
6806            If an Expression instance is passed, this is used as-is.
6807        dialect: the dialect used to parse the input expression.
6808        copy: whether to copy `expressions` (only applies to Expressions).
6809        **opts: other options to use to parse the input expressions.
6810
6811    Returns:
6812        The new condition
6813    """
6814    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, **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).
  • **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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
6817def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6818    """
6819    Wrap a condition with a NOT operator.
6820
6821    Example:
6822        >>> not_("this_suit='black'").sql()
6823        "NOT this_suit = 'black'"
6824
6825    Args:
6826        expression: the SQL code string to parse.
6827            If an Expression instance is passed, this is used as-is.
6828        dialect: the dialect used to parse the input expression.
6829        copy: whether to copy the expression or not.
6830        **opts: other options to use to parse the input expressions.
6831
6832    Returns:
6833        The new condition.
6834    """
6835    this = condition(
6836        expression,
6837        dialect=dialect,
6838        copy=copy,
6839        **opts,
6840    )
6841    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:
6844def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6845    """
6846    Wrap an expression in parentheses.
6847
6848    Example:
6849        >>> paren("5 + 3").sql()
6850        '(5 + 3)'
6851
6852    Args:
6853        expression: the SQL code string to parse.
6854            If an Expression instance is passed, this is used as-is.
6855        copy: whether to copy the expression or not.
6856
6857    Returns:
6858        The wrapped expression.
6859    """
6860    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):
6876def to_identifier(name, quoted=None, copy=True):
6877    """Builds an identifier.
6878
6879    Args:
6880        name: The name to turn into an identifier.
6881        quoted: Whether to force quote the identifier.
6882        copy: Whether to copy name if it's an Identifier.
6883
6884    Returns:
6885        The identifier ast node.
6886    """
6887
6888    if name is None:
6889        return None
6890
6891    if isinstance(name, Identifier):
6892        identifier = maybe_copy(name, copy)
6893    elif isinstance(name, str):
6894        identifier = Identifier(
6895            this=name,
6896            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6897        )
6898    else:
6899        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6900    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
6903def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6904    """
6905    Parses a given string into an identifier.
6906
6907    Args:
6908        name: The name to parse into an identifier.
6909        dialect: The dialect to parse against.
6910
6911    Returns:
6912        The identifier ast node.
6913    """
6914    try:
6915        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6916    except (ParseError, TokenError):
6917        expression = to_identifier(name)
6918
6919    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]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
6925def to_interval(interval: str | Literal) -> Interval:
6926    """Builds an interval expression from a string like '1 day' or '5 months'."""
6927    if isinstance(interval, Literal):
6928        if not interval.is_string:
6929            raise ValueError("Invalid interval string.")
6930
6931        interval = interval.this
6932
6933    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6934
6935    if not interval_parts:
6936        raise ValueError("Invalid interval string.")
6937
6938    return Interval(
6939        this=Literal.string(interval_parts.group(1)),
6940        unit=Var(this=interval_parts.group(2).upper()),
6941    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
6944def to_table(
6945    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6946) -> Table:
6947    """
6948    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6949    If a table is passed in then that table is returned.
6950
6951    Args:
6952        sql_path: a `[catalog].[schema].[table]` string.
6953        dialect: the source dialect according to which the table name will be parsed.
6954        copy: Whether to copy a table if it is passed in.
6955        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6956
6957    Returns:
6958        A table expression.
6959    """
6960    if isinstance(sql_path, Table):
6961        return maybe_copy(sql_path, copy=copy)
6962
6963    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6964
6965    for k, v in kwargs.items():
6966        table.set(k, v)
6967
6968    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
6971def to_column(
6972    sql_path: str | Column,
6973    quoted: t.Optional[bool] = None,
6974    dialect: DialectType = None,
6975    copy: bool = True,
6976    **kwargs,
6977) -> Column:
6978    """
6979    Create a column from a `[table].[column]` sql path. Table is optional.
6980    If a column is passed in then that column is returned.
6981
6982    Args:
6983        sql_path: a `[table].[column]` string.
6984        quoted: Whether or not to force quote identifiers.
6985        dialect: the source dialect according to which the column name will be parsed.
6986        copy: Whether to copy a column if it is passed in.
6987        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6988
6989    Returns:
6990        A column expression.
6991    """
6992    if isinstance(sql_path, Column):
6993        return maybe_copy(sql_path, copy=copy)
6994
6995    try:
6996        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6997    except ParseError:
6998        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6999
7000    for k, v in kwargs.items():
7001        col.set(k, v)
7002
7003    if quoted:
7004        for i in col.find_all(Identifier):
7005            i.set("quoted", True)
7006
7007    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
7010def alias_(
7011    expression: ExpOrStr,
7012    alias: t.Optional[str | Identifier],
7013    table: bool | t.Sequence[str | Identifier] = False,
7014    quoted: t.Optional[bool] = None,
7015    dialect: DialectType = None,
7016    copy: bool = True,
7017    **opts,
7018):
7019    """Create an Alias expression.
7020
7021    Example:
7022        >>> alias_('foo', 'bar').sql()
7023        'foo AS bar'
7024
7025        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7026        '(SELECT 1, 2) AS bar(a, b)'
7027
7028    Args:
7029        expression: the SQL code strings to parse.
7030            If an Expression instance is passed, this is used as-is.
7031        alias: the alias name to use. If the name has
7032            special characters it is quoted.
7033        table: Whether to create a table alias, can also be a list of columns.
7034        quoted: whether to quote the alias
7035        dialect: the dialect used to parse the input expression.
7036        copy: Whether to copy the expression.
7037        **opts: other options to use to parse the input expressions.
7038
7039    Returns:
7040        Alias: the aliased expression
7041    """
7042    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7043    alias = to_identifier(alias, quoted=quoted)
7044
7045    if table:
7046        table_alias = TableAlias(this=alias)
7047        exp.set("alias", table_alias)
7048
7049        if not isinstance(table, bool):
7050            for column in table:
7051                table_alias.append("columns", to_identifier(column, quoted=quoted))
7052
7053        return exp
7054
7055    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7056    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7057    # for the complete Window expression.
7058    #
7059    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7060
7061    if "alias" in exp.arg_types and not isinstance(exp, Window):
7062        exp.set("alias", alias)
7063        return exp
7064    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7067def subquery(
7068    expression: ExpOrStr,
7069    alias: t.Optional[Identifier | str] = None,
7070    dialect: DialectType = None,
7071    **opts,
7072) -> Select:
7073    """
7074    Build a subquery expression that's selected from.
7075
7076    Example:
7077        >>> subquery('select x from tbl', 'bar').select('x').sql()
7078        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7079
7080    Args:
7081        expression: the SQL code strings to parse.
7082            If an Expression instance is passed, this is used as-is.
7083        alias: the alias name to use.
7084        dialect: the dialect used to parse the input expression.
7085        **opts: other options to use to parse the input expressions.
7086
7087    Returns:
7088        A new Select instance with the subquery expression included.
7089    """
7090
7091    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7092    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):
7123def column(
7124    col,
7125    table=None,
7126    db=None,
7127    catalog=None,
7128    *,
7129    fields=None,
7130    quoted=None,
7131    copy=True,
7132):
7133    """
7134    Build a Column.
7135
7136    Args:
7137        col: Column name.
7138        table: Table name.
7139        db: Database name.
7140        catalog: Catalog name.
7141        fields: Additional fields using dots.
7142        quoted: Whether to force quotes on the column's identifiers.
7143        copy: Whether to copy identifiers if passed in.
7144
7145    Returns:
7146        The new Column instance.
7147    """
7148    this = Column(
7149        this=to_identifier(col, quoted=quoted, copy=copy),
7150        table=to_identifier(table, quoted=quoted, copy=copy),
7151        db=to_identifier(db, quoted=quoted, copy=copy),
7152        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7153    )
7154
7155    if fields:
7156        this = Dot.build(
7157            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7158        )
7159    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, DataType, DataType.Type], copy: bool = True, **opts) -> Cast:
7162def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7163    """Cast an expression to a data type.
7164
7165    Example:
7166        >>> cast('x + 1', 'int').sql()
7167        'CAST(x + 1 AS INT)'
7168
7169    Args:
7170        expression: The expression to cast.
7171        to: The datatype to cast to.
7172        copy: Whether to copy the supplied expressions.
7173
7174    Returns:
7175        The new Cast instance.
7176    """
7177    expr = maybe_parse(expression, copy=copy, **opts)
7178    data_type = DataType.build(to, copy=copy, **opts)
7179
7180    if expr.is_type(data_type):
7181        return expr
7182
7183    expr = Cast(this=expr, to=data_type)
7184    expr.type = data_type
7185
7186    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.
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:
7189def table_(
7190    table: Identifier | str,
7191    db: t.Optional[Identifier | str] = None,
7192    catalog: t.Optional[Identifier | str] = None,
7193    quoted: t.Optional[bool] = None,
7194    alias: t.Optional[Identifier | str] = None,
7195) -> Table:
7196    """Build a Table.
7197
7198    Args:
7199        table: Table name.
7200        db: Database name.
7201        catalog: Catalog name.
7202        quote: Whether to force quotes on the table's identifiers.
7203        alias: Table's alias.
7204
7205    Returns:
7206        The new Table instance.
7207    """
7208    return Table(
7209        this=to_identifier(table, quoted=quoted) if table else None,
7210        db=to_identifier(db, quoted=quoted) if db else None,
7211        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7212        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7213    )

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:
7216def values(
7217    values: t.Iterable[t.Tuple[t.Any, ...]],
7218    alias: t.Optional[str] = None,
7219    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7220) -> Values:
7221    """Build VALUES statement.
7222
7223    Example:
7224        >>> values([(1, '2')]).sql()
7225        "VALUES (1, '2')"
7226
7227    Args:
7228        values: values statements that will be converted to SQL
7229        alias: optional alias
7230        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7231         If either are provided then an alias is also required.
7232
7233    Returns:
7234        Values: the Values expression object
7235    """
7236    if columns and not alias:
7237        raise ValueError("Alias is required when providing columns")
7238
7239    return Values(
7240        expressions=[convert(tup) for tup in values],
7241        alias=(
7242            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7243            if columns
7244            else (TableAlias(this=to_identifier(alias)) if alias else None)
7245        ),
7246    )

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:
7249def var(name: t.Optional[ExpOrStr]) -> Var:
7250    """Build a SQL variable.
7251
7252    Example:
7253        >>> repr(var('x'))
7254        'Var(this=x)'
7255
7256        >>> repr(var(column('x', table='y')))
7257        'Var(this=x)'
7258
7259    Args:
7260        name: The name of the var or an expression who's name will become the var.
7261
7262    Returns:
7263        The new variable node.
7264    """
7265    if not name:
7266        raise ValueError("Cannot convert empty name into var.")
7267
7268    if isinstance(name, Expression):
7269        name = name.name
7270    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7273def rename_table(
7274    old_name: str | Table,
7275    new_name: str | Table,
7276    dialect: DialectType = None,
7277) -> AlterTable:
7278    """Build ALTER TABLE... RENAME... expression
7279
7280    Args:
7281        old_name: The old name of the table
7282        new_name: The new name of the table
7283        dialect: The dialect to parse the table.
7284
7285    Returns:
7286        Alter table expression
7287    """
7288    old_table = to_table(old_name, dialect=dialect)
7289    new_table = to_table(new_name, dialect=dialect)
7290    return AlterTable(
7291        this=old_table,
7292        actions=[
7293            RenameTable(this=new_table),
7294        ],
7295    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7298def rename_column(
7299    table_name: str | Table,
7300    old_column_name: str | Column,
7301    new_column_name: str | Column,
7302    exists: t.Optional[bool] = None,
7303    dialect: DialectType = None,
7304) -> AlterTable:
7305    """Build ALTER TABLE... RENAME COLUMN... expression
7306
7307    Args:
7308        table_name: Name of the table
7309        old_column: The old name of the column
7310        new_column: The new name of the column
7311        exists: Whether to add the `IF EXISTS` clause
7312        dialect: The dialect to parse the table/column.
7313
7314    Returns:
7315        Alter table expression
7316    """
7317    table = to_table(table_name, dialect=dialect)
7318    old_column = to_column(old_column_name, dialect=dialect)
7319    new_column = to_column(new_column_name, dialect=dialect)
7320    return AlterTable(
7321        this=table,
7322        actions=[
7323            RenameColumn(this=old_column, to=new_column, exists=exists),
7324        ],
7325    )

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:
7328def convert(value: t.Any, copy: bool = False) -> Expression:
7329    """Convert a python value into an expression object.
7330
7331    Raises an error if a conversion is not possible.
7332
7333    Args:
7334        value: A python object.
7335        copy: Whether to copy `value` (only applies to Expressions and collections).
7336
7337    Returns:
7338        The equivalent expression object.
7339    """
7340    if isinstance(value, Expression):
7341        return maybe_copy(value, copy)
7342    if isinstance(value, str):
7343        return Literal.string(value)
7344    if isinstance(value, bool):
7345        return Boolean(this=value)
7346    if value is None or (isinstance(value, float) and math.isnan(value)):
7347        return null()
7348    if isinstance(value, numbers.Number):
7349        return Literal.number(value)
7350    if isinstance(value, bytes):
7351        return HexString(this=value.hex())
7352    if isinstance(value, datetime.datetime):
7353        datetime_literal = Literal.string(
7354            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7355                sep=" "
7356            )
7357        )
7358        return TimeStrToTime(this=datetime_literal)
7359    if isinstance(value, datetime.date):
7360        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7361        return DateStrToDate(this=date_literal)
7362    if isinstance(value, tuple):
7363        if hasattr(value, "_fields"):
7364            return Struct(
7365                expressions=[
7366                    PropertyEQ(
7367                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7368                    )
7369                    for k in value._fields
7370                ]
7371            )
7372        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7373    if isinstance(value, list):
7374        return Array(expressions=[convert(v, copy=copy) for v in value])
7375    if isinstance(value, dict):
7376        return Map(
7377            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7378            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7379        )
7380    if hasattr(value, "__dict__"):
7381        return Struct(
7382            expressions=[
7383                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7384                for k, v in value.__dict__.items()
7385            ]
7386        )
7387    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:
7390def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7391    """
7392    Replace children of an expression with the result of a lambda fun(child) -> exp.
7393    """
7394    for k, v in tuple(expression.args.items()):
7395        is_list_arg = type(v) is list
7396
7397        child_nodes = v if is_list_arg else [v]
7398        new_child_nodes = []
7399
7400        for cn in child_nodes:
7401            if isinstance(cn, Expression):
7402                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7403                    new_child_nodes.append(child_node)
7404            else:
7405                new_child_nodes.append(cn)
7406
7407        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:
7410def replace_tree(
7411    expression: Expression,
7412    fun: t.Callable,
7413    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7414) -> Expression:
7415    """
7416    Replace an entire tree with the result of function calls on each node.
7417
7418    This will be traversed in reverse dfs, so leaves first.
7419    If new nodes are created as a result of function calls, they will also be traversed.
7420    """
7421    stack = list(expression.dfs(prune=prune))
7422
7423    while stack:
7424        node = stack.pop()
7425        new_node = fun(node)
7426
7427        if new_node is not node:
7428            node.replace(new_node)
7429
7430            if isinstance(new_node, Expression):
7431                stack.append(new_node)
7432
7433    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]:
7436def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7437    """
7438    Return all table names referenced through columns in an expression.
7439
7440    Example:
7441        >>> import sqlglot
7442        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7443        ['a', 'c']
7444
7445    Args:
7446        expression: expression to find table names.
7447        exclude: a table name to exclude
7448
7449    Returns:
7450        A list of unique names.
7451    """
7452    return {
7453        table
7454        for table in (column.table for column in expression.find_all(Column))
7455        if table and table != exclude
7456    }

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
7459def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7460    """Get the full name of a table as a string.
7461
7462    Args:
7463        table: Table expression node or string.
7464        dialect: The dialect to generate the table name for.
7465        identify: Determines when an identifier should be quoted. Possible values are:
7466            False (default): Never quote, except in cases where it's mandatory by the dialect.
7467            True: Always quote.
7468
7469    Examples:
7470        >>> from sqlglot import exp, parse_one
7471        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7472        'a.b.c'
7473
7474    Returns:
7475        The table name.
7476    """
7477
7478    table = maybe_parse(table, into=Table, dialect=dialect)
7479
7480    if not table:
7481        raise ValueError(f"Cannot parse {table}")
7482
7483    return ".".join(
7484        (
7485            part.sql(dialect=dialect, identify=True, copy=False)
7486            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7487            else part.name
7488        )
7489        for part in table.parts
7490    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
7493def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7494    """Returns a case normalized table name without quotes.
7495
7496    Args:
7497        table: the table to normalize
7498        dialect: the dialect to use for normalization rules
7499        copy: whether to copy the expression.
7500
7501    Examples:
7502        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7503        'A-B.c'
7504    """
7505    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7506
7507    return ".".join(
7508        p.name
7509        for p in normalize_identifiers(
7510            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7511        ).parts
7512    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
7515def replace_tables(
7516    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7517) -> E:
7518    """Replace all tables in expression according to the mapping.
7519
7520    Args:
7521        expression: expression node to be transformed and replaced.
7522        mapping: mapping of table names.
7523        dialect: the dialect of the mapping table
7524        copy: whether to copy the expression.
7525
7526    Examples:
7527        >>> from sqlglot import exp, parse_one
7528        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7529        'SELECT * FROM c /* a.b */'
7530
7531    Returns:
7532        The mapped expression.
7533    """
7534
7535    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7536
7537    def _replace_tables(node: Expression) -> Expression:
7538        if isinstance(node, Table):
7539            original = normalize_table_name(node, dialect=dialect)
7540            new_name = mapping.get(original)
7541
7542            if new_name:
7543                table = to_table(
7544                    new_name,
7545                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7546                    dialect=dialect,
7547                )
7548                table.add_comments([original])
7549                return table
7550        return node
7551
7552    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:
7555def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7556    """Replace placeholders in an expression.
7557
7558    Args:
7559        expression: expression node to be transformed and replaced.
7560        args: positional names that will substitute unnamed placeholders in the given order.
7561        kwargs: keyword arguments that will substitute named placeholders.
7562
7563    Examples:
7564        >>> from sqlglot import exp, parse_one
7565        >>> replace_placeholders(
7566        ...     parse_one("select * from :tbl where ? = ?"),
7567        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7568        ... ).sql()
7569        "SELECT * FROM foo WHERE str_col = 'b'"
7570
7571    Returns:
7572        The mapped expression.
7573    """
7574
7575    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7576        if isinstance(node, Placeholder):
7577            if node.this:
7578                new_name = kwargs.get(node.this)
7579                if new_name is not None:
7580                    return convert(new_name)
7581            else:
7582                try:
7583                    return convert(next(args))
7584                except StopIteration:
7585                    pass
7586        return node
7587
7588    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, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
7591def expand(
7592    expression: Expression,
7593    sources: t.Dict[str, Query],
7594    dialect: DialectType = None,
7595    copy: bool = True,
7596) -> Expression:
7597    """Transforms an expression by expanding all referenced sources into subqueries.
7598
7599    Examples:
7600        >>> from sqlglot import parse_one
7601        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7602        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7603
7604        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7605        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7606
7607    Args:
7608        expression: The expression to expand.
7609        sources: A dictionary of name to Queries.
7610        dialect: The dialect of the sources dict.
7611        copy: Whether to copy the expression during transformation. Defaults to True.
7612
7613    Returns:
7614        The transformed expression.
7615    """
7616    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7617
7618    def _expand(node: Expression):
7619        if isinstance(node, Table):
7620            name = normalize_table_name(node, dialect=dialect)
7621            source = sources.get(name)
7622            if source:
7623                subquery = source.subquery(node.alias or name)
7624                subquery.comments = [f"source: {name}"]
7625                return subquery.transform(_expand, copy=False)
7626        return node
7627
7628    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 dictionary of name to Queries.
  • dialect: The dialect of the sources dict.
  • 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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
7631def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7632    """
7633    Returns a Func expression.
7634
7635    Examples:
7636        >>> func("abs", 5).sql()
7637        'ABS(5)'
7638
7639        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7640        'CAST(5 AS DOUBLE)'
7641
7642    Args:
7643        name: the name of the function to build.
7644        args: the args used to instantiate the function of interest.
7645        copy: whether to copy the argument expressions.
7646        dialect: the source dialect.
7647        kwargs: the kwargs used to instantiate the function of interest.
7648
7649    Note:
7650        The arguments `args` and `kwargs` are mutually exclusive.
7651
7652    Returns:
7653        An instance of the function of interest, or an anonymous function, if `name` doesn't
7654        correspond to an existing `sqlglot.expressions.Func` class.
7655    """
7656    if args and kwargs:
7657        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7658
7659    from sqlglot.dialects.dialect import Dialect
7660
7661    dialect = Dialect.get_or_raise(dialect)
7662
7663    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7664    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7665
7666    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7667    if constructor:
7668        if converted:
7669            if "dialect" in constructor.__code__.co_varnames:
7670                function = constructor(converted, dialect=dialect)
7671            else:
7672                function = constructor(converted)
7673        elif constructor.__name__ == "from_arg_list":
7674            function = constructor.__self__(**kwargs)  # type: ignore
7675        else:
7676            constructor = FUNCTION_BY_NAME.get(name.upper())
7677            if constructor:
7678                function = constructor(**kwargs)
7679            else:
7680                raise ValueError(
7681                    f"Unable to convert '{name}' into a Func. Either manually construct "
7682                    "the Func expression of interest or parse the function call."
7683                )
7684    else:
7685        kwargs = kwargs or {"expressions": converted}
7686        function = Anonymous(this=name, **kwargs)
7687
7688    for error_message in function.error_messages(converted):
7689        raise ValueError(error_message)
7690
7691    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 Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
7694def case(
7695    expression: t.Optional[ExpOrStr] = None,
7696    **opts,
7697) -> Case:
7698    """
7699    Initialize a CASE statement.
7700
7701    Example:
7702        case().when("a = 1", "foo").else_("bar")
7703
7704    Args:
7705        expression: Optionally, the input expression (not all dialects support this)
7706        **opts: Extra keyword arguments for parsing `expression`
7707    """
7708    if expression is not None:
7709        this = maybe_parse(expression, **opts)
7710    else:
7711        this = None
7712    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
7715def array(
7716    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7717) -> Array:
7718    """
7719    Returns an array.
7720
7721    Examples:
7722        >>> array(1, 'x').sql()
7723        'ARRAY(1, x)'
7724
7725    Args:
7726        expressions: the expressions to add to the array.
7727        copy: whether to copy the argument expressions.
7728        dialect: the source dialect.
7729        kwargs: the kwargs used to instantiate the function of interest.
7730
7731    Returns:
7732        An array expression.
7733    """
7734    return Array(
7735        expressions=[
7736            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7737            for expression in expressions
7738        ]
7739    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
7742def tuple_(
7743    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7744) -> Tuple:
7745    """
7746    Returns an tuple.
7747
7748    Examples:
7749        >>> tuple_(1, 'x').sql()
7750        '(1, x)'
7751
7752    Args:
7753        expressions: the expressions to add to the tuple.
7754        copy: whether to copy the argument expressions.
7755        dialect: the source dialect.
7756        kwargs: the kwargs used to instantiate the function of interest.
7757
7758    Returns:
7759        A tuple expression.
7760    """
7761    return Tuple(
7762        expressions=[
7763            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7764            for expression in expressions
7765        ]
7766    )

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:
7769def true() -> Boolean:
7770    """
7771    Returns a true Boolean expression.
7772    """
7773    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7776def false() -> Boolean:
7777    """
7778    Returns a false Boolean expression.
7779    """
7780    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7783def null() -> Null:
7784    """
7785    Returns a Null expression.
7786    """
7787    return Null()

Returns a Null expression.

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