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    }
3047
3048    @property
3049    def name(self) -> str:
3050        if isinstance(self.this, Func):
3051            return ""
3052        return self.this.name
3053
3054    @property
3055    def db(self) -> str:
3056        return self.text("db")
3057
3058    @property
3059    def catalog(self) -> str:
3060        return self.text("catalog")
3061
3062    @property
3063    def selects(self) -> t.List[Expression]:
3064        return []
3065
3066    @property
3067    def named_selects(self) -> t.List[str]:
3068        return []
3069
3070    @property
3071    def parts(self) -> t.List[Expression]:
3072        """Return the parts of a table in order catalog, db, table."""
3073        parts: t.List[Expression] = []
3074
3075        for arg in ("catalog", "db", "this"):
3076            part = self.args.get(arg)
3077
3078            if isinstance(part, Dot):
3079                parts.extend(part.flatten())
3080            elif isinstance(part, Expression):
3081                parts.append(part)
3082
3083        return parts
3084
3085    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3086        parts = self.parts
3087        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3088        alias = self.args.get("alias")
3089        if alias:
3090            col = alias_(col, alias.this, copy=copy)
3091        return col
3092
3093
3094class SetOperation(Query):
3095    arg_types = {
3096        "with": False,
3097        "this": True,
3098        "expression": True,
3099        "distinct": False,
3100        "by_name": False,
3101        **QUERY_MODIFIERS,
3102    }
3103
3104    def select(
3105        self: S,
3106        *expressions: t.Optional[ExpOrStr],
3107        append: bool = True,
3108        dialect: DialectType = None,
3109        copy: bool = True,
3110        **opts,
3111    ) -> S:
3112        this = maybe_copy(self, copy)
3113        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3114        this.expression.unnest().select(
3115            *expressions, append=append, dialect=dialect, copy=False, **opts
3116        )
3117        return this
3118
3119    @property
3120    def named_selects(self) -> t.List[str]:
3121        return self.this.unnest().named_selects
3122
3123    @property
3124    def is_star(self) -> bool:
3125        return self.this.is_star or self.expression.is_star
3126
3127    @property
3128    def selects(self) -> t.List[Expression]:
3129        return self.this.unnest().selects
3130
3131    @property
3132    def left(self) -> Expression:
3133        return self.this
3134
3135    @property
3136    def right(self) -> Expression:
3137        return self.expression
3138
3139
3140class Union(SetOperation):
3141    pass
3142
3143
3144class Except(SetOperation):
3145    pass
3146
3147
3148class Intersect(SetOperation):
3149    pass
3150
3151
3152class Update(Expression):
3153    arg_types = {
3154        "with": False,
3155        "this": False,
3156        "expressions": True,
3157        "from": False,
3158        "where": False,
3159        "returning": False,
3160        "order": False,
3161        "limit": False,
3162    }
3163
3164
3165class Values(UDTF):
3166    arg_types = {"expressions": True, "alias": False}
3167
3168
3169class Var(Expression):
3170    pass
3171
3172
3173class Version(Expression):
3174    """
3175    Time travel, iceberg, bigquery etc
3176    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3177    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3178    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3179    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3180    this is either TIMESTAMP or VERSION
3181    kind is ("AS OF", "BETWEEN")
3182    """
3183
3184    arg_types = {"this": True, "kind": True, "expression": False}
3185
3186
3187class Schema(Expression):
3188    arg_types = {"this": False, "expressions": False}
3189
3190
3191# https://dev.mysql.com/doc/refman/8.0/en/select.html
3192# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
3193class Lock(Expression):
3194    arg_types = {"update": True, "expressions": False, "wait": False}
3195
3196
3197class Select(Query):
3198    arg_types = {
3199        "with": False,
3200        "kind": False,
3201        "expressions": False,
3202        "hint": False,
3203        "distinct": False,
3204        "into": False,
3205        "from": False,
3206        **QUERY_MODIFIERS,
3207    }
3208
3209    def from_(
3210        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3211    ) -> Select:
3212        """
3213        Set the FROM expression.
3214
3215        Example:
3216            >>> Select().from_("tbl").select("x").sql()
3217            'SELECT x FROM tbl'
3218
3219        Args:
3220            expression : the SQL code strings to parse.
3221                If a `From` instance is passed, this is used as-is.
3222                If another `Expression` instance is passed, it will be wrapped in a `From`.
3223            dialect: the dialect used to parse the input expression.
3224            copy: if `False`, modify this expression instance in-place.
3225            opts: other options to use to parse the input expressions.
3226
3227        Returns:
3228            The modified Select expression.
3229        """
3230        return _apply_builder(
3231            expression=expression,
3232            instance=self,
3233            arg="from",
3234            into=From,
3235            prefix="FROM",
3236            dialect=dialect,
3237            copy=copy,
3238            **opts,
3239        )
3240
3241    def group_by(
3242        self,
3243        *expressions: t.Optional[ExpOrStr],
3244        append: bool = True,
3245        dialect: DialectType = None,
3246        copy: bool = True,
3247        **opts,
3248    ) -> Select:
3249        """
3250        Set the GROUP BY expression.
3251
3252        Example:
3253            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3254            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3255
3256        Args:
3257            *expressions: the SQL code strings to parse.
3258                If a `Group` instance is passed, this is used as-is.
3259                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3260                If nothing is passed in then a group by is not applied to the expression
3261            append: if `True`, add to any existing expressions.
3262                Otherwise, this flattens all the `Group` expression into a single expression.
3263            dialect: the dialect used to parse the input expression.
3264            copy: if `False`, modify this expression instance in-place.
3265            opts: other options to use to parse the input expressions.
3266
3267        Returns:
3268            The modified Select expression.
3269        """
3270        if not expressions:
3271            return self if not copy else self.copy()
3272
3273        return _apply_child_list_builder(
3274            *expressions,
3275            instance=self,
3276            arg="group",
3277            append=append,
3278            copy=copy,
3279            prefix="GROUP BY",
3280            into=Group,
3281            dialect=dialect,
3282            **opts,
3283        )
3284
3285    def sort_by(
3286        self,
3287        *expressions: t.Optional[ExpOrStr],
3288        append: bool = True,
3289        dialect: DialectType = None,
3290        copy: bool = True,
3291        **opts,
3292    ) -> Select:
3293        """
3294        Set the SORT BY expression.
3295
3296        Example:
3297            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3298            'SELECT x FROM tbl SORT BY x DESC'
3299
3300        Args:
3301            *expressions: the SQL code strings to parse.
3302                If a `Group` instance is passed, this is used as-is.
3303                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3304            append: if `True`, add to any existing expressions.
3305                Otherwise, this flattens all the `Order` expression into a single expression.
3306            dialect: the dialect used to parse the input expression.
3307            copy: if `False`, modify this expression instance in-place.
3308            opts: other options to use to parse the input expressions.
3309
3310        Returns:
3311            The modified Select expression.
3312        """
3313        return _apply_child_list_builder(
3314            *expressions,
3315            instance=self,
3316            arg="sort",
3317            append=append,
3318            copy=copy,
3319            prefix="SORT BY",
3320            into=Sort,
3321            dialect=dialect,
3322            **opts,
3323        )
3324
3325    def cluster_by(
3326        self,
3327        *expressions: t.Optional[ExpOrStr],
3328        append: bool = True,
3329        dialect: DialectType = None,
3330        copy: bool = True,
3331        **opts,
3332    ) -> Select:
3333        """
3334        Set the CLUSTER BY expression.
3335
3336        Example:
3337            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3338            'SELECT x FROM tbl CLUSTER BY x DESC'
3339
3340        Args:
3341            *expressions: the SQL code strings to parse.
3342                If a `Group` instance is passed, this is used as-is.
3343                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3344            append: if `True`, add to any existing expressions.
3345                Otherwise, this flattens all the `Order` expression into a single expression.
3346            dialect: the dialect used to parse the input expression.
3347            copy: if `False`, modify this expression instance in-place.
3348            opts: other options to use to parse the input expressions.
3349
3350        Returns:
3351            The modified Select expression.
3352        """
3353        return _apply_child_list_builder(
3354            *expressions,
3355            instance=self,
3356            arg="cluster",
3357            append=append,
3358            copy=copy,
3359            prefix="CLUSTER BY",
3360            into=Cluster,
3361            dialect=dialect,
3362            **opts,
3363        )
3364
3365    def select(
3366        self,
3367        *expressions: t.Optional[ExpOrStr],
3368        append: bool = True,
3369        dialect: DialectType = None,
3370        copy: bool = True,
3371        **opts,
3372    ) -> Select:
3373        return _apply_list_builder(
3374            *expressions,
3375            instance=self,
3376            arg="expressions",
3377            append=append,
3378            dialect=dialect,
3379            into=Expression,
3380            copy=copy,
3381            **opts,
3382        )
3383
3384    def lateral(
3385        self,
3386        *expressions: t.Optional[ExpOrStr],
3387        append: bool = True,
3388        dialect: DialectType = None,
3389        copy: bool = True,
3390        **opts,
3391    ) -> Select:
3392        """
3393        Append to or set the LATERAL expressions.
3394
3395        Example:
3396            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3397            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3398
3399        Args:
3400            *expressions: the SQL code strings to parse.
3401                If an `Expression` instance is passed, it will be used as-is.
3402            append: if `True`, add to any existing expressions.
3403                Otherwise, this resets the expressions.
3404            dialect: the dialect used to parse the input expressions.
3405            copy: if `False`, modify this expression instance in-place.
3406            opts: other options to use to parse the input expressions.
3407
3408        Returns:
3409            The modified Select expression.
3410        """
3411        return _apply_list_builder(
3412            *expressions,
3413            instance=self,
3414            arg="laterals",
3415            append=append,
3416            into=Lateral,
3417            prefix="LATERAL VIEW",
3418            dialect=dialect,
3419            copy=copy,
3420            **opts,
3421        )
3422
3423    def join(
3424        self,
3425        expression: ExpOrStr,
3426        on: t.Optional[ExpOrStr] = None,
3427        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3428        append: bool = True,
3429        join_type: t.Optional[str] = None,
3430        join_alias: t.Optional[Identifier | str] = None,
3431        dialect: DialectType = None,
3432        copy: bool = True,
3433        **opts,
3434    ) -> Select:
3435        """
3436        Append to or set the JOIN expressions.
3437
3438        Example:
3439            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3440            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3441
3442            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3443            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3444
3445            Use `join_type` to change the type of join:
3446
3447            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3448            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3449
3450        Args:
3451            expression: the SQL code string to parse.
3452                If an `Expression` instance is passed, it will be used as-is.
3453            on: optionally specify the join "on" criteria as a SQL string.
3454                If an `Expression` instance is passed, it will be used as-is.
3455            using: optionally specify the join "using" criteria as a SQL string.
3456                If an `Expression` instance is passed, it will be used as-is.
3457            append: if `True`, add to any existing expressions.
3458                Otherwise, this resets the expressions.
3459            join_type: if set, alter the parsed join type.
3460            join_alias: an optional alias for the joined source.
3461            dialect: the dialect used to parse the input expressions.
3462            copy: if `False`, modify this expression instance in-place.
3463            opts: other options to use to parse the input expressions.
3464
3465        Returns:
3466            Select: the modified expression.
3467        """
3468        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3469
3470        try:
3471            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3472        except ParseError:
3473            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3474
3475        join = expression if isinstance(expression, Join) else Join(this=expression)
3476
3477        if isinstance(join.this, Select):
3478            join.this.replace(join.this.subquery())
3479
3480        if join_type:
3481            method: t.Optional[Token]
3482            side: t.Optional[Token]
3483            kind: t.Optional[Token]
3484
3485            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3486
3487            if method:
3488                join.set("method", method.text)
3489            if side:
3490                join.set("side", side.text)
3491            if kind:
3492                join.set("kind", kind.text)
3493
3494        if on:
3495            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3496            join.set("on", on)
3497
3498        if using:
3499            join = _apply_list_builder(
3500                *ensure_list(using),
3501                instance=join,
3502                arg="using",
3503                append=append,
3504                copy=copy,
3505                into=Identifier,
3506                **opts,
3507            )
3508
3509        if join_alias:
3510            join.set("this", alias_(join.this, join_alias, table=True))
3511
3512        return _apply_list_builder(
3513            join,
3514            instance=self,
3515            arg="joins",
3516            append=append,
3517            copy=copy,
3518            **opts,
3519        )
3520
3521    def where(
3522        self,
3523        *expressions: t.Optional[ExpOrStr],
3524        append: bool = True,
3525        dialect: DialectType = None,
3526        copy: bool = True,
3527        **opts,
3528    ) -> Select:
3529        """
3530        Append to or set the WHERE expressions.
3531
3532        Example:
3533            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3534            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3535
3536        Args:
3537            *expressions: the SQL code strings to parse.
3538                If an `Expression` instance is passed, it will be used as-is.
3539                Multiple expressions are combined with an AND operator.
3540            append: if `True`, AND the new expressions to any existing expression.
3541                Otherwise, this resets the expression.
3542            dialect: the dialect used to parse the input expressions.
3543            copy: if `False`, modify this expression instance in-place.
3544            opts: other options to use to parse the input expressions.
3545
3546        Returns:
3547            Select: the modified expression.
3548        """
3549        return _apply_conjunction_builder(
3550            *expressions,
3551            instance=self,
3552            arg="where",
3553            append=append,
3554            into=Where,
3555            dialect=dialect,
3556            copy=copy,
3557            **opts,
3558        )
3559
3560    def having(
3561        self,
3562        *expressions: t.Optional[ExpOrStr],
3563        append: bool = True,
3564        dialect: DialectType = None,
3565        copy: bool = True,
3566        **opts,
3567    ) -> Select:
3568        """
3569        Append to or set the HAVING expressions.
3570
3571        Example:
3572            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3573            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3574
3575        Args:
3576            *expressions: the SQL code strings to parse.
3577                If an `Expression` instance is passed, it will be used as-is.
3578                Multiple expressions are combined with an AND operator.
3579            append: if `True`, AND the new expressions to any existing expression.
3580                Otherwise, this resets the expression.
3581            dialect: the dialect used to parse the input expressions.
3582            copy: if `False`, modify this expression instance in-place.
3583            opts: other options to use to parse the input expressions.
3584
3585        Returns:
3586            The modified Select expression.
3587        """
3588        return _apply_conjunction_builder(
3589            *expressions,
3590            instance=self,
3591            arg="having",
3592            append=append,
3593            into=Having,
3594            dialect=dialect,
3595            copy=copy,
3596            **opts,
3597        )
3598
3599    def window(
3600        self,
3601        *expressions: t.Optional[ExpOrStr],
3602        append: bool = True,
3603        dialect: DialectType = None,
3604        copy: bool = True,
3605        **opts,
3606    ) -> Select:
3607        return _apply_list_builder(
3608            *expressions,
3609            instance=self,
3610            arg="windows",
3611            append=append,
3612            into=Window,
3613            dialect=dialect,
3614            copy=copy,
3615            **opts,
3616        )
3617
3618    def qualify(
3619        self,
3620        *expressions: t.Optional[ExpOrStr],
3621        append: bool = True,
3622        dialect: DialectType = None,
3623        copy: bool = True,
3624        **opts,
3625    ) -> Select:
3626        return _apply_conjunction_builder(
3627            *expressions,
3628            instance=self,
3629            arg="qualify",
3630            append=append,
3631            into=Qualify,
3632            dialect=dialect,
3633            copy=copy,
3634            **opts,
3635        )
3636
3637    def distinct(
3638        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3639    ) -> Select:
3640        """
3641        Set the OFFSET expression.
3642
3643        Example:
3644            >>> Select().from_("tbl").select("x").distinct().sql()
3645            'SELECT DISTINCT x FROM tbl'
3646
3647        Args:
3648            ons: the expressions to distinct on
3649            distinct: whether the Select should be distinct
3650            copy: if `False`, modify this expression instance in-place.
3651
3652        Returns:
3653            Select: the modified expression.
3654        """
3655        instance = maybe_copy(self, copy)
3656        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3657        instance.set("distinct", Distinct(on=on) if distinct else None)
3658        return instance
3659
3660    def ctas(
3661        self,
3662        table: ExpOrStr,
3663        properties: t.Optional[t.Dict] = None,
3664        dialect: DialectType = None,
3665        copy: bool = True,
3666        **opts,
3667    ) -> Create:
3668        """
3669        Convert this expression to a CREATE TABLE AS statement.
3670
3671        Example:
3672            >>> Select().select("*").from_("tbl").ctas("x").sql()
3673            'CREATE TABLE x AS SELECT * FROM tbl'
3674
3675        Args:
3676            table: the SQL code string to parse as the table name.
3677                If another `Expression` instance is passed, it will be used as-is.
3678            properties: an optional mapping of table properties
3679            dialect: the dialect used to parse the input table.
3680            copy: if `False`, modify this expression instance in-place.
3681            opts: other options to use to parse the input table.
3682
3683        Returns:
3684            The new Create expression.
3685        """
3686        instance = maybe_copy(self, copy)
3687        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3688
3689        properties_expression = None
3690        if properties:
3691            properties_expression = Properties.from_dict(properties)
3692
3693        return Create(
3694            this=table_expression,
3695            kind="TABLE",
3696            expression=instance,
3697            properties=properties_expression,
3698        )
3699
3700    def lock(self, update: bool = True, copy: bool = True) -> Select:
3701        """
3702        Set the locking read mode for this expression.
3703
3704        Examples:
3705            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3706            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3707
3708            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3709            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3710
3711        Args:
3712            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3713            copy: if `False`, modify this expression instance in-place.
3714
3715        Returns:
3716            The modified expression.
3717        """
3718        inst = maybe_copy(self, copy)
3719        inst.set("locks", [Lock(update=update)])
3720
3721        return inst
3722
3723    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3724        """
3725        Set hints for this expression.
3726
3727        Examples:
3728            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3729            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3730
3731        Args:
3732            hints: The SQL code strings to parse as the hints.
3733                If an `Expression` instance is passed, it will be used as-is.
3734            dialect: The dialect used to parse the hints.
3735            copy: If `False`, modify this expression instance in-place.
3736
3737        Returns:
3738            The modified expression.
3739        """
3740        inst = maybe_copy(self, copy)
3741        inst.set(
3742            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3743        )
3744
3745        return inst
3746
3747    @property
3748    def named_selects(self) -> t.List[str]:
3749        return [e.output_name for e in self.expressions if e.alias_or_name]
3750
3751    @property
3752    def is_star(self) -> bool:
3753        return any(expression.is_star for expression in self.expressions)
3754
3755    @property
3756    def selects(self) -> t.List[Expression]:
3757        return self.expressions
3758
3759
3760UNWRAPPED_QUERIES = (Select, SetOperation)
3761
3762
3763class Subquery(DerivedTable, Query):
3764    arg_types = {
3765        "this": True,
3766        "alias": False,
3767        "with": False,
3768        **QUERY_MODIFIERS,
3769    }
3770
3771    def unnest(self):
3772        """Returns the first non subquery."""
3773        expression = self
3774        while isinstance(expression, Subquery):
3775            expression = expression.this
3776        return expression
3777
3778    def unwrap(self) -> Subquery:
3779        expression = self
3780        while expression.same_parent and expression.is_wrapper:
3781            expression = t.cast(Subquery, expression.parent)
3782        return expression
3783
3784    def select(
3785        self,
3786        *expressions: t.Optional[ExpOrStr],
3787        append: bool = True,
3788        dialect: DialectType = None,
3789        copy: bool = True,
3790        **opts,
3791    ) -> Subquery:
3792        this = maybe_copy(self, copy)
3793        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3794        return this
3795
3796    @property
3797    def is_wrapper(self) -> bool:
3798        """
3799        Whether this Subquery acts as a simple wrapper around another expression.
3800
3801        SELECT * FROM (((SELECT * FROM t)))
3802                      ^
3803                      This corresponds to a "wrapper" Subquery node
3804        """
3805        return all(v is None for k, v in self.args.items() if k != "this")
3806
3807    @property
3808    def is_star(self) -> bool:
3809        return self.this.is_star
3810
3811    @property
3812    def output_name(self) -> str:
3813        return self.alias
3814
3815
3816class TableSample(Expression):
3817    arg_types = {
3818        "this": False,
3819        "expressions": False,
3820        "method": False,
3821        "bucket_numerator": False,
3822        "bucket_denominator": False,
3823        "bucket_field": False,
3824        "percent": False,
3825        "rows": False,
3826        "size": False,
3827        "seed": False,
3828    }
3829
3830
3831class Tag(Expression):
3832    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3833
3834    arg_types = {
3835        "this": False,
3836        "prefix": False,
3837        "postfix": False,
3838    }
3839
3840
3841# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
3842# https://duckdb.org/docs/sql/statements/pivot
3843class Pivot(Expression):
3844    arg_types = {
3845        "this": False,
3846        "alias": False,
3847        "expressions": False,
3848        "field": False,
3849        "unpivot": False,
3850        "using": False,
3851        "group": False,
3852        "columns": False,
3853        "include_nulls": False,
3854    }
3855
3856    @property
3857    def unpivot(self) -> bool:
3858        return bool(self.args.get("unpivot"))
3859
3860
3861class Window(Condition):
3862    arg_types = {
3863        "this": True,
3864        "partition_by": False,
3865        "order": False,
3866        "spec": False,
3867        "alias": False,
3868        "over": False,
3869        "first": False,
3870    }
3871
3872
3873class WindowSpec(Expression):
3874    arg_types = {
3875        "kind": False,
3876        "start": False,
3877        "start_side": False,
3878        "end": False,
3879        "end_side": False,
3880    }
3881
3882
3883class PreWhere(Expression):
3884    pass
3885
3886
3887class Where(Expression):
3888    pass
3889
3890
3891class Star(Expression):
3892    arg_types = {"except": False, "replace": False, "rename": False}
3893
3894    @property
3895    def name(self) -> str:
3896        return "*"
3897
3898    @property
3899    def output_name(self) -> str:
3900        return self.name
3901
3902
3903class Parameter(Condition):
3904    arg_types = {"this": True, "expression": False}
3905
3906
3907class SessionParameter(Condition):
3908    arg_types = {"this": True, "kind": False}
3909
3910
3911class Placeholder(Condition):
3912    arg_types = {"this": False, "kind": False}
3913
3914    @property
3915    def name(self) -> str:
3916        return self.this or "?"
3917
3918
3919class Null(Condition):
3920    arg_types: t.Dict[str, t.Any] = {}
3921
3922    @property
3923    def name(self) -> str:
3924        return "NULL"
3925
3926    def to_py(self) -> Lit[None]:
3927        return None
3928
3929
3930class Boolean(Condition):
3931    def to_py(self) -> bool:
3932        return self.this
3933
3934
3935class DataTypeParam(Expression):
3936    arg_types = {"this": True, "expression": False}
3937
3938    @property
3939    def name(self) -> str:
3940        return self.this.name
3941
3942
3943class DataType(Expression):
3944    arg_types = {
3945        "this": True,
3946        "expressions": False,
3947        "nested": False,
3948        "values": False,
3949        "prefix": False,
3950        "kind": False,
3951    }
3952
3953    class Type(AutoName):
3954        ARRAY = auto()
3955        AGGREGATEFUNCTION = auto()
3956        SIMPLEAGGREGATEFUNCTION = auto()
3957        BIGDECIMAL = auto()
3958        BIGINT = auto()
3959        BIGSERIAL = auto()
3960        BINARY = auto()
3961        BIT = auto()
3962        BOOLEAN = auto()
3963        BPCHAR = auto()
3964        CHAR = auto()
3965        DATE = auto()
3966        DATE32 = auto()
3967        DATEMULTIRANGE = auto()
3968        DATERANGE = auto()
3969        DATETIME = auto()
3970        DATETIME64 = auto()
3971        DECIMAL = auto()
3972        DOUBLE = auto()
3973        ENUM = auto()
3974        ENUM8 = auto()
3975        ENUM16 = auto()
3976        FIXEDSTRING = auto()
3977        FLOAT = auto()
3978        GEOGRAPHY = auto()
3979        GEOMETRY = auto()
3980        HLLSKETCH = auto()
3981        HSTORE = auto()
3982        IMAGE = auto()
3983        INET = auto()
3984        INT = auto()
3985        INT128 = auto()
3986        INT256 = auto()
3987        INT4MULTIRANGE = auto()
3988        INT4RANGE = auto()
3989        INT8MULTIRANGE = auto()
3990        INT8RANGE = auto()
3991        INTERVAL = auto()
3992        IPADDRESS = auto()
3993        IPPREFIX = auto()
3994        IPV4 = auto()
3995        IPV6 = auto()
3996        JSON = auto()
3997        JSONB = auto()
3998        LIST = auto()
3999        LONGBLOB = auto()
4000        LONGTEXT = auto()
4001        LOWCARDINALITY = auto()
4002        MAP = auto()
4003        MEDIUMBLOB = auto()
4004        MEDIUMINT = auto()
4005        MEDIUMTEXT = auto()
4006        MONEY = auto()
4007        NAME = auto()
4008        NCHAR = auto()
4009        NESTED = auto()
4010        NULL = auto()
4011        NULLABLE = auto()
4012        NUMMULTIRANGE = auto()
4013        NUMRANGE = auto()
4014        NVARCHAR = auto()
4015        OBJECT = auto()
4016        ROWVERSION = auto()
4017        SERIAL = auto()
4018        SET = auto()
4019        SMALLINT = auto()
4020        SMALLMONEY = auto()
4021        SMALLSERIAL = auto()
4022        STRUCT = auto()
4023        SUPER = auto()
4024        TEXT = auto()
4025        TINYBLOB = auto()
4026        TINYTEXT = auto()
4027        TIME = auto()
4028        TIMETZ = auto()
4029        TIMESTAMP = auto()
4030        TIMESTAMPNTZ = auto()
4031        TIMESTAMPLTZ = auto()
4032        TIMESTAMPTZ = auto()
4033        TIMESTAMP_S = auto()
4034        TIMESTAMP_MS = auto()
4035        TIMESTAMP_NS = auto()
4036        TINYINT = auto()
4037        TSMULTIRANGE = auto()
4038        TSRANGE = auto()
4039        TSTZMULTIRANGE = auto()
4040        TSTZRANGE = auto()
4041        UBIGINT = auto()
4042        UINT = auto()
4043        UINT128 = auto()
4044        UINT256 = auto()
4045        UMEDIUMINT = auto()
4046        UDECIMAL = auto()
4047        UNIQUEIDENTIFIER = auto()
4048        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4049        USERDEFINED = "USER-DEFINED"
4050        USMALLINT = auto()
4051        UTINYINT = auto()
4052        UUID = auto()
4053        VARBINARY = auto()
4054        VARCHAR = auto()
4055        VARIANT = auto()
4056        VECTOR = auto()
4057        XML = auto()
4058        YEAR = auto()
4059        TDIGEST = auto()
4060
4061    STRUCT_TYPES = {
4062        Type.NESTED,
4063        Type.OBJECT,
4064        Type.STRUCT,
4065    }
4066
4067    NESTED_TYPES = {
4068        *STRUCT_TYPES,
4069        Type.ARRAY,
4070        Type.MAP,
4071    }
4072
4073    TEXT_TYPES = {
4074        Type.CHAR,
4075        Type.NCHAR,
4076        Type.NVARCHAR,
4077        Type.TEXT,
4078        Type.VARCHAR,
4079        Type.NAME,
4080    }
4081
4082    SIGNED_INTEGER_TYPES = {
4083        Type.BIGINT,
4084        Type.INT,
4085        Type.INT128,
4086        Type.INT256,
4087        Type.MEDIUMINT,
4088        Type.SMALLINT,
4089        Type.TINYINT,
4090    }
4091
4092    UNSIGNED_INTEGER_TYPES = {
4093        Type.UBIGINT,
4094        Type.UINT,
4095        Type.UINT128,
4096        Type.UINT256,
4097        Type.UMEDIUMINT,
4098        Type.USMALLINT,
4099        Type.UTINYINT,
4100    }
4101
4102    INTEGER_TYPES = {
4103        *SIGNED_INTEGER_TYPES,
4104        *UNSIGNED_INTEGER_TYPES,
4105        Type.BIT,
4106    }
4107
4108    FLOAT_TYPES = {
4109        Type.DOUBLE,
4110        Type.FLOAT,
4111    }
4112
4113    REAL_TYPES = {
4114        *FLOAT_TYPES,
4115        Type.BIGDECIMAL,
4116        Type.DECIMAL,
4117        Type.MONEY,
4118        Type.SMALLMONEY,
4119        Type.UDECIMAL,
4120    }
4121
4122    NUMERIC_TYPES = {
4123        *INTEGER_TYPES,
4124        *REAL_TYPES,
4125    }
4126
4127    TEMPORAL_TYPES = {
4128        Type.DATE,
4129        Type.DATE32,
4130        Type.DATETIME,
4131        Type.DATETIME64,
4132        Type.TIME,
4133        Type.TIMESTAMP,
4134        Type.TIMESTAMPNTZ,
4135        Type.TIMESTAMPLTZ,
4136        Type.TIMESTAMPTZ,
4137        Type.TIMESTAMP_MS,
4138        Type.TIMESTAMP_NS,
4139        Type.TIMESTAMP_S,
4140        Type.TIMETZ,
4141    }
4142
4143    @classmethod
4144    def build(
4145        cls,
4146        dtype: DATA_TYPE,
4147        dialect: DialectType = None,
4148        udt: bool = False,
4149        copy: bool = True,
4150        **kwargs,
4151    ) -> DataType:
4152        """
4153        Constructs a DataType object.
4154
4155        Args:
4156            dtype: the data type of interest.
4157            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4158            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4159                DataType, thus creating a user-defined type.
4160            copy: whether to copy the data type.
4161            kwargs: additional arguments to pass in the constructor of DataType.
4162
4163        Returns:
4164            The constructed DataType object.
4165        """
4166        from sqlglot import parse_one
4167
4168        if isinstance(dtype, str):
4169            if dtype.upper() == "UNKNOWN":
4170                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4171
4172            try:
4173                data_type_exp = parse_one(
4174                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4175                )
4176            except ParseError:
4177                if udt:
4178                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4179                raise
4180        elif isinstance(dtype, DataType.Type):
4181            data_type_exp = DataType(this=dtype)
4182        elif isinstance(dtype, DataType):
4183            return maybe_copy(dtype, copy)
4184        else:
4185            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4186
4187        return DataType(**{**data_type_exp.args, **kwargs})
4188
4189    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4190        """
4191        Checks whether this DataType matches one of the provided data types. Nested types or precision
4192        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4193
4194        Args:
4195            dtypes: the data types to compare this DataType to.
4196
4197        Returns:
4198            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4199        """
4200        for dtype in dtypes:
4201            other = DataType.build(dtype, copy=False, udt=True)
4202
4203            if (
4204                other.expressions
4205                or self.this == DataType.Type.USERDEFINED
4206                or other.this == DataType.Type.USERDEFINED
4207            ):
4208                matches = self == other
4209            else:
4210                matches = self.this == other.this
4211
4212            if matches:
4213                return True
4214        return False
4215
4216
4217DATA_TYPE = t.Union[str, DataType, DataType.Type]
4218
4219
4220# https://www.postgresql.org/docs/15/datatype-pseudo.html
4221class PseudoType(DataType):
4222    arg_types = {"this": True}
4223
4224
4225# https://www.postgresql.org/docs/15/datatype-oid.html
4226class ObjectIdentifier(DataType):
4227    arg_types = {"this": True}
4228
4229
4230# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4231class SubqueryPredicate(Predicate):
4232    pass
4233
4234
4235class All(SubqueryPredicate):
4236    pass
4237
4238
4239class Any(SubqueryPredicate):
4240    pass
4241
4242
4243class Exists(SubqueryPredicate):
4244    pass
4245
4246
4247# Commands to interact with the databases or engines. For most of the command
4248# expressions we parse whatever comes after the command's name as a string.
4249class Command(Expression):
4250    arg_types = {"this": True, "expression": False}
4251
4252
4253class Transaction(Expression):
4254    arg_types = {"this": False, "modes": False, "mark": False}
4255
4256
4257class Commit(Expression):
4258    arg_types = {"chain": False, "this": False, "durability": False}
4259
4260
4261class Rollback(Expression):
4262    arg_types = {"savepoint": False, "this": False}
4263
4264
4265class AlterTable(Expression):
4266    arg_types = {
4267        "this": True,
4268        "actions": True,
4269        "exists": False,
4270        "only": False,
4271        "options": False,
4272        "cluster": False,
4273    }
4274
4275
4276class AddConstraint(Expression):
4277    arg_types = {"expressions": True}
4278
4279
4280class DropPartition(Expression):
4281    arg_types = {"expressions": True, "exists": False}
4282
4283
4284# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#replace-partition
4285class ReplacePartition(Expression):
4286    arg_types = {"expression": True, "source": True}
4287
4288
4289# Binary expressions like (ADD a b)
4290class Binary(Condition):
4291    arg_types = {"this": True, "expression": True}
4292
4293    @property
4294    def left(self) -> Expression:
4295        return self.this
4296
4297    @property
4298    def right(self) -> Expression:
4299        return self.expression
4300
4301
4302class Add(Binary):
4303    pass
4304
4305
4306class Connector(Binary):
4307    pass
4308
4309
4310class And(Connector):
4311    pass
4312
4313
4314class Or(Connector):
4315    pass
4316
4317
4318class BitwiseAnd(Binary):
4319    pass
4320
4321
4322class BitwiseLeftShift(Binary):
4323    pass
4324
4325
4326class BitwiseOr(Binary):
4327    pass
4328
4329
4330class BitwiseRightShift(Binary):
4331    pass
4332
4333
4334class BitwiseXor(Binary):
4335    pass
4336
4337
4338class Div(Binary):
4339    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4340
4341
4342class Overlaps(Binary):
4343    pass
4344
4345
4346class Dot(Binary):
4347    @property
4348    def is_star(self) -> bool:
4349        return self.expression.is_star
4350
4351    @property
4352    def name(self) -> str:
4353        return self.expression.name
4354
4355    @property
4356    def output_name(self) -> str:
4357        return self.name
4358
4359    @classmethod
4360    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4361        """Build a Dot object with a sequence of expressions."""
4362        if len(expressions) < 2:
4363            raise ValueError("Dot requires >= 2 expressions.")
4364
4365        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4366
4367    @property
4368    def parts(self) -> t.List[Expression]:
4369        """Return the parts of a table / column in order catalog, db, table."""
4370        this, *parts = self.flatten()
4371
4372        parts.reverse()
4373
4374        for arg in COLUMN_PARTS:
4375            part = this.args.get(arg)
4376
4377            if isinstance(part, Expression):
4378                parts.append(part)
4379
4380        parts.reverse()
4381        return parts
4382
4383
4384class DPipe(Binary):
4385    arg_types = {"this": True, "expression": True, "safe": False}
4386
4387
4388class EQ(Binary, Predicate):
4389    pass
4390
4391
4392class NullSafeEQ(Binary, Predicate):
4393    pass
4394
4395
4396class NullSafeNEQ(Binary, Predicate):
4397    pass
4398
4399
4400# Represents e.g. := in DuckDB which is mostly used for setting parameters
4401class PropertyEQ(Binary):
4402    pass
4403
4404
4405class Distance(Binary):
4406    pass
4407
4408
4409class Escape(Binary):
4410    pass
4411
4412
4413class Glob(Binary, Predicate):
4414    pass
4415
4416
4417class GT(Binary, Predicate):
4418    pass
4419
4420
4421class GTE(Binary, Predicate):
4422    pass
4423
4424
4425class ILike(Binary, Predicate):
4426    pass
4427
4428
4429class ILikeAny(Binary, Predicate):
4430    pass
4431
4432
4433class IntDiv(Binary):
4434    pass
4435
4436
4437class Is(Binary, Predicate):
4438    pass
4439
4440
4441class Kwarg(Binary):
4442    """Kwarg in special functions like func(kwarg => y)."""
4443
4444
4445class Like(Binary, Predicate):
4446    pass
4447
4448
4449class LikeAny(Binary, Predicate):
4450    pass
4451
4452
4453class LT(Binary, Predicate):
4454    pass
4455
4456
4457class LTE(Binary, Predicate):
4458    pass
4459
4460
4461class Mod(Binary):
4462    pass
4463
4464
4465class Mul(Binary):
4466    pass
4467
4468
4469class NEQ(Binary, Predicate):
4470    pass
4471
4472
4473# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
4474class Operator(Binary):
4475    arg_types = {"this": True, "operator": True, "expression": True}
4476
4477
4478class SimilarTo(Binary, Predicate):
4479    pass
4480
4481
4482class Slice(Binary):
4483    arg_types = {"this": False, "expression": False}
4484
4485
4486class Sub(Binary):
4487    pass
4488
4489
4490# Unary Expressions
4491# (NOT a)
4492class Unary(Condition):
4493    pass
4494
4495
4496class BitwiseNot(Unary):
4497    pass
4498
4499
4500class Not(Unary):
4501    pass
4502
4503
4504class Paren(Unary):
4505    @property
4506    def output_name(self) -> str:
4507        return self.this.name
4508
4509
4510class Neg(Unary):
4511    def to_py(self) -> int | Decimal:
4512        if self.is_number:
4513            return self.this.to_py() * -1
4514        return super().to_py()
4515
4516
4517class Alias(Expression):
4518    arg_types = {"this": True, "alias": False}
4519
4520    @property
4521    def output_name(self) -> str:
4522        return self.alias
4523
4524
4525# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
4526# other dialects require identifiers. This enables us to transpile between them easily.
4527class PivotAlias(Alias):
4528    pass
4529
4530
4531class Aliases(Expression):
4532    arg_types = {"this": True, "expressions": True}
4533
4534    @property
4535    def aliases(self):
4536        return self.expressions
4537
4538
4539# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
4540class AtIndex(Expression):
4541    arg_types = {"this": True, "expression": True}
4542
4543
4544class AtTimeZone(Expression):
4545    arg_types = {"this": True, "zone": True}
4546
4547
4548class FromTimeZone(Expression):
4549    arg_types = {"this": True, "zone": True}
4550
4551
4552class Between(Predicate):
4553    arg_types = {"this": True, "low": True, "high": True}
4554
4555
4556class Bracket(Condition):
4557    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4558    arg_types = {
4559        "this": True,
4560        "expressions": True,
4561        "offset": False,
4562        "safe": False,
4563        "returns_list_for_maps": False,
4564    }
4565
4566    @property
4567    def output_name(self) -> str:
4568        if len(self.expressions) == 1:
4569            return self.expressions[0].output_name
4570
4571        return super().output_name
4572
4573
4574class Distinct(Expression):
4575    arg_types = {"expressions": False, "on": False}
4576
4577
4578class In(Predicate):
4579    arg_types = {
4580        "this": True,
4581        "expressions": False,
4582        "query": False,
4583        "unnest": False,
4584        "field": False,
4585        "is_global": False,
4586    }
4587
4588
4589# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
4590class ForIn(Expression):
4591    arg_types = {"this": True, "expression": True}
4592
4593
4594class TimeUnit(Expression):
4595    """Automatically converts unit arg into a var."""
4596
4597    arg_types = {"unit": False}
4598
4599    UNABBREVIATED_UNIT_NAME = {
4600        "D": "DAY",
4601        "H": "HOUR",
4602        "M": "MINUTE",
4603        "MS": "MILLISECOND",
4604        "NS": "NANOSECOND",
4605        "Q": "QUARTER",
4606        "S": "SECOND",
4607        "US": "MICROSECOND",
4608        "W": "WEEK",
4609        "Y": "YEAR",
4610    }
4611
4612    VAR_LIKE = (Column, Literal, Var)
4613
4614    def __init__(self, **args):
4615        unit = args.get("unit")
4616        if isinstance(unit, self.VAR_LIKE):
4617            args["unit"] = Var(
4618                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4619            )
4620        elif isinstance(unit, Week):
4621            unit.set("this", Var(this=unit.this.name.upper()))
4622
4623        super().__init__(**args)
4624
4625    @property
4626    def unit(self) -> t.Optional[Var | IntervalSpan]:
4627        return self.args.get("unit")
4628
4629
4630class IntervalOp(TimeUnit):
4631    arg_types = {"unit": True, "expression": True}
4632
4633    def interval(self):
4634        return Interval(
4635            this=self.expression.copy(),
4636            unit=self.unit.copy(),
4637        )
4638
4639
4640# https://www.oracletutorial.com/oracle-basics/oracle-interval/
4641# https://trino.io/docs/current/language/types.html#interval-day-to-second
4642# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
4643class IntervalSpan(DataType):
4644    arg_types = {"this": True, "expression": True}
4645
4646
4647class Interval(TimeUnit):
4648    arg_types = {"this": False, "unit": False}
4649
4650
4651class IgnoreNulls(Expression):
4652    pass
4653
4654
4655class RespectNulls(Expression):
4656    pass
4657
4658
4659# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
4660class HavingMax(Expression):
4661    arg_types = {"this": True, "expression": True, "max": True}
4662
4663
4664# Functions
4665class Func(Condition):
4666    """
4667    The base class for all function expressions.
4668
4669    Attributes:
4670        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4671            treated as a variable length argument and the argument's value will be stored as a list.
4672        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4673            function expression. These values are used to map this node to a name during parsing as
4674            well as to provide the function's name during SQL string generation. By default the SQL
4675            name is set to the expression's class name transformed to snake case.
4676    """
4677
4678    is_var_len_args = False
4679
4680    @classmethod
4681    def from_arg_list(cls, args):
4682        if cls.is_var_len_args:
4683            all_arg_keys = list(cls.arg_types)
4684            # If this function supports variable length argument treat the last argument as such.
4685            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4686            num_non_var = len(non_var_len_arg_keys)
4687
4688            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4689            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4690        else:
4691            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4692
4693        return cls(**args_dict)
4694
4695    @classmethod
4696    def sql_names(cls):
4697        if cls is Func:
4698            raise NotImplementedError(
4699                "SQL name is only supported by concrete function implementations"
4700            )
4701        if "_sql_names" not in cls.__dict__:
4702            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4703        return cls._sql_names
4704
4705    @classmethod
4706    def sql_name(cls):
4707        return cls.sql_names()[0]
4708
4709    @classmethod
4710    def default_parser_mappings(cls):
4711        return {name: cls.from_arg_list for name in cls.sql_names()}
4712
4713
4714class AggFunc(Func):
4715    pass
4716
4717
4718class ParameterizedAgg(AggFunc):
4719    arg_types = {"this": True, "expressions": True, "params": True}
4720
4721
4722class Abs(Func):
4723    pass
4724
4725
4726class ArgMax(AggFunc):
4727    arg_types = {"this": True, "expression": True, "count": False}
4728    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
4729
4730
4731class ArgMin(AggFunc):
4732    arg_types = {"this": True, "expression": True, "count": False}
4733    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
4734
4735
4736class ApproxTopK(AggFunc):
4737    arg_types = {"this": True, "expression": False, "counters": False}
4738
4739
4740class Flatten(Func):
4741    pass
4742
4743
4744# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4745class Transform(Func):
4746    arg_types = {"this": True, "expression": True}
4747
4748
4749class Anonymous(Func):
4750    arg_types = {"this": True, "expressions": False}
4751    is_var_len_args = True
4752
4753    @property
4754    def name(self) -> str:
4755        return self.this if isinstance(self.this, str) else self.this.name
4756
4757
4758class AnonymousAggFunc(AggFunc):
4759    arg_types = {"this": True, "expressions": False}
4760    is_var_len_args = True
4761
4762
4763# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
4764class CombinedAggFunc(AnonymousAggFunc):
4765    arg_types = {"this": True, "expressions": False, "parts": True}
4766
4767
4768class CombinedParameterizedAgg(ParameterizedAgg):
4769    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
4770
4771
4772# https://docs.snowflake.com/en/sql-reference/functions/hll
4773# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4774class Hll(AggFunc):
4775    arg_types = {"this": True, "expressions": False}
4776    is_var_len_args = True
4777
4778
4779class ApproxDistinct(AggFunc):
4780    arg_types = {"this": True, "accuracy": False}
4781    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4782
4783
4784class Array(Func):
4785    arg_types = {"expressions": False}
4786    is_var_len_args = True
4787
4788
4789# https://docs.snowflake.com/en/sql-reference/functions/to_array
4790class ToArray(Func):
4791    pass
4792
4793
4794# https://materialize.com/docs/sql/types/list/
4795class List(Func):
4796    arg_types = {"expressions": False}
4797    is_var_len_args = True
4798
4799
4800# https://docs.snowflake.com/en/sql-reference/functions/to_char
4801# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
4802class ToChar(Func):
4803    arg_types = {"this": True, "format": False, "nlsparam": False}
4804
4805
4806# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
4807# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
4808class ToNumber(Func):
4809    arg_types = {
4810        "this": True,
4811        "format": False,
4812        "nlsparam": False,
4813        "precision": False,
4814        "scale": False,
4815    }
4816
4817
4818# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
4819class Convert(Func):
4820    arg_types = {"this": True, "expression": True, "style": False}
4821
4822
4823class GenerateSeries(Func):
4824    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
4825
4826
4827class ArrayAgg(AggFunc):
4828    pass
4829
4830
4831class ArrayUniqueAgg(AggFunc):
4832    pass
4833
4834
4835class ArrayAll(Func):
4836    arg_types = {"this": True, "expression": True}
4837
4838
4839# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
4840class ArrayAny(Func):
4841    arg_types = {"this": True, "expression": True}
4842
4843
4844class ArrayConcat(Func):
4845    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4846    arg_types = {"this": True, "expressions": False}
4847    is_var_len_args = True
4848
4849
4850class ArrayConstructCompact(Func):
4851    arg_types = {"expressions": True}
4852    is_var_len_args = True
4853
4854
4855class ArrayContains(Binary, Func):
4856    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
4857
4858
4859class ArrayContainsAll(Binary, Func):
4860    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
4861
4862
4863class ArrayFilter(Func):
4864    arg_types = {"this": True, "expression": True}
4865    _sql_names = ["FILTER", "ARRAY_FILTER"]
4866
4867
4868class ArrayToString(Func):
4869    arg_types = {"this": True, "expression": True, "null": False}
4870    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
4871
4872
4873class StringToArray(Func):
4874    arg_types = {"this": True, "expression": True, "null": False}
4875    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
4876
4877
4878class ArrayOverlaps(Binary, Func):
4879    pass
4880
4881
4882class ArraySize(Func):
4883    arg_types = {"this": True, "expression": False}
4884    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
4885
4886
4887class ArraySort(Func):
4888    arg_types = {"this": True, "expression": False}
4889
4890
4891class ArraySum(Func):
4892    arg_types = {"this": True, "expression": False}
4893
4894
4895class ArrayUnionAgg(AggFunc):
4896    pass
4897
4898
4899class Avg(AggFunc):
4900    pass
4901
4902
4903class AnyValue(AggFunc):
4904    pass
4905
4906
4907class Lag(AggFunc):
4908    arg_types = {"this": True, "offset": False, "default": False}
4909
4910
4911class Lead(AggFunc):
4912    arg_types = {"this": True, "offset": False, "default": False}
4913
4914
4915# some dialects have a distinction between first and first_value, usually first is an aggregate func
4916# and first_value is a window func
4917class First(AggFunc):
4918    pass
4919
4920
4921class Last(AggFunc):
4922    pass
4923
4924
4925class FirstValue(AggFunc):
4926    pass
4927
4928
4929class LastValue(AggFunc):
4930    pass
4931
4932
4933class NthValue(AggFunc):
4934    arg_types = {"this": True, "offset": True}
4935
4936
4937class Case(Func):
4938    arg_types = {"this": False, "ifs": True, "default": False}
4939
4940    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4941        instance = maybe_copy(self, copy)
4942        instance.append(
4943            "ifs",
4944            If(
4945                this=maybe_parse(condition, copy=copy, **opts),
4946                true=maybe_parse(then, copy=copy, **opts),
4947            ),
4948        )
4949        return instance
4950
4951    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4952        instance = maybe_copy(self, copy)
4953        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4954        return instance
4955
4956
4957class Cast(Func):
4958    arg_types = {
4959        "this": True,
4960        "to": True,
4961        "format": False,
4962        "safe": False,
4963        "action": False,
4964    }
4965
4966    @property
4967    def name(self) -> str:
4968        return self.this.name
4969
4970    @property
4971    def to(self) -> DataType:
4972        return self.args["to"]
4973
4974    @property
4975    def output_name(self) -> str:
4976        return self.name
4977
4978    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4979        """
4980        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4981        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4982        array<int> != array<float>.
4983
4984        Args:
4985            dtypes: the data types to compare this Cast's DataType to.
4986
4987        Returns:
4988            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4989        """
4990        return self.to.is_type(*dtypes)
4991
4992
4993class TryCast(Cast):
4994    pass
4995
4996
4997class Try(Func):
4998    pass
4999
5000
5001class CastToStrType(Func):
5002    arg_types = {"this": True, "to": True}
5003
5004
5005class Collate(Binary, Func):
5006    pass
5007
5008
5009class Ceil(Func):
5010    arg_types = {"this": True, "decimals": False}
5011    _sql_names = ["CEIL", "CEILING"]
5012
5013
5014class Coalesce(Func):
5015    arg_types = {"this": True, "expressions": False}
5016    is_var_len_args = True
5017    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5018
5019
5020class Chr(Func):
5021    arg_types = {"this": True, "charset": False, "expressions": False}
5022    is_var_len_args = True
5023    _sql_names = ["CHR", "CHAR"]
5024
5025
5026class Concat(Func):
5027    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5028    is_var_len_args = True
5029
5030
5031class ConcatWs(Concat):
5032    _sql_names = ["CONCAT_WS"]
5033
5034
5035# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5036class ConnectByRoot(Func):
5037    pass
5038
5039
5040class Count(AggFunc):
5041    arg_types = {"this": False, "expressions": False}
5042    is_var_len_args = True
5043
5044
5045class CountIf(AggFunc):
5046    _sql_names = ["COUNT_IF", "COUNTIF"]
5047
5048
5049# cube root
5050class Cbrt(Func):
5051    pass
5052
5053
5054class CurrentDate(Func):
5055    arg_types = {"this": False}
5056
5057
5058class CurrentDatetime(Func):
5059    arg_types = {"this": False}
5060
5061
5062class CurrentTime(Func):
5063    arg_types = {"this": False}
5064
5065
5066class CurrentTimestamp(Func):
5067    arg_types = {"this": False, "transaction": False}
5068
5069
5070class CurrentUser(Func):
5071    arg_types = {"this": False}
5072
5073
5074class DateAdd(Func, IntervalOp):
5075    arg_types = {"this": True, "expression": True, "unit": False}
5076
5077
5078class DateSub(Func, IntervalOp):
5079    arg_types = {"this": True, "expression": True, "unit": False}
5080
5081
5082class DateDiff(Func, TimeUnit):
5083    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5084    arg_types = {"this": True, "expression": True, "unit": False}
5085
5086
5087class DateTrunc(Func):
5088    arg_types = {"unit": True, "this": True, "zone": False}
5089
5090    def __init__(self, **args):
5091        unit = args.get("unit")
5092        if isinstance(unit, TimeUnit.VAR_LIKE):
5093            args["unit"] = Literal.string(
5094                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5095            )
5096        elif isinstance(unit, Week):
5097            unit.set("this", Literal.string(unit.this.name.upper()))
5098
5099        super().__init__(**args)
5100
5101    @property
5102    def unit(self) -> Expression:
5103        return self.args["unit"]
5104
5105
5106# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5107# expression can either be time_expr or time_zone
5108class Datetime(Func):
5109    arg_types = {"this": True, "expression": False}
5110
5111
5112class DatetimeAdd(Func, IntervalOp):
5113    arg_types = {"this": True, "expression": True, "unit": False}
5114
5115
5116class DatetimeSub(Func, IntervalOp):
5117    arg_types = {"this": True, "expression": True, "unit": False}
5118
5119
5120class DatetimeDiff(Func, TimeUnit):
5121    arg_types = {"this": True, "expression": True, "unit": False}
5122
5123
5124class DatetimeTrunc(Func, TimeUnit):
5125    arg_types = {"this": True, "unit": True, "zone": False}
5126
5127
5128class DayOfWeek(Func):
5129    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5130
5131
5132class DayOfMonth(Func):
5133    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5134
5135
5136class DayOfYear(Func):
5137    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5138
5139
5140class ToDays(Func):
5141    pass
5142
5143
5144class WeekOfYear(Func):
5145    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5146
5147
5148class MonthsBetween(Func):
5149    arg_types = {"this": True, "expression": True, "roundoff": False}
5150
5151
5152class LastDay(Func, TimeUnit):
5153    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5154    arg_types = {"this": True, "unit": False}
5155
5156
5157class Extract(Func):
5158    arg_types = {"this": True, "expression": True}
5159
5160
5161class Timestamp(Func):
5162    arg_types = {"this": False, "zone": False, "with_tz": False}
5163
5164
5165class TimestampAdd(Func, TimeUnit):
5166    arg_types = {"this": True, "expression": True, "unit": False}
5167
5168
5169class TimestampSub(Func, TimeUnit):
5170    arg_types = {"this": True, "expression": True, "unit": False}
5171
5172
5173class TimestampDiff(Func, TimeUnit):
5174    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5175    arg_types = {"this": True, "expression": True, "unit": False}
5176
5177
5178class TimestampTrunc(Func, TimeUnit):
5179    arg_types = {"this": True, "unit": True, "zone": False}
5180
5181
5182class TimeAdd(Func, TimeUnit):
5183    arg_types = {"this": True, "expression": True, "unit": False}
5184
5185
5186class TimeSub(Func, TimeUnit):
5187    arg_types = {"this": True, "expression": True, "unit": False}
5188
5189
5190class TimeDiff(Func, TimeUnit):
5191    arg_types = {"this": True, "expression": True, "unit": False}
5192
5193
5194class TimeTrunc(Func, TimeUnit):
5195    arg_types = {"this": True, "unit": True, "zone": False}
5196
5197
5198class DateFromParts(Func):
5199    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5200    arg_types = {"year": True, "month": True, "day": True}
5201
5202
5203class TimeFromParts(Func):
5204    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5205    arg_types = {
5206        "hour": True,
5207        "min": True,
5208        "sec": True,
5209        "nano": False,
5210        "fractions": False,
5211        "precision": False,
5212    }
5213
5214
5215class DateStrToDate(Func):
5216    pass
5217
5218
5219class DateToDateStr(Func):
5220    pass
5221
5222
5223class DateToDi(Func):
5224    pass
5225
5226
5227# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5228class Date(Func):
5229    arg_types = {"this": False, "zone": False, "expressions": False}
5230    is_var_len_args = True
5231
5232
5233class Day(Func):
5234    pass
5235
5236
5237class Decode(Func):
5238    arg_types = {"this": True, "charset": True, "replace": False}
5239
5240
5241class DiToDate(Func):
5242    pass
5243
5244
5245class Encode(Func):
5246    arg_types = {"this": True, "charset": True}
5247
5248
5249class Exp(Func):
5250    pass
5251
5252
5253# https://docs.snowflake.com/en/sql-reference/functions/flatten
5254class Explode(Func):
5255    arg_types = {"this": True, "expressions": False}
5256    is_var_len_args = True
5257
5258
5259class ExplodeOuter(Explode):
5260    pass
5261
5262
5263class Posexplode(Explode):
5264    pass
5265
5266
5267class PosexplodeOuter(Posexplode, ExplodeOuter):
5268    pass
5269
5270
5271class Unnest(Func, UDTF):
5272    arg_types = {
5273        "expressions": True,
5274        "alias": False,
5275        "offset": False,
5276    }
5277
5278    @property
5279    def selects(self) -> t.List[Expression]:
5280        columns = super().selects
5281        offset = self.args.get("offset")
5282        if offset:
5283            columns = columns + [to_identifier("offset") if offset is True else offset]
5284        return columns
5285
5286
5287class Floor(Func):
5288    arg_types = {"this": True, "decimals": False}
5289
5290
5291class FromBase64(Func):
5292    pass
5293
5294
5295class ToBase64(Func):
5296    pass
5297
5298
5299class GapFill(Func):
5300    arg_types = {
5301        "this": True,
5302        "ts_column": True,
5303        "bucket_width": True,
5304        "partitioning_columns": False,
5305        "value_columns": False,
5306        "origin": False,
5307        "ignore_nulls": False,
5308    }
5309
5310
5311class GenerateDateArray(Func):
5312    arg_types = {"start": True, "end": True, "interval": False}
5313
5314
5315class Greatest(Func):
5316    arg_types = {"this": True, "expressions": False}
5317    is_var_len_args = True
5318
5319
5320class GroupConcat(AggFunc):
5321    arg_types = {"this": True, "separator": False}
5322
5323
5324class Hex(Func):
5325    pass
5326
5327
5328class LowerHex(Hex):
5329    pass
5330
5331
5332class Xor(Connector, Func):
5333    arg_types = {"this": False, "expression": False, "expressions": False}
5334
5335
5336class If(Func):
5337    arg_types = {"this": True, "true": True, "false": False}
5338    _sql_names = ["IF", "IIF"]
5339
5340
5341class Nullif(Func):
5342    arg_types = {"this": True, "expression": True}
5343
5344
5345class Initcap(Func):
5346    arg_types = {"this": True, "expression": False}
5347
5348
5349class IsNan(Func):
5350    _sql_names = ["IS_NAN", "ISNAN"]
5351
5352
5353class IsInf(Func):
5354    _sql_names = ["IS_INF", "ISINF"]
5355
5356
5357class JSONPath(Expression):
5358    arg_types = {"expressions": True}
5359
5360    @property
5361    def output_name(self) -> str:
5362        last_segment = self.expressions[-1].this
5363        return last_segment if isinstance(last_segment, str) else ""
5364
5365
5366class JSONPathPart(Expression):
5367    arg_types = {}
5368
5369
5370class JSONPathFilter(JSONPathPart):
5371    arg_types = {"this": True}
5372
5373
5374class JSONPathKey(JSONPathPart):
5375    arg_types = {"this": True}
5376
5377
5378class JSONPathRecursive(JSONPathPart):
5379    arg_types = {"this": False}
5380
5381
5382class JSONPathRoot(JSONPathPart):
5383    pass
5384
5385
5386class JSONPathScript(JSONPathPart):
5387    arg_types = {"this": True}
5388
5389
5390class JSONPathSlice(JSONPathPart):
5391    arg_types = {"start": False, "end": False, "step": False}
5392
5393
5394class JSONPathSelector(JSONPathPart):
5395    arg_types = {"this": True}
5396
5397
5398class JSONPathSubscript(JSONPathPart):
5399    arg_types = {"this": True}
5400
5401
5402class JSONPathUnion(JSONPathPart):
5403    arg_types = {"expressions": True}
5404
5405
5406class JSONPathWildcard(JSONPathPart):
5407    pass
5408
5409
5410class FormatJson(Expression):
5411    pass
5412
5413
5414class JSONKeyValue(Expression):
5415    arg_types = {"this": True, "expression": True}
5416
5417
5418class JSONObject(Func):
5419    arg_types = {
5420        "expressions": False,
5421        "null_handling": False,
5422        "unique_keys": False,
5423        "return_type": False,
5424        "encoding": False,
5425    }
5426
5427
5428class JSONObjectAgg(AggFunc):
5429    arg_types = {
5430        "expressions": False,
5431        "null_handling": False,
5432        "unique_keys": False,
5433        "return_type": False,
5434        "encoding": False,
5435    }
5436
5437
5438# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
5439class JSONArray(Func):
5440    arg_types = {
5441        "expressions": True,
5442        "null_handling": False,
5443        "return_type": False,
5444        "strict": False,
5445    }
5446
5447
5448# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
5449class JSONArrayAgg(Func):
5450    arg_types = {
5451        "this": True,
5452        "order": False,
5453        "null_handling": False,
5454        "return_type": False,
5455        "strict": False,
5456    }
5457
5458
5459# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5460# Note: parsing of JSON column definitions is currently incomplete.
5461class JSONColumnDef(Expression):
5462    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
5463
5464
5465class JSONSchema(Expression):
5466    arg_types = {"expressions": True}
5467
5468
5469# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5470class JSONTable(Func):
5471    arg_types = {
5472        "this": True,
5473        "schema": True,
5474        "path": False,
5475        "error_handling": False,
5476        "empty_handling": False,
5477    }
5478
5479
5480class OpenJSONColumnDef(Expression):
5481    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
5482
5483
5484class OpenJSON(Func):
5485    arg_types = {"this": True, "path": False, "expressions": False}
5486
5487
5488class JSONBContains(Binary, Func):
5489    _sql_names = ["JSONB_CONTAINS"]
5490
5491
5492class JSONExtract(Binary, Func):
5493    arg_types = {
5494        "this": True,
5495        "expression": True,
5496        "only_json_types": False,
5497        "expressions": False,
5498        "variant_extract": False,
5499    }
5500    _sql_names = ["JSON_EXTRACT"]
5501    is_var_len_args = True
5502
5503    @property
5504    def output_name(self) -> str:
5505        return self.expression.output_name if not self.expressions else ""
5506
5507
5508class JSONExtractScalar(Binary, Func):
5509    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5510    _sql_names = ["JSON_EXTRACT_SCALAR"]
5511    is_var_len_args = True
5512
5513    @property
5514    def output_name(self) -> str:
5515        return self.expression.output_name
5516
5517
5518class JSONBExtract(Binary, Func):
5519    _sql_names = ["JSONB_EXTRACT"]
5520
5521
5522class JSONBExtractScalar(Binary, Func):
5523    _sql_names = ["JSONB_EXTRACT_SCALAR"]
5524
5525
5526class JSONFormat(Func):
5527    arg_types = {"this": False, "options": False}
5528    _sql_names = ["JSON_FORMAT"]
5529
5530
5531# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
5532class JSONArrayContains(Binary, Predicate, Func):
5533    _sql_names = ["JSON_ARRAY_CONTAINS"]
5534
5535
5536class ParseJSON(Func):
5537    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5538    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5539    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5540    arg_types = {"this": True, "expression": False, "safe": False}
5541
5542
5543class Least(Func):
5544    arg_types = {"this": True, "expressions": False}
5545    is_var_len_args = True
5546
5547
5548class Left(Func):
5549    arg_types = {"this": True, "expression": True}
5550
5551
5552class Right(Func):
5553    arg_types = {"this": True, "expression": True}
5554
5555
5556class Length(Func):
5557    arg_types = {"this": True, "binary": False}
5558    _sql_names = ["LENGTH", "LEN"]
5559
5560
5561class Levenshtein(Func):
5562    arg_types = {
5563        "this": True,
5564        "expression": False,
5565        "ins_cost": False,
5566        "del_cost": False,
5567        "sub_cost": False,
5568    }
5569
5570
5571class Ln(Func):
5572    pass
5573
5574
5575class Log(Func):
5576    arg_types = {"this": True, "expression": False}
5577
5578
5579class LogicalOr(AggFunc):
5580    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
5581
5582
5583class LogicalAnd(AggFunc):
5584    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
5585
5586
5587class Lower(Func):
5588    _sql_names = ["LOWER", "LCASE"]
5589
5590
5591class Map(Func):
5592    arg_types = {"keys": False, "values": False}
5593
5594    @property
5595    def keys(self) -> t.List[Expression]:
5596        keys = self.args.get("keys")
5597        return keys.expressions if keys else []
5598
5599    @property
5600    def values(self) -> t.List[Expression]:
5601        values = self.args.get("values")
5602        return values.expressions if values else []
5603
5604
5605# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
5606class ToMap(Func):
5607    pass
5608
5609
5610class MapFromEntries(Func):
5611    pass
5612
5613
5614# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
5615class ScopeResolution(Expression):
5616    arg_types = {"this": False, "expression": True}
5617
5618
5619class StarMap(Func):
5620    pass
5621
5622
5623class VarMap(Func):
5624    arg_types = {"keys": True, "values": True}
5625    is_var_len_args = True
5626
5627    @property
5628    def keys(self) -> t.List[Expression]:
5629        return self.args["keys"].expressions
5630
5631    @property
5632    def values(self) -> t.List[Expression]:
5633        return self.args["values"].expressions
5634
5635
5636# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
5637class MatchAgainst(Func):
5638    arg_types = {"this": True, "expressions": True, "modifier": False}
5639
5640
5641class Max(AggFunc):
5642    arg_types = {"this": True, "expressions": False}
5643    is_var_len_args = True
5644
5645
5646class MD5(Func):
5647    _sql_names = ["MD5"]
5648
5649
5650# Represents the variant of the MD5 function that returns a binary value
5651class MD5Digest(Func):
5652    _sql_names = ["MD5_DIGEST"]
5653
5654
5655class Min(AggFunc):
5656    arg_types = {"this": True, "expressions": False}
5657    is_var_len_args = True
5658
5659
5660class Month(Func):
5661    pass
5662
5663
5664class AddMonths(Func):
5665    arg_types = {"this": True, "expression": True}
5666
5667
5668class Nvl2(Func):
5669    arg_types = {"this": True, "true": True, "false": False}
5670
5671
5672# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5673class Predict(Func):
5674    arg_types = {"this": True, "expression": True, "params_struct": False}
5675
5676
5677class Pow(Binary, Func):
5678    _sql_names = ["POWER", "POW"]
5679
5680
5681class PercentileCont(AggFunc):
5682    arg_types = {"this": True, "expression": False}
5683
5684
5685class PercentileDisc(AggFunc):
5686    arg_types = {"this": True, "expression": False}
5687
5688
5689class Quantile(AggFunc):
5690    arg_types = {"this": True, "quantile": True}
5691
5692
5693class ApproxQuantile(Quantile):
5694    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5695
5696
5697class Quarter(Func):
5698    pass
5699
5700
5701# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
5702# teradata lower and upper bounds
5703class Rand(Func):
5704    _sql_names = ["RAND", "RANDOM"]
5705    arg_types = {"this": False, "lower": False, "upper": False}
5706
5707
5708class Randn(Func):
5709    arg_types = {"this": False}
5710
5711
5712class RangeN(Func):
5713    arg_types = {"this": True, "expressions": True, "each": False}
5714
5715
5716class ReadCSV(Func):
5717    _sql_names = ["READ_CSV"]
5718    is_var_len_args = True
5719    arg_types = {"this": True, "expressions": False}
5720
5721
5722class Reduce(Func):
5723    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5724
5725
5726class RegexpExtract(Func):
5727    arg_types = {
5728        "this": True,
5729        "expression": True,
5730        "position": False,
5731        "occurrence": False,
5732        "parameters": False,
5733        "group": False,
5734    }
5735
5736
5737class RegexpReplace(Func):
5738    arg_types = {
5739        "this": True,
5740        "expression": True,
5741        "replacement": False,
5742        "position": False,
5743        "occurrence": False,
5744        "modifiers": False,
5745    }
5746
5747
5748class RegexpLike(Binary, Func):
5749    arg_types = {"this": True, "expression": True, "flag": False}
5750
5751
5752class RegexpILike(Binary, Func):
5753    arg_types = {"this": True, "expression": True, "flag": False}
5754
5755
5756# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5757# limit is the number of times a pattern is applied
5758class RegexpSplit(Func):
5759    arg_types = {"this": True, "expression": True, "limit": False}
5760
5761
5762class Repeat(Func):
5763    arg_types = {"this": True, "times": True}
5764
5765
5766# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
5767# tsql third argument function == trunctaion if not 0
5768class Round(Func):
5769    arg_types = {"this": True, "decimals": False, "truncate": False}
5770
5771
5772class RowNumber(Func):
5773    arg_types: t.Dict[str, t.Any] = {}
5774
5775
5776class SafeDivide(Func):
5777    arg_types = {"this": True, "expression": True}
5778
5779
5780class SHA(Func):
5781    _sql_names = ["SHA", "SHA1"]
5782
5783
5784class SHA2(Func):
5785    _sql_names = ["SHA2"]
5786    arg_types = {"this": True, "length": False}
5787
5788
5789class Sign(Func):
5790    _sql_names = ["SIGN", "SIGNUM"]
5791
5792
5793class SortArray(Func):
5794    arg_types = {"this": True, "asc": False}
5795
5796
5797class Split(Func):
5798    arg_types = {"this": True, "expression": True, "limit": False}
5799
5800
5801# Start may be omitted in the case of postgres
5802# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5803class Substring(Func):
5804    arg_types = {"this": True, "start": False, "length": False}
5805
5806
5807class StandardHash(Func):
5808    arg_types = {"this": True, "expression": False}
5809
5810
5811class StartsWith(Func):
5812    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5813    arg_types = {"this": True, "expression": True}
5814
5815
5816class StrPosition(Func):
5817    arg_types = {
5818        "this": True,
5819        "substr": True,
5820        "position": False,
5821        "instance": False,
5822    }
5823
5824
5825class StrToDate(Func):
5826    arg_types = {"this": True, "format": False, "safe": False}
5827
5828
5829class StrToTime(Func):
5830    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
5831
5832
5833# Spark allows unix_timestamp()
5834# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5835class StrToUnix(Func):
5836    arg_types = {"this": False, "format": False}
5837
5838
5839# https://prestodb.io/docs/current/functions/string.html
5840# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5841class StrToMap(Func):
5842    arg_types = {
5843        "this": True,
5844        "pair_delim": False,
5845        "key_value_delim": False,
5846        "duplicate_resolution_callback": False,
5847    }
5848
5849
5850class NumberToStr(Func):
5851    arg_types = {"this": True, "format": True, "culture": False}
5852
5853
5854class FromBase(Func):
5855    arg_types = {"this": True, "expression": True}
5856
5857
5858class Struct(Func):
5859    arg_types = {"expressions": False}
5860    is_var_len_args = True
5861
5862
5863class StructExtract(Func):
5864    arg_types = {"this": True, "expression": True}
5865
5866
5867# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5868# https://docs.snowflake.com/en/sql-reference/functions/insert
5869class Stuff(Func):
5870    _sql_names = ["STUFF", "INSERT"]
5871    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5872
5873
5874class Sum(AggFunc):
5875    pass
5876
5877
5878class Sqrt(Func):
5879    pass
5880
5881
5882class Stddev(AggFunc):
5883    pass
5884
5885
5886class StddevPop(AggFunc):
5887    pass
5888
5889
5890class StddevSamp(AggFunc):
5891    pass
5892
5893
5894# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
5895class Time(Func):
5896    arg_types = {"this": False, "zone": False}
5897
5898
5899class TimeToStr(Func):
5900    arg_types = {"this": True, "format": True, "culture": False, "timezone": False}
5901
5902
5903class TimeToTimeStr(Func):
5904    pass
5905
5906
5907class TimeToUnix(Func):
5908    pass
5909
5910
5911class TimeStrToDate(Func):
5912    pass
5913
5914
5915class TimeStrToTime(Func):
5916    pass
5917
5918
5919class TimeStrToUnix(Func):
5920    pass
5921
5922
5923class Trim(Func):
5924    arg_types = {
5925        "this": True,
5926        "expression": False,
5927        "position": False,
5928        "collation": False,
5929    }
5930
5931
5932class TsOrDsAdd(Func, TimeUnit):
5933    # return_type is used to correctly cast the arguments of this expression when transpiling it
5934    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5935
5936    @property
5937    def return_type(self) -> DataType:
5938        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5939
5940
5941class TsOrDsDiff(Func, TimeUnit):
5942    arg_types = {"this": True, "expression": True, "unit": False}
5943
5944
5945class TsOrDsToDateStr(Func):
5946    pass
5947
5948
5949class TsOrDsToDate(Func):
5950    arg_types = {"this": True, "format": False, "safe": False}
5951
5952
5953class TsOrDsToTime(Func):
5954    pass
5955
5956
5957class TsOrDsToTimestamp(Func):
5958    pass
5959
5960
5961class TsOrDiToDi(Func):
5962    pass
5963
5964
5965class Unhex(Func):
5966    pass
5967
5968
5969# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
5970class UnixDate(Func):
5971    pass
5972
5973
5974class UnixToStr(Func):
5975    arg_types = {"this": True, "format": False}
5976
5977
5978# https://prestodb.io/docs/current/functions/datetime.html
5979# presto has weird zone/hours/minutes
5980class UnixToTime(Func):
5981    arg_types = {
5982        "this": True,
5983        "scale": False,
5984        "zone": False,
5985        "hours": False,
5986        "minutes": False,
5987        "format": False,
5988    }
5989
5990    SECONDS = Literal.number(0)
5991    DECIS = Literal.number(1)
5992    CENTIS = Literal.number(2)
5993    MILLIS = Literal.number(3)
5994    DECIMILLIS = Literal.number(4)
5995    CENTIMILLIS = Literal.number(5)
5996    MICROS = Literal.number(6)
5997    DECIMICROS = Literal.number(7)
5998    CENTIMICROS = Literal.number(8)
5999    NANOS = Literal.number(9)
6000
6001
6002class UnixToTimeStr(Func):
6003    pass
6004
6005
6006class TimestampFromParts(Func):
6007    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6008    arg_types = {
6009        "year": True,
6010        "month": True,
6011        "day": True,
6012        "hour": True,
6013        "min": True,
6014        "sec": True,
6015        "nano": False,
6016        "zone": False,
6017        "milli": False,
6018    }
6019
6020
6021class Upper(Func):
6022    _sql_names = ["UPPER", "UCASE"]
6023
6024
6025class Corr(Binary, AggFunc):
6026    pass
6027
6028
6029class Variance(AggFunc):
6030    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6031
6032
6033class VariancePop(AggFunc):
6034    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6035
6036
6037class CovarSamp(Binary, AggFunc):
6038    pass
6039
6040
6041class CovarPop(Binary, AggFunc):
6042    pass
6043
6044
6045class Week(Func):
6046    arg_types = {"this": True, "mode": False}
6047
6048
6049class XMLTable(Func):
6050    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
6051
6052
6053class Year(Func):
6054    pass
6055
6056
6057class Use(Expression):
6058    arg_types = {"this": True, "kind": False}
6059
6060
6061class Merge(Expression):
6062    arg_types = {
6063        "this": True,
6064        "using": True,
6065        "on": True,
6066        "expressions": True,
6067        "with": False,
6068    }
6069
6070
6071class When(Func):
6072    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6073
6074
6075# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
6076# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
6077class NextValueFor(Func):
6078    arg_types = {"this": True, "order": False}
6079
6080
6081# Refers to a trailing semi-colon. This is only used to preserve trailing comments
6082# select 1; -- my comment
6083class Semicolon(Expression):
6084    arg_types = {}
6085
6086
6087def _norm_arg(arg):
6088    return arg.lower() if type(arg) is str else arg
6089
6090
6091ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
6092FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
6093
6094JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
6095
6096PERCENTILES = (PercentileCont, PercentileDisc)
6097
6098
6099# Helpers
6100@t.overload
6101def maybe_parse(
6102    sql_or_expression: ExpOrStr,
6103    *,
6104    into: t.Type[E],
6105    dialect: DialectType = None,
6106    prefix: t.Optional[str] = None,
6107    copy: bool = False,
6108    **opts,
6109) -> E: ...
6110
6111
6112@t.overload
6113def maybe_parse(
6114    sql_or_expression: str | E,
6115    *,
6116    into: t.Optional[IntoType] = None,
6117    dialect: DialectType = None,
6118    prefix: t.Optional[str] = None,
6119    copy: bool = False,
6120    **opts,
6121) -> E: ...
6122
6123
6124def maybe_parse(
6125    sql_or_expression: ExpOrStr,
6126    *,
6127    into: t.Optional[IntoType] = None,
6128    dialect: DialectType = None,
6129    prefix: t.Optional[str] = None,
6130    copy: bool = False,
6131    **opts,
6132) -> Expression:
6133    """Gracefully handle a possible string or expression.
6134
6135    Example:
6136        >>> maybe_parse("1")
6137        Literal(this=1, is_string=False)
6138        >>> maybe_parse(to_identifier("x"))
6139        Identifier(this=x, quoted=False)
6140
6141    Args:
6142        sql_or_expression: the SQL code string or an expression
6143        into: the SQLGlot Expression to parse into
6144        dialect: the dialect used to parse the input expressions (in the case that an
6145            input expression is a SQL string).
6146        prefix: a string to prefix the sql with before it gets parsed
6147            (automatically includes a space)
6148        copy: whether to copy the expression.
6149        **opts: other options to use to parse the input expressions (again, in the case
6150            that an input expression is a SQL string).
6151
6152    Returns:
6153        Expression: the parsed or given expression.
6154    """
6155    if isinstance(sql_or_expression, Expression):
6156        if copy:
6157            return sql_or_expression.copy()
6158        return sql_or_expression
6159
6160    if sql_or_expression is None:
6161        raise ParseError("SQL cannot be None")
6162
6163    import sqlglot
6164
6165    sql = str(sql_or_expression)
6166    if prefix:
6167        sql = f"{prefix} {sql}"
6168
6169    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
6170
6171
6172@t.overload
6173def maybe_copy(instance: None, copy: bool = True) -> None: ...
6174
6175
6176@t.overload
6177def maybe_copy(instance: E, copy: bool = True) -> E: ...
6178
6179
6180def maybe_copy(instance, copy=True):
6181    return instance.copy() if copy and instance else instance
6182
6183
6184def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
6185    """Generate a textual representation of an Expression tree"""
6186    indent = "\n" + ("  " * (level + 1))
6187    delim = f",{indent}"
6188
6189    if isinstance(node, Expression):
6190        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
6191
6192        if (node.type or verbose) and not isinstance(node, DataType):
6193            args["_type"] = node.type
6194        if node.comments or verbose:
6195            args["_comments"] = node.comments
6196
6197        if verbose:
6198            args["_id"] = id(node)
6199
6200        # Inline leaves for a more compact representation
6201        if node.is_leaf():
6202            indent = ""
6203            delim = ", "
6204
6205        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
6206        return f"{node.__class__.__name__}({indent}{items})"
6207
6208    if isinstance(node, list):
6209        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
6210        items = f"{indent}{items}" if items else ""
6211        return f"[{items}]"
6212
6213    # Indent multiline strings to match the current level
6214    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
6215
6216
6217def _is_wrong_expression(expression, into):
6218    return isinstance(expression, Expression) and not isinstance(expression, into)
6219
6220
6221def _apply_builder(
6222    expression,
6223    instance,
6224    arg,
6225    copy=True,
6226    prefix=None,
6227    into=None,
6228    dialect=None,
6229    into_arg="this",
6230    **opts,
6231):
6232    if _is_wrong_expression(expression, into):
6233        expression = into(**{into_arg: expression})
6234    instance = maybe_copy(instance, copy)
6235    expression = maybe_parse(
6236        sql_or_expression=expression,
6237        prefix=prefix,
6238        into=into,
6239        dialect=dialect,
6240        **opts,
6241    )
6242    instance.set(arg, expression)
6243    return instance
6244
6245
6246def _apply_child_list_builder(
6247    *expressions,
6248    instance,
6249    arg,
6250    append=True,
6251    copy=True,
6252    prefix=None,
6253    into=None,
6254    dialect=None,
6255    properties=None,
6256    **opts,
6257):
6258    instance = maybe_copy(instance, copy)
6259    parsed = []
6260    properties = {} if properties is None else properties
6261
6262    for expression in expressions:
6263        if expression is not None:
6264            if _is_wrong_expression(expression, into):
6265                expression = into(expressions=[expression])
6266
6267            expression = maybe_parse(
6268                expression,
6269                into=into,
6270                dialect=dialect,
6271                prefix=prefix,
6272                **opts,
6273            )
6274            for k, v in expression.args.items():
6275                if k == "expressions":
6276                    parsed.extend(v)
6277                else:
6278                    properties[k] = v
6279
6280    existing = instance.args.get(arg)
6281    if append and existing:
6282        parsed = existing.expressions + parsed
6283
6284    child = into(expressions=parsed)
6285    for k, v in properties.items():
6286        child.set(k, v)
6287    instance.set(arg, child)
6288
6289    return instance
6290
6291
6292def _apply_list_builder(
6293    *expressions,
6294    instance,
6295    arg,
6296    append=True,
6297    copy=True,
6298    prefix=None,
6299    into=None,
6300    dialect=None,
6301    **opts,
6302):
6303    inst = maybe_copy(instance, copy)
6304
6305    expressions = [
6306        maybe_parse(
6307            sql_or_expression=expression,
6308            into=into,
6309            prefix=prefix,
6310            dialect=dialect,
6311            **opts,
6312        )
6313        for expression in expressions
6314        if expression is not None
6315    ]
6316
6317    existing_expressions = inst.args.get(arg)
6318    if append and existing_expressions:
6319        expressions = existing_expressions + expressions
6320
6321    inst.set(arg, expressions)
6322    return inst
6323
6324
6325def _apply_conjunction_builder(
6326    *expressions,
6327    instance,
6328    arg,
6329    into=None,
6330    append=True,
6331    copy=True,
6332    dialect=None,
6333    **opts,
6334):
6335    expressions = [exp for exp in expressions if exp is not None and exp != ""]
6336    if not expressions:
6337        return instance
6338
6339    inst = maybe_copy(instance, copy)
6340
6341    existing = inst.args.get(arg)
6342    if append and existing is not None:
6343        expressions = [existing.this if into else existing] + list(expressions)
6344
6345    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
6346
6347    inst.set(arg, into(this=node) if into else node)
6348    return inst
6349
6350
6351def _apply_cte_builder(
6352    instance: E,
6353    alias: ExpOrStr,
6354    as_: ExpOrStr,
6355    recursive: t.Optional[bool] = None,
6356    append: bool = True,
6357    dialect: DialectType = None,
6358    copy: bool = True,
6359    **opts,
6360) -> E:
6361    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
6362    as_expression = maybe_parse(as_, dialect=dialect, **opts)
6363    cte = CTE(this=as_expression, alias=alias_expression)
6364    return _apply_child_list_builder(
6365        cte,
6366        instance=instance,
6367        arg="with",
6368        append=append,
6369        copy=copy,
6370        into=With,
6371        properties={"recursive": recursive or False},
6372    )
6373
6374
6375def _combine(
6376    expressions: t.Sequence[t.Optional[ExpOrStr]],
6377    operator: t.Type[Connector],
6378    dialect: DialectType = None,
6379    copy: bool = True,
6380    **opts,
6381) -> Expression:
6382    conditions = [
6383        condition(expression, dialect=dialect, copy=copy, **opts)
6384        for expression in expressions
6385        if expression is not None
6386    ]
6387
6388    this, *rest = conditions
6389    if rest:
6390        this = _wrap(this, Connector)
6391    for expression in rest:
6392        this = operator(this=this, expression=_wrap(expression, Connector))
6393
6394    return this
6395
6396
6397def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
6398    return Paren(this=expression) if isinstance(expression, kind) else expression
6399
6400
6401def union(
6402    left: ExpOrStr,
6403    right: ExpOrStr,
6404    distinct: bool = True,
6405    dialect: DialectType = None,
6406    copy: bool = True,
6407    **opts,
6408) -> Union:
6409    """
6410    Initializes a syntax tree from one UNION expression.
6411
6412    Example:
6413        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6414        'SELECT * FROM foo UNION SELECT * FROM bla'
6415
6416    Args:
6417        left: the SQL code string corresponding to the left-hand side.
6418            If an `Expression` instance is passed, it will be used as-is.
6419        right: the SQL code string corresponding to the right-hand side.
6420            If an `Expression` instance is passed, it will be used as-is.
6421        distinct: set the DISTINCT flag if and only if this is true.
6422        dialect: the dialect used to parse the input expression.
6423        copy: whether to copy the expression.
6424        opts: other options to use to parse the input expressions.
6425
6426    Returns:
6427        The new Union instance.
6428    """
6429    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6430    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6431
6432    return Union(this=left, expression=right, distinct=distinct)
6433
6434
6435def intersect(
6436    left: ExpOrStr,
6437    right: ExpOrStr,
6438    distinct: bool = True,
6439    dialect: DialectType = None,
6440    copy: bool = True,
6441    **opts,
6442) -> Intersect:
6443    """
6444    Initializes a syntax tree from one INTERSECT expression.
6445
6446    Example:
6447        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6448        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6449
6450    Args:
6451        left: the SQL code string corresponding to the left-hand side.
6452            If an `Expression` instance is passed, it will be used as-is.
6453        right: the SQL code string corresponding to the right-hand side.
6454            If an `Expression` instance is passed, it will be used as-is.
6455        distinct: set the DISTINCT flag if and only if this is true.
6456        dialect: the dialect used to parse the input expression.
6457        copy: whether to copy the expression.
6458        opts: other options to use to parse the input expressions.
6459
6460    Returns:
6461        The new Intersect instance.
6462    """
6463    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6464    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6465
6466    return Intersect(this=left, expression=right, distinct=distinct)
6467
6468
6469def except_(
6470    left: ExpOrStr,
6471    right: ExpOrStr,
6472    distinct: bool = True,
6473    dialect: DialectType = None,
6474    copy: bool = True,
6475    **opts,
6476) -> Except:
6477    """
6478    Initializes a syntax tree from one EXCEPT expression.
6479
6480    Example:
6481        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6482        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6483
6484    Args:
6485        left: the SQL code string corresponding to the left-hand side.
6486            If an `Expression` instance is passed, it will be used as-is.
6487        right: the SQL code string corresponding to the right-hand side.
6488            If an `Expression` instance is passed, it will be used as-is.
6489        distinct: set the DISTINCT flag if and only if this is true.
6490        dialect: the dialect used to parse the input expression.
6491        copy: whether to copy the expression.
6492        opts: other options to use to parse the input expressions.
6493
6494    Returns:
6495        The new Except instance.
6496    """
6497    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6498    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6499
6500    return Except(this=left, expression=right, distinct=distinct)
6501
6502
6503def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6504    """
6505    Initializes a syntax tree from one or multiple SELECT expressions.
6506
6507    Example:
6508        >>> select("col1", "col2").from_("tbl").sql()
6509        'SELECT col1, col2 FROM tbl'
6510
6511    Args:
6512        *expressions: the SQL code string to parse as the expressions of a
6513            SELECT statement. If an Expression instance is passed, this is used as-is.
6514        dialect: the dialect used to parse the input expressions (in the case that an
6515            input expression is a SQL string).
6516        **opts: other options to use to parse the input expressions (again, in the case
6517            that an input expression is a SQL string).
6518
6519    Returns:
6520        Select: the syntax tree for the SELECT statement.
6521    """
6522    return Select().select(*expressions, dialect=dialect, **opts)
6523
6524
6525def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6526    """
6527    Initializes a syntax tree from a FROM expression.
6528
6529    Example:
6530        >>> from_("tbl").select("col1", "col2").sql()
6531        'SELECT col1, col2 FROM tbl'
6532
6533    Args:
6534        *expression: the SQL code string to parse as the FROM expressions of a
6535            SELECT statement. If an Expression instance is passed, this is used as-is.
6536        dialect: the dialect used to parse the input expression (in the case that the
6537            input expression is a SQL string).
6538        **opts: other options to use to parse the input expressions (again, in the case
6539            that the input expression is a SQL string).
6540
6541    Returns:
6542        Select: the syntax tree for the SELECT statement.
6543    """
6544    return Select().from_(expression, dialect=dialect, **opts)
6545
6546
6547def update(
6548    table: str | Table,
6549    properties: dict,
6550    where: t.Optional[ExpOrStr] = None,
6551    from_: t.Optional[ExpOrStr] = None,
6552    dialect: DialectType = None,
6553    **opts,
6554) -> Update:
6555    """
6556    Creates an update statement.
6557
6558    Example:
6559        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6560        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6561
6562    Args:
6563        *properties: dictionary of properties to set which are
6564            auto converted to sql objects eg None -> NULL
6565        where: sql conditional parsed into a WHERE statement
6566        from_: sql statement parsed into a FROM statement
6567        dialect: the dialect used to parse the input expressions.
6568        **opts: other options to use to parse the input expressions.
6569
6570    Returns:
6571        Update: the syntax tree for the UPDATE statement.
6572    """
6573    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6574    update_expr.set(
6575        "expressions",
6576        [
6577            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6578            for k, v in properties.items()
6579        ],
6580    )
6581    if from_:
6582        update_expr.set(
6583            "from",
6584            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6585        )
6586    if isinstance(where, Condition):
6587        where = Where(this=where)
6588    if where:
6589        update_expr.set(
6590            "where",
6591            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6592        )
6593    return update_expr
6594
6595
6596def delete(
6597    table: ExpOrStr,
6598    where: t.Optional[ExpOrStr] = None,
6599    returning: t.Optional[ExpOrStr] = None,
6600    dialect: DialectType = None,
6601    **opts,
6602) -> Delete:
6603    """
6604    Builds a delete statement.
6605
6606    Example:
6607        >>> delete("my_table", where="id > 1").sql()
6608        'DELETE FROM my_table WHERE id > 1'
6609
6610    Args:
6611        where: sql conditional parsed into a WHERE statement
6612        returning: sql conditional parsed into a RETURNING statement
6613        dialect: the dialect used to parse the input expressions.
6614        **opts: other options to use to parse the input expressions.
6615
6616    Returns:
6617        Delete: the syntax tree for the DELETE statement.
6618    """
6619    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6620    if where:
6621        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6622    if returning:
6623        delete_expr = t.cast(
6624            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6625        )
6626    return delete_expr
6627
6628
6629def insert(
6630    expression: ExpOrStr,
6631    into: ExpOrStr,
6632    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6633    overwrite: t.Optional[bool] = None,
6634    returning: t.Optional[ExpOrStr] = None,
6635    dialect: DialectType = None,
6636    copy: bool = True,
6637    **opts,
6638) -> Insert:
6639    """
6640    Builds an INSERT statement.
6641
6642    Example:
6643        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6644        'INSERT INTO tbl VALUES (1, 2, 3)'
6645
6646    Args:
6647        expression: the sql string or expression of the INSERT statement
6648        into: the tbl to insert data to.
6649        columns: optionally the table's column names.
6650        overwrite: whether to INSERT OVERWRITE or not.
6651        returning: sql conditional parsed into a RETURNING statement
6652        dialect: the dialect used to parse the input expressions.
6653        copy: whether to copy the expression.
6654        **opts: other options to use to parse the input expressions.
6655
6656    Returns:
6657        Insert: the syntax tree for the INSERT statement.
6658    """
6659    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6660    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6661
6662    if columns:
6663        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6664
6665    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6666
6667    if returning:
6668        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6669
6670    return insert
6671
6672
6673def condition(
6674    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6675) -> Condition:
6676    """
6677    Initialize a logical condition expression.
6678
6679    Example:
6680        >>> condition("x=1").sql()
6681        'x = 1'
6682
6683        This is helpful for composing larger logical syntax trees:
6684        >>> where = condition("x=1")
6685        >>> where = where.and_("y=1")
6686        >>> Select().from_("tbl").select("*").where(where).sql()
6687        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6688
6689    Args:
6690        *expression: the SQL code string to parse.
6691            If an Expression instance is passed, this is used as-is.
6692        dialect: the dialect used to parse the input expression (in the case that the
6693            input expression is a SQL string).
6694        copy: Whether to copy `expression` (only applies to expressions).
6695        **opts: other options to use to parse the input expressions (again, in the case
6696            that the input expression is a SQL string).
6697
6698    Returns:
6699        The new Condition instance
6700    """
6701    return maybe_parse(
6702        expression,
6703        into=Condition,
6704        dialect=dialect,
6705        copy=copy,
6706        **opts,
6707    )
6708
6709
6710def and_(
6711    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6712) -> Condition:
6713    """
6714    Combine multiple conditions with an AND logical operator.
6715
6716    Example:
6717        >>> and_("x=1", and_("y=1", "z=1")).sql()
6718        'x = 1 AND (y = 1 AND z = 1)'
6719
6720    Args:
6721        *expressions: the SQL code strings to parse.
6722            If an Expression instance is passed, this is used as-is.
6723        dialect: the dialect used to parse the input expression.
6724        copy: whether to copy `expressions` (only applies to Expressions).
6725        **opts: other options to use to parse the input expressions.
6726
6727    Returns:
6728        The new condition
6729    """
6730    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
6731
6732
6733def or_(
6734    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6735) -> Condition:
6736    """
6737    Combine multiple conditions with an OR logical operator.
6738
6739    Example:
6740        >>> or_("x=1", or_("y=1", "z=1")).sql()
6741        'x = 1 OR (y = 1 OR z = 1)'
6742
6743    Args:
6744        *expressions: the SQL code strings to parse.
6745            If an Expression instance is passed, this is used as-is.
6746        dialect: the dialect used to parse the input expression.
6747        copy: whether to copy `expressions` (only applies to Expressions).
6748        **opts: other options to use to parse the input expressions.
6749
6750    Returns:
6751        The new condition
6752    """
6753    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
6754
6755
6756def xor(
6757    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6758) -> Condition:
6759    """
6760    Combine multiple conditions with an XOR logical operator.
6761
6762    Example:
6763        >>> xor("x=1", xor("y=1", "z=1")).sql()
6764        'x = 1 XOR (y = 1 XOR z = 1)'
6765
6766    Args:
6767        *expressions: the SQL code strings to parse.
6768            If an Expression instance is passed, this is used as-is.
6769        dialect: the dialect used to parse the input expression.
6770        copy: whether to copy `expressions` (only applies to Expressions).
6771        **opts: other options to use to parse the input expressions.
6772
6773    Returns:
6774        The new condition
6775    """
6776    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, **opts))
6777
6778
6779def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6780    """
6781    Wrap a condition with a NOT operator.
6782
6783    Example:
6784        >>> not_("this_suit='black'").sql()
6785        "NOT this_suit = 'black'"
6786
6787    Args:
6788        expression: the SQL code string to parse.
6789            If an Expression instance is passed, this is used as-is.
6790        dialect: the dialect used to parse the input expression.
6791        copy: whether to copy the expression or not.
6792        **opts: other options to use to parse the input expressions.
6793
6794    Returns:
6795        The new condition.
6796    """
6797    this = condition(
6798        expression,
6799        dialect=dialect,
6800        copy=copy,
6801        **opts,
6802    )
6803    return Not(this=_wrap(this, Connector))
6804
6805
6806def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6807    """
6808    Wrap an expression in parentheses.
6809
6810    Example:
6811        >>> paren("5 + 3").sql()
6812        '(5 + 3)'
6813
6814    Args:
6815        expression: the SQL code string to parse.
6816            If an Expression instance is passed, this is used as-is.
6817        copy: whether to copy the expression or not.
6818
6819    Returns:
6820        The wrapped expression.
6821    """
6822    return Paren(this=maybe_parse(expression, copy=copy))
6823
6824
6825SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
6826
6827
6828@t.overload
6829def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
6830
6831
6832@t.overload
6833def to_identifier(
6834    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
6835) -> Identifier: ...
6836
6837
6838def to_identifier(name, quoted=None, copy=True):
6839    """Builds an identifier.
6840
6841    Args:
6842        name: The name to turn into an identifier.
6843        quoted: Whether to force quote the identifier.
6844        copy: Whether to copy name if it's an Identifier.
6845
6846    Returns:
6847        The identifier ast node.
6848    """
6849
6850    if name is None:
6851        return None
6852
6853    if isinstance(name, Identifier):
6854        identifier = maybe_copy(name, copy)
6855    elif isinstance(name, str):
6856        identifier = Identifier(
6857            this=name,
6858            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6859        )
6860    else:
6861        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6862    return identifier
6863
6864
6865def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6866    """
6867    Parses a given string into an identifier.
6868
6869    Args:
6870        name: The name to parse into an identifier.
6871        dialect: The dialect to parse against.
6872
6873    Returns:
6874        The identifier ast node.
6875    """
6876    try:
6877        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6878    except ParseError:
6879        expression = to_identifier(name)
6880
6881    return expression
6882
6883
6884INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6885
6886
6887def to_interval(interval: str | Literal) -> Interval:
6888    """Builds an interval expression from a string like '1 day' or '5 months'."""
6889    if isinstance(interval, Literal):
6890        if not interval.is_string:
6891            raise ValueError("Invalid interval string.")
6892
6893        interval = interval.this
6894
6895    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6896
6897    if not interval_parts:
6898        raise ValueError("Invalid interval string.")
6899
6900    return Interval(
6901        this=Literal.string(interval_parts.group(1)),
6902        unit=Var(this=interval_parts.group(2).upper()),
6903    )
6904
6905
6906def to_table(
6907    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6908) -> Table:
6909    """
6910    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6911    If a table is passed in then that table is returned.
6912
6913    Args:
6914        sql_path: a `[catalog].[schema].[table]` string.
6915        dialect: the source dialect according to which the table name will be parsed.
6916        copy: Whether to copy a table if it is passed in.
6917        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6918
6919    Returns:
6920        A table expression.
6921    """
6922    if isinstance(sql_path, Table):
6923        return maybe_copy(sql_path, copy=copy)
6924
6925    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6926
6927    for k, v in kwargs.items():
6928        table.set(k, v)
6929
6930    return table
6931
6932
6933def to_column(
6934    sql_path: str | Column,
6935    quoted: t.Optional[bool] = None,
6936    dialect: DialectType = None,
6937    copy: bool = True,
6938    **kwargs,
6939) -> Column:
6940    """
6941    Create a column from a `[table].[column]` sql path. Table is optional.
6942    If a column is passed in then that column is returned.
6943
6944    Args:
6945        sql_path: a `[table].[column]` string.
6946        quoted: Whether or not to force quote identifiers.
6947        dialect: the source dialect according to which the column name will be parsed.
6948        copy: Whether to copy a column if it is passed in.
6949        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6950
6951    Returns:
6952        A column expression.
6953    """
6954    if isinstance(sql_path, Column):
6955        return maybe_copy(sql_path, copy=copy)
6956
6957    try:
6958        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6959    except ParseError:
6960        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6961
6962    for k, v in kwargs.items():
6963        col.set(k, v)
6964
6965    if quoted:
6966        for i in col.find_all(Identifier):
6967            i.set("quoted", True)
6968
6969    return col
6970
6971
6972def alias_(
6973    expression: ExpOrStr,
6974    alias: t.Optional[str | Identifier],
6975    table: bool | t.Sequence[str | Identifier] = False,
6976    quoted: t.Optional[bool] = None,
6977    dialect: DialectType = None,
6978    copy: bool = True,
6979    **opts,
6980):
6981    """Create an Alias expression.
6982
6983    Example:
6984        >>> alias_('foo', 'bar').sql()
6985        'foo AS bar'
6986
6987        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6988        '(SELECT 1, 2) AS bar(a, b)'
6989
6990    Args:
6991        expression: the SQL code strings to parse.
6992            If an Expression instance is passed, this is used as-is.
6993        alias: the alias name to use. If the name has
6994            special characters it is quoted.
6995        table: Whether to create a table alias, can also be a list of columns.
6996        quoted: whether to quote the alias
6997        dialect: the dialect used to parse the input expression.
6998        copy: Whether to copy the expression.
6999        **opts: other options to use to parse the input expressions.
7000
7001    Returns:
7002        Alias: the aliased expression
7003    """
7004    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7005    alias = to_identifier(alias, quoted=quoted)
7006
7007    if table:
7008        table_alias = TableAlias(this=alias)
7009        exp.set("alias", table_alias)
7010
7011        if not isinstance(table, bool):
7012            for column in table:
7013                table_alias.append("columns", to_identifier(column, quoted=quoted))
7014
7015        return exp
7016
7017    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7018    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7019    # for the complete Window expression.
7020    #
7021    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7022
7023    if "alias" in exp.arg_types and not isinstance(exp, Window):
7024        exp.set("alias", alias)
7025        return exp
7026    return Alias(this=exp, alias=alias)
7027
7028
7029def subquery(
7030    expression: ExpOrStr,
7031    alias: t.Optional[Identifier | str] = None,
7032    dialect: DialectType = None,
7033    **opts,
7034) -> Select:
7035    """
7036    Build a subquery expression that's selected from.
7037
7038    Example:
7039        >>> subquery('select x from tbl', 'bar').select('x').sql()
7040        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7041
7042    Args:
7043        expression: the SQL code strings to parse.
7044            If an Expression instance is passed, this is used as-is.
7045        alias: the alias name to use.
7046        dialect: the dialect used to parse the input expression.
7047        **opts: other options to use to parse the input expressions.
7048
7049    Returns:
7050        A new Select instance with the subquery expression included.
7051    """
7052
7053    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7054    return Select().from_(expression, dialect=dialect, **opts)
7055
7056
7057@t.overload
7058def column(
7059    col: str | Identifier,
7060    table: t.Optional[str | Identifier] = None,
7061    db: t.Optional[str | Identifier] = None,
7062    catalog: t.Optional[str | Identifier] = None,
7063    *,
7064    fields: t.Collection[t.Union[str, Identifier]],
7065    quoted: t.Optional[bool] = None,
7066    copy: bool = True,
7067) -> Dot:
7068    pass
7069
7070
7071@t.overload
7072def column(
7073    col: str | Identifier,
7074    table: t.Optional[str | Identifier] = None,
7075    db: t.Optional[str | Identifier] = None,
7076    catalog: t.Optional[str | Identifier] = None,
7077    *,
7078    fields: Lit[None] = None,
7079    quoted: t.Optional[bool] = None,
7080    copy: bool = True,
7081) -> Column:
7082    pass
7083
7084
7085def column(
7086    col,
7087    table=None,
7088    db=None,
7089    catalog=None,
7090    *,
7091    fields=None,
7092    quoted=None,
7093    copy=True,
7094):
7095    """
7096    Build a Column.
7097
7098    Args:
7099        col: Column name.
7100        table: Table name.
7101        db: Database name.
7102        catalog: Catalog name.
7103        fields: Additional fields using dots.
7104        quoted: Whether to force quotes on the column's identifiers.
7105        copy: Whether to copy identifiers if passed in.
7106
7107    Returns:
7108        The new Column instance.
7109    """
7110    this = Column(
7111        this=to_identifier(col, quoted=quoted, copy=copy),
7112        table=to_identifier(table, quoted=quoted, copy=copy),
7113        db=to_identifier(db, quoted=quoted, copy=copy),
7114        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7115    )
7116
7117    if fields:
7118        this = Dot.build(
7119            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7120        )
7121    return this
7122
7123
7124def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7125    """Cast an expression to a data type.
7126
7127    Example:
7128        >>> cast('x + 1', 'int').sql()
7129        'CAST(x + 1 AS INT)'
7130
7131    Args:
7132        expression: The expression to cast.
7133        to: The datatype to cast to.
7134        copy: Whether to copy the supplied expressions.
7135
7136    Returns:
7137        The new Cast instance.
7138    """
7139    expr = maybe_parse(expression, copy=copy, **opts)
7140    data_type = DataType.build(to, copy=copy, **opts)
7141
7142    if expr.is_type(data_type):
7143        return expr
7144
7145    expr = Cast(this=expr, to=data_type)
7146    expr.type = data_type
7147
7148    return expr
7149
7150
7151def table_(
7152    table: Identifier | str,
7153    db: t.Optional[Identifier | str] = None,
7154    catalog: t.Optional[Identifier | str] = None,
7155    quoted: t.Optional[bool] = None,
7156    alias: t.Optional[Identifier | str] = None,
7157) -> Table:
7158    """Build a Table.
7159
7160    Args:
7161        table: Table name.
7162        db: Database name.
7163        catalog: Catalog name.
7164        quote: Whether to force quotes on the table's identifiers.
7165        alias: Table's alias.
7166
7167    Returns:
7168        The new Table instance.
7169    """
7170    return Table(
7171        this=to_identifier(table, quoted=quoted) if table else None,
7172        db=to_identifier(db, quoted=quoted) if db else None,
7173        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7174        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7175    )
7176
7177
7178def values(
7179    values: t.Iterable[t.Tuple[t.Any, ...]],
7180    alias: t.Optional[str] = None,
7181    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7182) -> Values:
7183    """Build VALUES statement.
7184
7185    Example:
7186        >>> values([(1, '2')]).sql()
7187        "VALUES (1, '2')"
7188
7189    Args:
7190        values: values statements that will be converted to SQL
7191        alias: optional alias
7192        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7193         If either are provided then an alias is also required.
7194
7195    Returns:
7196        Values: the Values expression object
7197    """
7198    if columns and not alias:
7199        raise ValueError("Alias is required when providing columns")
7200
7201    return Values(
7202        expressions=[convert(tup) for tup in values],
7203        alias=(
7204            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7205            if columns
7206            else (TableAlias(this=to_identifier(alias)) if alias else None)
7207        ),
7208    )
7209
7210
7211def var(name: t.Optional[ExpOrStr]) -> Var:
7212    """Build a SQL variable.
7213
7214    Example:
7215        >>> repr(var('x'))
7216        'Var(this=x)'
7217
7218        >>> repr(var(column('x', table='y')))
7219        'Var(this=x)'
7220
7221    Args:
7222        name: The name of the var or an expression who's name will become the var.
7223
7224    Returns:
7225        The new variable node.
7226    """
7227    if not name:
7228        raise ValueError("Cannot convert empty name into var.")
7229
7230    if isinstance(name, Expression):
7231        name = name.name
7232    return Var(this=name)
7233
7234
7235def rename_table(
7236    old_name: str | Table,
7237    new_name: str | Table,
7238    dialect: DialectType = None,
7239) -> AlterTable:
7240    """Build ALTER TABLE... RENAME... expression
7241
7242    Args:
7243        old_name: The old name of the table
7244        new_name: The new name of the table
7245        dialect: The dialect to parse the table.
7246
7247    Returns:
7248        Alter table expression
7249    """
7250    old_table = to_table(old_name, dialect=dialect)
7251    new_table = to_table(new_name, dialect=dialect)
7252    return AlterTable(
7253        this=old_table,
7254        actions=[
7255            RenameTable(this=new_table),
7256        ],
7257    )
7258
7259
7260def rename_column(
7261    table_name: str | Table,
7262    old_column_name: str | Column,
7263    new_column_name: str | Column,
7264    exists: t.Optional[bool] = None,
7265    dialect: DialectType = None,
7266) -> AlterTable:
7267    """Build ALTER TABLE... RENAME COLUMN... expression
7268
7269    Args:
7270        table_name: Name of the table
7271        old_column: The old name of the column
7272        new_column: The new name of the column
7273        exists: Whether to add the `IF EXISTS` clause
7274        dialect: The dialect to parse the table/column.
7275
7276    Returns:
7277        Alter table expression
7278    """
7279    table = to_table(table_name, dialect=dialect)
7280    old_column = to_column(old_column_name, dialect=dialect)
7281    new_column = to_column(new_column_name, dialect=dialect)
7282    return AlterTable(
7283        this=table,
7284        actions=[
7285            RenameColumn(this=old_column, to=new_column, exists=exists),
7286        ],
7287    )
7288
7289
7290def convert(value: t.Any, copy: bool = False) -> Expression:
7291    """Convert a python value into an expression object.
7292
7293    Raises an error if a conversion is not possible.
7294
7295    Args:
7296        value: A python object.
7297        copy: Whether to copy `value` (only applies to Expressions and collections).
7298
7299    Returns:
7300        The equivalent expression object.
7301    """
7302    if isinstance(value, Expression):
7303        return maybe_copy(value, copy)
7304    if isinstance(value, str):
7305        return Literal.string(value)
7306    if isinstance(value, bool):
7307        return Boolean(this=value)
7308    if value is None or (isinstance(value, float) and math.isnan(value)):
7309        return null()
7310    if isinstance(value, numbers.Number):
7311        return Literal.number(value)
7312    if isinstance(value, bytes):
7313        return HexString(this=value.hex())
7314    if isinstance(value, datetime.datetime):
7315        datetime_literal = Literal.string(
7316            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7317                sep=" "
7318            )
7319        )
7320        return TimeStrToTime(this=datetime_literal)
7321    if isinstance(value, datetime.date):
7322        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7323        return DateStrToDate(this=date_literal)
7324    if isinstance(value, tuple):
7325        if hasattr(value, "_fields"):
7326            return Struct(
7327                expressions=[
7328                    PropertyEQ(
7329                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7330                    )
7331                    for k in value._fields
7332                ]
7333            )
7334        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7335    if isinstance(value, list):
7336        return Array(expressions=[convert(v, copy=copy) for v in value])
7337    if isinstance(value, dict):
7338        return Map(
7339            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7340            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7341        )
7342    if hasattr(value, "__dict__"):
7343        return Struct(
7344            expressions=[
7345                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7346                for k, v in value.__dict__.items()
7347            ]
7348        )
7349    raise ValueError(f"Cannot convert {value}")
7350
7351
7352def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7353    """
7354    Replace children of an expression with the result of a lambda fun(child) -> exp.
7355    """
7356    for k, v in tuple(expression.args.items()):
7357        is_list_arg = type(v) is list
7358
7359        child_nodes = v if is_list_arg else [v]
7360        new_child_nodes = []
7361
7362        for cn in child_nodes:
7363            if isinstance(cn, Expression):
7364                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7365                    new_child_nodes.append(child_node)
7366            else:
7367                new_child_nodes.append(cn)
7368
7369        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
7370
7371
7372def replace_tree(
7373    expression: Expression,
7374    fun: t.Callable,
7375    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7376) -> Expression:
7377    """
7378    Replace an entire tree with the result of function calls on each node.
7379
7380    This will be traversed in reverse dfs, so leaves first.
7381    If new nodes are created as a result of function calls, they will also be traversed.
7382    """
7383    stack = list(expression.dfs(prune=prune))
7384
7385    while stack:
7386        node = stack.pop()
7387        new_node = fun(node)
7388
7389        if new_node is not node:
7390            node.replace(new_node)
7391
7392            if isinstance(new_node, Expression):
7393                stack.append(new_node)
7394
7395    return new_node
7396
7397
7398def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7399    """
7400    Return all table names referenced through columns in an expression.
7401
7402    Example:
7403        >>> import sqlglot
7404        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7405        ['a', 'c']
7406
7407    Args:
7408        expression: expression to find table names.
7409        exclude: a table name to exclude
7410
7411    Returns:
7412        A list of unique names.
7413    """
7414    return {
7415        table
7416        for table in (column.table for column in expression.find_all(Column))
7417        if table and table != exclude
7418    }
7419
7420
7421def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7422    """Get the full name of a table as a string.
7423
7424    Args:
7425        table: Table expression node or string.
7426        dialect: The dialect to generate the table name for.
7427        identify: Determines when an identifier should be quoted. Possible values are:
7428            False (default): Never quote, except in cases where it's mandatory by the dialect.
7429            True: Always quote.
7430
7431    Examples:
7432        >>> from sqlglot import exp, parse_one
7433        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7434        'a.b.c'
7435
7436    Returns:
7437        The table name.
7438    """
7439
7440    table = maybe_parse(table, into=Table, dialect=dialect)
7441
7442    if not table:
7443        raise ValueError(f"Cannot parse {table}")
7444
7445    return ".".join(
7446        (
7447            part.sql(dialect=dialect, identify=True, copy=False)
7448            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7449            else part.name
7450        )
7451        for part in table.parts
7452    )
7453
7454
7455def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7456    """Returns a case normalized table name without quotes.
7457
7458    Args:
7459        table: the table to normalize
7460        dialect: the dialect to use for normalization rules
7461        copy: whether to copy the expression.
7462
7463    Examples:
7464        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7465        'A-B.c'
7466    """
7467    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7468
7469    return ".".join(
7470        p.name
7471        for p in normalize_identifiers(
7472            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7473        ).parts
7474    )
7475
7476
7477def replace_tables(
7478    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7479) -> E:
7480    """Replace all tables in expression according to the mapping.
7481
7482    Args:
7483        expression: expression node to be transformed and replaced.
7484        mapping: mapping of table names.
7485        dialect: the dialect of the mapping table
7486        copy: whether to copy the expression.
7487
7488    Examples:
7489        >>> from sqlglot import exp, parse_one
7490        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7491        'SELECT * FROM c /* a.b */'
7492
7493    Returns:
7494        The mapped expression.
7495    """
7496
7497    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7498
7499    def _replace_tables(node: Expression) -> Expression:
7500        if isinstance(node, Table):
7501            original = normalize_table_name(node, dialect=dialect)
7502            new_name = mapping.get(original)
7503
7504            if new_name:
7505                table = to_table(
7506                    new_name,
7507                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7508                    dialect=dialect,
7509                )
7510                table.add_comments([original])
7511                return table
7512        return node
7513
7514    return expression.transform(_replace_tables, copy=copy)  # type: ignore
7515
7516
7517def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7518    """Replace placeholders in an expression.
7519
7520    Args:
7521        expression: expression node to be transformed and replaced.
7522        args: positional names that will substitute unnamed placeholders in the given order.
7523        kwargs: keyword arguments that will substitute named placeholders.
7524
7525    Examples:
7526        >>> from sqlglot import exp, parse_one
7527        >>> replace_placeholders(
7528        ...     parse_one("select * from :tbl where ? = ?"),
7529        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7530        ... ).sql()
7531        "SELECT * FROM foo WHERE str_col = 'b'"
7532
7533    Returns:
7534        The mapped expression.
7535    """
7536
7537    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7538        if isinstance(node, Placeholder):
7539            if node.this:
7540                new_name = kwargs.get(node.this)
7541                if new_name is not None:
7542                    return convert(new_name)
7543            else:
7544                try:
7545                    return convert(next(args))
7546                except StopIteration:
7547                    pass
7548        return node
7549
7550    return expression.transform(_replace_placeholders, iter(args), **kwargs)
7551
7552
7553def expand(
7554    expression: Expression,
7555    sources: t.Dict[str, Query],
7556    dialect: DialectType = None,
7557    copy: bool = True,
7558) -> Expression:
7559    """Transforms an expression by expanding all referenced sources into subqueries.
7560
7561    Examples:
7562        >>> from sqlglot import parse_one
7563        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7564        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7565
7566        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7567        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7568
7569    Args:
7570        expression: The expression to expand.
7571        sources: A dictionary of name to Queries.
7572        dialect: The dialect of the sources dict.
7573        copy: Whether to copy the expression during transformation. Defaults to True.
7574
7575    Returns:
7576        The transformed expression.
7577    """
7578    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7579
7580    def _expand(node: Expression):
7581        if isinstance(node, Table):
7582            name = normalize_table_name(node, dialect=dialect)
7583            source = sources.get(name)
7584            if source:
7585                subquery = source.subquery(node.alias or name)
7586                subquery.comments = [f"source: {name}"]
7587                return subquery.transform(_expand, copy=False)
7588        return node
7589
7590    return expression.transform(_expand, copy=copy)
7591
7592
7593def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7594    """
7595    Returns a Func expression.
7596
7597    Examples:
7598        >>> func("abs", 5).sql()
7599        'ABS(5)'
7600
7601        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7602        'CAST(5 AS DOUBLE)'
7603
7604    Args:
7605        name: the name of the function to build.
7606        args: the args used to instantiate the function of interest.
7607        copy: whether to copy the argument expressions.
7608        dialect: the source dialect.
7609        kwargs: the kwargs used to instantiate the function of interest.
7610
7611    Note:
7612        The arguments `args` and `kwargs` are mutually exclusive.
7613
7614    Returns:
7615        An instance of the function of interest, or an anonymous function, if `name` doesn't
7616        correspond to an existing `sqlglot.expressions.Func` class.
7617    """
7618    if args and kwargs:
7619        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7620
7621    from sqlglot.dialects.dialect import Dialect
7622
7623    dialect = Dialect.get_or_raise(dialect)
7624
7625    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7626    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7627
7628    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7629    if constructor:
7630        if converted:
7631            if "dialect" in constructor.__code__.co_varnames:
7632                function = constructor(converted, dialect=dialect)
7633            else:
7634                function = constructor(converted)
7635        elif constructor.__name__ == "from_arg_list":
7636            function = constructor.__self__(**kwargs)  # type: ignore
7637        else:
7638            constructor = FUNCTION_BY_NAME.get(name.upper())
7639            if constructor:
7640                function = constructor(**kwargs)
7641            else:
7642                raise ValueError(
7643                    f"Unable to convert '{name}' into a Func. Either manually construct "
7644                    "the Func expression of interest or parse the function call."
7645                )
7646    else:
7647        kwargs = kwargs or {"expressions": converted}
7648        function = Anonymous(this=name, **kwargs)
7649
7650    for error_message in function.error_messages(converted):
7651        raise ValueError(error_message)
7652
7653    return function
7654
7655
7656def case(
7657    expression: t.Optional[ExpOrStr] = None,
7658    **opts,
7659) -> Case:
7660    """
7661    Initialize a CASE statement.
7662
7663    Example:
7664        case().when("a = 1", "foo").else_("bar")
7665
7666    Args:
7667        expression: Optionally, the input expression (not all dialects support this)
7668        **opts: Extra keyword arguments for parsing `expression`
7669    """
7670    if expression is not None:
7671        this = maybe_parse(expression, **opts)
7672    else:
7673        this = None
7674    return Case(this=this, ifs=[])
7675
7676
7677def array(
7678    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7679) -> Array:
7680    """
7681    Returns an array.
7682
7683    Examples:
7684        >>> array(1, 'x').sql()
7685        'ARRAY(1, x)'
7686
7687    Args:
7688        expressions: the expressions to add to the array.
7689        copy: whether to copy the argument expressions.
7690        dialect: the source dialect.
7691        kwargs: the kwargs used to instantiate the function of interest.
7692
7693    Returns:
7694        An array expression.
7695    """
7696    return Array(
7697        expressions=[
7698            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7699            for expression in expressions
7700        ]
7701    )
7702
7703
7704def tuple_(
7705    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7706) -> Tuple:
7707    """
7708    Returns an tuple.
7709
7710    Examples:
7711        >>> tuple_(1, 'x').sql()
7712        '(1, x)'
7713
7714    Args:
7715        expressions: the expressions to add to the tuple.
7716        copy: whether to copy the argument expressions.
7717        dialect: the source dialect.
7718        kwargs: the kwargs used to instantiate the function of interest.
7719
7720    Returns:
7721        A tuple expression.
7722    """
7723    return Tuple(
7724        expressions=[
7725            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7726            for expression in expressions
7727        ]
7728    )
7729
7730
7731def true() -> Boolean:
7732    """
7733    Returns a true Boolean expression.
7734    """
7735    return Boolean(this=True)
7736
7737
7738def false() -> Boolean:
7739    """
7740    Returns a false Boolean expression.
7741    """
7742    return Boolean(this=False)
7743
7744
7745def null() -> Null:
7746    """
7747    Returns a Null expression.
7748    """
7749    return Null()
7750
7751
7752NONNULL_CONSTANTS = (
7753    Literal,
7754    Boolean,
7755)
7756
7757CONSTANTS = (
7758    Literal,
7759    Boolean,
7760    Null,
7761)
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    }
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
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}
name: str
3049    @property
3050    def name(self) -> str:
3051        if isinstance(self.this, Func):
3052            return ""
3053        return self.this.name
db: str
3055    @property
3056    def db(self) -> str:
3057        return self.text("db")
catalog: str
3059    @property
3060    def catalog(self) -> str:
3061        return self.text("catalog")
selects: List[Expression]
3063    @property
3064    def selects(self) -> t.List[Expression]:
3065        return []
named_selects: List[str]
3067    @property
3068    def named_selects(self) -> t.List[str]:
3069        return []
parts: List[Expression]
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

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
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
key = 'table'
class SetOperation(Query):
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
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:
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

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]
3120    @property
3121    def named_selects(self) -> t.List[str]:
3122        return self.this.unnest().named_selects

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

left: Expression
3132    @property
3133    def left(self) -> Expression:
3134        return self.this
right: Expression
3136    @property
3137    def right(self) -> Expression:
3138        return self.expression
key = 'setoperation'
class Union(SetOperation):
3141class Union(SetOperation):
3142    pass
key = 'union'
class Except(SetOperation):
3145class Except(SetOperation):
3146    pass
key = 'except'
class Intersect(SetOperation):
3149class Intersect(SetOperation):
3150    pass
key = 'intersect'
class Update(Expression):
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    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
3166class Values(UDTF):
3167    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3170class Var(Expression):
3171    pass
key = 'var'
class Version(Expression):
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}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3188class Schema(Expression):
3189    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3194class Lock(Expression):
3195    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
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
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:
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        )

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

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

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

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

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

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

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

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

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:
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        )
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:
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        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
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

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

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

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

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]
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]

Returns the output names of the query's projections.

is_star: bool
3752    @property
3753    def is_star(self) -> bool:
3754        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

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

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
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
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):
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

Returns the first non subquery.

def unwrap(self) -> Subquery:
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
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:
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

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
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")

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
3808    @property
3809    def is_star(self) -> bool:
3810        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3812    @property
3813    def output_name(self) -> str:
3814        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):
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    }
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):
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    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
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"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3857    @property
3858    def unpivot(self) -> bool:
3859        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
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    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3874class WindowSpec(Expression):
3875    arg_types = {
3876        "kind": False,
3877        "start": False,
3878        "start_side": False,
3879        "end": False,
3880        "end_side": False,
3881    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3884class PreWhere(Expression):
3885    pass
key = 'prewhere'
class Where(Expression):
3888class Where(Expression):
3889    pass
key = 'where'
class Star(Expression):
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
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3895    @property
3896    def name(self) -> str:
3897        return "*"
output_name: str
3899    @property
3900    def output_name(self) -> str:
3901        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):
3904class Parameter(Condition):
3905    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3908class SessionParameter(Condition):
3909    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3912class Placeholder(Condition):
3913    arg_types = {"this": False, "kind": False}
3914
3915    @property
3916    def name(self) -> str:
3917        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3915    @property
3916    def name(self) -> str:
3917        return self.this or "?"
key = 'placeholder'
class Null(Condition):
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
arg_types: Dict[str, Any] = {}
name: str
3923    @property
3924    def name(self) -> str:
3925        return "NULL"
def to_py(self) -> Literal[None]:
3927    def to_py(self) -> Lit[None]:
3928        return None

Returns a Python object equivalent of the SQL node.

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

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
3936class DataTypeParam(Expression):
3937    arg_types = {"this": True, "expression": False}
3938
3939    @property
3940    def name(self) -> str:
3941        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3939    @property
3940    def name(self) -> str:
3941        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
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
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT: 'UINT'>}
INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.UINT: 'UINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>}
NUMERIC_TYPES = {<Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT256: 'UINT256'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.BIGINT: 'BIGINT'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.BIT: 'BIT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.INT256: 'INT256'>, <Type.UINT128: 'UINT128'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.INT128: 'INT128'>, <Type.FLOAT: 'FLOAT'>, <Type.UINT: 'UINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIME: 'TIME'>, <Type.DATETIME: 'DATETIME'>}
@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:
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})

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

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):
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()

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):
4222class PseudoType(DataType):
4223    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4227class ObjectIdentifier(DataType):
4228    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4232class SubqueryPredicate(Predicate):
4233    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4236class All(SubqueryPredicate):
4237    pass
key = 'all'
class Any(SubqueryPredicate):
4240class Any(SubqueryPredicate):
4241    pass
key = 'any'
class Exists(SubqueryPredicate):
4244class Exists(SubqueryPredicate):
4245    pass
key = 'exists'
class Command(Expression):
4250class Command(Expression):
4251    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4254class Transaction(Expression):
4255    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4258class Commit(Expression):
4259    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4262class Rollback(Expression):
4263    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
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    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4277class AddConstraint(Expression):
4278    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4281class DropPartition(Expression):
4282    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4286class ReplacePartition(Expression):
4287    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
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
arg_types = {'this': True, 'expression': True}
left: Expression
4294    @property
4295    def left(self) -> Expression:
4296        return self.this
right: Expression
4298    @property
4299    def right(self) -> Expression:
4300        return self.expression
key = 'binary'
class Add(Binary):
4303class Add(Binary):
4304    pass
key = 'add'
class Connector(Binary):
4307class Connector(Binary):
4308    pass
key = 'connector'
class And(Connector):
4311class And(Connector):
4312    pass
key = 'and'
class Or(Connector):
4315class Or(Connector):
4316    pass
key = 'or'
class BitwiseAnd(Binary):
4319class BitwiseAnd(Binary):
4320    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4323class BitwiseLeftShift(Binary):
4324    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4327class BitwiseOr(Binary):
4328    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4331class BitwiseRightShift(Binary):
4332    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4335class BitwiseXor(Binary):
4336    pass
key = 'bitwisexor'
class Div(Binary):
4339class Div(Binary):
4340    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):
4343class Overlaps(Binary):
4344    pass
key = 'overlaps'
class Dot(Binary):
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
is_star: bool
4348    @property
4349    def is_star(self) -> bool:
4350        return self.expression.is_star

Checks whether an expression is a star.

name: str
4352    @property
4353    def name(self) -> str:
4354        return self.expression.name
output_name: str
4356    @property
4357    def output_name(self) -> str:
4358        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:
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))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
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

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

key = 'dot'
class DPipe(Binary):
4385class DPipe(Binary):
4386    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4389class EQ(Binary, Predicate):
4390    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4393class NullSafeEQ(Binary, Predicate):
4394    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4397class NullSafeNEQ(Binary, Predicate):
4398    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4402class PropertyEQ(Binary):
4403    pass
key = 'propertyeq'
class Distance(Binary):
4406class Distance(Binary):
4407    pass
key = 'distance'
class Escape(Binary):
4410class Escape(Binary):
4411    pass
key = 'escape'
class Glob(Binary, Predicate):
4414class Glob(Binary, Predicate):
4415    pass
key = 'glob'
class GT(Binary, Predicate):
4418class GT(Binary, Predicate):
4419    pass
key = 'gt'
class GTE(Binary, Predicate):
4422class GTE(Binary, Predicate):
4423    pass
key = 'gte'
class ILike(Binary, Predicate):
4426class ILike(Binary, Predicate):
4427    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4430class ILikeAny(Binary, Predicate):
4431    pass
key = 'ilikeany'
class IntDiv(Binary):
4434class IntDiv(Binary):
4435    pass
key = 'intdiv'
class Is(Binary, Predicate):
4438class Is(Binary, Predicate):
4439    pass
key = 'is'
class Kwarg(Binary):
4442class Kwarg(Binary):
4443    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4446class Like(Binary, Predicate):
4447    pass
key = 'like'
class LikeAny(Binary, Predicate):
4450class LikeAny(Binary, Predicate):
4451    pass
key = 'likeany'
class LT(Binary, Predicate):
4454class LT(Binary, Predicate):
4455    pass
key = 'lt'
class LTE(Binary, Predicate):
4458class LTE(Binary, Predicate):
4459    pass
key = 'lte'
class Mod(Binary):
4462class Mod(Binary):
4463    pass
key = 'mod'
class Mul(Binary):
4466class Mul(Binary):
4467    pass
key = 'mul'
class NEQ(Binary, Predicate):
4470class NEQ(Binary, Predicate):
4471    pass
key = 'neq'
class Operator(Binary):
4475class Operator(Binary):
4476    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4479class SimilarTo(Binary, Predicate):
4480    pass
key = 'similarto'
class Slice(Binary):
4483class Slice(Binary):
4484    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4487class Sub(Binary):
4488    pass
key = 'sub'
class Unary(Condition):
4493class Unary(Condition):
4494    pass
key = 'unary'
class BitwiseNot(Unary):
4497class BitwiseNot(Unary):
4498    pass
key = 'bitwisenot'
class Not(Unary):
4501class Not(Unary):
4502    pass
key = 'not'
class Paren(Unary):
4505class Paren(Unary):
4506    @property
4507    def output_name(self) -> str:
4508        return self.this.name
output_name: str
4506    @property
4507    def output_name(self) -> str:
4508        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):
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()
def to_py(self) -> int | decimal.Decimal:
4512    def to_py(self) -> int | Decimal:
4513        if self.is_number:
4514            return self.this.to_py() * -1
4515        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4518class Alias(Expression):
4519    arg_types = {"this": True, "alias": False}
4520
4521    @property
4522    def output_name(self) -> str:
4523        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4521    @property
4522    def output_name(self) -> str:
4523        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):
4528class PivotAlias(Alias):
4529    pass
key = 'pivotalias'
class Aliases(Expression):
4532class Aliases(Expression):
4533    arg_types = {"this": True, "expressions": True}
4534
4535    @property
4536    def aliases(self):
4537        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4535    @property
4536    def aliases(self):
4537        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4541class AtIndex(Expression):
4542    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4545class AtTimeZone(Expression):
4546    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4549class FromTimeZone(Expression):
4550    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4553class Between(Predicate):
4554    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
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
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
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

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):
4575class Distinct(Expression):
4576    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
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    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4591class ForIn(Expression):
4592    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
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")

Automatically converts unit arg into a var.

TimeUnit(**args)
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)
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]
4626    @property
4627    def unit(self) -> t.Optional[Var | IntervalSpan]:
4628        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
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        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4634    def interval(self):
4635        return Interval(
4636            this=self.expression.copy(),
4637            unit=self.unit.copy(),
4638        )
key = 'intervalop'
class IntervalSpan(DataType):
4644class IntervalSpan(DataType):
4645    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4648class Interval(TimeUnit):
4649    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4652class IgnoreNulls(Expression):
4653    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4656class RespectNulls(Expression):
4657    pass
key = 'respectnulls'
class HavingMax(Expression):
4661class HavingMax(Expression):
4662    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
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()}

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):
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)
@classmethod
def sql_names(cls):
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
@classmethod
def sql_name(cls):
4706    @classmethod
4707    def sql_name(cls):
4708        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4710    @classmethod
4711    def default_parser_mappings(cls):
4712        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4715class AggFunc(Func):
4716    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4719class ParameterizedAgg(AggFunc):
4720    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4723class Abs(Func):
4724    pass
key = 'abs'
class ArgMax(AggFunc):
4727class ArgMax(AggFunc):
4728    arg_types = {"this": True, "expression": True, "count": False}
4729    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4732class ArgMin(AggFunc):
4733    arg_types = {"this": True, "expression": True, "count": False}
4734    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4737class ApproxTopK(AggFunc):
4738    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4741class Flatten(Func):
4742    pass
key = 'flatten'
class Transform(Func):
4746class Transform(Func):
4747    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
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
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
4754    @property
4755    def name(self) -> str:
4756        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4759class AnonymousAggFunc(AggFunc):
4760    arg_types = {"this": True, "expressions": False}
4761    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4765class CombinedAggFunc(AnonymousAggFunc):
4766    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4769class CombinedParameterizedAgg(ParameterizedAgg):
4770    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):
4775class Hll(AggFunc):
4776    arg_types = {"this": True, "expressions": False}
4777    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4780class ApproxDistinct(AggFunc):
4781    arg_types = {"this": True, "accuracy": False}
4782    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4785class Array(Func):
4786    arg_types = {"expressions": False}
4787    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4791class ToArray(Func):
4792    pass
key = 'toarray'
class List(Func):
4796class List(Func):
4797    arg_types = {"expressions": False}
4798    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class ToChar(Func):
4803class ToChar(Func):
4804    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4809class ToNumber(Func):
4810    arg_types = {
4811        "this": True,
4812        "format": False,
4813        "nlsparam": False,
4814        "precision": False,
4815        "scale": False,
4816    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4820class Convert(Func):
4821    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4824class GenerateSeries(Func):
4825    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):
4828class ArrayAgg(AggFunc):
4829    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4832class ArrayUniqueAgg(AggFunc):
4833    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4836class ArrayAll(Func):
4837    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4841class ArrayAny(Func):
4842    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4845class ArrayConcat(Func):
4846    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4847    arg_types = {"this": True, "expressions": False}
4848    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4851class ArrayConstructCompact(Func):
4852    arg_types = {"expressions": True}
4853    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4856class ArrayContains(Binary, Func):
4857    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4860class ArrayContainsAll(Binary, Func):
4861    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4864class ArrayFilter(Func):
4865    arg_types = {"this": True, "expression": True}
4866    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4869class ArrayToString(Func):
4870    arg_types = {"this": True, "expression": True, "null": False}
4871    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4874class StringToArray(Func):
4875    arg_types = {"this": True, "expression": True, "null": False}
4876    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4879class ArrayOverlaps(Binary, Func):
4880    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4883class ArraySize(Func):
4884    arg_types = {"this": True, "expression": False}
4885    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4888class ArraySort(Func):
4889    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4892class ArraySum(Func):
4893    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4896class ArrayUnionAgg(AggFunc):
4897    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4900class Avg(AggFunc):
4901    pass
key = 'avg'
class AnyValue(AggFunc):
4904class AnyValue(AggFunc):
4905    pass
key = 'anyvalue'
class Lag(AggFunc):
4908class Lag(AggFunc):
4909    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4912class Lead(AggFunc):
4913    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4918class First(AggFunc):
4919    pass
key = 'first'
class Last(AggFunc):
4922class Last(AggFunc):
4923    pass
key = 'last'
class FirstValue(AggFunc):
4926class FirstValue(AggFunc):
4927    pass
key = 'firstvalue'
class LastValue(AggFunc):
4930class LastValue(AggFunc):
4931    pass
key = 'lastvalue'
class NthValue(AggFunc):
4934class NthValue(AggFunc):
4935    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4938class Case(Func):
4939    arg_types = {"this": False, "ifs": True, "default": False}
4940
4941    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4942        instance = maybe_copy(self, copy)
4943        instance.append(
4944            "ifs",
4945            If(
4946                this=maybe_parse(condition, copy=copy, **opts),
4947                true=maybe_parse(then, copy=copy, **opts),
4948            ),
4949        )
4950        return instance
4951
4952    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4953        instance = maybe_copy(self, copy)
4954        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4955        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:
4941    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4942        instance = maybe_copy(self, copy)
4943        instance.append(
4944            "ifs",
4945            If(
4946                this=maybe_parse(condition, copy=copy, **opts),
4947                true=maybe_parse(then, copy=copy, **opts),
4948            ),
4949        )
4950        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4952    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4953        instance = maybe_copy(self, copy)
4954        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4955        return instance
key = 'case'
class Cast(Func):
4958class Cast(Func):
4959    arg_types = {
4960        "this": True,
4961        "to": True,
4962        "format": False,
4963        "safe": False,
4964        "action": False,
4965    }
4966
4967    @property
4968    def name(self) -> str:
4969        return self.this.name
4970
4971    @property
4972    def to(self) -> DataType:
4973        return self.args["to"]
4974
4975    @property
4976    def output_name(self) -> str:
4977        return self.name
4978
4979    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4980        """
4981        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4982        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4983        array<int> != array<float>.
4984
4985        Args:
4986            dtypes: the data types to compare this Cast's DataType to.
4987
4988        Returns:
4989            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4990        """
4991        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4967    @property
4968    def name(self) -> str:
4969        return self.this.name
to: DataType
4971    @property
4972    def to(self) -> DataType:
4973        return self.args["to"]
output_name: str
4975    @property
4976    def output_name(self) -> str:
4977        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:
4979    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4980        """
4981        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4982        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4983        array<int> != array<float>.
4984
4985        Args:
4986            dtypes: the data types to compare this Cast's DataType to.
4987
4988        Returns:
4989            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4990        """
4991        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):
4994class TryCast(Cast):
4995    pass
key = 'trycast'
class Try(Func):
4998class Try(Func):
4999    pass
key = 'try'
class CastToStrType(Func):
5002class CastToStrType(Func):
5003    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5006class Collate(Binary, Func):
5007    pass
key = 'collate'
class Ceil(Func):
5010class Ceil(Func):
5011    arg_types = {"this": True, "decimals": False}
5012    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5015class Coalesce(Func):
5016    arg_types = {"this": True, "expressions": False}
5017    is_var_len_args = True
5018    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5021class Chr(Func):
5022    arg_types = {"this": True, "charset": False, "expressions": False}
5023    is_var_len_args = True
5024    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5027class Concat(Func):
5028    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5029    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5032class ConcatWs(Concat):
5033    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5037class ConnectByRoot(Func):
5038    pass
key = 'connectbyroot'
class Count(AggFunc):
5041class Count(AggFunc):
5042    arg_types = {"this": False, "expressions": False}
5043    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5046class CountIf(AggFunc):
5047    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5051class Cbrt(Func):
5052    pass
key = 'cbrt'
class CurrentDate(Func):
5055class CurrentDate(Func):
5056    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5059class CurrentDatetime(Func):
5060    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5063class CurrentTime(Func):
5064    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5067class CurrentTimestamp(Func):
5068    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5071class CurrentUser(Func):
5072    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5075class DateAdd(Func, IntervalOp):
5076    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5079class DateSub(Func, IntervalOp):
5080    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5083class DateDiff(Func, TimeUnit):
5084    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5085    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5088class DateTrunc(Func):
5089    arg_types = {"unit": True, "this": True, "zone": False}
5090
5091    def __init__(self, **args):
5092        unit = args.get("unit")
5093        if isinstance(unit, TimeUnit.VAR_LIKE):
5094            args["unit"] = Literal.string(
5095                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5096            )
5097        elif isinstance(unit, Week):
5098            unit.set("this", Literal.string(unit.this.name.upper()))
5099
5100        super().__init__(**args)
5101
5102    @property
5103    def unit(self) -> Expression:
5104        return self.args["unit"]
DateTrunc(**args)
5091    def __init__(self, **args):
5092        unit = args.get("unit")
5093        if isinstance(unit, TimeUnit.VAR_LIKE):
5094            args["unit"] = Literal.string(
5095                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5096            )
5097        elif isinstance(unit, Week):
5098            unit.set("this", Literal.string(unit.this.name.upper()))
5099
5100        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5102    @property
5103    def unit(self) -> Expression:
5104        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5109class Datetime(Func):
5110    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5113class DatetimeAdd(Func, IntervalOp):
5114    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5117class DatetimeSub(Func, IntervalOp):
5118    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5121class DatetimeDiff(Func, TimeUnit):
5122    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5125class DatetimeTrunc(Func, TimeUnit):
5126    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5129class DayOfWeek(Func):
5130    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5133class DayOfMonth(Func):
5134    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5137class DayOfYear(Func):
5138    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5141class ToDays(Func):
5142    pass
key = 'todays'
class WeekOfYear(Func):
5145class WeekOfYear(Func):
5146    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5149class MonthsBetween(Func):
5150    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5153class LastDay(Func, TimeUnit):
5154    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5155    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5158class Extract(Func):
5159    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5162class Timestamp(Func):
5163    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5166class TimestampAdd(Func, TimeUnit):
5167    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5170class TimestampSub(Func, TimeUnit):
5171    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5174class TimestampDiff(Func, TimeUnit):
5175    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5176    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5179class TimestampTrunc(Func, TimeUnit):
5180    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5183class TimeAdd(Func, TimeUnit):
5184    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5187class TimeSub(Func, TimeUnit):
5188    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5191class TimeDiff(Func, TimeUnit):
5192    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5195class TimeTrunc(Func, TimeUnit):
5196    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5199class DateFromParts(Func):
5200    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5201    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5204class TimeFromParts(Func):
5205    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5206    arg_types = {
5207        "hour": True,
5208        "min": True,
5209        "sec": True,
5210        "nano": False,
5211        "fractions": False,
5212        "precision": False,
5213    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5216class DateStrToDate(Func):
5217    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5220class DateToDateStr(Func):
5221    pass
key = 'datetodatestr'
class DateToDi(Func):
5224class DateToDi(Func):
5225    pass
key = 'datetodi'
class Date(Func):
5229class Date(Func):
5230    arg_types = {"this": False, "zone": False, "expressions": False}
5231    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5234class Day(Func):
5235    pass
key = 'day'
class Decode(Func):
5238class Decode(Func):
5239    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5242class DiToDate(Func):
5243    pass
key = 'ditodate'
class Encode(Func):
5246class Encode(Func):
5247    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5250class Exp(Func):
5251    pass
key = 'exp'
class Explode(Func):
5255class Explode(Func):
5256    arg_types = {"this": True, "expressions": False}
5257    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5260class ExplodeOuter(Explode):
5261    pass
key = 'explodeouter'
class Posexplode(Explode):
5264class Posexplode(Explode):
5265    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5268class PosexplodeOuter(Posexplode, ExplodeOuter):
5269    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5272class Unnest(Func, UDTF):
5273    arg_types = {
5274        "expressions": True,
5275        "alias": False,
5276        "offset": False,
5277    }
5278
5279    @property
5280    def selects(self) -> t.List[Expression]:
5281        columns = super().selects
5282        offset = self.args.get("offset")
5283        if offset:
5284            columns = columns + [to_identifier("offset") if offset is True else offset]
5285        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5279    @property
5280    def selects(self) -> t.List[Expression]:
5281        columns = super().selects
5282        offset = self.args.get("offset")
5283        if offset:
5284            columns = columns + [to_identifier("offset") if offset is True else offset]
5285        return columns
key = 'unnest'
class Floor(Func):
5288class Floor(Func):
5289    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5292class FromBase64(Func):
5293    pass
key = 'frombase64'
class ToBase64(Func):
5296class ToBase64(Func):
5297    pass
key = 'tobase64'
class GapFill(Func):
5300class GapFill(Func):
5301    arg_types = {
5302        "this": True,
5303        "ts_column": True,
5304        "bucket_width": True,
5305        "partitioning_columns": False,
5306        "value_columns": False,
5307        "origin": False,
5308        "ignore_nulls": False,
5309    }
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):
5312class GenerateDateArray(Func):
5313    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5316class Greatest(Func):
5317    arg_types = {"this": True, "expressions": False}
5318    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5321class GroupConcat(AggFunc):
5322    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5325class Hex(Func):
5326    pass
key = 'hex'
class LowerHex(Hex):
5329class LowerHex(Hex):
5330    pass
key = 'lowerhex'
class Xor(Connector, Func):
5333class Xor(Connector, Func):
5334    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5337class If(Func):
5338    arg_types = {"this": True, "true": True, "false": False}
5339    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5342class Nullif(Func):
5343    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5346class Initcap(Func):
5347    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5350class IsNan(Func):
5351    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5354class IsInf(Func):
5355    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5358class JSONPath(Expression):
5359    arg_types = {"expressions": True}
5360
5361    @property
5362    def output_name(self) -> str:
5363        last_segment = self.expressions[-1].this
5364        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5361    @property
5362    def output_name(self) -> str:
5363        last_segment = self.expressions[-1].this
5364        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):
5367class JSONPathPart(Expression):
5368    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5371class JSONPathFilter(JSONPathPart):
5372    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5375class JSONPathKey(JSONPathPart):
5376    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5379class JSONPathRecursive(JSONPathPart):
5380    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5383class JSONPathRoot(JSONPathPart):
5384    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5387class JSONPathScript(JSONPathPart):
5388    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5391class JSONPathSlice(JSONPathPart):
5392    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5395class JSONPathSelector(JSONPathPart):
5396    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5399class JSONPathSubscript(JSONPathPart):
5400    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5403class JSONPathUnion(JSONPathPart):
5404    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5407class JSONPathWildcard(JSONPathPart):
5408    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5411class FormatJson(Expression):
5412    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5415class JSONKeyValue(Expression):
5416    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5419class JSONObject(Func):
5420    arg_types = {
5421        "expressions": False,
5422        "null_handling": False,
5423        "unique_keys": False,
5424        "return_type": False,
5425        "encoding": False,
5426    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5429class JSONObjectAgg(AggFunc):
5430    arg_types = {
5431        "expressions": False,
5432        "null_handling": False,
5433        "unique_keys": False,
5434        "return_type": False,
5435        "encoding": False,
5436    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5440class JSONArray(Func):
5441    arg_types = {
5442        "expressions": True,
5443        "null_handling": False,
5444        "return_type": False,
5445        "strict": False,
5446    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5450class JSONArrayAgg(Func):
5451    arg_types = {
5452        "this": True,
5453        "order": False,
5454        "null_handling": False,
5455        "return_type": False,
5456        "strict": False,
5457    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5462class JSONColumnDef(Expression):
5463    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):
5466class JSONSchema(Expression):
5467    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5471class JSONTable(Func):
5472    arg_types = {
5473        "this": True,
5474        "schema": True,
5475        "path": False,
5476        "error_handling": False,
5477        "empty_handling": False,
5478    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5481class OpenJSONColumnDef(Expression):
5482    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):
5485class OpenJSON(Func):
5486    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5489class JSONBContains(Binary, Func):
5490    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5493class JSONExtract(Binary, Func):
5494    arg_types = {
5495        "this": True,
5496        "expression": True,
5497        "only_json_types": False,
5498        "expressions": False,
5499        "variant_extract": False,
5500    }
5501    _sql_names = ["JSON_EXTRACT"]
5502    is_var_len_args = True
5503
5504    @property
5505    def output_name(self) -> str:
5506        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
5504    @property
5505    def output_name(self) -> str:
5506        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):
5509class JSONExtractScalar(Binary, Func):
5510    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5511    _sql_names = ["JSON_EXTRACT_SCALAR"]
5512    is_var_len_args = True
5513
5514    @property
5515    def output_name(self) -> str:
5516        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
5514    @property
5515    def output_name(self) -> str:
5516        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):
5519class JSONBExtract(Binary, Func):
5520    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5523class JSONBExtractScalar(Binary, Func):
5524    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5527class JSONFormat(Func):
5528    arg_types = {"this": False, "options": False}
5529    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5533class JSONArrayContains(Binary, Predicate, Func):
5534    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5537class ParseJSON(Func):
5538    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5539    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5540    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5541    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5544class Least(Func):
5545    arg_types = {"this": True, "expressions": False}
5546    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5549class Left(Func):
5550    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5557class Length(Func):
5558    arg_types = {"this": True, "binary": False}
5559    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5562class Levenshtein(Func):
5563    arg_types = {
5564        "this": True,
5565        "expression": False,
5566        "ins_cost": False,
5567        "del_cost": False,
5568        "sub_cost": False,
5569    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5572class Ln(Func):
5573    pass
key = 'ln'
class Log(Func):
5576class Log(Func):
5577    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5580class LogicalOr(AggFunc):
5581    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5584class LogicalAnd(AggFunc):
5585    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5588class Lower(Func):
5589    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5592class Map(Func):
5593    arg_types = {"keys": False, "values": False}
5594
5595    @property
5596    def keys(self) -> t.List[Expression]:
5597        keys = self.args.get("keys")
5598        return keys.expressions if keys else []
5599
5600    @property
5601    def values(self) -> t.List[Expression]:
5602        values = self.args.get("values")
5603        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5595    @property
5596    def keys(self) -> t.List[Expression]:
5597        keys = self.args.get("keys")
5598        return keys.expressions if keys else []
values: List[Expression]
5600    @property
5601    def values(self) -> t.List[Expression]:
5602        values = self.args.get("values")
5603        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5607class ToMap(Func):
5608    pass
key = 'tomap'
class MapFromEntries(Func):
5611class MapFromEntries(Func):
5612    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5616class ScopeResolution(Expression):
5617    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class StarMap(Func):
5620class StarMap(Func):
5621    pass
key = 'starmap'
class VarMap(Func):
5624class VarMap(Func):
5625    arg_types = {"keys": True, "values": True}
5626    is_var_len_args = True
5627
5628    @property
5629    def keys(self) -> t.List[Expression]:
5630        return self.args["keys"].expressions
5631
5632    @property
5633    def values(self) -> t.List[Expression]:
5634        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5628    @property
5629    def keys(self) -> t.List[Expression]:
5630        return self.args["keys"].expressions
values: List[Expression]
5632    @property
5633    def values(self) -> t.List[Expression]:
5634        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5638class MatchAgainst(Func):
5639    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5642class Max(AggFunc):
5643    arg_types = {"this": True, "expressions": False}
5644    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5647class MD5(Func):
5648    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5652class MD5Digest(Func):
5653    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5656class Min(AggFunc):
5657    arg_types = {"this": True, "expressions": False}
5658    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5661class Month(Func):
5662    pass
key = 'month'
class AddMonths(Func):
5665class AddMonths(Func):
5666    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5669class Nvl2(Func):
5670    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5674class Predict(Func):
5675    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5678class Pow(Binary, Func):
5679    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5682class PercentileCont(AggFunc):
5683    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5686class PercentileDisc(AggFunc):
5687    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5690class Quantile(AggFunc):
5691    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5694class ApproxQuantile(Quantile):
5695    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):
5698class Quarter(Func):
5699    pass
key = 'quarter'
class Rand(Func):
5704class Rand(Func):
5705    _sql_names = ["RAND", "RANDOM"]
5706    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5709class Randn(Func):
5710    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5713class RangeN(Func):
5714    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5717class ReadCSV(Func):
5718    _sql_names = ["READ_CSV"]
5719    is_var_len_args = True
5720    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5723class Reduce(Func):
5724    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):
5727class RegexpExtract(Func):
5728    arg_types = {
5729        "this": True,
5730        "expression": True,
5731        "position": False,
5732        "occurrence": False,
5733        "parameters": False,
5734        "group": False,
5735    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5738class RegexpReplace(Func):
5739    arg_types = {
5740        "this": True,
5741        "expression": True,
5742        "replacement": False,
5743        "position": False,
5744        "occurrence": False,
5745        "modifiers": False,
5746    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5749class RegexpLike(Binary, Func):
5750    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5753class RegexpILike(Binary, Func):
5754    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5759class RegexpSplit(Func):
5760    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5763class Repeat(Func):
5764    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5769class Round(Func):
5770    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5773class RowNumber(Func):
5774    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5777class SafeDivide(Func):
5778    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5781class SHA(Func):
5782    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5785class SHA2(Func):
5786    _sql_names = ["SHA2"]
5787    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5790class Sign(Func):
5791    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5794class SortArray(Func):
5795    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5798class Split(Func):
5799    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5804class Substring(Func):
5805    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5808class StandardHash(Func):
5809    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5812class StartsWith(Func):
5813    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5814    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5817class StrPosition(Func):
5818    arg_types = {
5819        "this": True,
5820        "substr": True,
5821        "position": False,
5822        "instance": False,
5823    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5826class StrToDate(Func):
5827    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5830class StrToTime(Func):
5831    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):
5836class StrToUnix(Func):
5837    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5842class StrToMap(Func):
5843    arg_types = {
5844        "this": True,
5845        "pair_delim": False,
5846        "key_value_delim": False,
5847        "duplicate_resolution_callback": False,
5848    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5851class NumberToStr(Func):
5852    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5855class FromBase(Func):
5856    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5859class Struct(Func):
5860    arg_types = {"expressions": False}
5861    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5864class StructExtract(Func):
5865    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5870class Stuff(Func):
5871    _sql_names = ["STUFF", "INSERT"]
5872    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):
5875class Sum(AggFunc):
5876    pass
key = 'sum'
class Sqrt(Func):
5879class Sqrt(Func):
5880    pass
key = 'sqrt'
class Stddev(AggFunc):
5883class Stddev(AggFunc):
5884    pass
key = 'stddev'
class StddevPop(AggFunc):
5887class StddevPop(AggFunc):
5888    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5891class StddevSamp(AggFunc):
5892    pass
key = 'stddevsamp'
class Time(Func):
5896class Time(Func):
5897    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5900class TimeToStr(Func):
5901    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):
5904class TimeToTimeStr(Func):
5905    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5908class TimeToUnix(Func):
5909    pass
key = 'timetounix'
class TimeStrToDate(Func):
5912class TimeStrToDate(Func):
5913    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5916class TimeStrToTime(Func):
5917    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5920class TimeStrToUnix(Func):
5921    pass
key = 'timestrtounix'
class Trim(Func):
5924class Trim(Func):
5925    arg_types = {
5926        "this": True,
5927        "expression": False,
5928        "position": False,
5929        "collation": False,
5930    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5933class TsOrDsAdd(Func, TimeUnit):
5934    # return_type is used to correctly cast the arguments of this expression when transpiling it
5935    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5936
5937    @property
5938    def return_type(self) -> DataType:
5939        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
5937    @property
5938    def return_type(self) -> DataType:
5939        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5942class TsOrDsDiff(Func, TimeUnit):
5943    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5946class TsOrDsToDateStr(Func):
5947    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5950class TsOrDsToDate(Func):
5951    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5954class TsOrDsToTime(Func):
5955    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5958class TsOrDsToTimestamp(Func):
5959    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5962class TsOrDiToDi(Func):
5963    pass
key = 'tsorditodi'
class Unhex(Func):
5966class Unhex(Func):
5967    pass
key = 'unhex'
class UnixDate(Func):
5971class UnixDate(Func):
5972    pass
key = 'unixdate'
class UnixToStr(Func):
5975class UnixToStr(Func):
5976    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5981class UnixToTime(Func):
5982    arg_types = {
5983        "this": True,
5984        "scale": False,
5985        "zone": False,
5986        "hours": False,
5987        "minutes": False,
5988        "format": False,
5989    }
5990
5991    SECONDS = Literal.number(0)
5992    DECIS = Literal.number(1)
5993    CENTIS = Literal.number(2)
5994    MILLIS = Literal.number(3)
5995    DECIMILLIS = Literal.number(4)
5996    CENTIMILLIS = Literal.number(5)
5997    MICROS = Literal.number(6)
5998    DECIMICROS = Literal.number(7)
5999    CENTIMICROS = Literal.number(8)
6000    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):
6003class UnixToTimeStr(Func):
6004    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6007class TimestampFromParts(Func):
6008    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6009    arg_types = {
6010        "year": True,
6011        "month": True,
6012        "day": True,
6013        "hour": True,
6014        "min": True,
6015        "sec": True,
6016        "nano": False,
6017        "zone": False,
6018        "milli": False,
6019    }
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):
6022class Upper(Func):
6023    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6026class Corr(Binary, AggFunc):
6027    pass
key = 'corr'
class Variance(AggFunc):
6030class Variance(AggFunc):
6031    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6034class VariancePop(AggFunc):
6035    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6038class CovarSamp(Binary, AggFunc):
6039    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6042class CovarPop(Binary, AggFunc):
6043    pass
key = 'covarpop'
class Week(Func):
6046class Week(Func):
6047    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6050class XMLTable(Func):
6051    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):
6054class Year(Func):
6055    pass
key = 'year'
class Use(Expression):
6058class Use(Expression):
6059    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6062class Merge(Expression):
6063    arg_types = {
6064        "this": True,
6065        "using": True,
6066        "on": True,
6067        "expressions": True,
6068        "with": False,
6069    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6072class When(Func):
6073    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):
6078class NextValueFor(Func):
6079    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6084class Semicolon(Expression):
6085    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 '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'>, '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:
6125def maybe_parse(
6126    sql_or_expression: ExpOrStr,
6127    *,
6128    into: t.Optional[IntoType] = None,
6129    dialect: DialectType = None,
6130    prefix: t.Optional[str] = None,
6131    copy: bool = False,
6132    **opts,
6133) -> Expression:
6134    """Gracefully handle a possible string or expression.
6135
6136    Example:
6137        >>> maybe_parse("1")
6138        Literal(this=1, is_string=False)
6139        >>> maybe_parse(to_identifier("x"))
6140        Identifier(this=x, quoted=False)
6141
6142    Args:
6143        sql_or_expression: the SQL code string or an expression
6144        into: the SQLGlot Expression to parse into
6145        dialect: the dialect used to parse the input expressions (in the case that an
6146            input expression is a SQL string).
6147        prefix: a string to prefix the sql with before it gets parsed
6148            (automatically includes a space)
6149        copy: whether to copy the expression.
6150        **opts: other options to use to parse the input expressions (again, in the case
6151            that an input expression is a SQL string).
6152
6153    Returns:
6154        Expression: the parsed or given expression.
6155    """
6156    if isinstance(sql_or_expression, Expression):
6157        if copy:
6158            return sql_or_expression.copy()
6159        return sql_or_expression
6160
6161    if sql_or_expression is None:
6162        raise ParseError("SQL cannot be None")
6163
6164    import sqlglot
6165
6166    sql = str(sql_or_expression)
6167    if prefix:
6168        sql = f"{prefix} {sql}"
6169
6170    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):
6181def maybe_copy(instance, copy=True):
6182    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:
6402def union(
6403    left: ExpOrStr,
6404    right: ExpOrStr,
6405    distinct: bool = True,
6406    dialect: DialectType = None,
6407    copy: bool = True,
6408    **opts,
6409) -> Union:
6410    """
6411    Initializes a syntax tree from one UNION expression.
6412
6413    Example:
6414        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6415        'SELECT * FROM foo UNION SELECT * FROM bla'
6416
6417    Args:
6418        left: the SQL code string corresponding to the left-hand side.
6419            If an `Expression` instance is passed, it will be used as-is.
6420        right: the SQL code string corresponding to the right-hand side.
6421            If an `Expression` instance is passed, it will be used as-is.
6422        distinct: set the DISTINCT flag if and only if this is true.
6423        dialect: the dialect used to parse the input expression.
6424        copy: whether to copy the expression.
6425        opts: other options to use to parse the input expressions.
6426
6427    Returns:
6428        The new Union instance.
6429    """
6430    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6431    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6432
6433    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:
6436def intersect(
6437    left: ExpOrStr,
6438    right: ExpOrStr,
6439    distinct: bool = True,
6440    dialect: DialectType = None,
6441    copy: bool = True,
6442    **opts,
6443) -> Intersect:
6444    """
6445    Initializes a syntax tree from one INTERSECT expression.
6446
6447    Example:
6448        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6449        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6450
6451    Args:
6452        left: the SQL code string corresponding to the left-hand side.
6453            If an `Expression` instance is passed, it will be used as-is.
6454        right: the SQL code string corresponding to the right-hand side.
6455            If an `Expression` instance is passed, it will be used as-is.
6456        distinct: set the DISTINCT flag if and only if this is true.
6457        dialect: the dialect used to parse the input expression.
6458        copy: whether to copy the expression.
6459        opts: other options to use to parse the input expressions.
6460
6461    Returns:
6462        The new Intersect instance.
6463    """
6464    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6465    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6466
6467    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:
6470def except_(
6471    left: ExpOrStr,
6472    right: ExpOrStr,
6473    distinct: bool = True,
6474    dialect: DialectType = None,
6475    copy: bool = True,
6476    **opts,
6477) -> Except:
6478    """
6479    Initializes a syntax tree from one EXCEPT expression.
6480
6481    Example:
6482        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6483        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6484
6485    Args:
6486        left: the SQL code string corresponding to the left-hand side.
6487            If an `Expression` instance is passed, it will be used as-is.
6488        right: the SQL code string corresponding to the right-hand side.
6489            If an `Expression` instance is passed, it will be used as-is.
6490        distinct: set the DISTINCT flag if and only if this is true.
6491        dialect: the dialect used to parse the input expression.
6492        copy: whether to copy the expression.
6493        opts: other options to use to parse the input expressions.
6494
6495    Returns:
6496        The new Except instance.
6497    """
6498    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6499    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6500
6501    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:
6504def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6505    """
6506    Initializes a syntax tree from one or multiple SELECT expressions.
6507
6508    Example:
6509        >>> select("col1", "col2").from_("tbl").sql()
6510        'SELECT col1, col2 FROM tbl'
6511
6512    Args:
6513        *expressions: the SQL code string to parse as the expressions of a
6514            SELECT statement. If an Expression instance is passed, this is used as-is.
6515        dialect: the dialect used to parse the input expressions (in the case that an
6516            input expression is a SQL string).
6517        **opts: other options to use to parse the input expressions (again, in the case
6518            that an input expression is a SQL string).
6519
6520    Returns:
6521        Select: the syntax tree for the SELECT statement.
6522    """
6523    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:
6526def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6527    """
6528    Initializes a syntax tree from a FROM expression.
6529
6530    Example:
6531        >>> from_("tbl").select("col1", "col2").sql()
6532        'SELECT col1, col2 FROM tbl'
6533
6534    Args:
6535        *expression: the SQL code string to parse as the FROM expressions of a
6536            SELECT statement. If an Expression instance is passed, this is used as-is.
6537        dialect: the dialect used to parse the input expression (in the case that the
6538            input expression is a SQL string).
6539        **opts: other options to use to parse the input expressions (again, in the case
6540            that the input expression is a SQL string).
6541
6542    Returns:
6543        Select: the syntax tree for the SELECT statement.
6544    """
6545    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:
6548def update(
6549    table: str | Table,
6550    properties: dict,
6551    where: t.Optional[ExpOrStr] = None,
6552    from_: t.Optional[ExpOrStr] = None,
6553    dialect: DialectType = None,
6554    **opts,
6555) -> Update:
6556    """
6557    Creates an update statement.
6558
6559    Example:
6560        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6561        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6562
6563    Args:
6564        *properties: dictionary of properties to set which are
6565            auto converted to sql objects eg None -> NULL
6566        where: sql conditional parsed into a WHERE statement
6567        from_: sql statement parsed into a FROM statement
6568        dialect: the dialect used to parse the input expressions.
6569        **opts: other options to use to parse the input expressions.
6570
6571    Returns:
6572        Update: the syntax tree for the UPDATE statement.
6573    """
6574    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6575    update_expr.set(
6576        "expressions",
6577        [
6578            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6579            for k, v in properties.items()
6580        ],
6581    )
6582    if from_:
6583        update_expr.set(
6584            "from",
6585            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6586        )
6587    if isinstance(where, Condition):
6588        where = Where(this=where)
6589    if where:
6590        update_expr.set(
6591            "where",
6592            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6593        )
6594    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:
6597def delete(
6598    table: ExpOrStr,
6599    where: t.Optional[ExpOrStr] = None,
6600    returning: t.Optional[ExpOrStr] = None,
6601    dialect: DialectType = None,
6602    **opts,
6603) -> Delete:
6604    """
6605    Builds a delete statement.
6606
6607    Example:
6608        >>> delete("my_table", where="id > 1").sql()
6609        'DELETE FROM my_table WHERE id > 1'
6610
6611    Args:
6612        where: sql conditional parsed into a WHERE statement
6613        returning: sql conditional parsed into a RETURNING statement
6614        dialect: the dialect used to parse the input expressions.
6615        **opts: other options to use to parse the input expressions.
6616
6617    Returns:
6618        Delete: the syntax tree for the DELETE statement.
6619    """
6620    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6621    if where:
6622        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6623    if returning:
6624        delete_expr = t.cast(
6625            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6626        )
6627    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:
6630def insert(
6631    expression: ExpOrStr,
6632    into: ExpOrStr,
6633    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6634    overwrite: t.Optional[bool] = None,
6635    returning: t.Optional[ExpOrStr] = None,
6636    dialect: DialectType = None,
6637    copy: bool = True,
6638    **opts,
6639) -> Insert:
6640    """
6641    Builds an INSERT statement.
6642
6643    Example:
6644        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6645        'INSERT INTO tbl VALUES (1, 2, 3)'
6646
6647    Args:
6648        expression: the sql string or expression of the INSERT statement
6649        into: the tbl to insert data to.
6650        columns: optionally the table's column names.
6651        overwrite: whether to INSERT OVERWRITE or not.
6652        returning: sql conditional parsed into a RETURNING statement
6653        dialect: the dialect used to parse the input expressions.
6654        copy: whether to copy the expression.
6655        **opts: other options to use to parse the input expressions.
6656
6657    Returns:
6658        Insert: the syntax tree for the INSERT statement.
6659    """
6660    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6661    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6662
6663    if columns:
6664        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6665
6666    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6667
6668    if returning:
6669        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6670
6671    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:
6674def condition(
6675    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6676) -> Condition:
6677    """
6678    Initialize a logical condition expression.
6679
6680    Example:
6681        >>> condition("x=1").sql()
6682        'x = 1'
6683
6684        This is helpful for composing larger logical syntax trees:
6685        >>> where = condition("x=1")
6686        >>> where = where.and_("y=1")
6687        >>> Select().from_("tbl").select("*").where(where).sql()
6688        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6689
6690    Args:
6691        *expression: the SQL code string to parse.
6692            If an Expression instance is passed, this is used as-is.
6693        dialect: the dialect used to parse the input expression (in the case that the
6694            input expression is a SQL string).
6695        copy: Whether to copy `expression` (only applies to expressions).
6696        **opts: other options to use to parse the input expressions (again, in the case
6697            that the input expression is a SQL string).
6698
6699    Returns:
6700        The new Condition instance
6701    """
6702    return maybe_parse(
6703        expression,
6704        into=Condition,
6705        dialect=dialect,
6706        copy=copy,
6707        **opts,
6708    )

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

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

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

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

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

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

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

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

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

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

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:
7732def true() -> Boolean:
7733    """
7734    Returns a true Boolean expression.
7735    """
7736    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7739def false() -> Boolean:
7740    """
7741    Returns a false Boolean expression.
7742    """
7743    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7746def null() -> Null:
7747    """
7748    Returns a Null expression.
7749    """
7750    return Null()

Returns a Null expression.

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