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

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

def to_dot(self) -> Dot | Identifier:
1592    def to_dot(self) -> Dot | Identifier:
1593        """Converts the column into a dot expression."""
1594        parts = self.parts
1595        parent = self.parent
1596
1597        while parent:
1598            if isinstance(parent, Dot):
1599                parts.append(parent.expression)
1600            parent = parent.parent
1601
1602        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1605class ColumnPosition(Expression):
1606    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1609class ColumnDef(Expression):
1610    arg_types = {
1611        "this": True,
1612        "kind": False,
1613        "constraints": False,
1614        "exists": False,
1615        "position": False,
1616    }
1617
1618    @property
1619    def constraints(self) -> t.List[ColumnConstraint]:
1620        return self.args.get("constraints") or []
1621
1622    @property
1623    def kind(self) -> t.Optional[DataType]:
1624        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1618    @property
1619    def constraints(self) -> t.List[ColumnConstraint]:
1620        return self.args.get("constraints") or []
kind: Optional[DataType]
1622    @property
1623    def kind(self) -> t.Optional[DataType]:
1624        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1627class AlterColumn(Expression):
1628    arg_types = {
1629        "this": True,
1630        "dtype": False,
1631        "collate": False,
1632        "using": False,
1633        "default": False,
1634        "drop": False,
1635        "comment": False,
1636        "allow_null": False,
1637    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1641class AlterDistStyle(Expression):
1642    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1645class AlterSortKey(Expression):
1646    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1649class AlterSet(Expression):
1650    arg_types = {
1651        "expressions": False,
1652        "option": False,
1653        "tablespace": False,
1654        "access_method": False,
1655        "file_format": False,
1656        "copy_options": False,
1657        "tag": False,
1658        "location": False,
1659        "serde": False,
1660    }
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):
1663class RenameColumn(Expression):
1664    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1667class RenameTable(Expression):
1668    pass
key = 'renametable'
class SwapTable(Expression):
1671class SwapTable(Expression):
1672    pass
key = 'swaptable'
class Comment(Expression):
1675class Comment(Expression):
1676    arg_types = {
1677        "this": True,
1678        "kind": True,
1679        "expression": True,
1680        "exists": False,
1681        "materialized": False,
1682    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1685class Comprehension(Expression):
1686    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):
1690class MergeTreeTTLAction(Expression):
1691    arg_types = {
1692        "this": True,
1693        "delete": False,
1694        "recompress": False,
1695        "to_disk": False,
1696        "to_volume": False,
1697    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1701class MergeTreeTTL(Expression):
1702    arg_types = {
1703        "expressions": True,
1704        "where": False,
1705        "group": False,
1706        "aggregates": False,
1707    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1711class IndexConstraintOption(Expression):
1712    arg_types = {
1713        "key_block_size": False,
1714        "using": False,
1715        "parser": False,
1716        "comment": False,
1717        "visible": False,
1718        "engine_attr": False,
1719        "secondary_engine_attr": False,
1720    }
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):
1723class ColumnConstraint(Expression):
1724    arg_types = {"this": False, "kind": True}
1725
1726    @property
1727    def kind(self) -> ColumnConstraintKind:
1728        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1726    @property
1727    def kind(self) -> ColumnConstraintKind:
1728        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1731class ColumnConstraintKind(Expression):
1732    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1735class AutoIncrementColumnConstraint(ColumnConstraintKind):
1736    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1739class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1740    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1743class CaseSpecificColumnConstraint(ColumnConstraintKind):
1744    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1747class CharacterSetColumnConstraint(ColumnConstraintKind):
1748    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1751class CheckColumnConstraint(ColumnConstraintKind):
1752    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1755class ClusteredColumnConstraint(ColumnConstraintKind):
1756    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1759class CollateColumnConstraint(ColumnConstraintKind):
1760    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1763class CommentColumnConstraint(ColumnConstraintKind):
1764    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1767class CompressColumnConstraint(ColumnConstraintKind):
1768    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1771class DateFormatColumnConstraint(ColumnConstraintKind):
1772    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1775class DefaultColumnConstraint(ColumnConstraintKind):
1776    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1779class EncodeColumnConstraint(ColumnConstraintKind):
1780    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1784class ExcludeColumnConstraint(ColumnConstraintKind):
1785    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1788class EphemeralColumnConstraint(ColumnConstraintKind):
1789    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1792class WithOperator(Expression):
1793    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1796class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1797    # this: True -> ALWAYS, this: False -> BY DEFAULT
1798    arg_types = {
1799        "this": False,
1800        "expression": False,
1801        "on_null": False,
1802        "start": False,
1803        "increment": False,
1804        "minvalue": False,
1805        "maxvalue": False,
1806        "cycle": False,
1807    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1810class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1811    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1816class IndexColumnConstraint(ColumnConstraintKind):
1817    arg_types = {
1818        "this": False,
1819        "expressions": False,
1820        "kind": False,
1821        "index_type": False,
1822        "options": False,
1823        "expression": False,  # Clickhouse
1824        "granularity": False,
1825    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1828class InlineLengthColumnConstraint(ColumnConstraintKind):
1829    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1832class NonClusteredColumnConstraint(ColumnConstraintKind):
1833    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1836class NotForReplicationColumnConstraint(ColumnConstraintKind):
1837    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1841class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1842    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1845class NotNullColumnConstraint(ColumnConstraintKind):
1846    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1850class OnUpdateColumnConstraint(ColumnConstraintKind):
1851    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1855class TagColumnConstraint(ColumnConstraintKind):
1856    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1860class TransformColumnConstraint(ColumnConstraintKind):
1861    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1864class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1865    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1868class TitleColumnConstraint(ColumnConstraintKind):
1869    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1872class UniqueColumnConstraint(ColumnConstraintKind):
1873    arg_types = {"this": False, "index_type": False, "on_conflict": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1876class UppercaseColumnConstraint(ColumnConstraintKind):
1877    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1880class PathColumnConstraint(ColumnConstraintKind):
1881    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1885class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1886    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1891class ComputedColumnConstraint(ColumnConstraintKind):
1892    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1895class Constraint(Expression):
1896    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1899class Delete(DML):
1900    arg_types = {
1901        "with": False,
1902        "this": False,
1903        "using": False,
1904        "where": False,
1905        "returning": False,
1906        "limit": False,
1907        "tables": False,  # Multiple-Table Syntax (MySQL)
1908    }
1909
1910    def delete(
1911        self,
1912        table: ExpOrStr,
1913        dialect: DialectType = None,
1914        copy: bool = True,
1915        **opts,
1916    ) -> Delete:
1917        """
1918        Create a DELETE expression or replace the table on an existing DELETE expression.
1919
1920        Example:
1921            >>> delete("tbl").sql()
1922            'DELETE FROM tbl'
1923
1924        Args:
1925            table: the table from which to delete.
1926            dialect: the dialect used to parse the input expression.
1927            copy: if `False`, modify this expression instance in-place.
1928            opts: other options to use to parse the input expressions.
1929
1930        Returns:
1931            Delete: the modified expression.
1932        """
1933        return _apply_builder(
1934            expression=table,
1935            instance=self,
1936            arg="this",
1937            dialect=dialect,
1938            into=Table,
1939            copy=copy,
1940            **opts,
1941        )
1942
1943    def where(
1944        self,
1945        *expressions: t.Optional[ExpOrStr],
1946        append: bool = True,
1947        dialect: DialectType = None,
1948        copy: bool = True,
1949        **opts,
1950    ) -> Delete:
1951        """
1952        Append to or set the WHERE expressions.
1953
1954        Example:
1955            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1956            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1957
1958        Args:
1959            *expressions: the SQL code strings to parse.
1960                If an `Expression` instance is passed, it will be used as-is.
1961                Multiple expressions are combined with an AND operator.
1962            append: if `True`, AND the new expressions to any existing expression.
1963                Otherwise, this resets the expression.
1964            dialect: the dialect used to parse the input expressions.
1965            copy: if `False`, modify this expression instance in-place.
1966            opts: other options to use to parse the input expressions.
1967
1968        Returns:
1969            Delete: the modified expression.
1970        """
1971        return _apply_conjunction_builder(
1972            *expressions,
1973            instance=self,
1974            arg="where",
1975            append=append,
1976            into=Where,
1977            dialect=dialect,
1978            copy=copy,
1979            **opts,
1980        )
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:
1910    def delete(
1911        self,
1912        table: ExpOrStr,
1913        dialect: DialectType = None,
1914        copy: bool = True,
1915        **opts,
1916    ) -> Delete:
1917        """
1918        Create a DELETE expression or replace the table on an existing DELETE expression.
1919
1920        Example:
1921            >>> delete("tbl").sql()
1922            'DELETE FROM tbl'
1923
1924        Args:
1925            table: the table from which to delete.
1926            dialect: the dialect used to parse the input expression.
1927            copy: if `False`, modify this expression instance in-place.
1928            opts: other options to use to parse the input expressions.
1929
1930        Returns:
1931            Delete: the modified expression.
1932        """
1933        return _apply_builder(
1934            expression=table,
1935            instance=self,
1936            arg="this",
1937            dialect=dialect,
1938            into=Table,
1939            copy=copy,
1940            **opts,
1941        )

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

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):
1983class Drop(Expression):
1984    arg_types = {
1985        "this": False,
1986        "kind": False,
1987        "expressions": False,
1988        "exists": False,
1989        "temporary": False,
1990        "materialized": False,
1991        "cascade": False,
1992        "constraints": False,
1993        "purge": False,
1994        "cluster": False,
1995    }
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):
1998class Filter(Expression):
1999    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2002class Check(Expression):
2003    pass
key = 'check'
class Changes(Expression):
2006class Changes(Expression):
2007    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2011class Connect(Expression):
2012    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2015class CopyParameter(Expression):
2016    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(Expression):
2019class Copy(Expression):
2020    arg_types = {
2021        "this": True,
2022        "kind": True,
2023        "files": True,
2024        "credentials": False,
2025        "format": False,
2026        "params": False,
2027    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2030class Credentials(Expression):
2031    arg_types = {
2032        "credentials": False,
2033        "encryption": False,
2034        "storage": False,
2035        "iam_role": False,
2036        "region": False,
2037    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2040class Prior(Expression):
2041    pass
key = 'prior'
class Directory(Expression):
2044class Directory(Expression):
2045    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2046    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2049class ForeignKey(Expression):
2050    arg_types = {
2051        "expressions": True,
2052        "reference": False,
2053        "delete": False,
2054        "update": False,
2055    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2058class ColumnPrefix(Expression):
2059    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2062class PrimaryKey(Expression):
2063    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2068class Into(Expression):
2069    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2072class From(Expression):
2073    @property
2074    def name(self) -> str:
2075        return self.this.name
2076
2077    @property
2078    def alias_or_name(self) -> str:
2079        return self.this.alias_or_name
name: str
2073    @property
2074    def name(self) -> str:
2075        return self.this.name
alias_or_name: str
2077    @property
2078    def alias_or_name(self) -> str:
2079        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2082class Having(Expression):
2083    pass
key = 'having'
class Hint(Expression):
2086class Hint(Expression):
2087    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2090class JoinHint(Expression):
2091    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2094class Identifier(Expression):
2095    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2096
2097    @property
2098    def quoted(self) -> bool:
2099        return bool(self.args.get("quoted"))
2100
2101    @property
2102    def hashable_args(self) -> t.Any:
2103        return (self.this, self.quoted)
2104
2105    @property
2106    def output_name(self) -> str:
2107        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2097    @property
2098    def quoted(self) -> bool:
2099        return bool(self.args.get("quoted"))
hashable_args: Any
2101    @property
2102    def hashable_args(self) -> t.Any:
2103        return (self.this, self.quoted)
output_name: str
2105    @property
2106    def output_name(self) -> str:
2107        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):
2111class Opclass(Expression):
2112    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2115class Index(Expression):
2116    arg_types = {
2117        "this": False,
2118        "table": False,
2119        "unique": False,
2120        "primary": False,
2121        "amp": False,  # teradata
2122        "params": False,
2123    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2126class IndexParameters(Expression):
2127    arg_types = {
2128        "using": False,
2129        "include": False,
2130        "columns": False,
2131        "with_storage": False,
2132        "partition_by": False,
2133        "tablespace": False,
2134        "where": False,
2135        "on": False,
2136    }
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):
2139class Insert(DDL, DML):
2140    arg_types = {
2141        "hint": False,
2142        "with": False,
2143        "is_function": False,
2144        "this": False,
2145        "expression": False,
2146        "conflict": False,
2147        "returning": False,
2148        "overwrite": False,
2149        "exists": False,
2150        "alternative": False,
2151        "where": False,
2152        "ignore": False,
2153        "by_name": False,
2154        "stored": False,
2155    }
2156
2157    def with_(
2158        self,
2159        alias: ExpOrStr,
2160        as_: ExpOrStr,
2161        recursive: t.Optional[bool] = None,
2162        append: bool = True,
2163        dialect: DialectType = None,
2164        copy: bool = True,
2165        **opts,
2166    ) -> Insert:
2167        """
2168        Append to or set the common table expressions.
2169
2170        Example:
2171            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2172            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2173
2174        Args:
2175            alias: the SQL code string to parse as the table name.
2176                If an `Expression` instance is passed, this is used as-is.
2177            as_: the SQL code string to parse as the table expression.
2178                If an `Expression` instance is passed, it will be used as-is.
2179            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2180            append: if `True`, add to any existing expressions.
2181                Otherwise, this resets the expressions.
2182            dialect: the dialect used to parse the input expression.
2183            copy: if `False`, modify this expression instance in-place.
2184            opts: other options to use to parse the input expressions.
2185
2186        Returns:
2187            The modified expression.
2188        """
2189        return _apply_cte_builder(
2190            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2191        )
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:
2157    def with_(
2158        self,
2159        alias: ExpOrStr,
2160        as_: ExpOrStr,
2161        recursive: t.Optional[bool] = None,
2162        append: bool = True,
2163        dialect: DialectType = None,
2164        copy: bool = True,
2165        **opts,
2166    ) -> Insert:
2167        """
2168        Append to or set the common table expressions.
2169
2170        Example:
2171            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2172            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2173
2174        Args:
2175            alias: the SQL code string to parse as the table name.
2176                If an `Expression` instance is passed, this is used as-is.
2177            as_: the SQL code string to parse as the table expression.
2178                If an `Expression` instance is passed, it will be used as-is.
2179            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2180            append: if `True`, add to any existing expressions.
2181                Otherwise, this resets the expressions.
2182            dialect: the dialect used to parse the input expression.
2183            copy: if `False`, modify this expression instance in-place.
2184            opts: other options to use to parse the input expressions.
2185
2186        Returns:
2187            The modified expression.
2188        """
2189        return _apply_cte_builder(
2190            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2191        )

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):
2194class OnConflict(Expression):
2195    arg_types = {
2196        "duplicate": False,
2197        "expressions": False,
2198        "action": False,
2199        "conflict_keys": False,
2200        "constraint": False,
2201    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2204class Returning(Expression):
2205    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2209class Introducer(Expression):
2210    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2214class National(Expression):
2215    pass
key = 'national'
class LoadData(Expression):
2218class LoadData(Expression):
2219    arg_types = {
2220        "this": True,
2221        "local": False,
2222        "overwrite": False,
2223        "inpath": True,
2224        "partition": False,
2225        "input_format": False,
2226        "serde": False,
2227    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2230class Partition(Expression):
2231    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2234class PartitionRange(Expression):
2235    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2239class PartitionId(Expression):
2240    pass
key = 'partitionid'
class Fetch(Expression):
2243class Fetch(Expression):
2244    arg_types = {
2245        "direction": False,
2246        "count": False,
2247        "percent": False,
2248        "with_ties": False,
2249    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2252class Group(Expression):
2253    arg_types = {
2254        "expressions": False,
2255        "grouping_sets": False,
2256        "cube": False,
2257        "rollup": False,
2258        "totals": False,
2259        "all": False,
2260    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2263class Lambda(Expression):
2264    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2267class Limit(Expression):
2268    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):
2271class Literal(Condition):
2272    arg_types = {"this": True, "is_string": True}
2273
2274    @property
2275    def hashable_args(self) -> t.Any:
2276        return (self.this, self.args.get("is_string"))
2277
2278    @classmethod
2279    def number(cls, number) -> Literal:
2280        return cls(this=str(number), is_string=False)
2281
2282    @classmethod
2283    def string(cls, string) -> Literal:
2284        return cls(this=str(string), is_string=True)
2285
2286    @property
2287    def output_name(self) -> str:
2288        return self.name
2289
2290    def to_py(self) -> int | str | Decimal:
2291        if self.is_number:
2292            try:
2293                return int(self.this)
2294            except ValueError:
2295                return Decimal(self.this)
2296        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2274    @property
2275    def hashable_args(self) -> t.Any:
2276        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2278    @classmethod
2279    def number(cls, number) -> Literal:
2280        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2282    @classmethod
2283    def string(cls, string) -> Literal:
2284        return cls(this=str(string), is_string=True)
output_name: str
2286    @property
2287    def output_name(self) -> str:
2288        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:
2290    def to_py(self) -> int | str | Decimal:
2291        if self.is_number:
2292            try:
2293                return int(self.this)
2294            except ValueError:
2295                return Decimal(self.this)
2296        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2299class Join(Expression):
2300    arg_types = {
2301        "this": True,
2302        "on": False,
2303        "side": False,
2304        "kind": False,
2305        "using": False,
2306        "method": False,
2307        "global": False,
2308        "hint": False,
2309        "match_condition": False,  # Snowflake
2310    }
2311
2312    @property
2313    def method(self) -> str:
2314        return self.text("method").upper()
2315
2316    @property
2317    def kind(self) -> str:
2318        return self.text("kind").upper()
2319
2320    @property
2321    def side(self) -> str:
2322        return self.text("side").upper()
2323
2324    @property
2325    def hint(self) -> str:
2326        return self.text("hint").upper()
2327
2328    @property
2329    def alias_or_name(self) -> str:
2330        return self.this.alias_or_name
2331
2332    def on(
2333        self,
2334        *expressions: t.Optional[ExpOrStr],
2335        append: bool = True,
2336        dialect: DialectType = None,
2337        copy: bool = True,
2338        **opts,
2339    ) -> Join:
2340        """
2341        Append to or set the ON expressions.
2342
2343        Example:
2344            >>> import sqlglot
2345            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2346            'JOIN x ON y = 1'
2347
2348        Args:
2349            *expressions: the SQL code strings to parse.
2350                If an `Expression` instance is passed, it will be used as-is.
2351                Multiple expressions are combined with an AND operator.
2352            append: if `True`, AND the new expressions to any existing expression.
2353                Otherwise, this resets the expression.
2354            dialect: the dialect used to parse the input expressions.
2355            copy: if `False`, modify this expression instance in-place.
2356            opts: other options to use to parse the input expressions.
2357
2358        Returns:
2359            The modified Join expression.
2360        """
2361        join = _apply_conjunction_builder(
2362            *expressions,
2363            instance=self,
2364            arg="on",
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )
2370
2371        if join.kind == "CROSS":
2372            join.set("kind", None)
2373
2374        return join
2375
2376    def using(
2377        self,
2378        *expressions: t.Optional[ExpOrStr],
2379        append: bool = True,
2380        dialect: DialectType = None,
2381        copy: bool = True,
2382        **opts,
2383    ) -> Join:
2384        """
2385        Append to or set the USING expressions.
2386
2387        Example:
2388            >>> import sqlglot
2389            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2390            'JOIN x USING (foo, bla)'
2391
2392        Args:
2393            *expressions: the SQL code strings to parse.
2394                If an `Expression` instance is passed, it will be used as-is.
2395            append: if `True`, concatenate the new expressions to the existing "using" list.
2396                Otherwise, this resets the expression.
2397            dialect: the dialect used to parse the input expressions.
2398            copy: if `False`, modify this expression instance in-place.
2399            opts: other options to use to parse the input expressions.
2400
2401        Returns:
2402            The modified Join expression.
2403        """
2404        join = _apply_list_builder(
2405            *expressions,
2406            instance=self,
2407            arg="using",
2408            append=append,
2409            dialect=dialect,
2410            copy=copy,
2411            **opts,
2412        )
2413
2414        if join.kind == "CROSS":
2415            join.set("kind", None)
2416
2417        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
2312    @property
2313    def method(self) -> str:
2314        return self.text("method").upper()
kind: str
2316    @property
2317    def kind(self) -> str:
2318        return self.text("kind").upper()
side: str
2320    @property
2321    def side(self) -> str:
2322        return self.text("side").upper()
hint: str
2324    @property
2325    def hint(self) -> str:
2326        return self.text("hint").upper()
alias_or_name: str
2328    @property
2329    def alias_or_name(self) -> str:
2330        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:
2332    def on(
2333        self,
2334        *expressions: t.Optional[ExpOrStr],
2335        append: bool = True,
2336        dialect: DialectType = None,
2337        copy: bool = True,
2338        **opts,
2339    ) -> Join:
2340        """
2341        Append to or set the ON expressions.
2342
2343        Example:
2344            >>> import sqlglot
2345            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2346            'JOIN x ON y = 1'
2347
2348        Args:
2349            *expressions: the SQL code strings to parse.
2350                If an `Expression` instance is passed, it will be used as-is.
2351                Multiple expressions are combined with an AND operator.
2352            append: if `True`, AND the new expressions to any existing expression.
2353                Otherwise, this resets the expression.
2354            dialect: the dialect used to parse the input expressions.
2355            copy: if `False`, modify this expression instance in-place.
2356            opts: other options to use to parse the input expressions.
2357
2358        Returns:
2359            The modified Join expression.
2360        """
2361        join = _apply_conjunction_builder(
2362            *expressions,
2363            instance=self,
2364            arg="on",
2365            append=append,
2366            dialect=dialect,
2367            copy=copy,
2368            **opts,
2369        )
2370
2371        if join.kind == "CROSS":
2372            join.set("kind", None)
2373
2374        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:
2376    def using(
2377        self,
2378        *expressions: t.Optional[ExpOrStr],
2379        append: bool = True,
2380        dialect: DialectType = None,
2381        copy: bool = True,
2382        **opts,
2383    ) -> Join:
2384        """
2385        Append to or set the USING expressions.
2386
2387        Example:
2388            >>> import sqlglot
2389            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2390            'JOIN x USING (foo, bla)'
2391
2392        Args:
2393            *expressions: the SQL code strings to parse.
2394                If an `Expression` instance is passed, it will be used as-is.
2395            append: if `True`, concatenate the new expressions to the existing "using" list.
2396                Otherwise, this resets the expression.
2397            dialect: the dialect used to parse the input expressions.
2398            copy: if `False`, modify this expression instance in-place.
2399            opts: other options to use to parse the input expressions.
2400
2401        Returns:
2402            The modified Join expression.
2403        """
2404        join = _apply_list_builder(
2405            *expressions,
2406            instance=self,
2407            arg="using",
2408            append=append,
2409            dialect=dialect,
2410            copy=copy,
2411            **opts,
2412        )
2413
2414        if join.kind == "CROSS":
2415            join.set("kind", None)
2416
2417        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):
2420class Lateral(UDTF):
2421    arg_types = {
2422        "this": True,
2423        "view": False,
2424        "outer": False,
2425        "alias": False,
2426        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2427    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2430class MatchRecognizeMeasure(Expression):
2431    arg_types = {
2432        "this": True,
2433        "window_frame": False,
2434    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2437class MatchRecognize(Expression):
2438    arg_types = {
2439        "partition_by": False,
2440        "order": False,
2441        "measures": False,
2442        "rows": False,
2443        "after": False,
2444        "pattern": False,
2445        "define": False,
2446        "alias": False,
2447    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2452class Final(Expression):
2453    pass
key = 'final'
class Offset(Expression):
2456class Offset(Expression):
2457    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2460class Order(Expression):
2461    arg_types = {
2462        "this": False,
2463        "expressions": True,
2464        "interpolate": False,
2465        "siblings": False,
2466    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2470class WithFill(Expression):
2471    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2476class Cluster(Order):
2477    pass
key = 'cluster'
class Distribute(Order):
2480class Distribute(Order):
2481    pass
key = 'distribute'
class Sort(Order):
2484class Sort(Order):
2485    pass
key = 'sort'
class Ordered(Expression):
2488class Ordered(Expression):
2489    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):
2492class Property(Expression):
2493    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2496class AllowedValuesProperty(Expression):
2497    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2500class AlgorithmProperty(Property):
2501    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2504class AutoIncrementProperty(Property):
2505    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2509class AutoRefreshProperty(Property):
2510    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2513class BackupProperty(Property):
2514    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2517class BlockCompressionProperty(Property):
2518    arg_types = {
2519        "autotemp": False,
2520        "always": False,
2521        "default": False,
2522        "manual": False,
2523        "never": False,
2524    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2527class CharacterSetProperty(Property):
2528    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2531class ChecksumProperty(Property):
2532    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2535class CollateProperty(Property):
2536    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2539class CopyGrantsProperty(Property):
2540    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2543class DataBlocksizeProperty(Property):
2544    arg_types = {
2545        "size": False,
2546        "units": False,
2547        "minimum": False,
2548        "maximum": False,
2549        "default": False,
2550    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2553class DataDeletionProperty(Property):
2554    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):
2557class DefinerProperty(Property):
2558    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2561class DistKeyProperty(Property):
2562    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2565class DistStyleProperty(Property):
2566    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2569class EngineProperty(Property):
2570    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2573class HeapProperty(Property):
2574    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2577class ToTableProperty(Property):
2578    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2581class ExecuteAsProperty(Property):
2582    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2585class ExternalProperty(Property):
2586    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2589class FallbackProperty(Property):
2590    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2593class FileFormatProperty(Property):
2594    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2597class FreespaceProperty(Property):
2598    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2601class GlobalProperty(Property):
2602    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2605class IcebergProperty(Property):
2606    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2609class InheritsProperty(Property):
2610    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2613class InputModelProperty(Property):
2614    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2617class OutputModelProperty(Property):
2618    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2621class IsolatedLoadingProperty(Property):
2622    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2625class JournalProperty(Property):
2626    arg_types = {
2627        "no": False,
2628        "dual": False,
2629        "before": False,
2630        "local": False,
2631        "after": False,
2632    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2635class LanguageProperty(Property):
2636    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2640class ClusteredByProperty(Property):
2641    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2644class DictProperty(Property):
2645    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2648class DictSubProperty(Property):
2649    pass
key = 'dictsubproperty'
class DictRange(Property):
2652class DictRange(Property):
2653    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2656class DynamicProperty(Property):
2657    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2662class OnCluster(Property):
2663    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2666class LikeProperty(Property):
2667    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2670class LocationProperty(Property):
2671    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2674class LockProperty(Property):
2675    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2678class LockingProperty(Property):
2679    arg_types = {
2680        "this": False,
2681        "kind": True,
2682        "for_or_in": False,
2683        "lock_type": True,
2684        "override": False,
2685    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2688class LogProperty(Property):
2689    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2692class MaterializedProperty(Property):
2693    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2696class MergeBlockRatioProperty(Property):
2697    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):
2700class NoPrimaryIndexProperty(Property):
2701    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2704class OnProperty(Property):
2705    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2708class OnCommitProperty(Property):
2709    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2712class PartitionedByProperty(Property):
2713    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2717class PartitionBoundSpec(Expression):
2718    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2719    arg_types = {
2720        "this": False,
2721        "expression": False,
2722        "from_expressions": False,
2723        "to_expressions": False,
2724    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2727class PartitionedOfProperty(Property):
2728    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2729    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2732class RemoteWithConnectionModelProperty(Property):
2733    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2736class ReturnsProperty(Property):
2737    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):
2740class StrictProperty(Property):
2741    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2744class RowFormatProperty(Property):
2745    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2748class RowFormatDelimitedProperty(Property):
2749    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2750    arg_types = {
2751        "fields": False,
2752        "escaped": False,
2753        "collection_items": False,
2754        "map_keys": False,
2755        "lines": False,
2756        "null": False,
2757        "serde": False,
2758    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2761class RowFormatSerdeProperty(Property):
2762    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2766class QueryTransform(Expression):
2767    arg_types = {
2768        "expressions": True,
2769        "command_script": True,
2770        "schema": False,
2771        "row_format_before": False,
2772        "record_writer": False,
2773        "row_format_after": False,
2774        "record_reader": False,
2775    }
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):
2778class SampleProperty(Property):
2779    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2782class SchemaCommentProperty(Property):
2783    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2786class SerdeProperties(Property):
2787    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2790class SetProperty(Property):
2791    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2794class SharingProperty(Property):
2795    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2798class SetConfigProperty(Property):
2799    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2802class SettingsProperty(Property):
2803    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2806class SortKeyProperty(Property):
2807    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2810class SqlReadWriteProperty(Property):
2811    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2814class SqlSecurityProperty(Property):
2815    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2818class StabilityProperty(Property):
2819    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2822class TemporaryProperty(Property):
2823    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2826class SecureProperty(Property):
2827    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2830class TransformModelProperty(Property):
2831    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2834class TransientProperty(Property):
2835    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2838class UnloggedProperty(Property):
2839    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2843class ViewAttributeProperty(Property):
2844    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2847class VolatileProperty(Property):
2848    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2851class WithDataProperty(Property):
2852    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2855class WithJournalTableProperty(Property):
2856    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2859class WithSchemaBindingProperty(Property):
2860    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2863class WithSystemVersioningProperty(Property):
2864    arg_types = {
2865        "on": False,
2866        "this": False,
2867        "data_consistency": False,
2868        "retention_period": False,
2869        "with": True,
2870    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2873class Properties(Expression):
2874    arg_types = {"expressions": True}
2875
2876    NAME_TO_PROPERTY = {
2877        "ALGORITHM": AlgorithmProperty,
2878        "AUTO_INCREMENT": AutoIncrementProperty,
2879        "CHARACTER SET": CharacterSetProperty,
2880        "CLUSTERED_BY": ClusteredByProperty,
2881        "COLLATE": CollateProperty,
2882        "COMMENT": SchemaCommentProperty,
2883        "DEFINER": DefinerProperty,
2884        "DISTKEY": DistKeyProperty,
2885        "DISTSTYLE": DistStyleProperty,
2886        "ENGINE": EngineProperty,
2887        "EXECUTE AS": ExecuteAsProperty,
2888        "FORMAT": FileFormatProperty,
2889        "LANGUAGE": LanguageProperty,
2890        "LOCATION": LocationProperty,
2891        "LOCK": LockProperty,
2892        "PARTITIONED_BY": PartitionedByProperty,
2893        "RETURNS": ReturnsProperty,
2894        "ROW_FORMAT": RowFormatProperty,
2895        "SORTKEY": SortKeyProperty,
2896    }
2897
2898    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2899
2900    # CREATE property locations
2901    # Form: schema specified
2902    #   create [POST_CREATE]
2903    #     table a [POST_NAME]
2904    #     (b int) [POST_SCHEMA]
2905    #     with ([POST_WITH])
2906    #     index (b) [POST_INDEX]
2907    #
2908    # Form: alias selection
2909    #   create [POST_CREATE]
2910    #     table a [POST_NAME]
2911    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2912    #     index (c) [POST_INDEX]
2913    class Location(AutoName):
2914        POST_CREATE = auto()
2915        POST_NAME = auto()
2916        POST_SCHEMA = auto()
2917        POST_WITH = auto()
2918        POST_ALIAS = auto()
2919        POST_EXPRESSION = auto()
2920        POST_INDEX = auto()
2921        UNSUPPORTED = auto()
2922
2923    @classmethod
2924    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2925        expressions = []
2926        for key, value in properties_dict.items():
2927            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2928            if property_cls:
2929                expressions.append(property_cls(this=convert(value)))
2930            else:
2931                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2932
2933        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:
2923    @classmethod
2924    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2925        expressions = []
2926        for key, value in properties_dict.items():
2927            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2928            if property_cls:
2929                expressions.append(property_cls(this=convert(value)))
2930            else:
2931                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2932
2933        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2913    class Location(AutoName):
2914        POST_CREATE = auto()
2915        POST_NAME = auto()
2916        POST_SCHEMA = auto()
2917        POST_WITH = auto()
2918        POST_ALIAS = auto()
2919        POST_EXPRESSION = auto()
2920        POST_INDEX = auto()
2921        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):
2936class Qualify(Expression):
2937    pass
key = 'qualify'
class InputOutputFormat(Expression):
2940class InputOutputFormat(Expression):
2941    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2945class Return(Expression):
2946    pass
key = 'return'
class Reference(Expression):
2949class Reference(Expression):
2950    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2953class Tuple(Expression):
2954    arg_types = {"expressions": False}
2955
2956    def isin(
2957        self,
2958        *expressions: t.Any,
2959        query: t.Optional[ExpOrStr] = None,
2960        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2961        copy: bool = True,
2962        **opts,
2963    ) -> In:
2964        return In(
2965            this=maybe_copy(self, copy),
2966            expressions=[convert(e, copy=copy) for e in expressions],
2967            query=maybe_parse(query, copy=copy, **opts) if query else None,
2968            unnest=(
2969                Unnest(
2970                    expressions=[
2971                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2972                        for e in ensure_list(unnest)
2973                    ]
2974                )
2975                if unnest
2976                else None
2977            ),
2978        )
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:
2956    def isin(
2957        self,
2958        *expressions: t.Any,
2959        query: t.Optional[ExpOrStr] = None,
2960        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2961        copy: bool = True,
2962        **opts,
2963    ) -> In:
2964        return In(
2965            this=maybe_copy(self, copy),
2966            expressions=[convert(e, copy=copy) for e in expressions],
2967            query=maybe_parse(query, copy=copy, **opts) if query else None,
2968            unnest=(
2969                Unnest(
2970                    expressions=[
2971                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2972                        for e in ensure_list(unnest)
2973                    ]
2974                )
2975                if unnest
2976                else None
2977            ),
2978        )
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):
3009class QueryOption(Expression):
3010    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3014class WithTableHint(Expression):
3015    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3019class IndexTableHint(Expression):
3020    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3024class HistoricalData(Expression):
3025    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3028class Table(Expression):
3029    arg_types = {
3030        "this": False,
3031        "alias": False,
3032        "db": False,
3033        "catalog": False,
3034        "laterals": False,
3035        "joins": False,
3036        "pivots": False,
3037        "hints": False,
3038        "system_time": False,
3039        "version": False,
3040        "format": False,
3041        "pattern": False,
3042        "ordinality": False,
3043        "when": False,
3044        "only": False,
3045        "partition": False,
3046        "changes": False,
3047        "rows_from": False,
3048    }
3049
3050    @property
3051    def name(self) -> str:
3052        if isinstance(self.this, Func):
3053            return ""
3054        return self.this.name
3055
3056    @property
3057    def db(self) -> str:
3058        return self.text("db")
3059
3060    @property
3061    def catalog(self) -> str:
3062        return self.text("catalog")
3063
3064    @property
3065    def selects(self) -> t.List[Expression]:
3066        return []
3067
3068    @property
3069    def named_selects(self) -> t.List[str]:
3070        return []
3071
3072    @property
3073    def parts(self) -> t.List[Expression]:
3074        """Return the parts of a table in order catalog, db, table."""
3075        parts: t.List[Expression] = []
3076
3077        for arg in ("catalog", "db", "this"):
3078            part = self.args.get(arg)
3079
3080            if isinstance(part, Dot):
3081                parts.extend(part.flatten())
3082            elif isinstance(part, Expression):
3083                parts.append(part)
3084
3085        return parts
3086
3087    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3088        parts = self.parts
3089        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3090        alias = self.args.get("alias")
3091        if alias:
3092            col = alias_(col, alias.this, copy=copy)
3093        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
3050    @property
3051    def name(self) -> str:
3052        if isinstance(self.this, Func):
3053            return ""
3054        return self.this.name
db: str
3056    @property
3057    def db(self) -> str:
3058        return self.text("db")
catalog: str
3060    @property
3061    def catalog(self) -> str:
3062        return self.text("catalog")
selects: List[Expression]
3064    @property
3065    def selects(self) -> t.List[Expression]:
3066        return []
named_selects: List[str]
3068    @property
3069    def named_selects(self) -> t.List[str]:
3070        return []
parts: List[Expression]
3072    @property
3073    def parts(self) -> t.List[Expression]:
3074        """Return the parts of a table in order catalog, db, table."""
3075        parts: t.List[Expression] = []
3076
3077        for arg in ("catalog", "db", "this"):
3078            part = self.args.get(arg)
3079
3080            if isinstance(part, Dot):
3081                parts.extend(part.flatten())
3082            elif isinstance(part, Expression):
3083                parts.append(part)
3084
3085        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3125    @property
3126    def is_star(self) -> bool:
3127        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3129    @property
3130    def selects(self) -> t.List[Expression]:
3131        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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:
3367    def select(
3368        self,
3369        *expressions: t.Optional[ExpOrStr],
3370        append: bool = True,
3371        dialect: DialectType = None,
3372        copy: bool = True,
3373        **opts,
3374    ) -> Select:
3375        return _apply_list_builder(
3376            *expressions,
3377            instance=self,
3378            arg="expressions",
3379            append=append,
3380            dialect=dialect,
3381            into=Expression,
3382            copy=copy,
3383            **opts,
3384        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3757    @property
3758    def selects(self) -> t.List[Expression]:
3759        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3780    def unwrap(self) -> Subquery:
3781        expression = self
3782        while expression.same_parent and expression.is_wrapper:
3783            expression = t.cast(Subquery, expression.parent)
3784        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:
3786    def select(
3787        self,
3788        *expressions: t.Optional[ExpOrStr],
3789        append: bool = True,
3790        dialect: DialectType = None,
3791        copy: bool = True,
3792        **opts,
3793    ) -> Subquery:
3794        this = maybe_copy(self, copy)
3795        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3796        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
3798    @property
3799    def is_wrapper(self) -> bool:
3800        """
3801        Whether this Subquery acts as a simple wrapper around another expression.
3802
3803        SELECT * FROM (((SELECT * FROM t)))
3804                      ^
3805                      This corresponds to a "wrapper" Subquery node
3806        """
3807        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
3809    @property
3810    def is_star(self) -> bool:
3811        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3813    @property
3814    def output_name(self) -> str:
3815        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):
3818class TableSample(Expression):
3819    arg_types = {
3820        "this": False,
3821        "expressions": False,
3822        "method": False,
3823        "bucket_numerator": False,
3824        "bucket_denominator": False,
3825        "bucket_field": False,
3826        "percent": False,
3827        "rows": False,
3828        "size": False,
3829        "seed": False,
3830    }
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):
3833class Tag(Expression):
3834    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3835
3836    arg_types = {
3837        "this": False,
3838        "prefix": False,
3839        "postfix": False,
3840    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3845class Pivot(Expression):
3846    arg_types = {
3847        "this": False,
3848        "alias": False,
3849        "expressions": False,
3850        "field": False,
3851        "unpivot": False,
3852        "using": False,
3853        "group": False,
3854        "columns": False,
3855        "include_nulls": False,
3856    }
3857
3858    @property
3859    def unpivot(self) -> bool:
3860        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}
unpivot: bool
3858    @property
3859    def unpivot(self) -> bool:
3860        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3863class Window(Condition):
3864    arg_types = {
3865        "this": True,
3866        "partition_by": False,
3867        "order": False,
3868        "spec": False,
3869        "alias": False,
3870        "over": False,
3871        "first": False,
3872    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3875class WindowSpec(Expression):
3876    arg_types = {
3877        "kind": False,
3878        "start": False,
3879        "start_side": False,
3880        "end": False,
3881        "end_side": False,
3882    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3885class PreWhere(Expression):
3886    pass
key = 'prewhere'
class Where(Expression):
3889class Where(Expression):
3890    pass
key = 'where'
class Star(Expression):
3893class Star(Expression):
3894    arg_types = {"except": False, "replace": False, "rename": False}
3895
3896    @property
3897    def name(self) -> str:
3898        return "*"
3899
3900    @property
3901    def output_name(self) -> str:
3902        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3896    @property
3897    def name(self) -> str:
3898        return "*"
output_name: str
3900    @property
3901    def output_name(self) -> str:
3902        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):
3905class Parameter(Condition):
3906    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3909class SessionParameter(Condition):
3910    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3913class Placeholder(Condition):
3914    arg_types = {"this": False, "kind": False}
3915
3916    @property
3917    def name(self) -> str:
3918        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3916    @property
3917    def name(self) -> str:
3918        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3921class Null(Condition):
3922    arg_types: t.Dict[str, t.Any] = {}
3923
3924    @property
3925    def name(self) -> str:
3926        return "NULL"
3927
3928    def to_py(self) -> Lit[None]:
3929        return None
arg_types: Dict[str, Any] = {}
name: str
3924    @property
3925    def name(self) -> str:
3926        return "NULL"
def to_py(self) -> Literal[None]:
3928    def to_py(self) -> Lit[None]:
3929        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3932class Boolean(Condition):
3933    def to_py(self) -> bool:
3934        return self.this
def to_py(self) -> bool:
3933    def to_py(self) -> bool:
3934        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

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

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

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

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

key = 'kwarg'
class Like(Binary, Predicate):
4447class Like(Binary, Predicate):
4448    pass
key = 'like'
class LikeAny(Binary, Predicate):
4451class LikeAny(Binary, Predicate):
4452    pass
key = 'likeany'
class LT(Binary, Predicate):
4455class LT(Binary, Predicate):
4456    pass
key = 'lt'
class LTE(Binary, Predicate):
4459class LTE(Binary, Predicate):
4460    pass
key = 'lte'
class Mod(Binary):
4463class Mod(Binary):
4464    pass
key = 'mod'
class Mul(Binary):
4467class Mul(Binary):
4468    pass
key = 'mul'
class NEQ(Binary, Predicate):
4471class NEQ(Binary, Predicate):
4472    pass
key = 'neq'
class Operator(Binary):
4476class Operator(Binary):
4477    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4480class SimilarTo(Binary, Predicate):
4481    pass
key = 'similarto'
class Slice(Binary):
4484class Slice(Binary):
4485    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4488class Sub(Binary):
4489    pass
key = 'sub'
class Unary(Condition):
4494class Unary(Condition):
4495    pass
key = 'unary'
class BitwiseNot(Unary):
4498class BitwiseNot(Unary):
4499    pass
key = 'bitwisenot'
class Not(Unary):
4502class Not(Unary):
4503    pass
key = 'not'
class Paren(Unary):
4506class Paren(Unary):
4507    @property
4508    def output_name(self) -> str:
4509        return self.this.name
output_name: str
4507    @property
4508    def output_name(self) -> str:
4509        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):
4512class Neg(Unary):
4513    def to_py(self) -> int | Decimal:
4514        if self.is_number:
4515            return self.this.to_py() * -1
4516        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4513    def to_py(self) -> int | Decimal:
4514        if self.is_number:
4515            return self.this.to_py() * -1
4516        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4519class Alias(Expression):
4520    arg_types = {"this": True, "alias": False}
4521
4522    @property
4523    def output_name(self) -> str:
4524        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4522    @property
4523    def output_name(self) -> str:
4524        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):
4529class PivotAlias(Alias):
4530    pass
key = 'pivotalias'
class Aliases(Expression):
4533class Aliases(Expression):
4534    arg_types = {"this": True, "expressions": True}
4535
4536    @property
4537    def aliases(self):
4538        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4536    @property
4537    def aliases(self):
4538        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4542class AtIndex(Expression):
4543    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4546class AtTimeZone(Expression):
4547    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4550class FromTimeZone(Expression):
4551    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4554class Between(Predicate):
4555    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4558class Bracket(Condition):
4559    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4560    arg_types = {
4561        "this": True,
4562        "expressions": True,
4563        "offset": False,
4564        "safe": False,
4565        "returns_list_for_maps": False,
4566    }
4567
4568    @property
4569    def output_name(self) -> str:
4570        if len(self.expressions) == 1:
4571            return self.expressions[0].output_name
4572
4573        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4568    @property
4569    def output_name(self) -> str:
4570        if len(self.expressions) == 1:
4571            return self.expressions[0].output_name
4572
4573        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):
4576class Distinct(Expression):
4577    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4580class In(Predicate):
4581    arg_types = {
4582        "this": True,
4583        "expressions": False,
4584        "query": False,
4585        "unnest": False,
4586        "field": False,
4587        "is_global": False,
4588    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4592class ForIn(Expression):
4593    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4596class TimeUnit(Expression):
4597    """Automatically converts unit arg into a var."""
4598
4599    arg_types = {"unit": False}
4600
4601    UNABBREVIATED_UNIT_NAME = {
4602        "D": "DAY",
4603        "H": "HOUR",
4604        "M": "MINUTE",
4605        "MS": "MILLISECOND",
4606        "NS": "NANOSECOND",
4607        "Q": "QUARTER",
4608        "S": "SECOND",
4609        "US": "MICROSECOND",
4610        "W": "WEEK",
4611        "Y": "YEAR",
4612    }
4613
4614    VAR_LIKE = (Column, Literal, Var)
4615
4616    def __init__(self, **args):
4617        unit = args.get("unit")
4618        if isinstance(unit, self.VAR_LIKE):
4619            args["unit"] = Var(
4620                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4621            )
4622        elif isinstance(unit, Week):
4623            unit.set("this", Var(this=unit.this.name.upper()))
4624
4625        super().__init__(**args)
4626
4627    @property
4628    def unit(self) -> t.Optional[Var | IntervalSpan]:
4629        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4616    def __init__(self, **args):
4617        unit = args.get("unit")
4618        if isinstance(unit, self.VAR_LIKE):
4619            args["unit"] = Var(
4620                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4621            )
4622        elif isinstance(unit, Week):
4623            unit.set("this", Var(this=unit.this.name.upper()))
4624
4625        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]
4627    @property
4628    def unit(self) -> t.Optional[Var | IntervalSpan]:
4629        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4632class IntervalOp(TimeUnit):
4633    arg_types = {"unit": True, "expression": True}
4634
4635    def interval(self):
4636        return Interval(
4637            this=self.expression.copy(),
4638            unit=self.unit.copy(),
4639        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4635    def interval(self):
4636        return Interval(
4637            this=self.expression.copy(),
4638            unit=self.unit.copy(),
4639        )
key = 'intervalop'
class IntervalSpan(DataType):
4645class IntervalSpan(DataType):
4646    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4649class Interval(TimeUnit):
4650    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4653class IgnoreNulls(Expression):
4654    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4657class RespectNulls(Expression):
4658    pass
key = 'respectnulls'
class HavingMax(Expression):
4662class HavingMax(Expression):
4663    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4667class Func(Condition):
4668    """
4669    The base class for all function expressions.
4670
4671    Attributes:
4672        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4673            treated as a variable length argument and the argument's value will be stored as a list.
4674        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4675            function expression. These values are used to map this node to a name during parsing as
4676            well as to provide the function's name during SQL string generation. By default the SQL
4677            name is set to the expression's class name transformed to snake case.
4678    """
4679
4680    is_var_len_args = False
4681
4682    @classmethod
4683    def from_arg_list(cls, args):
4684        if cls.is_var_len_args:
4685            all_arg_keys = list(cls.arg_types)
4686            # If this function supports variable length argument treat the last argument as such.
4687            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4688            num_non_var = len(non_var_len_arg_keys)
4689
4690            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4691            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4692        else:
4693            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4694
4695        return cls(**args_dict)
4696
4697    @classmethod
4698    def sql_names(cls):
4699        if cls is Func:
4700            raise NotImplementedError(
4701                "SQL name is only supported by concrete function implementations"
4702            )
4703        if "_sql_names" not in cls.__dict__:
4704            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4705        return cls._sql_names
4706
4707    @classmethod
4708    def sql_name(cls):
4709        return cls.sql_names()[0]
4710
4711    @classmethod
4712    def default_parser_mappings(cls):
4713        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):
4682    @classmethod
4683    def from_arg_list(cls, args):
4684        if cls.is_var_len_args:
4685            all_arg_keys = list(cls.arg_types)
4686            # If this function supports variable length argument treat the last argument as such.
4687            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4688            num_non_var = len(non_var_len_arg_keys)
4689
4690            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4691            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4692        else:
4693            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4694
4695        return cls(**args_dict)
@classmethod
def sql_names(cls):
4697    @classmethod
4698    def sql_names(cls):
4699        if cls is Func:
4700            raise NotImplementedError(
4701                "SQL name is only supported by concrete function implementations"
4702            )
4703        if "_sql_names" not in cls.__dict__:
4704            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4705        return cls._sql_names
@classmethod
def sql_name(cls):
4707    @classmethod
4708    def sql_name(cls):
4709        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4711    @classmethod
4712    def default_parser_mappings(cls):
4713        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4716class AggFunc(Func):
4717    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4720class ParameterizedAgg(AggFunc):
4721    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4724class Abs(Func):
4725    pass
key = 'abs'
class ArgMax(AggFunc):
4728class ArgMax(AggFunc):
4729    arg_types = {"this": True, "expression": True, "count": False}
4730    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4733class ArgMin(AggFunc):
4734    arg_types = {"this": True, "expression": True, "count": False}
4735    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4738class ApproxTopK(AggFunc):
4739    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4742class Flatten(Func):
4743    pass
key = 'flatten'
class Transform(Func):
4747class Transform(Func):
4748    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4751class Anonymous(Func):
4752    arg_types = {"this": True, "expressions": False}
4753    is_var_len_args = True
4754
4755    @property
4756    def name(self) -> str:
4757        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
4755    @property
4756    def name(self) -> str:
4757        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4760class AnonymousAggFunc(AggFunc):
4761    arg_types = {"this": True, "expressions": False}
4762    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4766class CombinedAggFunc(AnonymousAggFunc):
4767    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4770class CombinedParameterizedAgg(ParameterizedAgg):
4771    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):
4776class Hll(AggFunc):
4777    arg_types = {"this": True, "expressions": False}
4778    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4781class ApproxDistinct(AggFunc):
4782    arg_types = {"this": True, "accuracy": False}
4783    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4786class Array(Func):
4787    arg_types = {"expressions": False}
4788    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4792class ToArray(Func):
4793    pass
key = 'toarray'
class List(Func):
4797class List(Func):
4798    arg_types = {"expressions": False}
4799    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4803class Pad(Func):
4804    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):
4809class ToChar(Func):
4810    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4815class ToNumber(Func):
4816    arg_types = {
4817        "this": True,
4818        "format": False,
4819        "nlsparam": False,
4820        "precision": False,
4821        "scale": False,
4822    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4826class Convert(Func):
4827    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4830class GenerateSeries(Func):
4831    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 ArrayAgg(AggFunc):
4834class ArrayAgg(AggFunc):
4835    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4838class ArrayUniqueAgg(AggFunc):
4839    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4842class ArrayAll(Func):
4843    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4847class ArrayAny(Func):
4848    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4851class ArrayConcat(Func):
4852    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4853    arg_types = {"this": True, "expressions": False}
4854    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4857class ArrayConstructCompact(Func):
4858    arg_types = {"expressions": True}
4859    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4862class ArrayContains(Binary, Func):
4863    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4866class ArrayContainsAll(Binary, Func):
4867    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4870class ArrayFilter(Func):
4871    arg_types = {"this": True, "expression": True}
4872    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4875class ArrayToString(Func):
4876    arg_types = {"this": True, "expression": True, "null": False}
4877    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4880class StringToArray(Func):
4881    arg_types = {"this": True, "expression": True, "null": False}
4882    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4885class ArrayOverlaps(Binary, Func):
4886    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4889class ArraySize(Func):
4890    arg_types = {"this": True, "expression": False}
4891    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4894class ArraySort(Func):
4895    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4898class ArraySum(Func):
4899    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4902class ArrayUnionAgg(AggFunc):
4903    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4906class Avg(AggFunc):
4907    pass
key = 'avg'
class AnyValue(AggFunc):
4910class AnyValue(AggFunc):
4911    pass
key = 'anyvalue'
class Lag(AggFunc):
4914class Lag(AggFunc):
4915    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4918class Lead(AggFunc):
4919    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4924class First(AggFunc):
4925    pass
key = 'first'
class Last(AggFunc):
4928class Last(AggFunc):
4929    pass
key = 'last'
class FirstValue(AggFunc):
4932class FirstValue(AggFunc):
4933    pass
key = 'firstvalue'
class LastValue(AggFunc):
4936class LastValue(AggFunc):
4937    pass
key = 'lastvalue'
class NthValue(AggFunc):
4940class NthValue(AggFunc):
4941    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4944class Case(Func):
4945    arg_types = {"this": False, "ifs": True, "default": False}
4946
4947    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4948        instance = maybe_copy(self, copy)
4949        instance.append(
4950            "ifs",
4951            If(
4952                this=maybe_parse(condition, copy=copy, **opts),
4953                true=maybe_parse(then, copy=copy, **opts),
4954            ),
4955        )
4956        return instance
4957
4958    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4959        instance = maybe_copy(self, copy)
4960        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4961        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:
4947    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4948        instance = maybe_copy(self, copy)
4949        instance.append(
4950            "ifs",
4951            If(
4952                this=maybe_parse(condition, copy=copy, **opts),
4953                true=maybe_parse(then, copy=copy, **opts),
4954            ),
4955        )
4956        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4958    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4959        instance = maybe_copy(self, copy)
4960        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4961        return instance
key = 'case'
class Cast(Func):
4964class Cast(Func):
4965    arg_types = {
4966        "this": True,
4967        "to": True,
4968        "format": False,
4969        "safe": False,
4970        "action": False,
4971    }
4972
4973    @property
4974    def name(self) -> str:
4975        return self.this.name
4976
4977    @property
4978    def to(self) -> DataType:
4979        return self.args["to"]
4980
4981    @property
4982    def output_name(self) -> str:
4983        return self.name
4984
4985    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4986        """
4987        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4988        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4989        array<int> != array<float>.
4990
4991        Args:
4992            dtypes: the data types to compare this Cast's DataType to.
4993
4994        Returns:
4995            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4996        """
4997        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4973    @property
4974    def name(self) -> str:
4975        return self.this.name
to: DataType
4977    @property
4978    def to(self) -> DataType:
4979        return self.args["to"]
output_name: str
4981    @property
4982    def output_name(self) -> str:
4983        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:
4985    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4986        """
4987        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4988        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4989        array<int> != array<float>.
4990
4991        Args:
4992            dtypes: the data types to compare this Cast's DataType to.
4993
4994        Returns:
4995            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4996        """
4997        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):
5000class TryCast(Cast):
5001    pass
key = 'trycast'
class Try(Func):
5004class Try(Func):
5005    pass
key = 'try'
class CastToStrType(Func):
5008class CastToStrType(Func):
5009    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5012class Collate(Binary, Func):
5013    pass
key = 'collate'
class Ceil(Func):
5016class Ceil(Func):
5017    arg_types = {"this": True, "decimals": False}
5018    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5021class Coalesce(Func):
5022    arg_types = {"this": True, "expressions": False}
5023    is_var_len_args = True
5024    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5027class Chr(Func):
5028    arg_types = {"this": True, "charset": False, "expressions": False}
5029    is_var_len_args = True
5030    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5033class Concat(Func):
5034    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5035    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5038class ConcatWs(Concat):
5039    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5043class ConnectByRoot(Func):
5044    pass
key = 'connectbyroot'
class Count(AggFunc):
5047class Count(AggFunc):
5048    arg_types = {"this": False, "expressions": False}
5049    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5052class CountIf(AggFunc):
5053    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5057class Cbrt(Func):
5058    pass
key = 'cbrt'
class CurrentDate(Func):
5061class CurrentDate(Func):
5062    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5065class CurrentDatetime(Func):
5066    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5069class CurrentTime(Func):
5070    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5073class CurrentTimestamp(Func):
5074    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5077class CurrentUser(Func):
5078    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5081class DateAdd(Func, IntervalOp):
5082    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5085class DateSub(Func, IntervalOp):
5086    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5089class DateDiff(Func, TimeUnit):
5090    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5091    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5094class DateTrunc(Func):
5095    arg_types = {"unit": True, "this": True, "zone": False}
5096
5097    def __init__(self, **args):
5098        unit = args.get("unit")
5099        if isinstance(unit, TimeUnit.VAR_LIKE):
5100            args["unit"] = Literal.string(
5101                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5102            )
5103        elif isinstance(unit, Week):
5104            unit.set("this", Literal.string(unit.this.name.upper()))
5105
5106        super().__init__(**args)
5107
5108    @property
5109    def unit(self) -> Expression:
5110        return self.args["unit"]
DateTrunc(**args)
5097    def __init__(self, **args):
5098        unit = args.get("unit")
5099        if isinstance(unit, TimeUnit.VAR_LIKE):
5100            args["unit"] = Literal.string(
5101                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5102            )
5103        elif isinstance(unit, Week):
5104            unit.set("this", Literal.string(unit.this.name.upper()))
5105
5106        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5108    @property
5109    def unit(self) -> Expression:
5110        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5115class Datetime(Func):
5116    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5119class DatetimeAdd(Func, IntervalOp):
5120    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5123class DatetimeSub(Func, IntervalOp):
5124    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5127class DatetimeDiff(Func, TimeUnit):
5128    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5131class DatetimeTrunc(Func, TimeUnit):
5132    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5135class DayOfWeek(Func):
5136    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5139class DayOfMonth(Func):
5140    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5143class DayOfYear(Func):
5144    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5147class ToDays(Func):
5148    pass
key = 'todays'
class WeekOfYear(Func):
5151class WeekOfYear(Func):
5152    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5155class MonthsBetween(Func):
5156    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5159class LastDay(Func, TimeUnit):
5160    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5161    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5164class Extract(Func):
5165    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5168class Timestamp(Func):
5169    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5172class TimestampAdd(Func, TimeUnit):
5173    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5176class TimestampSub(Func, TimeUnit):
5177    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5180class TimestampDiff(Func, TimeUnit):
5181    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5182    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5185class TimestampTrunc(Func, TimeUnit):
5186    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5189class TimeAdd(Func, TimeUnit):
5190    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5193class TimeSub(Func, TimeUnit):
5194    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5197class TimeDiff(Func, TimeUnit):
5198    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5201class TimeTrunc(Func, TimeUnit):
5202    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5205class DateFromParts(Func):
5206    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5207    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5210class TimeFromParts(Func):
5211    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5212    arg_types = {
5213        "hour": True,
5214        "min": True,
5215        "sec": True,
5216        "nano": False,
5217        "fractions": False,
5218        "precision": False,
5219    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5222class DateStrToDate(Func):
5223    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5226class DateToDateStr(Func):
5227    pass
key = 'datetodatestr'
class DateToDi(Func):
5230class DateToDi(Func):
5231    pass
key = 'datetodi'
class Date(Func):
5235class Date(Func):
5236    arg_types = {"this": False, "zone": False, "expressions": False}
5237    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5240class Day(Func):
5241    pass
key = 'day'
class Decode(Func):
5244class Decode(Func):
5245    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5248class DiToDate(Func):
5249    pass
key = 'ditodate'
class Encode(Func):
5252class Encode(Func):
5253    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5256class Exp(Func):
5257    pass
key = 'exp'
class Explode(Func):
5261class Explode(Func):
5262    arg_types = {"this": True, "expressions": False}
5263    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5266class ExplodeOuter(Explode):
5267    pass
key = 'explodeouter'
class Posexplode(Explode):
5270class Posexplode(Explode):
5271    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5274class PosexplodeOuter(Posexplode, ExplodeOuter):
5275    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5278class Unnest(Func, UDTF):
5279    arg_types = {
5280        "expressions": True,
5281        "alias": False,
5282        "offset": False,
5283    }
5284
5285    @property
5286    def selects(self) -> t.List[Expression]:
5287        columns = super().selects
5288        offset = self.args.get("offset")
5289        if offset:
5290            columns = columns + [to_identifier("offset") if offset is True else offset]
5291        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5285    @property
5286    def selects(self) -> t.List[Expression]:
5287        columns = super().selects
5288        offset = self.args.get("offset")
5289        if offset:
5290            columns = columns + [to_identifier("offset") if offset is True else offset]
5291        return columns
key = 'unnest'
class Floor(Func):
5294class Floor(Func):
5295    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5298class FromBase64(Func):
5299    pass
key = 'frombase64'
class ToBase64(Func):
5302class ToBase64(Func):
5303    pass
key = 'tobase64'
class GapFill(Func):
5306class GapFill(Func):
5307    arg_types = {
5308        "this": True,
5309        "ts_column": True,
5310        "bucket_width": True,
5311        "partitioning_columns": False,
5312        "value_columns": False,
5313        "origin": False,
5314        "ignore_nulls": False,
5315    }
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):
5318class GenerateDateArray(Func):
5319    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5322class Greatest(Func):
5323    arg_types = {"this": True, "expressions": False}
5324    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5327class GroupConcat(AggFunc):
5328    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5331class Hex(Func):
5332    pass
key = 'hex'
class LowerHex(Hex):
5335class LowerHex(Hex):
5336    pass
key = 'lowerhex'
class Xor(Connector, Func):
5339class Xor(Connector, Func):
5340    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5343class If(Func):
5344    arg_types = {"this": True, "true": True, "false": False}
5345    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5348class Nullif(Func):
5349    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5352class Initcap(Func):
5353    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5356class IsNan(Func):
5357    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5360class IsInf(Func):
5361    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5364class JSONPath(Expression):
5365    arg_types = {"expressions": True}
5366
5367    @property
5368    def output_name(self) -> str:
5369        last_segment = self.expressions[-1].this
5370        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5367    @property
5368    def output_name(self) -> str:
5369        last_segment = self.expressions[-1].this
5370        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):
5373class JSONPathPart(Expression):
5374    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5377class JSONPathFilter(JSONPathPart):
5378    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5381class JSONPathKey(JSONPathPart):
5382    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5385class JSONPathRecursive(JSONPathPart):
5386    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5389class JSONPathRoot(JSONPathPart):
5390    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5393class JSONPathScript(JSONPathPart):
5394    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5397class JSONPathSlice(JSONPathPart):
5398    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5401class JSONPathSelector(JSONPathPart):
5402    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5405class JSONPathSubscript(JSONPathPart):
5406    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5409class JSONPathUnion(JSONPathPart):
5410    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5413class JSONPathWildcard(JSONPathPart):
5414    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5417class FormatJson(Expression):
5418    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5421class JSONKeyValue(Expression):
5422    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5425class JSONObject(Func):
5426    arg_types = {
5427        "expressions": False,
5428        "null_handling": False,
5429        "unique_keys": False,
5430        "return_type": False,
5431        "encoding": False,
5432    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5435class JSONObjectAgg(AggFunc):
5436    arg_types = {
5437        "expressions": False,
5438        "null_handling": False,
5439        "unique_keys": False,
5440        "return_type": False,
5441        "encoding": False,
5442    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5446class JSONArray(Func):
5447    arg_types = {
5448        "expressions": True,
5449        "null_handling": False,
5450        "return_type": False,
5451        "strict": False,
5452    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5456class JSONArrayAgg(Func):
5457    arg_types = {
5458        "this": True,
5459        "order": False,
5460        "null_handling": False,
5461        "return_type": False,
5462        "strict": False,
5463    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5468class JSONColumnDef(Expression):
5469    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):
5472class JSONSchema(Expression):
5473    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5477class JSONTable(Func):
5478    arg_types = {
5479        "this": True,
5480        "schema": True,
5481        "path": False,
5482        "error_handling": False,
5483        "empty_handling": False,
5484    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5487class OpenJSONColumnDef(Expression):
5488    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):
5491class OpenJSON(Func):
5492    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5495class JSONBContains(Binary, Func):
5496    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5499class JSONExtract(Binary, Func):
5500    arg_types = {
5501        "this": True,
5502        "expression": True,
5503        "only_json_types": False,
5504        "expressions": False,
5505        "variant_extract": False,
5506    }
5507    _sql_names = ["JSON_EXTRACT"]
5508    is_var_len_args = True
5509
5510    @property
5511    def output_name(self) -> str:
5512        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
5510    @property
5511    def output_name(self) -> str:
5512        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):
5515class JSONExtractScalar(Binary, Func):
5516    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5517    _sql_names = ["JSON_EXTRACT_SCALAR"]
5518    is_var_len_args = True
5519
5520    @property
5521    def output_name(self) -> str:
5522        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
5520    @property
5521    def output_name(self) -> str:
5522        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):
5525class JSONBExtract(Binary, Func):
5526    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5529class JSONBExtractScalar(Binary, Func):
5530    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5533class JSONFormat(Func):
5534    arg_types = {"this": False, "options": False}
5535    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5539class JSONArrayContains(Binary, Predicate, Func):
5540    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5543class ParseJSON(Func):
5544    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5545    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5546    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5547    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5550class Least(Func):
5551    arg_types = {"this": True, "expressions": False}
5552    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5555class Left(Func):
5556    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5563class Length(Func):
5564    arg_types = {"this": True, "binary": False}
5565    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5568class Levenshtein(Func):
5569    arg_types = {
5570        "this": True,
5571        "expression": False,
5572        "ins_cost": False,
5573        "del_cost": False,
5574        "sub_cost": False,
5575    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5578class Ln(Func):
5579    pass
key = 'ln'
class Log(Func):
5582class Log(Func):
5583    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5586class LogicalOr(AggFunc):
5587    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5590class LogicalAnd(AggFunc):
5591    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5594class Lower(Func):
5595    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5598class Map(Func):
5599    arg_types = {"keys": False, "values": False}
5600
5601    @property
5602    def keys(self) -> t.List[Expression]:
5603        keys = self.args.get("keys")
5604        return keys.expressions if keys else []
5605
5606    @property
5607    def values(self) -> t.List[Expression]:
5608        values = self.args.get("values")
5609        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5601    @property
5602    def keys(self) -> t.List[Expression]:
5603        keys = self.args.get("keys")
5604        return keys.expressions if keys else []
values: List[Expression]
5606    @property
5607    def values(self) -> t.List[Expression]:
5608        values = self.args.get("values")
5609        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5613class ToMap(Func):
5614    pass
key = 'tomap'
class MapFromEntries(Func):
5617class MapFromEntries(Func):
5618    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5622class ScopeResolution(Expression):
5623    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class StarMap(Func):
5626class StarMap(Func):
5627    pass
key = 'starmap'
class VarMap(Func):
5630class VarMap(Func):
5631    arg_types = {"keys": True, "values": True}
5632    is_var_len_args = True
5633
5634    @property
5635    def keys(self) -> t.List[Expression]:
5636        return self.args["keys"].expressions
5637
5638    @property
5639    def values(self) -> t.List[Expression]:
5640        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5634    @property
5635    def keys(self) -> t.List[Expression]:
5636        return self.args["keys"].expressions
values: List[Expression]
5638    @property
5639    def values(self) -> t.List[Expression]:
5640        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5644class MatchAgainst(Func):
5645    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5648class Max(AggFunc):
5649    arg_types = {"this": True, "expressions": False}
5650    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5653class MD5(Func):
5654    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5658class MD5Digest(Func):
5659    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5662class Min(AggFunc):
5663    arg_types = {"this": True, "expressions": False}
5664    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5667class Month(Func):
5668    pass
key = 'month'
class AddMonths(Func):
5671class AddMonths(Func):
5672    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5675class Nvl2(Func):
5676    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5680class Predict(Func):
5681    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5684class Pow(Binary, Func):
5685    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5688class PercentileCont(AggFunc):
5689    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5692class PercentileDisc(AggFunc):
5693    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5696class Quantile(AggFunc):
5697    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5700class ApproxQuantile(Quantile):
5701    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):
5704class Quarter(Func):
5705    pass
key = 'quarter'
class Rand(Func):
5710class Rand(Func):
5711    _sql_names = ["RAND", "RANDOM"]
5712    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5715class Randn(Func):
5716    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5719class RangeN(Func):
5720    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5723class ReadCSV(Func):
5724    _sql_names = ["READ_CSV"]
5725    is_var_len_args = True
5726    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5729class Reduce(Func):
5730    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):
5733class RegexpExtract(Func):
5734    arg_types = {
5735        "this": True,
5736        "expression": True,
5737        "position": False,
5738        "occurrence": False,
5739        "parameters": False,
5740        "group": False,
5741    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5744class RegexpReplace(Func):
5745    arg_types = {
5746        "this": True,
5747        "expression": True,
5748        "replacement": False,
5749        "position": False,
5750        "occurrence": False,
5751        "modifiers": False,
5752    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5755class RegexpLike(Binary, Func):
5756    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5759class RegexpILike(Binary, Func):
5760    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5765class RegexpSplit(Func):
5766    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5769class Repeat(Func):
5770    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5775class Round(Func):
5776    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5779class RowNumber(Func):
5780    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5783class SafeDivide(Func):
5784    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5787class SHA(Func):
5788    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5791class SHA2(Func):
5792    _sql_names = ["SHA2"]
5793    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5796class Sign(Func):
5797    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5800class SortArray(Func):
5801    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5804class Split(Func):
5805    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5810class Substring(Func):
5811    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5814class StandardHash(Func):
5815    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5818class StartsWith(Func):
5819    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5820    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5823class StrPosition(Func):
5824    arg_types = {
5825        "this": True,
5826        "substr": True,
5827        "position": False,
5828        "instance": False,
5829    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5832class StrToDate(Func):
5833    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5836class StrToTime(Func):
5837    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):
5842class StrToUnix(Func):
5843    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5848class StrToMap(Func):
5849    arg_types = {
5850        "this": True,
5851        "pair_delim": False,
5852        "key_value_delim": False,
5853        "duplicate_resolution_callback": False,
5854    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5857class NumberToStr(Func):
5858    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5861class FromBase(Func):
5862    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5865class Struct(Func):
5866    arg_types = {"expressions": False}
5867    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5870class StructExtract(Func):
5871    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5876class Stuff(Func):
5877    _sql_names = ["STUFF", "INSERT"]
5878    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):
5881class Sum(AggFunc):
5882    pass
key = 'sum'
class Sqrt(Func):
5885class Sqrt(Func):
5886    pass
key = 'sqrt'
class Stddev(AggFunc):
5889class Stddev(AggFunc):
5890    pass
key = 'stddev'
class StddevPop(AggFunc):
5893class StddevPop(AggFunc):
5894    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5897class StddevSamp(AggFunc):
5898    pass
key = 'stddevsamp'
class Time(Func):
5902class Time(Func):
5903    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5906class TimeToStr(Func):
5907    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):
5910class TimeToTimeStr(Func):
5911    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5914class TimeToUnix(Func):
5915    pass
key = 'timetounix'
class TimeStrToDate(Func):
5918class TimeStrToDate(Func):
5919    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5922class TimeStrToTime(Func):
5923    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5926class TimeStrToUnix(Func):
5927    pass
key = 'timestrtounix'
class Trim(Func):
5930class Trim(Func):
5931    arg_types = {
5932        "this": True,
5933        "expression": False,
5934        "position": False,
5935        "collation": False,
5936    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5939class TsOrDsAdd(Func, TimeUnit):
5940    # return_type is used to correctly cast the arguments of this expression when transpiling it
5941    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5942
5943    @property
5944    def return_type(self) -> DataType:
5945        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
5943    @property
5944    def return_type(self) -> DataType:
5945        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5948class TsOrDsDiff(Func, TimeUnit):
5949    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5952class TsOrDsToDateStr(Func):
5953    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5956class TsOrDsToDate(Func):
5957    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5960class TsOrDsToTime(Func):
5961    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5964class TsOrDsToTimestamp(Func):
5965    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5968class TsOrDiToDi(Func):
5969    pass
key = 'tsorditodi'
class Unhex(Func):
5972class Unhex(Func):
5973    pass
key = 'unhex'
class UnixDate(Func):
5977class UnixDate(Func):
5978    pass
key = 'unixdate'
class UnixToStr(Func):
5981class UnixToStr(Func):
5982    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5987class UnixToTime(Func):
5988    arg_types = {
5989        "this": True,
5990        "scale": False,
5991        "zone": False,
5992        "hours": False,
5993        "minutes": False,
5994        "format": False,
5995    }
5996
5997    SECONDS = Literal.number(0)
5998    DECIS = Literal.number(1)
5999    CENTIS = Literal.number(2)
6000    MILLIS = Literal.number(3)
6001    DECIMILLIS = Literal.number(4)
6002    CENTIMILLIS = Literal.number(5)
6003    MICROS = Literal.number(6)
6004    DECIMICROS = Literal.number(7)
6005    CENTIMICROS = Literal.number(8)
6006    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):
6009class UnixToTimeStr(Func):
6010    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6013class TimestampFromParts(Func):
6014    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6015    arg_types = {
6016        "year": True,
6017        "month": True,
6018        "day": True,
6019        "hour": True,
6020        "min": True,
6021        "sec": True,
6022        "nano": False,
6023        "zone": False,
6024        "milli": False,
6025    }
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):
6028class Upper(Func):
6029    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6032class Corr(Binary, AggFunc):
6033    pass
key = 'corr'
class Variance(AggFunc):
6036class Variance(AggFunc):
6037    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6040class VariancePop(AggFunc):
6041    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6044class CovarSamp(Binary, AggFunc):
6045    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6048class CovarPop(Binary, AggFunc):
6049    pass
key = 'covarpop'
class Week(Func):
6052class Week(Func):
6053    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6056class XMLTable(Func):
6057    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):
6060class Year(Func):
6061    pass
key = 'year'
class Use(Expression):
6064class Use(Expression):
6065    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6068class Merge(Expression):
6069    arg_types = {
6070        "this": True,
6071        "using": True,
6072        "on": True,
6073        "expressions": True,
6074        "with": False,
6075    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6078class When(Func):
6079    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):
6084class NextValueFor(Func):
6085    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6090class Semicolon(Expression):
6091    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 '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 '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'>, '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'>, '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'>, '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:
6131def maybe_parse(
6132    sql_or_expression: ExpOrStr,
6133    *,
6134    into: t.Optional[IntoType] = None,
6135    dialect: DialectType = None,
6136    prefix: t.Optional[str] = None,
6137    copy: bool = False,
6138    **opts,
6139) -> Expression:
6140    """Gracefully handle a possible string or expression.
6141
6142    Example:
6143        >>> maybe_parse("1")
6144        Literal(this=1, is_string=False)
6145        >>> maybe_parse(to_identifier("x"))
6146        Identifier(this=x, quoted=False)
6147
6148    Args:
6149        sql_or_expression: the SQL code string or an expression
6150        into: the SQLGlot Expression to parse into
6151        dialect: the dialect used to parse the input expressions (in the case that an
6152            input expression is a SQL string).
6153        prefix: a string to prefix the sql with before it gets parsed
6154            (automatically includes a space)
6155        copy: whether to copy the expression.
6156        **opts: other options to use to parse the input expressions (again, in the case
6157            that an input expression is a SQL string).
6158
6159    Returns:
6160        Expression: the parsed or given expression.
6161    """
6162    if isinstance(sql_or_expression, Expression):
6163        if copy:
6164            return sql_or_expression.copy()
6165        return sql_or_expression
6166
6167    if sql_or_expression is None:
6168        raise ParseError("SQL cannot be None")
6169
6170    import sqlglot
6171
6172    sql = str(sql_or_expression)
6173    if prefix:
6174        sql = f"{prefix} {sql}"
6175
6176    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):
6187def maybe_copy(instance, copy=True):
6188    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:
6408def union(
6409    left: ExpOrStr,
6410    right: ExpOrStr,
6411    distinct: bool = True,
6412    dialect: DialectType = None,
6413    copy: bool = True,
6414    **opts,
6415) -> Union:
6416    """
6417    Initializes a syntax tree from one UNION expression.
6418
6419    Example:
6420        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6421        'SELECT * FROM foo UNION SELECT * FROM bla'
6422
6423    Args:
6424        left: the SQL code string corresponding to the left-hand side.
6425            If an `Expression` instance is passed, it will be used as-is.
6426        right: the SQL code string corresponding to the right-hand side.
6427            If an `Expression` instance is passed, it will be used as-is.
6428        distinct: set the DISTINCT flag if and only if this is true.
6429        dialect: the dialect used to parse the input expression.
6430        copy: whether to copy the expression.
6431        opts: other options to use to parse the input expressions.
6432
6433    Returns:
6434        The new Union instance.
6435    """
6436    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6437    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6438
6439    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:
6442def intersect(
6443    left: ExpOrStr,
6444    right: ExpOrStr,
6445    distinct: bool = True,
6446    dialect: DialectType = None,
6447    copy: bool = True,
6448    **opts,
6449) -> Intersect:
6450    """
6451    Initializes a syntax tree from one INTERSECT expression.
6452
6453    Example:
6454        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6455        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6456
6457    Args:
6458        left: the SQL code string corresponding to the left-hand side.
6459            If an `Expression` instance is passed, it will be used as-is.
6460        right: the SQL code string corresponding to the right-hand side.
6461            If an `Expression` instance is passed, it will be used as-is.
6462        distinct: set the DISTINCT flag if and only if this is true.
6463        dialect: the dialect used to parse the input expression.
6464        copy: whether to copy the expression.
6465        opts: other options to use to parse the input expressions.
6466
6467    Returns:
6468        The new Intersect instance.
6469    """
6470    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6471    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6472
6473    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:
6476def except_(
6477    left: ExpOrStr,
6478    right: ExpOrStr,
6479    distinct: bool = True,
6480    dialect: DialectType = None,
6481    copy: bool = True,
6482    **opts,
6483) -> Except:
6484    """
6485    Initializes a syntax tree from one EXCEPT expression.
6486
6487    Example:
6488        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6489        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6490
6491    Args:
6492        left: the SQL code string corresponding to the left-hand side.
6493            If an `Expression` instance is passed, it will be used as-is.
6494        right: the SQL code string corresponding to the right-hand side.
6495            If an `Expression` instance is passed, it will be used as-is.
6496        distinct: set the DISTINCT flag if and only if this is true.
6497        dialect: the dialect used to parse the input expression.
6498        copy: whether to copy the expression.
6499        opts: other options to use to parse the input expressions.
6500
6501    Returns:
6502        The new Except instance.
6503    """
6504    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6505    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6506
6507    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:
6510def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6511    """
6512    Initializes a syntax tree from one or multiple SELECT expressions.
6513
6514    Example:
6515        >>> select("col1", "col2").from_("tbl").sql()
6516        'SELECT col1, col2 FROM tbl'
6517
6518    Args:
6519        *expressions: the SQL code string to parse as the expressions of a
6520            SELECT statement. If an Expression instance is passed, this is used as-is.
6521        dialect: the dialect used to parse the input expressions (in the case that an
6522            input expression is a SQL string).
6523        **opts: other options to use to parse the input expressions (again, in the case
6524            that an input expression is a SQL string).
6525
6526    Returns:
6527        Select: the syntax tree for the SELECT statement.
6528    """
6529    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:
6532def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6533    """
6534    Initializes a syntax tree from a FROM expression.
6535
6536    Example:
6537        >>> from_("tbl").select("col1", "col2").sql()
6538        'SELECT col1, col2 FROM tbl'
6539
6540    Args:
6541        *expression: the SQL code string to parse as the FROM expressions of a
6542            SELECT statement. If an Expression instance is passed, this is used as-is.
6543        dialect: the dialect used to parse the input expression (in the case that the
6544            input expression is a SQL string).
6545        **opts: other options to use to parse the input expressions (again, in the case
6546            that the input expression is a SQL string).
6547
6548    Returns:
6549        Select: the syntax tree for the SELECT statement.
6550    """
6551    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:
6554def update(
6555    table: str | Table,
6556    properties: dict,
6557    where: t.Optional[ExpOrStr] = None,
6558    from_: t.Optional[ExpOrStr] = None,
6559    dialect: DialectType = None,
6560    **opts,
6561) -> Update:
6562    """
6563    Creates an update statement.
6564
6565    Example:
6566        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6567        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6568
6569    Args:
6570        *properties: dictionary of properties to set which are
6571            auto converted to sql objects eg None -> NULL
6572        where: sql conditional parsed into a WHERE statement
6573        from_: sql statement parsed into a FROM statement
6574        dialect: the dialect used to parse the input expressions.
6575        **opts: other options to use to parse the input expressions.
6576
6577    Returns:
6578        Update: the syntax tree for the UPDATE statement.
6579    """
6580    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6581    update_expr.set(
6582        "expressions",
6583        [
6584            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6585            for k, v in properties.items()
6586        ],
6587    )
6588    if from_:
6589        update_expr.set(
6590            "from",
6591            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6592        )
6593    if isinstance(where, Condition):
6594        where = Where(this=where)
6595    if where:
6596        update_expr.set(
6597            "where",
6598            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6599        )
6600    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:
6603def delete(
6604    table: ExpOrStr,
6605    where: t.Optional[ExpOrStr] = None,
6606    returning: t.Optional[ExpOrStr] = None,
6607    dialect: DialectType = None,
6608    **opts,
6609) -> Delete:
6610    """
6611    Builds a delete statement.
6612
6613    Example:
6614        >>> delete("my_table", where="id > 1").sql()
6615        'DELETE FROM my_table WHERE id > 1'
6616
6617    Args:
6618        where: sql conditional parsed into a WHERE statement
6619        returning: sql conditional parsed into a RETURNING statement
6620        dialect: the dialect used to parse the input expressions.
6621        **opts: other options to use to parse the input expressions.
6622
6623    Returns:
6624        Delete: the syntax tree for the DELETE statement.
6625    """
6626    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6627    if where:
6628        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6629    if returning:
6630        delete_expr = t.cast(
6631            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6632        )
6633    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:
6636def insert(
6637    expression: ExpOrStr,
6638    into: ExpOrStr,
6639    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6640    overwrite: t.Optional[bool] = None,
6641    returning: t.Optional[ExpOrStr] = None,
6642    dialect: DialectType = None,
6643    copy: bool = True,
6644    **opts,
6645) -> Insert:
6646    """
6647    Builds an INSERT statement.
6648
6649    Example:
6650        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6651        'INSERT INTO tbl VALUES (1, 2, 3)'
6652
6653    Args:
6654        expression: the sql string or expression of the INSERT statement
6655        into: the tbl to insert data to.
6656        columns: optionally the table's column names.
6657        overwrite: whether to INSERT OVERWRITE or not.
6658        returning: sql conditional parsed into a RETURNING statement
6659        dialect: the dialect used to parse the input expressions.
6660        copy: whether to copy the expression.
6661        **opts: other options to use to parse the input expressions.
6662
6663    Returns:
6664        Insert: the syntax tree for the INSERT statement.
6665    """
6666    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6667    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6668
6669    if columns:
6670        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6671
6672    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6673
6674    if returning:
6675        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6676
6677    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:
6680def condition(
6681    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6682) -> Condition:
6683    """
6684    Initialize a logical condition expression.
6685
6686    Example:
6687        >>> condition("x=1").sql()
6688        'x = 1'
6689
6690        This is helpful for composing larger logical syntax trees:
6691        >>> where = condition("x=1")
6692        >>> where = where.and_("y=1")
6693        >>> Select().from_("tbl").select("*").where(where).sql()
6694        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6695
6696    Args:
6697        *expression: the SQL code string to parse.
6698            If an Expression instance is passed, this is used as-is.
6699        dialect: the dialect used to parse the input expression (in the case that the
6700            input expression is a SQL string).
6701        copy: Whether to copy `expression` (only applies to expressions).
6702        **opts: other options to use to parse the input expressions (again, in the case
6703            that the input expression is a SQL string).
6704
6705    Returns:
6706        The new Condition instance
6707    """
6708    return maybe_parse(
6709        expression,
6710        into=Condition,
6711        dialect=dialect,
6712        copy=copy,
6713        **opts,
6714    )

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:
6717def and_(
6718    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6719) -> Condition:
6720    """
6721    Combine multiple conditions with an AND logical operator.
6722
6723    Example:
6724        >>> and_("x=1", and_("y=1", "z=1")).sql()
6725        'x = 1 AND (y = 1 AND z = 1)'
6726
6727    Args:
6728        *expressions: the SQL code strings to parse.
6729            If an Expression instance is passed, this is used as-is.
6730        dialect: the dialect used to parse the input expression.
6731        copy: whether to copy `expressions` (only applies to Expressions).
6732        **opts: other options to use to parse the input expressions.
6733
6734    Returns:
6735        The new condition
6736    """
6737    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:
6740def or_(
6741    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6742) -> Condition:
6743    """
6744    Combine multiple conditions with an OR logical operator.
6745
6746    Example:
6747        >>> or_("x=1", or_("y=1", "z=1")).sql()
6748        'x = 1 OR (y = 1 OR z = 1)'
6749
6750    Args:
6751        *expressions: the SQL code strings to parse.
6752            If an Expression instance is passed, this is used as-is.
6753        dialect: the dialect used to parse the input expression.
6754        copy: whether to copy `expressions` (only applies to Expressions).
6755        **opts: other options to use to parse the input expressions.
6756
6757    Returns:
6758        The new condition
6759    """
6760    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:
6763def xor(
6764    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6765) -> Condition:
6766    """
6767    Combine multiple conditions with an XOR logical operator.
6768
6769    Example:
6770        >>> xor("x=1", xor("y=1", "z=1")).sql()
6771        'x = 1 XOR (y = 1 XOR z = 1)'
6772
6773    Args:
6774        *expressions: the SQL code strings to parse.
6775            If an Expression instance is passed, this is used as-is.
6776        dialect: the dialect used to parse the input expression.
6777        copy: whether to copy `expressions` (only applies to Expressions).
6778        **opts: other options to use to parse the input expressions.
6779
6780    Returns:
6781        The new condition
6782    """
6783    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:
6786def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6787    """
6788    Wrap a condition with a NOT operator.
6789
6790    Example:
6791        >>> not_("this_suit='black'").sql()
6792        "NOT this_suit = 'black'"
6793
6794    Args:
6795        expression: the SQL code string to parse.
6796            If an Expression instance is passed, this is used as-is.
6797        dialect: the dialect used to parse the input expression.
6798        copy: whether to copy the expression or not.
6799        **opts: other options to use to parse the input expressions.
6800
6801    Returns:
6802        The new condition.
6803    """
6804    this = condition(
6805        expression,
6806        dialect=dialect,
6807        copy=copy,
6808        **opts,
6809    )
6810    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:
6813def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6814    """
6815    Wrap an expression in parentheses.
6816
6817    Example:
6818        >>> paren("5 + 3").sql()
6819        '(5 + 3)'
6820
6821    Args:
6822        expression: the SQL code string to parse.
6823            If an Expression instance is passed, this is used as-is.
6824        copy: whether to copy the expression or not.
6825
6826    Returns:
6827        The wrapped expression.
6828    """
6829    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):
6845def to_identifier(name, quoted=None, copy=True):
6846    """Builds an identifier.
6847
6848    Args:
6849        name: The name to turn into an identifier.
6850        quoted: Whether to force quote the identifier.
6851        copy: Whether to copy name if it's an Identifier.
6852
6853    Returns:
6854        The identifier ast node.
6855    """
6856
6857    if name is None:
6858        return None
6859
6860    if isinstance(name, Identifier):
6861        identifier = maybe_copy(name, copy)
6862    elif isinstance(name, str):
6863        identifier = Identifier(
6864            this=name,
6865            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6866        )
6867    else:
6868        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6869    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:
6872def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6873    """
6874    Parses a given string into an identifier.
6875
6876    Args:
6877        name: The name to parse into an identifier.
6878        dialect: The dialect to parse against.
6879
6880    Returns:
6881        The identifier ast node.
6882    """
6883    try:
6884        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6885    except ParseError:
6886        expression = to_identifier(name)
6887
6888    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:
6894def to_interval(interval: str | Literal) -> Interval:
6895    """Builds an interval expression from a string like '1 day' or '5 months'."""
6896    if isinstance(interval, Literal):
6897        if not interval.is_string:
6898            raise ValueError("Invalid interval string.")
6899
6900        interval = interval.this
6901
6902    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6903
6904    if not interval_parts:
6905        raise ValueError("Invalid interval string.")
6906
6907    return Interval(
6908        this=Literal.string(interval_parts.group(1)),
6909        unit=Var(this=interval_parts.group(2).upper()),
6910    )

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:
6913def to_table(
6914    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6915) -> Table:
6916    """
6917    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6918    If a table is passed in then that table is returned.
6919
6920    Args:
6921        sql_path: a `[catalog].[schema].[table]` string.
6922        dialect: the source dialect according to which the table name will be parsed.
6923        copy: Whether to copy a table if it is passed in.
6924        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6925
6926    Returns:
6927        A table expression.
6928    """
6929    if isinstance(sql_path, Table):
6930        return maybe_copy(sql_path, copy=copy)
6931
6932    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6933
6934    for k, v in kwargs.items():
6935        table.set(k, v)
6936
6937    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:
6940def to_column(
6941    sql_path: str | Column,
6942    quoted: t.Optional[bool] = None,
6943    dialect: DialectType = None,
6944    copy: bool = True,
6945    **kwargs,
6946) -> Column:
6947    """
6948    Create a column from a `[table].[column]` sql path. Table is optional.
6949    If a column is passed in then that column is returned.
6950
6951    Args:
6952        sql_path: a `[table].[column]` string.
6953        quoted: Whether or not to force quote identifiers.
6954        dialect: the source dialect according to which the column name will be parsed.
6955        copy: Whether to copy a column if it is passed in.
6956        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6957
6958    Returns:
6959        A column expression.
6960    """
6961    if isinstance(sql_path, Column):
6962        return maybe_copy(sql_path, copy=copy)
6963
6964    try:
6965        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6966    except ParseError:
6967        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6968
6969    for k, v in kwargs.items():
6970        col.set(k, v)
6971
6972    if quoted:
6973        for i in col.find_all(Identifier):
6974            i.set("quoted", True)
6975
6976    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):
6979def alias_(
6980    expression: ExpOrStr,
6981    alias: t.Optional[str | Identifier],
6982    table: bool | t.Sequence[str | Identifier] = False,
6983    quoted: t.Optional[bool] = None,
6984    dialect: DialectType = None,
6985    copy: bool = True,
6986    **opts,
6987):
6988    """Create an Alias expression.
6989
6990    Example:
6991        >>> alias_('foo', 'bar').sql()
6992        'foo AS bar'
6993
6994        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6995        '(SELECT 1, 2) AS bar(a, b)'
6996
6997    Args:
6998        expression: the SQL code strings to parse.
6999            If an Expression instance is passed, this is used as-is.
7000        alias: the alias name to use. If the name has
7001            special characters it is quoted.
7002        table: Whether to create a table alias, can also be a list of columns.
7003        quoted: whether to quote the alias
7004        dialect: the dialect used to parse the input expression.
7005        copy: Whether to copy the expression.
7006        **opts: other options to use to parse the input expressions.
7007
7008    Returns:
7009        Alias: the aliased expression
7010    """
7011    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7012    alias = to_identifier(alias, quoted=quoted)
7013
7014    if table:
7015        table_alias = TableAlias(this=alias)
7016        exp.set("alias", table_alias)
7017
7018        if not isinstance(table, bool):
7019            for column in table:
7020                table_alias.append("columns", to_identifier(column, quoted=quoted))
7021
7022        return exp
7023
7024    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7025    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7026    # for the complete Window expression.
7027    #
7028    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7029
7030    if "alias" in exp.arg_types and not isinstance(exp, Window):
7031        exp.set("alias", alias)
7032        return exp
7033    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:
7036def subquery(
7037    expression: ExpOrStr,
7038    alias: t.Optional[Identifier | str] = None,
7039    dialect: DialectType = None,
7040    **opts,
7041) -> Select:
7042    """
7043    Build a subquery expression that's selected from.
7044
7045    Example:
7046        >>> subquery('select x from tbl', 'bar').select('x').sql()
7047        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7048
7049    Args:
7050        expression: the SQL code strings to parse.
7051            If an Expression instance is passed, this is used as-is.
7052        alias: the alias name to use.
7053        dialect: the dialect used to parse the input expression.
7054        **opts: other options to use to parse the input expressions.
7055
7056    Returns:
7057        A new Select instance with the subquery expression included.
7058    """
7059
7060    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7061    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):
7092def column(
7093    col,
7094    table=None,
7095    db=None,
7096    catalog=None,
7097    *,
7098    fields=None,
7099    quoted=None,
7100    copy=True,
7101):
7102    """
7103    Build a Column.
7104
7105    Args:
7106        col: Column name.
7107        table: Table name.
7108        db: Database name.
7109        catalog: Catalog name.
7110        fields: Additional fields using dots.
7111        quoted: Whether to force quotes on the column's identifiers.
7112        copy: Whether to copy identifiers if passed in.
7113
7114    Returns:
7115        The new Column instance.
7116    """
7117    this = Column(
7118        this=to_identifier(col, quoted=quoted, copy=copy),
7119        table=to_identifier(table, quoted=quoted, copy=copy),
7120        db=to_identifier(db, quoted=quoted, copy=copy),
7121        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7122    )
7123
7124    if fields:
7125        this = Dot.build(
7126            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7127        )
7128    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:
7131def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7132    """Cast an expression to a data type.
7133
7134    Example:
7135        >>> cast('x + 1', 'int').sql()
7136        'CAST(x + 1 AS INT)'
7137
7138    Args:
7139        expression: The expression to cast.
7140        to: The datatype to cast to.
7141        copy: Whether to copy the supplied expressions.
7142
7143    Returns:
7144        The new Cast instance.
7145    """
7146    expr = maybe_parse(expression, copy=copy, **opts)
7147    data_type = DataType.build(to, copy=copy, **opts)
7148
7149    if expr.is_type(data_type):
7150        return expr
7151
7152    expr = Cast(this=expr, to=data_type)
7153    expr.type = data_type
7154
7155    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:
7158def table_(
7159    table: Identifier | str,
7160    db: t.Optional[Identifier | str] = None,
7161    catalog: t.Optional[Identifier | str] = None,
7162    quoted: t.Optional[bool] = None,
7163    alias: t.Optional[Identifier | str] = None,
7164) -> Table:
7165    """Build a Table.
7166
7167    Args:
7168        table: Table name.
7169        db: Database name.
7170        catalog: Catalog name.
7171        quote: Whether to force quotes on the table's identifiers.
7172        alias: Table's alias.
7173
7174    Returns:
7175        The new Table instance.
7176    """
7177    return Table(
7178        this=to_identifier(table, quoted=quoted) if table else None,
7179        db=to_identifier(db, quoted=quoted) if db else None,
7180        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7181        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7182    )

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:
7185def values(
7186    values: t.Iterable[t.Tuple[t.Any, ...]],
7187    alias: t.Optional[str] = None,
7188    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7189) -> Values:
7190    """Build VALUES statement.
7191
7192    Example:
7193        >>> values([(1, '2')]).sql()
7194        "VALUES (1, '2')"
7195
7196    Args:
7197        values: values statements that will be converted to SQL
7198        alias: optional alias
7199        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7200         If either are provided then an alias is also required.
7201
7202    Returns:
7203        Values: the Values expression object
7204    """
7205    if columns and not alias:
7206        raise ValueError("Alias is required when providing columns")
7207
7208    return Values(
7209        expressions=[convert(tup) for tup in values],
7210        alias=(
7211            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7212            if columns
7213            else (TableAlias(this=to_identifier(alias)) if alias else None)
7214        ),
7215    )

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:
7218def var(name: t.Optional[ExpOrStr]) -> Var:
7219    """Build a SQL variable.
7220
7221    Example:
7222        >>> repr(var('x'))
7223        'Var(this=x)'
7224
7225        >>> repr(var(column('x', table='y')))
7226        'Var(this=x)'
7227
7228    Args:
7229        name: The name of the var or an expression who's name will become the var.
7230
7231    Returns:
7232        The new variable node.
7233    """
7234    if not name:
7235        raise ValueError("Cannot convert empty name into var.")
7236
7237    if isinstance(name, Expression):
7238        name = name.name
7239    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:
7242def rename_table(
7243    old_name: str | Table,
7244    new_name: str | Table,
7245    dialect: DialectType = None,
7246) -> AlterTable:
7247    """Build ALTER TABLE... RENAME... expression
7248
7249    Args:
7250        old_name: The old name of the table
7251        new_name: The new name of the table
7252        dialect: The dialect to parse the table.
7253
7254    Returns:
7255        Alter table expression
7256    """
7257    old_table = to_table(old_name, dialect=dialect)
7258    new_table = to_table(new_name, dialect=dialect)
7259    return AlterTable(
7260        this=old_table,
7261        actions=[
7262            RenameTable(this=new_table),
7263        ],
7264    )

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:
7267def rename_column(
7268    table_name: str | Table,
7269    old_column_name: str | Column,
7270    new_column_name: str | Column,
7271    exists: t.Optional[bool] = None,
7272    dialect: DialectType = None,
7273) -> AlterTable:
7274    """Build ALTER TABLE... RENAME COLUMN... expression
7275
7276    Args:
7277        table_name: Name of the table
7278        old_column: The old name of the column
7279        new_column: The new name of the column
7280        exists: Whether to add the `IF EXISTS` clause
7281        dialect: The dialect to parse the table/column.
7282
7283    Returns:
7284        Alter table expression
7285    """
7286    table = to_table(table_name, dialect=dialect)
7287    old_column = to_column(old_column_name, dialect=dialect)
7288    new_column = to_column(new_column_name, dialect=dialect)
7289    return AlterTable(
7290        this=table,
7291        actions=[
7292            RenameColumn(this=old_column, to=new_column, exists=exists),
7293        ],
7294    )

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

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:
7428def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7429    """Get the full name of a table as a string.
7430
7431    Args:
7432        table: Table expression node or string.
7433        dialect: The dialect to generate the table name for.
7434        identify: Determines when an identifier should be quoted. Possible values are:
7435            False (default): Never quote, except in cases where it's mandatory by the dialect.
7436            True: Always quote.
7437
7438    Examples:
7439        >>> from sqlglot import exp, parse_one
7440        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7441        'a.b.c'
7442
7443    Returns:
7444        The table name.
7445    """
7446
7447    table = maybe_parse(table, into=Table, dialect=dialect)
7448
7449    if not table:
7450        raise ValueError(f"Cannot parse {table}")
7451
7452    return ".".join(
7453        (
7454            part.sql(dialect=dialect, identify=True, copy=False)
7455            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7456            else part.name
7457        )
7458        for part in table.parts
7459    )

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:
7462def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7463    """Returns a case normalized table name without quotes.
7464
7465    Args:
7466        table: the table to normalize
7467        dialect: the dialect to use for normalization rules
7468        copy: whether to copy the expression.
7469
7470    Examples:
7471        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7472        'A-B.c'
7473    """
7474    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7475
7476    return ".".join(
7477        p.name
7478        for p in normalize_identifiers(
7479            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7480        ).parts
7481    )

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

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:
7711def tuple_(
7712    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7713) -> Tuple:
7714    """
7715    Returns an tuple.
7716
7717    Examples:
7718        >>> tuple_(1, 'x').sql()
7719        '(1, x)'
7720
7721    Args:
7722        expressions: the expressions to add to the tuple.
7723        copy: whether to copy the argument expressions.
7724        dialect: the source dialect.
7725        kwargs: the kwargs used to instantiate the function of interest.
7726
7727    Returns:
7728        A tuple expression.
7729    """
7730    return Tuple(
7731        expressions=[
7732            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7733            for expression in expressions
7734        ]
7735    )

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:
7738def true() -> Boolean:
7739    """
7740    Returns a true Boolean expression.
7741    """
7742    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7745def false() -> Boolean:
7746    """
7747    Returns a false Boolean expression.
7748    """
7749    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7752def null() -> Null:
7753    """
7754    Returns a Null expression.
7755    """
7756    return Null()

Returns a Null expression.

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