Edit on GitHub

Expressions

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

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


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

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

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

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

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
102    def __init__(self, **args: t.Any):
103        self.args: t.Dict[str, t.Any] = args
104        self.parent: t.Optional[Expression] = None
105        self.arg_key: t.Optional[str] = None
106        self.index: t.Optional[int] = None
107        self.comments: t.Optional[t.List[str]] = None
108        self._type: t.Optional[DataType] = None
109        self._meta: t.Optional[t.Dict[str, t.Any]] = None
110        self._hash: t.Optional[int] = None
111
112        for arg_key, value in self.args.items():
113            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
hashable_args: Any
118    @property
119    def hashable_args(self) -> t.Any:
120        return frozenset(
121            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
122            for k, v in self.args.items()
123            if not (v is None or v is False or (type(v) is list and not v))
124        )
this: Any
132    @property
133    def this(self) -> t.Any:
134        """
135        Retrieves the argument with key "this".
136        """
137        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

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

is_string: bool
167    @property
168    def is_string(self) -> bool:
169        """
170        Checks whether a Literal expression is a string.
171        """
172        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

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

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
243    @property
244    def type(self) -> t.Optional[DataType]:
245        return self._type
def is_type(self, *dtypes) -> bool:
253    def is_type(self, *dtypes) -> bool:
254        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
256    def is_leaf(self) -> bool:
257        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
259    @property
260    def meta(self) -> t.Dict[str, t.Any]:
261        if self._meta is None:
262            self._meta = {}
263        return self._meta
def copy(self):
299    def copy(self):
300        """
301        Returns a deep copy of the expression.
302        """
303        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]] = None) -> None:
305    def add_comments(self, comments: t.Optional[t.List[str]] = None) -> None:
306        if self.comments is None:
307            self.comments = []
308
309        if comments:
310            for comment in comments:
311                _, *meta = comment.split(SQLGLOT_META)
312                if meta:
313                    for kv in "".join(meta).split(","):
314                        k, *v = kv.split("=")
315                        value = v[0].strip() if v else True
316                        self.meta[k.strip()] = value
317                self.comments.append(comment)
def pop_comments(self) -> List[str]:
319    def pop_comments(self) -> t.List[str]:
320        comments = self.comments or []
321        self.comments = None
322        return comments
def append(self, arg_key: str, value: Any) -> None:
324    def append(self, arg_key: str, value: t.Any) -> None:
325        """
326        Appends value to arg_key if it's a list or sets it as a new list.
327
328        Args:
329            arg_key (str): name of the list expression arg
330            value (Any): value to append to the list
331        """
332        if type(self.args.get(arg_key)) is not list:
333            self.args[arg_key] = []
334        self._set_parent(arg_key, value)
335        values = self.args[arg_key]
336        if hasattr(value, "parent"):
337            value.index = len(values)
338        values.append(value)

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

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set(self, arg_key: str, value: Any, index: Optional[int] = None) -> None:
340    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
341        """
342        Sets arg_key to value.
343
344        Args:
345            arg_key: name of the expression arg.
346            value: value to set the arg to.
347            index: if the arg is a list, this specifies what position to add the value in it.
348        """
349        if index is not None:
350            expressions = self.args.get(arg_key) or []
351
352            if seq_get(expressions, index) is None:
353                return
354            if value is None:
355                expressions.pop(index)
356                for v in expressions[index:]:
357                    v.index = v.index - 1
358                return
359
360            if isinstance(value, list):
361                expressions.pop(index)
362                expressions[index:index] = value
363            else:
364                expressions[index] = value
365
366            value = expressions
367        elif value is None:
368            self.args.pop(arg_key, None)
369            return
370
371        self.args[arg_key] = value
372        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
depth: int
386    @property
387    def depth(self) -> int:
388        """
389        Returns the depth of this tree.
390        """
391        if self.parent:
392            return self.parent.depth + 1
393        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
395    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
396        """Yields the key and expression for all arguments, exploding list args."""
397        # remove tuple when python 3.7 is deprecated
398        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
399            if type(vs) is list:
400                for v in reversed(vs) if reverse else vs:
401                    if hasattr(v, "parent"):
402                        yield v
403            else:
404                if hasattr(vs, "parent"):
405                    yield vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
407    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
408        """
409        Returns the first node in this tree which matches at least one of
410        the specified types.
411
412        Args:
413            expression_types: the expression type(s) to match.
414            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
415
416        Returns:
417            The node which matches the criteria or None if no such node was found.
418        """
419        return next(self.find_all(*expression_types, bfs=bfs), None)

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

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

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

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
421    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
422        """
423        Returns a generator object which visits all nodes in this tree and only
424        yields those that match at least one of the specified expression types.
425
426        Args:
427            expression_types: the expression type(s) to match.
428            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
429
430        Returns:
431            The generator object.
432        """
433        for expression in self.walk(bfs=bfs):
434            if isinstance(expression, expression_types):
435                yield expression

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

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

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
437    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
438        """
439        Returns a nearest parent matching expression_types.
440
441        Args:
442            expression_types: the expression type(s) to match.
443
444        Returns:
445            The parent node.
446        """
447        ancestor = self.parent
448        while ancestor and not isinstance(ancestor, expression_types):
449            ancestor = ancestor.parent
450        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

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

The parent node.

parent_select: Optional[Select]
452    @property
453    def parent_select(self) -> t.Optional[Select]:
454        """
455        Returns the parent select statement.
456        """
457        return self.find_ancestor(Select)

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
473    def walk(
474        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
475    ) -> t.Iterator[Expression]:
476        """
477        Returns a generator object which visits all nodes in this tree.
478
479        Args:
480            bfs: if set to True the BFS traversal order will be applied,
481                otherwise the DFS traversal will be used instead.
482            prune: callable that returns True if the generator should stop traversing
483                this branch of the tree.
484
485        Returns:
486            the generator object.
487        """
488        if bfs:
489            yield from self.bfs(prune=prune)
490        else:
491            yield from self.dfs(prune=prune)

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

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

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
493    def dfs(
494        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
495    ) -> t.Iterator[Expression]:
496        """
497        Returns a generator object which visits all nodes in this tree in
498        the DFS (Depth-first) order.
499
500        Returns:
501            The generator object.
502        """
503        stack = [self]
504
505        while stack:
506            node = stack.pop()
507
508            yield node
509
510            if prune and prune(node):
511                continue
512
513            for v in node.iter_expressions(reverse=True):
514                stack.append(v)

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

Returns:

The generator object.

def bfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
516    def bfs(
517        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
518    ) -> t.Iterator[Expression]:
519        """
520        Returns a generator object which visits all nodes in this tree in
521        the BFS (Breadth-first) order.
522
523        Returns:
524            The generator object.
525        """
526        queue = deque([self])
527
528        while queue:
529            node = queue.popleft()
530
531            yield node
532
533            if prune and prune(node):
534                continue
535
536            for v in node.iter_expressions():
537                queue.append(v)

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

Returns:

The generator object.

def unnest(self):
539    def unnest(self):
540        """
541        Returns the first non parenthesis child or self.
542        """
543        expression = self
544        while type(expression) is Paren:
545            expression = expression.this
546        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
562    def flatten(self, unnest=True):
563        """
564        Returns a generator which yields child nodes whose parents are the same class.
565
566        A AND B AND C -> [A, B, C]
567        """
568        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
569            if type(node) is not self.__class__:
570                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

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

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

def to_s(self) -> str:
578    def to_s(self) -> str:
579        """
580        Same as __repr__, but includes additional information which can be useful
581        for debugging, like empty or missing args and the AST nodes' object IDs.
582        """
583        return _to_s(self, verbose=True)

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

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
585    def sql(self, dialect: DialectType = None, **opts) -> str:
586        """
587        Returns SQL string representation of this tree.
588
589        Args:
590            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
591            opts: other `sqlglot.generator.Generator` options.
592
593        Returns:
594            The SQL string.
595        """
596        from sqlglot.dialects import Dialect
597
598        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

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

The SQL string.

def transform( self, fun: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
600    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
601        """
602        Visits all tree nodes (excluding already transformed ones)
603        and applies the given transformation function to each node.
604
605        Args:
606            fun: a function which takes a node as an argument and returns a
607                new transformed node or the same node without modifications. If the function
608                returns None, then the corresponding node will be removed from the syntax tree.
609            copy: if set to True a new tree instance is constructed, otherwise the tree is
610                modified in place.
611
612        Returns:
613            The transformed tree.
614        """
615        root = None
616        new_node = None
617
618        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
619            parent, arg_key, index = node.parent, node.arg_key, node.index
620            new_node = fun(node, *args, **kwargs)
621
622            if not root:
623                root = new_node
624            elif new_node is not node:
625                parent.set(arg_key, new_node, index)
626
627        assert root
628        return root.assert_is(Expression)

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

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

The transformed tree.

def replace(self, expression):
636    def replace(self, expression):
637        """
638        Swap out this expression with a new expression.
639
640        For example::
641
642            >>> tree = Select().select("x").from_("tbl")
643            >>> tree.find(Column).replace(column("y"))
644            Column(
645              this=Identifier(this=y, quoted=False))
646            >>> tree.sql()
647            'SELECT y FROM tbl'
648
649        Args:
650            expression: new node
651
652        Returns:
653            The new expression or expressions.
654        """
655        parent = self.parent
656
657        if not parent or parent is expression:
658            return expression
659
660        key = self.arg_key
661        value = parent.args.get(key)
662
663        if type(expression) is list and isinstance(value, Expression):
664            # We are trying to replace an Expression with a list, so it's assumed that
665            # the intention was to really replace the parent of this expression.
666            value.parent.replace(expression)
667        else:
668            parent.set(key, expression, self.index)
669
670        if expression is not self:
671            self.parent = None
672            self.arg_key = None
673            self.index = None
674
675        return expression

Swap out this expression with a new expression.

For example::

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

The new expression or expressions.

def pop(self: ~E) -> ~E:
677    def pop(self: E) -> E:
678        """
679        Remove this expression from its AST.
680
681        Returns:
682            The popped expression.
683        """
684        self.replace(None)
685        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
687    def assert_is(self, type_: t.Type[E]) -> E:
688        """
689        Assert that this `Expression` is an instance of `type_`.
690
691        If it is NOT an instance of `type_`, this raises an assertion error.
692        Otherwise, this returns this expression.
693
694        Examples:
695            This is useful for type security in chained expressions:
696
697            >>> import sqlglot
698            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
699            'SELECT x, z FROM y'
700        """
701        if not isinstance(self, type_):
702            raise AssertionError(f"{self} is not {type_}.")
703        return self

Assert that this Expression is an instance of type_.

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

Examples:

This is useful for type security in chained expressions:

>>> import sqlglot
>>> sqlglot.parse_one("SELECT x from y").assert_is(Select)select("z").sql()
'SELECT x, z FROM y'
def error_messages(self, args: Optional[Sequence] = None) -> List[str]:
705    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
706        """
707        Checks if this expression is valid (e.g. all mandatory args are set).
708
709        Args:
710            args: a sequence of values that were used to instantiate a Func expression. This is used
711                to check that the provided arguments don't exceed the function argument limit.
712
713        Returns:
714            A list of error messages for all possible errors that were found.
715        """
716        errors: t.List[str] = []
717
718        for k in self.args:
719            if k not in self.arg_types:
720                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
721        for k, mandatory in self.arg_types.items():
722            v = self.args.get(k)
723            if mandatory and (v is None or (isinstance(v, list) and not v)):
724                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
725
726        if (
727            args
728            and isinstance(self, Func)
729            and len(args) > len(self.arg_types)
730            and not self.is_var_len_args
731        ):
732            errors.append(
733                f"The number of provided arguments ({len(args)}) is greater than "
734                f"the maximum number of supported arguments ({len(self.arg_types)})"
735            )
736
737        return errors

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

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

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

def dump(self):
739    def dump(self):
740        """
741        Dump this Expression to a JSON-serializable dict.
742        """
743        from sqlglot.serde import dump
744
745        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
747    @classmethod
748    def load(cls, obj):
749        """
750        Load a dict (as returned by `Expression.dump`) into an Expression instance.
751        """
752        from sqlglot.serde import load
753
754        return load(obj)

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

def and_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
756    def and_(
757        self,
758        *expressions: t.Optional[ExpOrStr],
759        dialect: DialectType = None,
760        copy: bool = True,
761        **opts,
762    ) -> Condition:
763        """
764        AND this condition with one or multiple expressions.
765
766        Example:
767            >>> condition("x=1").and_("y=1").sql()
768            'x = 1 AND y = 1'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expression` instance is passed, it will be used as-is.
773            dialect: the dialect used to parse the input expression.
774            copy: whether to copy the involved expressions (only applies to Expressions).
775            opts: other options to use to parse the input expressions.
776
777        Returns:
778            The new And condition.
779        """
780        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1")and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
782    def or_(
783        self,
784        *expressions: t.Optional[ExpOrStr],
785        dialect: DialectType = None,
786        copy: bool = True,
787        **opts,
788    ) -> Condition:
789        """
790        OR this condition with one or multiple expressions.
791
792        Example:
793            >>> condition("x=1").or_("y=1").sql()
794            'x = 1 OR y = 1'
795
796        Args:
797            *expressions: the SQL code strings to parse.
798                If an `Expression` instance is passed, it will be used as-is.
799            dialect: the dialect used to parse the input expression.
800            copy: whether to copy the involved expressions (only applies to Expressions).
801            opts: other options to use to parse the input expressions.
802
803        Returns:
804            The new Or condition.
805        """
806        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1")or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
808    def not_(self, copy: bool = True):
809        """
810        Wrap this condition with NOT.
811
812        Example:
813            >>> condition("x=1").not_().sql()
814            'NOT x = 1'
815
816        Args:
817            copy: whether to copy this object.
818
819        Returns:
820            The new Not instance.
821        """
822        return not_(self, copy=copy)

Wrap this condition with NOT.

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

The new Not instance.

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

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select()select("x")from_("tbl")subquery()
>>> Select()select("x")from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1041    def limit(
1042        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1043    ) -> Q:
1044        """
1045        Adds a LIMIT clause to this query.
1046
1047        Example:
1048            >>> select("1").union(select("1")).limit(1).sql()
1049            'SELECT 1 UNION SELECT 1 LIMIT 1'
1050
1051        Args:
1052            expression: the SQL code string to parse.
1053                This can also be an integer.
1054                If a `Limit` instance is passed, it will be used as-is.
1055                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1056            dialect: the dialect used to parse the input expression.
1057            copy: if `False`, modify this expression instance in-place.
1058            opts: other options to use to parse the input expressions.
1059
1060        Returns:
1061            A limited Select expression.
1062        """
1063        return _apply_builder(
1064            expression=expression,
1065            instance=self,
1066            arg="limit",
1067            into=Limit,
1068            prefix="LIMIT",
1069            dialect=dialect,
1070            copy=copy,
1071            into_arg="expression",
1072            **opts,
1073        )

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

Set the ORDER BY expression.

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

The modified Select expression.

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1165    def select(
1166        self: Q,
1167        *expressions: t.Optional[ExpOrStr],
1168        append: bool = True,
1169        dialect: DialectType = None,
1170        copy: bool = True,
1171        **opts,
1172    ) -> Q:
1173        """
1174        Append to or set the SELECT expressions.
1175
1176        Example:
1177            >>> Select().select("x", "y").sql()
1178            'SELECT x, y'
1179
1180        Args:
1181            *expressions: the SQL code strings to parse.
1182                If an `Expression` instance is passed, it will be used as-is.
1183            append: if `True`, add to any existing expressions.
1184                Otherwise, this resets the expressions.
1185            dialect: the dialect used to parse the input expressions.
1186            copy: if `False`, modify this expression instance in-place.
1187            opts: other options to use to parse the input expressions.
1188
1189        Returns:
1190            The modified Query expression.
1191        """
1192        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

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

The modified Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1194    def with_(
1195        self: Q,
1196        alias: ExpOrStr,
1197        as_: ExpOrStr,
1198        recursive: t.Optional[bool] = None,
1199        append: bool = True,
1200        dialect: DialectType = None,
1201        copy: bool = True,
1202        **opts,
1203    ) -> Q:
1204        """
1205        Append to or set the common table expressions.
1206
1207        Example:
1208            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1209            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1210
1211        Args:
1212            alias: the SQL code string to parse as the table name.
1213                If an `Expression` instance is passed, this is used as-is.
1214            as_: the SQL code string to parse as the table expression.
1215                If an `Expression` instance is passed, it will be used as-is.
1216            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1217            append: if `True`, add to any existing expressions.
1218                Otherwise, this resets the expressions.
1219            dialect: the dialect used to parse the input expression.
1220            copy: if `False`, modify this expression instance in-place.
1221            opts: other options to use to parse the input expressions.
1222
1223        Returns:
1224            The modified expression.
1225        """
1226        return _apply_cte_builder(
1227            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1228        )

Append to or set the common table expressions.

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

The modified expression.

def union( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1230    def union(
1231        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1232    ) -> Union:
1233        """
1234        Builds a UNION expression.
1235
1236        Example:
1237            >>> import sqlglot
1238            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1239            'SELECT * FROM foo UNION SELECT * FROM bla'
1240
1241        Args:
1242            expression: the SQL code string.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            distinct: set the DISTINCT flag if and only if this is true.
1245            dialect: the dialect used to parse the input expression.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The new Union expression.
1250        """
1251        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

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

The new Union expression.

def intersect( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1253    def intersect(
1254        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1255    ) -> Intersect:
1256        """
1257        Builds an INTERSECT expression.
1258
1259        Example:
1260            >>> import sqlglot
1261            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1262            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1263
1264        Args:
1265            expression: the SQL code string.
1266                If an `Expression` instance is passed, it will be used as-is.
1267            distinct: set the DISTINCT flag if and only if this is true.
1268            dialect: the dialect used to parse the input expression.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The new Intersect expression.
1273        """
1274        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

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

The new Intersect expression.

def except_( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1276    def except_(
1277        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1278    ) -> Except:
1279        """
1280        Builds an EXCEPT expression.
1281
1282        Example:
1283            >>> import sqlglot
1284            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1285            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1286
1287        Args:
1288            expression: the SQL code string.
1289                If an `Expression` instance is passed, it will be used as-is.
1290            distinct: set the DISTINCT flag if and only if this is true.
1291            dialect: the dialect used to parse the input expression.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The new Except expression.
1296        """
1297        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

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

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1300class UDTF(DerivedTable):
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
selects: List[Expression]
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1307class Cache(Expression):
1308    arg_types = {
1309        "this": True,
1310        "lazy": False,
1311        "options": False,
1312        "expression": False,
1313    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1316class Uncache(Expression):
1317    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1320class Refresh(Expression):
1321    pass
key = 'refresh'
class DDL(Expression):
1324class DDL(Expression):
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []
1330
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        return self.expression.selects if isinstance(self.expression, Query) else []
1335
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []

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

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

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

named_selects: List[str]
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []

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

key = 'ddl'
class DML(Expression):
1345class DML(Expression):
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> DML:
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

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

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1590    @property
1591    def parts(self) -> t.List[Identifier]:
1592        """Return the parts of a column in order catalog, db, table, name."""
1593        return [
1594            t.cast(Identifier, self.args[part])
1595            for part in ("catalog", "db", "table", "this")
1596            if self.args.get(part)
1597        ]

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

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

Converts the column into a dot expression.

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

Create a DELETE expression or replace the table on an existing DELETE expression.

Example:
>>> delete("tbl").sql()
'DELETE FROM tbl'
Arguments:
  • table: the table from which to delete.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

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

Append to or set the WHERE expressions.

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

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
1990class Drop(Expression):
1991    arg_types = {
1992        "this": False,
1993        "kind": False,
1994        "expressions": False,
1995        "exists": False,
1996        "temporary": False,
1997        "materialized": False,
1998        "cascade": False,
1999        "constraints": False,
2000        "purge": False,
2001        "cluster": False,
2002    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
key = 'drop'
class Filter(Expression):
2005class Filter(Expression):
2006    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2009class Check(Expression):
2010    pass
key = 'check'
class Changes(Expression):
2013class Changes(Expression):
2014    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2018class Connect(Expression):
2019    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2022class CopyParameter(Expression):
2023    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2026class Copy(DML):
2027    arg_types = {
2028        "this": True,
2029        "kind": True,
2030        "files": True,
2031        "credentials": False,
2032        "format": False,
2033        "params": False,
2034    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2037class Credentials(Expression):
2038    arg_types = {
2039        "credentials": False,
2040        "encryption": False,
2041        "storage": False,
2042        "iam_role": False,
2043        "region": False,
2044    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2047class Prior(Expression):
2048    pass
key = 'prior'
class Directory(Expression):
2051class Directory(Expression):
2052    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2053    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2056class ForeignKey(Expression):
2057    arg_types = {
2058        "expressions": True,
2059        "reference": False,
2060        "delete": False,
2061        "update": False,
2062    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2065class ColumnPrefix(Expression):
2066    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2069class PrimaryKey(Expression):
2070    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2075class Into(Expression):
2076    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2079class From(Expression):
2080    @property
2081    def name(self) -> str:
2082        return self.this.name
2083
2084    @property
2085    def alias_or_name(self) -> str:
2086        return self.this.alias_or_name
name: str
2080    @property
2081    def name(self) -> str:
2082        return self.this.name
alias_or_name: str
2084    @property
2085    def alias_or_name(self) -> str:
2086        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2089class Having(Expression):
2090    pass
key = 'having'
class Hint(Expression):
2093class Hint(Expression):
2094    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2097class JoinHint(Expression):
2098    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2101class Identifier(Expression):
2102    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2103
2104    @property
2105    def quoted(self) -> bool:
2106        return bool(self.args.get("quoted"))
2107
2108    @property
2109    def hashable_args(self) -> t.Any:
2110        return (self.this, self.quoted)
2111
2112    @property
2113    def output_name(self) -> str:
2114        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2104    @property
2105    def quoted(self) -> bool:
2106        return bool(self.args.get("quoted"))
hashable_args: Any
2108    @property
2109    def hashable_args(self) -> t.Any:
2110        return (self.this, self.quoted)
output_name: str
2112    @property
2113    def output_name(self) -> str:
2114        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
2118class Opclass(Expression):
2119    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2122class Index(Expression):
2123    arg_types = {
2124        "this": False,
2125        "table": False,
2126        "unique": False,
2127        "primary": False,
2128        "amp": False,  # teradata
2129        "params": False,
2130    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2133class IndexParameters(Expression):
2134    arg_types = {
2135        "using": False,
2136        "include": False,
2137        "columns": False,
2138        "with_storage": False,
2139        "partition_by": False,
2140        "tablespace": False,
2141        "where": False,
2142        "on": False,
2143    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
class Insert(DDL, DML):
2146class Insert(DDL, DML):
2147    arg_types = {
2148        "hint": False,
2149        "with": False,
2150        "is_function": False,
2151        "this": False,
2152        "expression": False,
2153        "conflict": False,
2154        "returning": False,
2155        "overwrite": False,
2156        "exists": False,
2157        "alternative": False,
2158        "where": False,
2159        "ignore": False,
2160        "by_name": False,
2161        "stored": False,
2162    }
2163
2164    def with_(
2165        self,
2166        alias: ExpOrStr,
2167        as_: ExpOrStr,
2168        recursive: t.Optional[bool] = None,
2169        append: bool = True,
2170        dialect: DialectType = None,
2171        copy: bool = True,
2172        **opts,
2173    ) -> Insert:
2174        """
2175        Append to or set the common table expressions.
2176
2177        Example:
2178            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2179            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2180
2181        Args:
2182            alias: the SQL code string to parse as the table name.
2183                If an `Expression` instance is passed, this is used as-is.
2184            as_: the SQL code string to parse as the table expression.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2187            append: if `True`, add to any existing expressions.
2188                Otherwise, this resets the expressions.
2189            dialect: the dialect used to parse the input expression.
2190            copy: if `False`, modify this expression instance in-place.
2191            opts: other options to use to parse the input expressions.
2192
2193        Returns:
2194            The modified expression.
2195        """
2196        return _apply_cte_builder(
2197            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2198        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2164    def with_(
2165        self,
2166        alias: ExpOrStr,
2167        as_: ExpOrStr,
2168        recursive: t.Optional[bool] = None,
2169        append: bool = True,
2170        dialect: DialectType = None,
2171        copy: bool = True,
2172        **opts,
2173    ) -> Insert:
2174        """
2175        Append to or set the common table expressions.
2176
2177        Example:
2178            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2179            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2180
2181        Args:
2182            alias: the SQL code string to parse as the table name.
2183                If an `Expression` instance is passed, this is used as-is.
2184            as_: the SQL code string to parse as the table expression.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2187            append: if `True`, add to any existing expressions.
2188                Otherwise, this resets the expressions.
2189            dialect: the dialect used to parse the input expression.
2190            copy: if `False`, modify this expression instance in-place.
2191            opts: other options to use to parse the input expressions.
2192
2193        Returns:
2194            The modified expression.
2195        """
2196        return _apply_cte_builder(
2197            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2198        )

Append to or set the common table expressions.

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

The modified expression.

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

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def to_py(self) -> int | str | decimal.Decimal:
2297    def to_py(self) -> int | str | Decimal:
2298        if self.is_number:
2299            try:
2300                return int(self.this)
2301            except ValueError:
2302                return Decimal(self.this)
2303        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2306class Join(Expression):
2307    arg_types = {
2308        "this": True,
2309        "on": False,
2310        "side": False,
2311        "kind": False,
2312        "using": False,
2313        "method": False,
2314        "global": False,
2315        "hint": False,
2316        "match_condition": False,  # Snowflake
2317    }
2318
2319    @property
2320    def method(self) -> str:
2321        return self.text("method").upper()
2322
2323    @property
2324    def kind(self) -> str:
2325        return self.text("kind").upper()
2326
2327    @property
2328    def side(self) -> str:
2329        return self.text("side").upper()
2330
2331    @property
2332    def hint(self) -> str:
2333        return self.text("hint").upper()
2334
2335    @property
2336    def alias_or_name(self) -> str:
2337        return self.this.alias_or_name
2338
2339    def on(
2340        self,
2341        *expressions: t.Optional[ExpOrStr],
2342        append: bool = True,
2343        dialect: DialectType = None,
2344        copy: bool = True,
2345        **opts,
2346    ) -> Join:
2347        """
2348        Append to or set the ON expressions.
2349
2350        Example:
2351            >>> import sqlglot
2352            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2353            'JOIN x ON y = 1'
2354
2355        Args:
2356            *expressions: the SQL code strings to parse.
2357                If an `Expression` instance is passed, it will be used as-is.
2358                Multiple expressions are combined with an AND operator.
2359            append: if `True`, AND the new expressions to any existing expression.
2360                Otherwise, this resets the expression.
2361            dialect: the dialect used to parse the input expressions.
2362            copy: if `False`, modify this expression instance in-place.
2363            opts: other options to use to parse the input expressions.
2364
2365        Returns:
2366            The modified Join expression.
2367        """
2368        join = _apply_conjunction_builder(
2369            *expressions,
2370            instance=self,
2371            arg="on",
2372            append=append,
2373            dialect=dialect,
2374            copy=copy,
2375            **opts,
2376        )
2377
2378        if join.kind == "CROSS":
2379            join.set("kind", None)
2380
2381        return join
2382
2383    def using(
2384        self,
2385        *expressions: t.Optional[ExpOrStr],
2386        append: bool = True,
2387        dialect: DialectType = None,
2388        copy: bool = True,
2389        **opts,
2390    ) -> Join:
2391        """
2392        Append to or set the USING expressions.
2393
2394        Example:
2395            >>> import sqlglot
2396            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2397            'JOIN x USING (foo, bla)'
2398
2399        Args:
2400            *expressions: the SQL code strings to parse.
2401                If an `Expression` instance is passed, it will be used as-is.
2402            append: if `True`, concatenate the new expressions to the existing "using" list.
2403                Otherwise, this resets the expression.
2404            dialect: the dialect used to parse the input expressions.
2405            copy: if `False`, modify this expression instance in-place.
2406            opts: other options to use to parse the input expressions.
2407
2408        Returns:
2409            The modified Join expression.
2410        """
2411        join = _apply_list_builder(
2412            *expressions,
2413            instance=self,
2414            arg="using",
2415            append=append,
2416            dialect=dialect,
2417            copy=copy,
2418            **opts,
2419        )
2420
2421        if join.kind == "CROSS":
2422            join.set("kind", None)
2423
2424        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False}
method: str
2319    @property
2320    def method(self) -> str:
2321        return self.text("method").upper()
kind: str
2323    @property
2324    def kind(self) -> str:
2325        return self.text("kind").upper()
side: str
2327    @property
2328    def side(self) -> str:
2329        return self.text("side").upper()
hint: str
2331    @property
2332    def hint(self) -> str:
2333        return self.text("hint").upper()
alias_or_name: str
2335    @property
2336    def alias_or_name(self) -> str:
2337        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2339    def on(
2340        self,
2341        *expressions: t.Optional[ExpOrStr],
2342        append: bool = True,
2343        dialect: DialectType = None,
2344        copy: bool = True,
2345        **opts,
2346    ) -> Join:
2347        """
2348        Append to or set the ON expressions.
2349
2350        Example:
2351            >>> import sqlglot
2352            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2353            'JOIN x ON y = 1'
2354
2355        Args:
2356            *expressions: the SQL code strings to parse.
2357                If an `Expression` instance is passed, it will be used as-is.
2358                Multiple expressions are combined with an AND operator.
2359            append: if `True`, AND the new expressions to any existing expression.
2360                Otherwise, this resets the expression.
2361            dialect: the dialect used to parse the input expressions.
2362            copy: if `False`, modify this expression instance in-place.
2363            opts: other options to use to parse the input expressions.
2364
2365        Returns:
2366            The modified Join expression.
2367        """
2368        join = _apply_conjunction_builder(
2369            *expressions,
2370            instance=self,
2371            arg="on",
2372            append=append,
2373            dialect=dialect,
2374            copy=copy,
2375            **opts,
2376        )
2377
2378        if join.kind == "CROSS":
2379            join.set("kind", None)
2380
2381        return join

Append to or set the ON expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
'JOIN x ON y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2383    def using(
2384        self,
2385        *expressions: t.Optional[ExpOrStr],
2386        append: bool = True,
2387        dialect: DialectType = None,
2388        copy: bool = True,
2389        **opts,
2390    ) -> Join:
2391        """
2392        Append to or set the USING expressions.
2393
2394        Example:
2395            >>> import sqlglot
2396            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2397            'JOIN x USING (foo, bla)'
2398
2399        Args:
2400            *expressions: the SQL code strings to parse.
2401                If an `Expression` instance is passed, it will be used as-is.
2402            append: if `True`, concatenate the new expressions to the existing "using" list.
2403                Otherwise, this resets the expression.
2404            dialect: the dialect used to parse the input expressions.
2405            copy: if `False`, modify this expression instance in-place.
2406            opts: other options to use to parse the input expressions.
2407
2408        Returns:
2409            The modified Join expression.
2410        """
2411        join = _apply_list_builder(
2412            *expressions,
2413            instance=self,
2414            arg="using",
2415            append=append,
2416            dialect=dialect,
2417            copy=copy,
2418            **opts,
2419        )
2420
2421        if join.kind == "CROSS":
2422            join.set("kind", None)
2423
2424        return join

Append to or set the USING expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
'JOIN x USING (foo, bla)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, concatenate the new expressions to the existing "using" list. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

key = 'join'
class Lateral(UDTF):
2427class Lateral(UDTF):
2428    arg_types = {
2429        "this": True,
2430        "view": False,
2431        "outer": False,
2432        "alias": False,
2433        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2434    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2437class MatchRecognizeMeasure(Expression):
2438    arg_types = {
2439        "this": True,
2440        "window_frame": False,
2441    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2444class MatchRecognize(Expression):
2445    arg_types = {
2446        "partition_by": False,
2447        "order": False,
2448        "measures": False,
2449        "rows": False,
2450        "after": False,
2451        "pattern": False,
2452        "define": False,
2453        "alias": False,
2454    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2459class Final(Expression):
2460    pass
key = 'final'
class Offset(Expression):
2463class Offset(Expression):
2464    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2467class Order(Expression):
2468    arg_types = {
2469        "this": False,
2470        "expressions": True,
2471        "interpolate": False,
2472        "siblings": False,
2473    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2477class WithFill(Expression):
2478    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2483class Cluster(Order):
2484    pass
key = 'cluster'
class Distribute(Order):
2487class Distribute(Order):
2488    pass
key = 'distribute'
class Sort(Order):
2491class Sort(Order):
2492    pass
key = 'sort'
class Ordered(Expression):
2495class Ordered(Expression):
2496    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2499class Property(Expression):
2500    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2503class AllowedValuesProperty(Expression):
2504    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2507class AlgorithmProperty(Property):
2508    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2511class AutoIncrementProperty(Property):
2512    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2516class AutoRefreshProperty(Property):
2517    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2520class BackupProperty(Property):
2521    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2524class BlockCompressionProperty(Property):
2525    arg_types = {
2526        "autotemp": False,
2527        "always": False,
2528        "default": False,
2529        "manual": False,
2530        "never": False,
2531    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2534class CharacterSetProperty(Property):
2535    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2538class ChecksumProperty(Property):
2539    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2542class CollateProperty(Property):
2543    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2546class CopyGrantsProperty(Property):
2547    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2550class DataBlocksizeProperty(Property):
2551    arg_types = {
2552        "size": False,
2553        "units": False,
2554        "minimum": False,
2555        "maximum": False,
2556        "default": False,
2557    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2560class DataDeletionProperty(Property):
2561    arg_types = {"on": True, "filter_col": False, "retention_period": False}
arg_types = {'on': True, 'filter_col': False, 'retention_period': False}
key = 'datadeletionproperty'
class DefinerProperty(Property):
2564class DefinerProperty(Property):
2565    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2568class DistKeyProperty(Property):
2569    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2572class DistStyleProperty(Property):
2573    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2576class EngineProperty(Property):
2577    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2580class HeapProperty(Property):
2581    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2584class ToTableProperty(Property):
2585    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2588class ExecuteAsProperty(Property):
2589    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2592class ExternalProperty(Property):
2593    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2596class FallbackProperty(Property):
2597    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2600class FileFormatProperty(Property):
2601    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2604class FreespaceProperty(Property):
2605    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2608class GlobalProperty(Property):
2609    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2612class IcebergProperty(Property):
2613    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2616class InheritsProperty(Property):
2617    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2620class InputModelProperty(Property):
2621    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2624class OutputModelProperty(Property):
2625    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2628class IsolatedLoadingProperty(Property):
2629    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2632class JournalProperty(Property):
2633    arg_types = {
2634        "no": False,
2635        "dual": False,
2636        "before": False,
2637        "local": False,
2638        "after": False,
2639    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2642class LanguageProperty(Property):
2643    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2647class ClusteredByProperty(Property):
2648    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2651class DictProperty(Property):
2652    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2655class DictSubProperty(Property):
2656    pass
key = 'dictsubproperty'
class DictRange(Property):
2659class DictRange(Property):
2660    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2663class DynamicProperty(Property):
2664    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2669class OnCluster(Property):
2670    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2673class LikeProperty(Property):
2674    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2677class LocationProperty(Property):
2678    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2681class LockProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2685class LockingProperty(Property):
2686    arg_types = {
2687        "this": False,
2688        "kind": True,
2689        "for_or_in": False,
2690        "lock_type": True,
2691        "override": False,
2692    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2695class LogProperty(Property):
2696    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2699class MaterializedProperty(Property):
2700    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2703class MergeBlockRatioProperty(Property):
2704    arg_types = {"this": False, "no": False, "default": False, "percent": False}
arg_types = {'this': False, 'no': False, 'default': False, 'percent': False}
key = 'mergeblockratioproperty'
class NoPrimaryIndexProperty(Property):
2707class NoPrimaryIndexProperty(Property):
2708    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2711class OnProperty(Property):
2712    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2715class OnCommitProperty(Property):
2716    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2719class PartitionedByProperty(Property):
2720    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2724class PartitionBoundSpec(Expression):
2725    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2726    arg_types = {
2727        "this": False,
2728        "expression": False,
2729        "from_expressions": False,
2730        "to_expressions": False,
2731    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2734class PartitionedOfProperty(Property):
2735    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2736    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2739class RemoteWithConnectionModelProperty(Property):
2740    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2743class ReturnsProperty(Property):
2744    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
arg_types = {'this': False, 'is_table': False, 'table': False, 'null': False}
key = 'returnsproperty'
class StrictProperty(Property):
2747class StrictProperty(Property):
2748    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2751class RowFormatProperty(Property):
2752    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2755class RowFormatDelimitedProperty(Property):
2756    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2757    arg_types = {
2758        "fields": False,
2759        "escaped": False,
2760        "collection_items": False,
2761        "map_keys": False,
2762        "lines": False,
2763        "null": False,
2764        "serde": False,
2765    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2768class RowFormatSerdeProperty(Property):
2769    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2773class QueryTransform(Expression):
2774    arg_types = {
2775        "expressions": True,
2776        "command_script": True,
2777        "schema": False,
2778        "row_format_before": False,
2779        "record_writer": False,
2780        "row_format_after": False,
2781        "record_reader": False,
2782    }
arg_types = {'expressions': True, 'command_script': True, 'schema': False, 'row_format_before': False, 'record_writer': False, 'row_format_after': False, 'record_reader': False}
key = 'querytransform'
class SampleProperty(Property):
2785class SampleProperty(Property):
2786    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2789class SchemaCommentProperty(Property):
2790    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2793class SerdeProperties(Property):
2794    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2797class SetProperty(Property):
2798    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2801class SharingProperty(Property):
2802    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2805class SetConfigProperty(Property):
2806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2809class SettingsProperty(Property):
2810    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2813class SortKeyProperty(Property):
2814    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2817class SqlReadWriteProperty(Property):
2818    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2821class SqlSecurityProperty(Property):
2822    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2825class StabilityProperty(Property):
2826    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2829class TemporaryProperty(Property):
2830    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2833class SecureProperty(Property):
2834    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2837class TransformModelProperty(Property):
2838    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2841class TransientProperty(Property):
2842    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2845class UnloggedProperty(Property):
2846    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2850class ViewAttributeProperty(Property):
2851    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2854class VolatileProperty(Property):
2855    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2858class WithDataProperty(Property):
2859    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2862class WithJournalTableProperty(Property):
2863    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2866class WithSchemaBindingProperty(Property):
2867    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2870class WithSystemVersioningProperty(Property):
2871    arg_types = {
2872        "on": False,
2873        "this": False,
2874        "data_consistency": False,
2875        "retention_period": False,
2876        "with": True,
2877    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2880class Properties(Expression):
2881    arg_types = {"expressions": True}
2882
2883    NAME_TO_PROPERTY = {
2884        "ALGORITHM": AlgorithmProperty,
2885        "AUTO_INCREMENT": AutoIncrementProperty,
2886        "CHARACTER SET": CharacterSetProperty,
2887        "CLUSTERED_BY": ClusteredByProperty,
2888        "COLLATE": CollateProperty,
2889        "COMMENT": SchemaCommentProperty,
2890        "DEFINER": DefinerProperty,
2891        "DISTKEY": DistKeyProperty,
2892        "DISTSTYLE": DistStyleProperty,
2893        "ENGINE": EngineProperty,
2894        "EXECUTE AS": ExecuteAsProperty,
2895        "FORMAT": FileFormatProperty,
2896        "LANGUAGE": LanguageProperty,
2897        "LOCATION": LocationProperty,
2898        "LOCK": LockProperty,
2899        "PARTITIONED_BY": PartitionedByProperty,
2900        "RETURNS": ReturnsProperty,
2901        "ROW_FORMAT": RowFormatProperty,
2902        "SORTKEY": SortKeyProperty,
2903    }
2904
2905    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2906
2907    # CREATE property locations
2908    # Form: schema specified
2909    #   create [POST_CREATE]
2910    #     table a [POST_NAME]
2911    #     (b int) [POST_SCHEMA]
2912    #     with ([POST_WITH])
2913    #     index (b) [POST_INDEX]
2914    #
2915    # Form: alias selection
2916    #   create [POST_CREATE]
2917    #     table a [POST_NAME]
2918    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2919    #     index (c) [POST_INDEX]
2920    class Location(AutoName):
2921        POST_CREATE = auto()
2922        POST_NAME = auto()
2923        POST_SCHEMA = auto()
2924        POST_WITH = auto()
2925        POST_ALIAS = auto()
2926        POST_EXPRESSION = auto()
2927        POST_INDEX = auto()
2928        UNSUPPORTED = auto()
2929
2930    @classmethod
2931    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2932        expressions = []
2933        for key, value in properties_dict.items():
2934            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2935            if property_cls:
2936                expressions.append(property_cls(this=convert(value)))
2937            else:
2938                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2939
2940        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2930    @classmethod
2931    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2932        expressions = []
2933        for key, value in properties_dict.items():
2934            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2935            if property_cls:
2936                expressions.append(property_cls(this=convert(value)))
2937            else:
2938                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2939
2940        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2920    class Location(AutoName):
2921        POST_CREATE = auto()
2922        POST_NAME = auto()
2923        POST_SCHEMA = auto()
2924        POST_WITH = auto()
2925        POST_ALIAS = auto()
2926        POST_EXPRESSION = auto()
2927        POST_INDEX = auto()
2928        UNSUPPORTED = auto()

An enumeration.

POST_CREATE = <Location.POST_CREATE: 'POST_CREATE'>
POST_NAME = <Location.POST_NAME: 'POST_NAME'>
POST_SCHEMA = <Location.POST_SCHEMA: 'POST_SCHEMA'>
POST_WITH = <Location.POST_WITH: 'POST_WITH'>
POST_ALIAS = <Location.POST_ALIAS: 'POST_ALIAS'>
POST_EXPRESSION = <Location.POST_EXPRESSION: 'POST_EXPRESSION'>
POST_INDEX = <Location.POST_INDEX: 'POST_INDEX'>
UNSUPPORTED = <Location.UNSUPPORTED: 'UNSUPPORTED'>
Inherited Members
enum.Enum
name
value
class Qualify(Expression):
2943class Qualify(Expression):
2944    pass
key = 'qualify'
class InputOutputFormat(Expression):
2947class InputOutputFormat(Expression):
2948    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2952class Return(Expression):
2953    pass
key = 'return'
class Reference(Expression):
2956class Reference(Expression):
2957    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2960class Tuple(Expression):
2961    arg_types = {"expressions": False}
2962
2963    def isin(
2964        self,
2965        *expressions: t.Any,
2966        query: t.Optional[ExpOrStr] = None,
2967        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2968        copy: bool = True,
2969        **opts,
2970    ) -> In:
2971        return In(
2972            this=maybe_copy(self, copy),
2973            expressions=[convert(e, copy=copy) for e in expressions],
2974            query=maybe_parse(query, copy=copy, **opts) if query else None,
2975            unnest=(
2976                Unnest(
2977                    expressions=[
2978                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2979                        for e in ensure_list(unnest)
2980                    ]
2981                )
2982                if unnest
2983                else None
2984            ),
2985        )
arg_types = {'expressions': False}
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
2963    def isin(
2964        self,
2965        *expressions: t.Any,
2966        query: t.Optional[ExpOrStr] = None,
2967        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2968        copy: bool = True,
2969        **opts,
2970    ) -> In:
2971        return In(
2972            this=maybe_copy(self, copy),
2973            expressions=[convert(e, copy=copy) for e in expressions],
2974            query=maybe_parse(query, copy=copy, **opts) if query else None,
2975            unnest=(
2976                Unnest(
2977                    expressions=[
2978                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2979                        for e in ensure_list(unnest)
2980                    ]
2981                )
2982                if unnest
2983                else None
2984            ),
2985        )
key = 'tuple'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
class QueryOption(Expression):
3016class QueryOption(Expression):
3017    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3021class WithTableHint(Expression):
3022    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3026class IndexTableHint(Expression):
3027    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3031class HistoricalData(Expression):
3032    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3035class Table(Expression):
3036    arg_types = {
3037        "this": False,
3038        "alias": False,
3039        "db": False,
3040        "catalog": False,
3041        "laterals": False,
3042        "joins": False,
3043        "pivots": False,
3044        "hints": False,
3045        "system_time": False,
3046        "version": False,
3047        "format": False,
3048        "pattern": False,
3049        "ordinality": False,
3050        "when": False,
3051        "only": False,
3052        "partition": False,
3053        "changes": False,
3054        "rows_from": False,
3055    }
3056
3057    @property
3058    def name(self) -> str:
3059        if isinstance(self.this, Func):
3060            return ""
3061        return self.this.name
3062
3063    @property
3064    def db(self) -> str:
3065        return self.text("db")
3066
3067    @property
3068    def catalog(self) -> str:
3069        return self.text("catalog")
3070
3071    @property
3072    def selects(self) -> t.List[Expression]:
3073        return []
3074
3075    @property
3076    def named_selects(self) -> t.List[str]:
3077        return []
3078
3079    @property
3080    def parts(self) -> t.List[Expression]:
3081        """Return the parts of a table in order catalog, db, table."""
3082        parts: t.List[Expression] = []
3083
3084        for arg in ("catalog", "db", "this"):
3085            part = self.args.get(arg)
3086
3087            if isinstance(part, Dot):
3088                parts.extend(part.flatten())
3089            elif isinstance(part, Expression):
3090                parts.append(part)
3091
3092        return parts
3093
3094    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3095        parts = self.parts
3096        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3097        alias = self.args.get("alias")
3098        if alias:
3099            col = alias_(col, alias.this, copy=copy)
3100        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False, 'partition': False, 'changes': False, 'rows_from': False}
name: str
3057    @property
3058    def name(self) -> str:
3059        if isinstance(self.this, Func):
3060            return ""
3061        return self.this.name
db: str
3063    @property
3064    def db(self) -> str:
3065        return self.text("db")
catalog: str
3067    @property
3068    def catalog(self) -> str:
3069        return self.text("catalog")
selects: List[Expression]
3071    @property
3072    def selects(self) -> t.List[Expression]:
3073        return []
named_selects: List[str]
3075    @property
3076    def named_selects(self) -> t.List[str]:
3077        return []
parts: List[Expression]
3079    @property
3080    def parts(self) -> t.List[Expression]:
3081        """Return the parts of a table in order catalog, db, table."""
3082        parts: t.List[Expression] = []
3083
3084        for arg in ("catalog", "db", "this"):
3085            part = self.args.get(arg)
3086
3087            if isinstance(part, Dot):
3088                parts.extend(part.flatten())
3089            elif isinstance(part, Expression):
3090                parts.append(part)
3091
3092        return parts

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

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

Append to or set the SELECT expressions.

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

The modified Query expression.

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

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

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

Set the FROM expression.

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

The modified Select expression.

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

Set the GROUP BY expression.

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

The modified Select expression.

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

Set the SORT BY expression.

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

The modified Select expression.

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

Set the CLUSTER BY expression.

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

The modified Select expression.

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

Append to or set the SELECT expressions.

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

The modified Query expression.

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

Append to or set the LATERAL expressions.

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

The modified Select expression.

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

Append to or set the JOIN expressions.

Example:
>>> Select()select("*")from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
>>> Select()select("1")from_("a").join("b", using=["x", "y", "z"]).sql()
'SELECT 1 FROM a JOIN b USING (x, y, z)'

Use join_type to change the type of join:

>>> Select()select("*")from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • join_type: if set, alter the parsed join type.
  • join_alias: an optional alias for the joined source.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

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

Append to or set the WHERE expressions.

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

Select: the modified expression.

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

Append to or set the HAVING expressions.

Example:
>>> Select()select("x", "COUNT(y)")from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3608    def window(
3609        self,
3610        *expressions: t.Optional[ExpOrStr],
3611        append: bool = True,
3612        dialect: DialectType = None,
3613        copy: bool = True,
3614        **opts,
3615    ) -> Select:
3616        return _apply_list_builder(
3617            *expressions,
3618            instance=self,
3619            arg="windows",
3620            append=append,
3621            into=Window,
3622            dialect=dialect,
3623            copy=copy,
3624            **opts,
3625        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3627    def qualify(
3628        self,
3629        *expressions: t.Optional[ExpOrStr],
3630        append: bool = True,
3631        dialect: DialectType = None,
3632        copy: bool = True,
3633        **opts,
3634    ) -> Select:
3635        return _apply_conjunction_builder(
3636            *expressions,
3637            instance=self,
3638            arg="qualify",
3639            append=append,
3640            into=Qualify,
3641            dialect=dialect,
3642            copy=copy,
3643            **opts,
3644        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3646    def distinct(
3647        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3648    ) -> Select:
3649        """
3650        Set the OFFSET expression.
3651
3652        Example:
3653            >>> Select().from_("tbl").select("x").distinct().sql()
3654            'SELECT DISTINCT x FROM tbl'
3655
3656        Args:
3657            ons: the expressions to distinct on
3658            distinct: whether the Select should be distinct
3659            copy: if `False`, modify this expression instance in-place.
3660
3661        Returns:
3662            Select: the modified expression.
3663        """
3664        instance = maybe_copy(self, copy)
3665        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3666        instance.set("distinct", Distinct(on=on) if distinct else None)
3667        return instance

Set the OFFSET expression.

Example:
>>> Select()from_("tbl")select("x").distinct().sql()
'SELECT DISTINCT x FROM tbl'
Arguments:
  • ons: the expressions to distinct on
  • distinct: whether the Select should be distinct
  • copy: if False, modify this expression instance in-place.
Returns:

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
3669    def ctas(
3670        self,
3671        table: ExpOrStr,
3672        properties: t.Optional[t.Dict] = None,
3673        dialect: DialectType = None,
3674        copy: bool = True,
3675        **opts,
3676    ) -> Create:
3677        """
3678        Convert this expression to a CREATE TABLE AS statement.
3679
3680        Example:
3681            >>> Select().select("*").from_("tbl").ctas("x").sql()
3682            'CREATE TABLE x AS SELECT * FROM tbl'
3683
3684        Args:
3685            table: the SQL code string to parse as the table name.
3686                If another `Expression` instance is passed, it will be used as-is.
3687            properties: an optional mapping of table properties
3688            dialect: the dialect used to parse the input table.
3689            copy: if `False`, modify this expression instance in-place.
3690            opts: other options to use to parse the input table.
3691
3692        Returns:
3693            The new Create expression.
3694        """
3695        instance = maybe_copy(self, copy)
3696        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3697
3698        properties_expression = None
3699        if properties:
3700            properties_expression = Properties.from_dict(properties)
3701
3702        return Create(
3703            this=table_expression,
3704            kind="TABLE",
3705            expression=instance,
3706            properties=properties_expression,
3707        )

Convert this expression to a CREATE TABLE AS statement.

Example:
>>> Select()select("*")from_("tbl").ctas("x").sql()
'CREATE TABLE x AS SELECT * FROM tbl'
Arguments:
  • table: the SQL code string to parse as the table name. If another Expression instance is passed, it will be used as-is.
  • properties: an optional mapping of table properties
  • dialect: the dialect used to parse the input table.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input table.
Returns:

The new Create expression.

def lock( self, update: bool = True, copy: bool = True) -> Select:
3709    def lock(self, update: bool = True, copy: bool = True) -> Select:
3710        """
3711        Set the locking read mode for this expression.
3712
3713        Examples:
3714            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3715            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3716
3717            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3718            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3719
3720        Args:
3721            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3722            copy: if `False`, modify this expression instance in-place.
3723
3724        Returns:
3725            The modified expression.
3726        """
3727        inst = maybe_copy(self, copy)
3728        inst.set("locks", [Lock(update=update)])
3729
3730        return inst

Set the locking read mode for this expression.

Examples:
>>> Select()select("x")from_("tbl").where("x = 'a'").lock().sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
>>> Select()select("x")from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
Arguments:
  • update: if True, the locking type will be FOR UPDATE, else it will be FOR SHARE.
  • copy: if False, modify this expression instance in-place.
Returns:

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
3732    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3733        """
3734        Set hints for this expression.
3735
3736        Examples:
3737            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3738            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3739
3740        Args:
3741            hints: The SQL code strings to parse as the hints.
3742                If an `Expression` instance is passed, it will be used as-is.
3743            dialect: The dialect used to parse the hints.
3744            copy: If `False`, modify this expression instance in-place.
3745
3746        Returns:
3747            The modified expression.
3748        """
3749        inst = maybe_copy(self, copy)
3750        inst.set(
3751            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3752        )
3753
3754        return inst

Set hints for this expression.

Examples:
>>> Select()select("x")from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
'SELECT /*+ BROADCAST(y) */ x FROM tbl'
Arguments:
  • hints: The SQL code strings to parse as the hints. If an Expression instance is passed, it will be used as-is.
  • dialect: The dialect used to parse the hints.
  • copy: If False, modify this expression instance in-place.
Returns:

The modified expression.

named_selects: List[str]
3756    @property
3757    def named_selects(self) -> t.List[str]:
3758        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
3760    @property
3761    def is_star(self) -> bool:
3762        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

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

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3787    def unwrap(self) -> Subquery:
3788        expression = self
3789        while expression.same_parent and expression.is_wrapper:
3790            expression = t.cast(Subquery, expression.parent)
3791        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
3793    def select(
3794        self,
3795        *expressions: t.Optional[ExpOrStr],
3796        append: bool = True,
3797        dialect: DialectType = None,
3798        copy: bool = True,
3799        **opts,
3800    ) -> Subquery:
3801        this = maybe_copy(self, copy)
3802        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3803        return this

Append to or set the SELECT expressions.

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

The modified Query expression.

is_wrapper: bool
3805    @property
3806    def is_wrapper(self) -> bool:
3807        """
3808        Whether this Subquery acts as a simple wrapper around another expression.
3809
3810        SELECT * FROM (((SELECT * FROM t)))
3811                      ^
3812                      This corresponds to a "wrapper" Subquery node
3813        """
3814        return all(v is None for k, v in self.args.items() if k != "this")

Whether this Subquery acts as a simple wrapper around another expression.

SELECT * FROM (((SELECT * FROM t))) ^ This corresponds to a "wrapper" Subquery node

is_star: bool
3816    @property
3817    def is_star(self) -> bool:
3818        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3820    @property
3821    def output_name(self) -> str:
3822        return self.alias

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'subquery'
class TableSample(Expression):
3825class TableSample(Expression):
3826    arg_types = {
3827        "this": False,
3828        "expressions": False,
3829        "method": False,
3830        "bucket_numerator": False,
3831        "bucket_denominator": False,
3832        "bucket_field": False,
3833        "percent": False,
3834        "rows": False,
3835        "size": False,
3836        "seed": False,
3837    }
arg_types = {'this': False, 'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
3840class Tag(Expression):
3841    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3842
3843    arg_types = {
3844        "this": False,
3845        "prefix": False,
3846        "postfix": False,
3847    }

Tags are used for generating arbitrary sql like SELECT x.

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

Returns a Python object equivalent of the SQL node.

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

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
3944class DataTypeParam(Expression):
3945    arg_types = {"this": True, "expression": False}
3946
3947    @property
3948    def name(self) -> str:
3949        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3947    @property
3948    def name(self) -> str:
3949        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3952class DataType(Expression):
3953    arg_types = {
3954        "this": True,
3955        "expressions": False,
3956        "nested": False,
3957        "values": False,
3958        "prefix": False,
3959        "kind": False,
3960    }
3961
3962    class Type(AutoName):
3963        ARRAY = auto()
3964        AGGREGATEFUNCTION = auto()
3965        SIMPLEAGGREGATEFUNCTION = auto()
3966        BIGDECIMAL = auto()
3967        BIGINT = auto()
3968        BIGSERIAL = auto()
3969        BINARY = auto()
3970        BIT = auto()
3971        BOOLEAN = auto()
3972        BPCHAR = auto()
3973        CHAR = auto()
3974        DATE = auto()
3975        DATE32 = auto()
3976        DATEMULTIRANGE = auto()
3977        DATERANGE = auto()
3978        DATETIME = auto()
3979        DATETIME64 = auto()
3980        DECIMAL = auto()
3981        DOUBLE = auto()
3982        ENUM = auto()
3983        ENUM8 = auto()
3984        ENUM16 = auto()
3985        FIXEDSTRING = auto()
3986        FLOAT = auto()
3987        GEOGRAPHY = auto()
3988        GEOMETRY = auto()
3989        HLLSKETCH = auto()
3990        HSTORE = auto()
3991        IMAGE = auto()
3992        INET = auto()
3993        INT = auto()
3994        INT128 = auto()
3995        INT256 = auto()
3996        INT4MULTIRANGE = auto()
3997        INT4RANGE = auto()
3998        INT8MULTIRANGE = auto()
3999        INT8RANGE = auto()
4000        INTERVAL = auto()
4001        IPADDRESS = auto()
4002        IPPREFIX = auto()
4003        IPV4 = auto()
4004        IPV6 = auto()
4005        JSON = auto()
4006        JSONB = auto()
4007        LIST = auto()
4008        LONGBLOB = auto()
4009        LONGTEXT = auto()
4010        LOWCARDINALITY = auto()
4011        MAP = auto()
4012        MEDIUMBLOB = auto()
4013        MEDIUMINT = auto()
4014        MEDIUMTEXT = auto()
4015        MONEY = auto()
4016        NAME = auto()
4017        NCHAR = auto()
4018        NESTED = auto()
4019        NULL = auto()
4020        NULLABLE = auto()
4021        NUMMULTIRANGE = auto()
4022        NUMRANGE = auto()
4023        NVARCHAR = auto()
4024        OBJECT = auto()
4025        ROWVERSION = auto()
4026        SERIAL = auto()
4027        SET = auto()
4028        SMALLINT = auto()
4029        SMALLMONEY = auto()
4030        SMALLSERIAL = auto()
4031        STRUCT = auto()
4032        SUPER = auto()
4033        TEXT = auto()
4034        TINYBLOB = auto()
4035        TINYTEXT = auto()
4036        TIME = auto()
4037        TIMETZ = auto()
4038        TIMESTAMP = auto()
4039        TIMESTAMPNTZ = auto()
4040        TIMESTAMPLTZ = auto()
4041        TIMESTAMPTZ = auto()
4042        TIMESTAMP_S = auto()
4043        TIMESTAMP_MS = auto()
4044        TIMESTAMP_NS = auto()
4045        TINYINT = auto()
4046        TSMULTIRANGE = auto()
4047        TSRANGE = auto()
4048        TSTZMULTIRANGE = auto()
4049        TSTZRANGE = auto()
4050        UBIGINT = auto()
4051        UINT = auto()
4052        UINT128 = auto()
4053        UINT256 = auto()
4054        UMEDIUMINT = auto()
4055        UDECIMAL = auto()
4056        UNIQUEIDENTIFIER = auto()
4057        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4058        USERDEFINED = "USER-DEFINED"
4059        USMALLINT = auto()
4060        UTINYINT = auto()
4061        UUID = auto()
4062        VARBINARY = auto()
4063        VARCHAR = auto()
4064        VARIANT = auto()
4065        VECTOR = auto()
4066        XML = auto()
4067        YEAR = auto()
4068        TDIGEST = auto()
4069
4070    STRUCT_TYPES = {
4071        Type.NESTED,
4072        Type.OBJECT,
4073        Type.STRUCT,
4074    }
4075
4076    NESTED_TYPES = {
4077        *STRUCT_TYPES,
4078        Type.ARRAY,
4079        Type.MAP,
4080    }
4081
4082    TEXT_TYPES = {
4083        Type.CHAR,
4084        Type.NCHAR,
4085        Type.NVARCHAR,
4086        Type.TEXT,
4087        Type.VARCHAR,
4088        Type.NAME,
4089    }
4090
4091    SIGNED_INTEGER_TYPES = {
4092        Type.BIGINT,
4093        Type.INT,
4094        Type.INT128,
4095        Type.INT256,
4096        Type.MEDIUMINT,
4097        Type.SMALLINT,
4098        Type.TINYINT,
4099    }
4100
4101    UNSIGNED_INTEGER_TYPES = {
4102        Type.UBIGINT,
4103        Type.UINT,
4104        Type.UINT128,
4105        Type.UINT256,
4106        Type.UMEDIUMINT,
4107        Type.USMALLINT,
4108        Type.UTINYINT,
4109    }
4110
4111    INTEGER_TYPES = {
4112        *SIGNED_INTEGER_TYPES,
4113        *UNSIGNED_INTEGER_TYPES,
4114        Type.BIT,
4115    }
4116
4117    FLOAT_TYPES = {
4118        Type.DOUBLE,
4119        Type.FLOAT,
4120    }
4121
4122    REAL_TYPES = {
4123        *FLOAT_TYPES,
4124        Type.BIGDECIMAL,
4125        Type.DECIMAL,
4126        Type.MONEY,
4127        Type.SMALLMONEY,
4128        Type.UDECIMAL,
4129    }
4130
4131    NUMERIC_TYPES = {
4132        *INTEGER_TYPES,
4133        *REAL_TYPES,
4134    }
4135
4136    TEMPORAL_TYPES = {
4137        Type.DATE,
4138        Type.DATE32,
4139        Type.DATETIME,
4140        Type.DATETIME64,
4141        Type.TIME,
4142        Type.TIMESTAMP,
4143        Type.TIMESTAMPNTZ,
4144        Type.TIMESTAMPLTZ,
4145        Type.TIMESTAMPTZ,
4146        Type.TIMESTAMP_MS,
4147        Type.TIMESTAMP_NS,
4148        Type.TIMESTAMP_S,
4149        Type.TIMETZ,
4150    }
4151
4152    @classmethod
4153    def build(
4154        cls,
4155        dtype: DATA_TYPE,
4156        dialect: DialectType = None,
4157        udt: bool = False,
4158        copy: bool = True,
4159        **kwargs,
4160    ) -> DataType:
4161        """
4162        Constructs a DataType object.
4163
4164        Args:
4165            dtype: the data type of interest.
4166            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4167            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4168                DataType, thus creating a user-defined type.
4169            copy: whether to copy the data type.
4170            kwargs: additional arguments to pass in the constructor of DataType.
4171
4172        Returns:
4173            The constructed DataType object.
4174        """
4175        from sqlglot import parse_one
4176
4177        if isinstance(dtype, str):
4178            if dtype.upper() == "UNKNOWN":
4179                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4180
4181            try:
4182                data_type_exp = parse_one(
4183                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4184                )
4185            except ParseError:
4186                if udt:
4187                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4188                raise
4189        elif isinstance(dtype, DataType.Type):
4190            data_type_exp = DataType(this=dtype)
4191        elif isinstance(dtype, DataType):
4192            return maybe_copy(dtype, copy)
4193        else:
4194            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4195
4196        return DataType(**{**data_type_exp.args, **kwargs})
4197
4198    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4199        """
4200        Checks whether this DataType matches one of the provided data types. Nested types or precision
4201        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4202
4203        Args:
4204            dtypes: the data types to compare this DataType to.
4205
4206        Returns:
4207            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4208        """
4209        for dtype in dtypes:
4210            other = DataType.build(dtype, copy=False, udt=True)
4211
4212            if (
4213                other.expressions
4214                or self.this == DataType.Type.USERDEFINED
4215                or other.this == DataType.Type.USERDEFINED
4216            ):
4217                matches = self == other
4218            else:
4219                matches = self.this == other.this
4220
4221            if matches:
4222                return True
4223        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>}
NESTED_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.MAP: 'MAP'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLINT: 'SMALLINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>}
INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.INT: 'INT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.MONEY: 'MONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.INT: 'INT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.BIGINT: 'BIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.MONEY: 'MONEY'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT256: 'UINT256'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME64: 'DATETIME64'>}
@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:
4152    @classmethod
4153    def build(
4154        cls,
4155        dtype: DATA_TYPE,
4156        dialect: DialectType = None,
4157        udt: bool = False,
4158        copy: bool = True,
4159        **kwargs,
4160    ) -> DataType:
4161        """
4162        Constructs a DataType object.
4163
4164        Args:
4165            dtype: the data type of interest.
4166            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4167            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4168                DataType, thus creating a user-defined type.
4169            copy: whether to copy the data type.
4170            kwargs: additional arguments to pass in the constructor of DataType.
4171
4172        Returns:
4173            The constructed DataType object.
4174        """
4175        from sqlglot import parse_one
4176
4177        if isinstance(dtype, str):
4178            if dtype.upper() == "UNKNOWN":
4179                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4180
4181            try:
4182                data_type_exp = parse_one(
4183                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4184                )
4185            except ParseError:
4186                if udt:
4187                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4188                raise
4189        elif isinstance(dtype, DataType.Type):
4190            data_type_exp = DataType(this=dtype)
4191        elif isinstance(dtype, DataType):
4192            return maybe_copy(dtype, copy)
4193        else:
4194            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4195
4196        return DataType(**{**data_type_exp.args, **kwargs})

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:
4198    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4199        """
4200        Checks whether this DataType matches one of the provided data types. Nested types or precision
4201        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4202
4203        Args:
4204            dtypes: the data types to compare this DataType to.
4205
4206        Returns:
4207            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4208        """
4209        for dtype in dtypes:
4210            other = DataType.build(dtype, copy=False, udt=True)
4211
4212            if (
4213                other.expressions
4214                or self.this == DataType.Type.USERDEFINED
4215                or other.this == DataType.Type.USERDEFINED
4216            ):
4217                matches = self == other
4218            else:
4219                matches = self.this == other.this
4220
4221            if matches:
4222                return True
4223        return False

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):
3962    class Type(AutoName):
3963        ARRAY = auto()
3964        AGGREGATEFUNCTION = auto()
3965        SIMPLEAGGREGATEFUNCTION = auto()
3966        BIGDECIMAL = auto()
3967        BIGINT = auto()
3968        BIGSERIAL = auto()
3969        BINARY = auto()
3970        BIT = auto()
3971        BOOLEAN = auto()
3972        BPCHAR = auto()
3973        CHAR = auto()
3974        DATE = auto()
3975        DATE32 = auto()
3976        DATEMULTIRANGE = auto()
3977        DATERANGE = auto()
3978        DATETIME = auto()
3979        DATETIME64 = auto()
3980        DECIMAL = auto()
3981        DOUBLE = auto()
3982        ENUM = auto()
3983        ENUM8 = auto()
3984        ENUM16 = auto()
3985        FIXEDSTRING = auto()
3986        FLOAT = auto()
3987        GEOGRAPHY = auto()
3988        GEOMETRY = auto()
3989        HLLSKETCH = auto()
3990        HSTORE = auto()
3991        IMAGE = auto()
3992        INET = auto()
3993        INT = auto()
3994        INT128 = auto()
3995        INT256 = auto()
3996        INT4MULTIRANGE = auto()
3997        INT4RANGE = auto()
3998        INT8MULTIRANGE = auto()
3999        INT8RANGE = auto()
4000        INTERVAL = auto()
4001        IPADDRESS = auto()
4002        IPPREFIX = auto()
4003        IPV4 = auto()
4004        IPV6 = auto()
4005        JSON = auto()
4006        JSONB = auto()
4007        LIST = auto()
4008        LONGBLOB = auto()
4009        LONGTEXT = auto()
4010        LOWCARDINALITY = auto()
4011        MAP = auto()
4012        MEDIUMBLOB = auto()
4013        MEDIUMINT = auto()
4014        MEDIUMTEXT = auto()
4015        MONEY = auto()
4016        NAME = auto()
4017        NCHAR = auto()
4018        NESTED = auto()
4019        NULL = auto()
4020        NULLABLE = auto()
4021        NUMMULTIRANGE = auto()
4022        NUMRANGE = auto()
4023        NVARCHAR = auto()
4024        OBJECT = auto()
4025        ROWVERSION = auto()
4026        SERIAL = auto()
4027        SET = auto()
4028        SMALLINT = auto()
4029        SMALLMONEY = auto()
4030        SMALLSERIAL = auto()
4031        STRUCT = auto()
4032        SUPER = auto()
4033        TEXT = auto()
4034        TINYBLOB = auto()
4035        TINYTEXT = auto()
4036        TIME = auto()
4037        TIMETZ = auto()
4038        TIMESTAMP = auto()
4039        TIMESTAMPNTZ = auto()
4040        TIMESTAMPLTZ = auto()
4041        TIMESTAMPTZ = auto()
4042        TIMESTAMP_S = auto()
4043        TIMESTAMP_MS = auto()
4044        TIMESTAMP_NS = auto()
4045        TINYINT = auto()
4046        TSMULTIRANGE = auto()
4047        TSRANGE = auto()
4048        TSTZMULTIRANGE = auto()
4049        TSTZRANGE = auto()
4050        UBIGINT = auto()
4051        UINT = auto()
4052        UINT128 = auto()
4053        UINT256 = auto()
4054        UMEDIUMINT = auto()
4055        UDECIMAL = auto()
4056        UNIQUEIDENTIFIER = auto()
4057        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4058        USERDEFINED = "USER-DEFINED"
4059        USMALLINT = auto()
4060        UTINYINT = auto()
4061        UUID = auto()
4062        VARBINARY = auto()
4063        VARCHAR = auto()
4064        VARIANT = auto()
4065        VECTOR = auto()
4066        XML = auto()
4067        YEAR = auto()
4068        TDIGEST = auto()

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):
4230class PseudoType(DataType):
4231    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4235class ObjectIdentifier(DataType):
4236    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4240class SubqueryPredicate(Predicate):
4241    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4244class All(SubqueryPredicate):
4245    pass
key = 'all'
class Any(SubqueryPredicate):
4248class Any(SubqueryPredicate):
4249    pass
key = 'any'
class Exists(SubqueryPredicate):
4252class Exists(SubqueryPredicate):
4253    pass
key = 'exists'
class Command(Expression):
4258class Command(Expression):
4259    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4262class Transaction(Expression):
4263    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4266class Commit(Expression):
4267    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4270class Rollback(Expression):
4271    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4274class AlterTable(Expression):
4275    arg_types = {
4276        "this": True,
4277        "actions": True,
4278        "exists": False,
4279        "only": False,
4280        "options": False,
4281        "cluster": False,
4282    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4285class AddConstraint(Expression):
4286    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4289class DropPartition(Expression):
4290    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4294class ReplacePartition(Expression):
4295    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4299class Binary(Condition):
4300    arg_types = {"this": True, "expression": True}
4301
4302    @property
4303    def left(self) -> Expression:
4304        return self.this
4305
4306    @property
4307    def right(self) -> Expression:
4308        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4302    @property
4303    def left(self) -> Expression:
4304        return self.this
right: Expression
4306    @property
4307    def right(self) -> Expression:
4308        return self.expression
key = 'binary'
class Add(Binary):
4311class Add(Binary):
4312    pass
key = 'add'
class Connector(Binary):
4315class Connector(Binary):
4316    pass
key = 'connector'
class And(Connector):
4319class And(Connector):
4320    pass
key = 'and'
class Or(Connector):
4323class Or(Connector):
4324    pass
key = 'or'
class BitwiseAnd(Binary):
4327class BitwiseAnd(Binary):
4328    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4331class BitwiseLeftShift(Binary):
4332    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4335class BitwiseOr(Binary):
4336    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4339class BitwiseRightShift(Binary):
4340    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4343class BitwiseXor(Binary):
4344    pass
key = 'bitwisexor'
class Div(Binary):
4347class Div(Binary):
4348    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):
4351class Overlaps(Binary):
4352    pass
key = 'overlaps'
class Dot(Binary):
4355class Dot(Binary):
4356    @property
4357    def is_star(self) -> bool:
4358        return self.expression.is_star
4359
4360    @property
4361    def name(self) -> str:
4362        return self.expression.name
4363
4364    @property
4365    def output_name(self) -> str:
4366        return self.name
4367
4368    @classmethod
4369    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4370        """Build a Dot object with a sequence of expressions."""
4371        if len(expressions) < 2:
4372            raise ValueError("Dot requires >= 2 expressions.")
4373
4374        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4375
4376    @property
4377    def parts(self) -> t.List[Expression]:
4378        """Return the parts of a table / column in order catalog, db, table."""
4379        this, *parts = self.flatten()
4380
4381        parts.reverse()
4382
4383        for arg in COLUMN_PARTS:
4384            part = this.args.get(arg)
4385
4386            if isinstance(part, Expression):
4387                parts.append(part)
4388
4389        parts.reverse()
4390        return parts
is_star: bool
4356    @property
4357    def is_star(self) -> bool:
4358        return self.expression.is_star

Checks whether an expression is a star.

name: str
4360    @property
4361    def name(self) -> str:
4362        return self.expression.name
output_name: str
4364    @property
4365    def output_name(self) -> str:
4366        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:
4368    @classmethod
4369    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4370        """Build a Dot object with a sequence of expressions."""
4371        if len(expressions) < 2:
4372            raise ValueError("Dot requires >= 2 expressions.")
4373
4374        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
4376    @property
4377    def parts(self) -> t.List[Expression]:
4378        """Return the parts of a table / column in order catalog, db, table."""
4379        this, *parts = self.flatten()
4380
4381        parts.reverse()
4382
4383        for arg in COLUMN_PARTS:
4384            part = this.args.get(arg)
4385
4386            if isinstance(part, Expression):
4387                parts.append(part)
4388
4389        parts.reverse()
4390        return parts

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

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

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

key = 'kwarg'
class Like(Binary, Predicate):
4454class Like(Binary, Predicate):
4455    pass
key = 'like'
class LikeAny(Binary, Predicate):
4458class LikeAny(Binary, Predicate):
4459    pass
key = 'likeany'
class LT(Binary, Predicate):
4462class LT(Binary, Predicate):
4463    pass
key = 'lt'
class LTE(Binary, Predicate):
4466class LTE(Binary, Predicate):
4467    pass
key = 'lte'
class Mod(Binary):
4470class Mod(Binary):
4471    pass
key = 'mod'
class Mul(Binary):
4474class Mul(Binary):
4475    pass
key = 'mul'
class NEQ(Binary, Predicate):
4478class NEQ(Binary, Predicate):
4479    pass
key = 'neq'
class Operator(Binary):
4483class Operator(Binary):
4484    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4487class SimilarTo(Binary, Predicate):
4488    pass
key = 'similarto'
class Slice(Binary):
4491class Slice(Binary):
4492    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4495class Sub(Binary):
4496    pass
key = 'sub'
class Unary(Condition):
4501class Unary(Condition):
4502    pass
key = 'unary'
class BitwiseNot(Unary):
4505class BitwiseNot(Unary):
4506    pass
key = 'bitwisenot'
class Not(Unary):
4509class Not(Unary):
4510    pass
key = 'not'
class Paren(Unary):
4513class Paren(Unary):
4514    @property
4515    def output_name(self) -> str:
4516        return self.this.name
output_name: str
4514    @property
4515    def output_name(self) -> str:
4516        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):
4519class Neg(Unary):
4520    def to_py(self) -> int | Decimal:
4521        if self.is_number:
4522            return self.this.to_py() * -1
4523        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4520    def to_py(self) -> int | Decimal:
4521        if self.is_number:
4522            return self.this.to_py() * -1
4523        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4526class Alias(Expression):
4527    arg_types = {"this": True, "alias": False}
4528
4529    @property
4530    def output_name(self) -> str:
4531        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4529    @property
4530    def output_name(self) -> str:
4531        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):
4536class PivotAlias(Alias):
4537    pass
key = 'pivotalias'
class Aliases(Expression):
4540class Aliases(Expression):
4541    arg_types = {"this": True, "expressions": True}
4542
4543    @property
4544    def aliases(self):
4545        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4543    @property
4544    def aliases(self):
4545        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4549class AtIndex(Expression):
4550    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4553class AtTimeZone(Expression):
4554    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4557class FromTimeZone(Expression):
4558    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4561class Between(Predicate):
4562    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4565class Bracket(Condition):
4566    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4567    arg_types = {
4568        "this": True,
4569        "expressions": True,
4570        "offset": False,
4571        "safe": False,
4572        "returns_list_for_maps": False,
4573    }
4574
4575    @property
4576    def output_name(self) -> str:
4577        if len(self.expressions) == 1:
4578            return self.expressions[0].output_name
4579
4580        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4575    @property
4576    def output_name(self) -> str:
4577        if len(self.expressions) == 1:
4578            return self.expressions[0].output_name
4579
4580        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):
4583class Distinct(Expression):
4584    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4587class In(Predicate):
4588    arg_types = {
4589        "this": True,
4590        "expressions": False,
4591        "query": False,
4592        "unnest": False,
4593        "field": False,
4594        "is_global": False,
4595    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4599class ForIn(Expression):
4600    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4603class TimeUnit(Expression):
4604    """Automatically converts unit arg into a var."""
4605
4606    arg_types = {"unit": False}
4607
4608    UNABBREVIATED_UNIT_NAME = {
4609        "D": "DAY",
4610        "H": "HOUR",
4611        "M": "MINUTE",
4612        "MS": "MILLISECOND",
4613        "NS": "NANOSECOND",
4614        "Q": "QUARTER",
4615        "S": "SECOND",
4616        "US": "MICROSECOND",
4617        "W": "WEEK",
4618        "Y": "YEAR",
4619    }
4620
4621    VAR_LIKE = (Column, Literal, Var)
4622
4623    def __init__(self, **args):
4624        unit = args.get("unit")
4625        if isinstance(unit, self.VAR_LIKE):
4626            args["unit"] = Var(
4627                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4628            )
4629        elif isinstance(unit, Week):
4630            unit.set("this", Var(this=unit.this.name.upper()))
4631
4632        super().__init__(**args)
4633
4634    @property
4635    def unit(self) -> t.Optional[Var | IntervalSpan]:
4636        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4623    def __init__(self, **args):
4624        unit = args.get("unit")
4625        if isinstance(unit, self.VAR_LIKE):
4626            args["unit"] = Var(
4627                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4628            )
4629        elif isinstance(unit, Week):
4630            unit.set("this", Var(this=unit.this.name.upper()))
4631
4632        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]
4634    @property
4635    def unit(self) -> t.Optional[Var | IntervalSpan]:
4636        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4639class IntervalOp(TimeUnit):
4640    arg_types = {"unit": True, "expression": True}
4641
4642    def interval(self):
4643        return Interval(
4644            this=self.expression.copy(),
4645            unit=self.unit.copy(),
4646        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4642    def interval(self):
4643        return Interval(
4644            this=self.expression.copy(),
4645            unit=self.unit.copy(),
4646        )
key = 'intervalop'
class IntervalSpan(DataType):
4652class IntervalSpan(DataType):
4653    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4656class Interval(TimeUnit):
4657    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4660class IgnoreNulls(Expression):
4661    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4664class RespectNulls(Expression):
4665    pass
key = 'respectnulls'
class HavingMax(Expression):
4669class HavingMax(Expression):
4670    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4674class Func(Condition):
4675    """
4676    The base class for all function expressions.
4677
4678    Attributes:
4679        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4680            treated as a variable length argument and the argument's value will be stored as a list.
4681        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4682            function expression. These values are used to map this node to a name during parsing as
4683            well as to provide the function's name during SQL string generation. By default the SQL
4684            name is set to the expression's class name transformed to snake case.
4685    """
4686
4687    is_var_len_args = False
4688
4689    @classmethod
4690    def from_arg_list(cls, args):
4691        if cls.is_var_len_args:
4692            all_arg_keys = list(cls.arg_types)
4693            # If this function supports variable length argument treat the last argument as such.
4694            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4695            num_non_var = len(non_var_len_arg_keys)
4696
4697            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4698            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4699        else:
4700            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4701
4702        return cls(**args_dict)
4703
4704    @classmethod
4705    def sql_names(cls):
4706        if cls is Func:
4707            raise NotImplementedError(
4708                "SQL name is only supported by concrete function implementations"
4709            )
4710        if "_sql_names" not in cls.__dict__:
4711            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4712        return cls._sql_names
4713
4714    @classmethod
4715    def sql_name(cls):
4716        return cls.sql_names()[0]
4717
4718    @classmethod
4719    def default_parser_mappings(cls):
4720        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):
4689    @classmethod
4690    def from_arg_list(cls, args):
4691        if cls.is_var_len_args:
4692            all_arg_keys = list(cls.arg_types)
4693            # If this function supports variable length argument treat the last argument as such.
4694            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4695            num_non_var = len(non_var_len_arg_keys)
4696
4697            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4698            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4699        else:
4700            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4701
4702        return cls(**args_dict)
@classmethod
def sql_names(cls):
4704    @classmethod
4705    def sql_names(cls):
4706        if cls is Func:
4707            raise NotImplementedError(
4708                "SQL name is only supported by concrete function implementations"
4709            )
4710        if "_sql_names" not in cls.__dict__:
4711            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4712        return cls._sql_names
@classmethod
def sql_name(cls):
4714    @classmethod
4715    def sql_name(cls):
4716        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4718    @classmethod
4719    def default_parser_mappings(cls):
4720        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4723class AggFunc(Func):
4724    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4727class ParameterizedAgg(AggFunc):
4728    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4731class Abs(Func):
4732    pass
key = 'abs'
class ArgMax(AggFunc):
4735class ArgMax(AggFunc):
4736    arg_types = {"this": True, "expression": True, "count": False}
4737    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4740class ArgMin(AggFunc):
4741    arg_types = {"this": True, "expression": True, "count": False}
4742    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4745class ApproxTopK(AggFunc):
4746    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4749class Flatten(Func):
4750    pass
key = 'flatten'
class Transform(Func):
4754class Transform(Func):
4755    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4758class Anonymous(Func):
4759    arg_types = {"this": True, "expressions": False}
4760    is_var_len_args = True
4761
4762    @property
4763    def name(self) -> str:
4764        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
4762    @property
4763    def name(self) -> str:
4764        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4767class AnonymousAggFunc(AggFunc):
4768    arg_types = {"this": True, "expressions": False}
4769    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4773class CombinedAggFunc(AnonymousAggFunc):
4774    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4777class CombinedParameterizedAgg(ParameterizedAgg):
4778    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):
4783class Hll(AggFunc):
4784    arg_types = {"this": True, "expressions": False}
4785    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4788class ApproxDistinct(AggFunc):
4789    arg_types = {"this": True, "accuracy": False}
4790    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4793class Array(Func):
4794    arg_types = {"expressions": False}
4795    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4799class ToArray(Func):
4800    pass
key = 'toarray'
class List(Func):
4804class List(Func):
4805    arg_types = {"expressions": False}
4806    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4810class Pad(Func):
4811    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
arg_types = {'this': True, 'expression': True, 'fill_pattern': False, 'is_left': True}
key = 'pad'
class ToChar(Func):
4816class ToChar(Func):
4817    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4822class ToNumber(Func):
4823    arg_types = {
4824        "this": True,
4825        "format": False,
4826        "nlsparam": False,
4827        "precision": False,
4828        "scale": False,
4829    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4833class Convert(Func):
4834    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4837class GenerateSeries(Func):
4838    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):
4841class ArrayAgg(AggFunc):
4842    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4845class ArrayUniqueAgg(AggFunc):
4846    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4849class ArrayAll(Func):
4850    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4854class ArrayAny(Func):
4855    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4858class ArrayConcat(Func):
4859    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4860    arg_types = {"this": True, "expressions": False}
4861    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4864class ArrayConstructCompact(Func):
4865    arg_types = {"expressions": True}
4866    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4869class ArrayContains(Binary, Func):
4870    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4873class ArrayContainsAll(Binary, Func):
4874    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4877class ArrayFilter(Func):
4878    arg_types = {"this": True, "expression": True}
4879    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4882class ArrayToString(Func):
4883    arg_types = {"this": True, "expression": True, "null": False}
4884    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4887class StringToArray(Func):
4888    arg_types = {"this": True, "expression": True, "null": False}
4889    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4892class ArrayOverlaps(Binary, Func):
4893    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4896class ArraySize(Func):
4897    arg_types = {"this": True, "expression": False}
4898    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4901class ArraySort(Func):
4902    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4905class ArraySum(Func):
4906    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4909class ArrayUnionAgg(AggFunc):
4910    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4913class Avg(AggFunc):
4914    pass
key = 'avg'
class AnyValue(AggFunc):
4917class AnyValue(AggFunc):
4918    pass
key = 'anyvalue'
class Lag(AggFunc):
4921class Lag(AggFunc):
4922    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4925class Lead(AggFunc):
4926    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4931class First(AggFunc):
4932    pass
key = 'first'
class Last(AggFunc):
4935class Last(AggFunc):
4936    pass
key = 'last'
class FirstValue(AggFunc):
4939class FirstValue(AggFunc):
4940    pass
key = 'firstvalue'
class LastValue(AggFunc):
4943class LastValue(AggFunc):
4944    pass
key = 'lastvalue'
class NthValue(AggFunc):
4947class NthValue(AggFunc):
4948    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4951class Case(Func):
4952    arg_types = {"this": False, "ifs": True, "default": False}
4953
4954    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4955        instance = maybe_copy(self, copy)
4956        instance.append(
4957            "ifs",
4958            If(
4959                this=maybe_parse(condition, copy=copy, **opts),
4960                true=maybe_parse(then, copy=copy, **opts),
4961            ),
4962        )
4963        return instance
4964
4965    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4966        instance = maybe_copy(self, copy)
4967        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4968        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:
4954    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4955        instance = maybe_copy(self, copy)
4956        instance.append(
4957            "ifs",
4958            If(
4959                this=maybe_parse(condition, copy=copy, **opts),
4960                true=maybe_parse(then, copy=copy, **opts),
4961            ),
4962        )
4963        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4965    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4966        instance = maybe_copy(self, copy)
4967        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4968        return instance
key = 'case'
class Cast(Func):
4971class Cast(Func):
4972    arg_types = {
4973        "this": True,
4974        "to": True,
4975        "format": False,
4976        "safe": False,
4977        "action": False,
4978    }
4979
4980    @property
4981    def name(self) -> str:
4982        return self.this.name
4983
4984    @property
4985    def to(self) -> DataType:
4986        return self.args["to"]
4987
4988    @property
4989    def output_name(self) -> str:
4990        return self.name
4991
4992    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4993        """
4994        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4995        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4996        array<int> != array<float>.
4997
4998        Args:
4999            dtypes: the data types to compare this Cast's DataType to.
5000
5001        Returns:
5002            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5003        """
5004        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4980    @property
4981    def name(self) -> str:
4982        return self.this.name
to: DataType
4984    @property
4985    def to(self) -> DataType:
4986        return self.args["to"]
output_name: str
4988    @property
4989    def output_name(self) -> str:
4990        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:
4992    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4993        """
4994        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4995        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4996        array<int> != array<float>.
4997
4998        Args:
4999            dtypes: the data types to compare this Cast's DataType to.
5000
5001        Returns:
5002            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5003        """
5004        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):
5007class TryCast(Cast):
5008    pass
key = 'trycast'
class Try(Func):
5011class Try(Func):
5012    pass
key = 'try'
class CastToStrType(Func):
5015class CastToStrType(Func):
5016    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5019class Collate(Binary, Func):
5020    pass
key = 'collate'
class Ceil(Func):
5023class Ceil(Func):
5024    arg_types = {"this": True, "decimals": False}
5025    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5028class Coalesce(Func):
5029    arg_types = {"this": True, "expressions": False}
5030    is_var_len_args = True
5031    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5034class Chr(Func):
5035    arg_types = {"this": True, "charset": False, "expressions": False}
5036    is_var_len_args = True
5037    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5040class Concat(Func):
5041    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5042    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5045class ConcatWs(Concat):
5046    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5050class ConnectByRoot(Func):
5051    pass
key = 'connectbyroot'
class Count(AggFunc):
5054class Count(AggFunc):
5055    arg_types = {"this": False, "expressions": False}
5056    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5059class CountIf(AggFunc):
5060    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5064class Cbrt(Func):
5065    pass
key = 'cbrt'
class CurrentDate(Func):
5068class CurrentDate(Func):
5069    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5072class CurrentDatetime(Func):
5073    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5076class CurrentTime(Func):
5077    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5080class CurrentTimestamp(Func):
5081    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5084class CurrentUser(Func):
5085    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5088class DateAdd(Func, IntervalOp):
5089    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5092class DateSub(Func, IntervalOp):
5093    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5096class DateDiff(Func, TimeUnit):
5097    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5098    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5101class DateTrunc(Func):
5102    arg_types = {"unit": True, "this": True, "zone": False}
5103
5104    def __init__(self, **args):
5105        unit = args.get("unit")
5106        if isinstance(unit, TimeUnit.VAR_LIKE):
5107            args["unit"] = Literal.string(
5108                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5109            )
5110        elif isinstance(unit, Week):
5111            unit.set("this", Literal.string(unit.this.name.upper()))
5112
5113        super().__init__(**args)
5114
5115    @property
5116    def unit(self) -> Expression:
5117        return self.args["unit"]
DateTrunc(**args)
5104    def __init__(self, **args):
5105        unit = args.get("unit")
5106        if isinstance(unit, TimeUnit.VAR_LIKE):
5107            args["unit"] = Literal.string(
5108                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5109            )
5110        elif isinstance(unit, Week):
5111            unit.set("this", Literal.string(unit.this.name.upper()))
5112
5113        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5115    @property
5116    def unit(self) -> Expression:
5117        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5122class Datetime(Func):
5123    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5126class DatetimeAdd(Func, IntervalOp):
5127    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5130class DatetimeSub(Func, IntervalOp):
5131    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5134class DatetimeDiff(Func, TimeUnit):
5135    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5138class DatetimeTrunc(Func, TimeUnit):
5139    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5142class DayOfWeek(Func):
5143    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5146class DayOfMonth(Func):
5147    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5150class DayOfYear(Func):
5151    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5154class ToDays(Func):
5155    pass
key = 'todays'
class WeekOfYear(Func):
5158class WeekOfYear(Func):
5159    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5162class MonthsBetween(Func):
5163    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5166class LastDay(Func, TimeUnit):
5167    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5168    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5171class Extract(Func):
5172    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5175class Timestamp(Func):
5176    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5179class TimestampAdd(Func, TimeUnit):
5180    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5183class TimestampSub(Func, TimeUnit):
5184    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5187class TimestampDiff(Func, TimeUnit):
5188    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5189    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5192class TimestampTrunc(Func, TimeUnit):
5193    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5196class TimeAdd(Func, TimeUnit):
5197    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5200class TimeSub(Func, TimeUnit):
5201    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5204class TimeDiff(Func, TimeUnit):
5205    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5208class TimeTrunc(Func, TimeUnit):
5209    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5212class DateFromParts(Func):
5213    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5214    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5217class TimeFromParts(Func):
5218    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5219    arg_types = {
5220        "hour": True,
5221        "min": True,
5222        "sec": True,
5223        "nano": False,
5224        "fractions": False,
5225        "precision": False,
5226    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5229class DateStrToDate(Func):
5230    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5233class DateToDateStr(Func):
5234    pass
key = 'datetodatestr'
class DateToDi(Func):
5237class DateToDi(Func):
5238    pass
key = 'datetodi'
class Date(Func):
5242class Date(Func):
5243    arg_types = {"this": False, "zone": False, "expressions": False}
5244    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5247class Day(Func):
5248    pass
key = 'day'
class Decode(Func):
5251class Decode(Func):
5252    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5255class DiToDate(Func):
5256    pass
key = 'ditodate'
class Encode(Func):
5259class Encode(Func):
5260    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5263class Exp(Func):
5264    pass
key = 'exp'
class Explode(Func):
5268class Explode(Func):
5269    arg_types = {"this": True, "expressions": False}
5270    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5273class ExplodeOuter(Explode):
5274    pass
key = 'explodeouter'
class Posexplode(Explode):
5277class Posexplode(Explode):
5278    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5281class PosexplodeOuter(Posexplode, ExplodeOuter):
5282    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5285class Unnest(Func, UDTF):
5286    arg_types = {
5287        "expressions": True,
5288        "alias": False,
5289        "offset": False,
5290    }
5291
5292    @property
5293    def selects(self) -> t.List[Expression]:
5294        columns = super().selects
5295        offset = self.args.get("offset")
5296        if offset:
5297            columns = columns + [to_identifier("offset") if offset is True else offset]
5298        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5292    @property
5293    def selects(self) -> t.List[Expression]:
5294        columns = super().selects
5295        offset = self.args.get("offset")
5296        if offset:
5297            columns = columns + [to_identifier("offset") if offset is True else offset]
5298        return columns
key = 'unnest'
class Floor(Func):
5301class Floor(Func):
5302    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5305class FromBase64(Func):
5306    pass
key = 'frombase64'
class ToBase64(Func):
5309class ToBase64(Func):
5310    pass
key = 'tobase64'
class GapFill(Func):
5313class GapFill(Func):
5314    arg_types = {
5315        "this": True,
5316        "ts_column": True,
5317        "bucket_width": True,
5318        "partitioning_columns": False,
5319        "value_columns": False,
5320        "origin": False,
5321        "ignore_nulls": False,
5322    }
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):
5325class GenerateDateArray(Func):
5326    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5329class Greatest(Func):
5330    arg_types = {"this": True, "expressions": False}
5331    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5334class GroupConcat(AggFunc):
5335    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5338class Hex(Func):
5339    pass
key = 'hex'
class LowerHex(Hex):
5342class LowerHex(Hex):
5343    pass
key = 'lowerhex'
class Xor(Connector, Func):
5346class Xor(Connector, Func):
5347    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5350class If(Func):
5351    arg_types = {"this": True, "true": True, "false": False}
5352    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5355class Nullif(Func):
5356    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5359class Initcap(Func):
5360    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5363class IsNan(Func):
5364    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5367class IsInf(Func):
5368    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5371class JSONPath(Expression):
5372    arg_types = {"expressions": True}
5373
5374    @property
5375    def output_name(self) -> str:
5376        last_segment = self.expressions[-1].this
5377        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5374    @property
5375    def output_name(self) -> str:
5376        last_segment = self.expressions[-1].this
5377        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):
5380class JSONPathPart(Expression):
5381    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5384class JSONPathFilter(JSONPathPart):
5385    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5388class JSONPathKey(JSONPathPart):
5389    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5392class JSONPathRecursive(JSONPathPart):
5393    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5396class JSONPathRoot(JSONPathPart):
5397    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5400class JSONPathScript(JSONPathPart):
5401    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5404class JSONPathSlice(JSONPathPart):
5405    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5408class JSONPathSelector(JSONPathPart):
5409    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5412class JSONPathSubscript(JSONPathPart):
5413    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5416class JSONPathUnion(JSONPathPart):
5417    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5420class JSONPathWildcard(JSONPathPart):
5421    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5424class FormatJson(Expression):
5425    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5428class JSONKeyValue(Expression):
5429    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5432class JSONObject(Func):
5433    arg_types = {
5434        "expressions": False,
5435        "null_handling": False,
5436        "unique_keys": False,
5437        "return_type": False,
5438        "encoding": False,
5439    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5442class JSONObjectAgg(AggFunc):
5443    arg_types = {
5444        "expressions": False,
5445        "null_handling": False,
5446        "unique_keys": False,
5447        "return_type": False,
5448        "encoding": False,
5449    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5453class JSONArray(Func):
5454    arg_types = {
5455        "expressions": True,
5456        "null_handling": False,
5457        "return_type": False,
5458        "strict": False,
5459    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5463class JSONArrayAgg(Func):
5464    arg_types = {
5465        "this": True,
5466        "order": False,
5467        "null_handling": False,
5468        "return_type": False,
5469        "strict": False,
5470    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5475class JSONColumnDef(Expression):
5476    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):
5479class JSONSchema(Expression):
5480    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5484class JSONTable(Func):
5485    arg_types = {
5486        "this": True,
5487        "schema": True,
5488        "path": False,
5489        "error_handling": False,
5490        "empty_handling": False,
5491    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5495class ObjectInsert(Func):
5496    arg_types = {
5497        "this": True,
5498        "key": True,
5499        "value": True,
5500        "update_flag": False,
5501    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5504class OpenJSONColumnDef(Expression):
5505    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):
5508class OpenJSON(Func):
5509    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5512class JSONBContains(Binary, Func):
5513    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5516class JSONExtract(Binary, Func):
5517    arg_types = {
5518        "this": True,
5519        "expression": True,
5520        "only_json_types": False,
5521        "expressions": False,
5522        "variant_extract": False,
5523    }
5524    _sql_names = ["JSON_EXTRACT"]
5525    is_var_len_args = True
5526
5527    @property
5528    def output_name(self) -> str:
5529        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
5527    @property
5528    def output_name(self) -> str:
5529        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):
5532class JSONExtractScalar(Binary, Func):
5533    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5534    _sql_names = ["JSON_EXTRACT_SCALAR"]
5535    is_var_len_args = True
5536
5537    @property
5538    def output_name(self) -> str:
5539        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
5537    @property
5538    def output_name(self) -> str:
5539        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):
5542class JSONBExtract(Binary, Func):
5543    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5546class JSONBExtractScalar(Binary, Func):
5547    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5550class JSONFormat(Func):
5551    arg_types = {"this": False, "options": False}
5552    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5556class JSONArrayContains(Binary, Predicate, Func):
5557    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5560class ParseJSON(Func):
5561    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5562    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5563    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5564    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5567class Least(Func):
5568    arg_types = {"this": True, "expressions": False}
5569    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5572class Left(Func):
5573    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5580class Length(Func):
5581    arg_types = {"this": True, "binary": False}
5582    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5585class Levenshtein(Func):
5586    arg_types = {
5587        "this": True,
5588        "expression": False,
5589        "ins_cost": False,
5590        "del_cost": False,
5591        "sub_cost": False,
5592    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5595class Ln(Func):
5596    pass
key = 'ln'
class Log(Func):
5599class Log(Func):
5600    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5603class LogicalOr(AggFunc):
5604    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5607class LogicalAnd(AggFunc):
5608    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5611class Lower(Func):
5612    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5615class Map(Func):
5616    arg_types = {"keys": False, "values": False}
5617
5618    @property
5619    def keys(self) -> t.List[Expression]:
5620        keys = self.args.get("keys")
5621        return keys.expressions if keys else []
5622
5623    @property
5624    def values(self) -> t.List[Expression]:
5625        values = self.args.get("values")
5626        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5618    @property
5619    def keys(self) -> t.List[Expression]:
5620        keys = self.args.get("keys")
5621        return keys.expressions if keys else []
values: List[Expression]
5623    @property
5624    def values(self) -> t.List[Expression]:
5625        values = self.args.get("values")
5626        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5630class ToMap(Func):
5631    pass
key = 'tomap'
class MapFromEntries(Func):
5634class MapFromEntries(Func):
5635    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5639class ScopeResolution(Expression):
5640    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class StarMap(Func):
5643class StarMap(Func):
5644    pass
key = 'starmap'
class VarMap(Func):
5647class VarMap(Func):
5648    arg_types = {"keys": True, "values": True}
5649    is_var_len_args = True
5650
5651    @property
5652    def keys(self) -> t.List[Expression]:
5653        return self.args["keys"].expressions
5654
5655    @property
5656    def values(self) -> t.List[Expression]:
5657        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5651    @property
5652    def keys(self) -> t.List[Expression]:
5653        return self.args["keys"].expressions
values: List[Expression]
5655    @property
5656    def values(self) -> t.List[Expression]:
5657        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5661class MatchAgainst(Func):
5662    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5665class Max(AggFunc):
5666    arg_types = {"this": True, "expressions": False}
5667    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5670class MD5(Func):
5671    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5675class MD5Digest(Func):
5676    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5679class Min(AggFunc):
5680    arg_types = {"this": True, "expressions": False}
5681    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5684class Month(Func):
5685    pass
key = 'month'
class AddMonths(Func):
5688class AddMonths(Func):
5689    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5692class Nvl2(Func):
5693    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5697class Predict(Func):
5698    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5701class Pow(Binary, Func):
5702    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5705class PercentileCont(AggFunc):
5706    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5709class PercentileDisc(AggFunc):
5710    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5713class Quantile(AggFunc):
5714    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5717class ApproxQuantile(Quantile):
5718    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):
5721class Quarter(Func):
5722    pass
key = 'quarter'
class Rand(Func):
5727class Rand(Func):
5728    _sql_names = ["RAND", "RANDOM"]
5729    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5732class Randn(Func):
5733    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5736class RangeN(Func):
5737    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5740class ReadCSV(Func):
5741    _sql_names = ["READ_CSV"]
5742    is_var_len_args = True
5743    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5746class Reduce(Func):
5747    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):
5750class RegexpExtract(Func):
5751    arg_types = {
5752        "this": True,
5753        "expression": True,
5754        "position": False,
5755        "occurrence": False,
5756        "parameters": False,
5757        "group": False,
5758    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5761class RegexpReplace(Func):
5762    arg_types = {
5763        "this": True,
5764        "expression": True,
5765        "replacement": False,
5766        "position": False,
5767        "occurrence": False,
5768        "modifiers": False,
5769    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5772class RegexpLike(Binary, Func):
5773    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5776class RegexpILike(Binary, Func):
5777    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5782class RegexpSplit(Func):
5783    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5786class Repeat(Func):
5787    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5792class Round(Func):
5793    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5796class RowNumber(Func):
5797    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5800class SafeDivide(Func):
5801    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5804class SHA(Func):
5805    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5808class SHA2(Func):
5809    _sql_names = ["SHA2"]
5810    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5813class Sign(Func):
5814    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5817class SortArray(Func):
5818    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5821class Split(Func):
5822    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5827class Substring(Func):
5828    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5831class StandardHash(Func):
5832    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5835class StartsWith(Func):
5836    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5837    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5840class StrPosition(Func):
5841    arg_types = {
5842        "this": True,
5843        "substr": True,
5844        "position": False,
5845        "instance": False,
5846    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5849class StrToDate(Func):
5850    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5853class StrToTime(Func):
5854    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):
5859class StrToUnix(Func):
5860    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5865class StrToMap(Func):
5866    arg_types = {
5867        "this": True,
5868        "pair_delim": False,
5869        "key_value_delim": False,
5870        "duplicate_resolution_callback": False,
5871    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5874class NumberToStr(Func):
5875    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5878class FromBase(Func):
5879    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5882class Struct(Func):
5883    arg_types = {"expressions": False}
5884    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5887class StructExtract(Func):
5888    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5893class Stuff(Func):
5894    _sql_names = ["STUFF", "INSERT"]
5895    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):
5898class Sum(AggFunc):
5899    pass
key = 'sum'
class Sqrt(Func):
5902class Sqrt(Func):
5903    pass
key = 'sqrt'
class Stddev(AggFunc):
5906class Stddev(AggFunc):
5907    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
5910class StddevPop(AggFunc):
5911    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5914class StddevSamp(AggFunc):
5915    pass
key = 'stddevsamp'
class Time(Func):
5919class Time(Func):
5920    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5923class TimeToStr(Func):
5924    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):
5927class TimeToTimeStr(Func):
5928    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5931class TimeToUnix(Func):
5932    pass
key = 'timetounix'
class TimeStrToDate(Func):
5935class TimeStrToDate(Func):
5936    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5939class TimeStrToTime(Func):
5940    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5943class TimeStrToUnix(Func):
5944    pass
key = 'timestrtounix'
class Trim(Func):
5947class Trim(Func):
5948    arg_types = {
5949        "this": True,
5950        "expression": False,
5951        "position": False,
5952        "collation": False,
5953    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5956class TsOrDsAdd(Func, TimeUnit):
5957    # return_type is used to correctly cast the arguments of this expression when transpiling it
5958    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5959
5960    @property
5961    def return_type(self) -> DataType:
5962        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
5960    @property
5961    def return_type(self) -> DataType:
5962        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5965class TsOrDsDiff(Func, TimeUnit):
5966    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5969class TsOrDsToDateStr(Func):
5970    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5973class TsOrDsToDate(Func):
5974    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5977class TsOrDsToTime(Func):
5978    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5981class TsOrDsToTimestamp(Func):
5982    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5985class TsOrDiToDi(Func):
5986    pass
key = 'tsorditodi'
class Unhex(Func):
5989class Unhex(Func):
5990    pass
key = 'unhex'
class UnixDate(Func):
5994class UnixDate(Func):
5995    pass
key = 'unixdate'
class UnixToStr(Func):
5998class UnixToStr(Func):
5999    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6004class UnixToTime(Func):
6005    arg_types = {
6006        "this": True,
6007        "scale": False,
6008        "zone": False,
6009        "hours": False,
6010        "minutes": False,
6011        "format": False,
6012    }
6013
6014    SECONDS = Literal.number(0)
6015    DECIS = Literal.number(1)
6016    CENTIS = Literal.number(2)
6017    MILLIS = Literal.number(3)
6018    DECIMILLIS = Literal.number(4)
6019    CENTIMILLIS = Literal.number(5)
6020    MICROS = Literal.number(6)
6021    DECIMICROS = Literal.number(7)
6022    CENTIMICROS = Literal.number(8)
6023    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):
6026class UnixToTimeStr(Func):
6027    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6030class TimestampFromParts(Func):
6031    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6032    arg_types = {
6033        "year": True,
6034        "month": True,
6035        "day": True,
6036        "hour": True,
6037        "min": True,
6038        "sec": True,
6039        "nano": False,
6040        "zone": False,
6041        "milli": False,
6042    }
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):
6045class Upper(Func):
6046    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6049class Corr(Binary, AggFunc):
6050    pass
key = 'corr'
class Variance(AggFunc):
6053class Variance(AggFunc):
6054    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6057class VariancePop(AggFunc):
6058    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6061class CovarSamp(Binary, AggFunc):
6062    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6065class CovarPop(Binary, AggFunc):
6066    pass
key = 'covarpop'
class Week(Func):
6069class Week(Func):
6070    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6073class XMLTable(Func):
6074    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):
6077class Year(Func):
6078    pass
key = 'year'
class Use(Expression):
6081class Use(Expression):
6082    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6085class Merge(Expression):
6086    arg_types = {
6087        "this": True,
6088        "using": True,
6089        "on": True,
6090        "expressions": True,
6091        "with": False,
6092    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6095class When(Func):
6096    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):
6101class NextValueFor(Func):
6102    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6107class Semicolon(Expression):
6108    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 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6148def maybe_parse(
6149    sql_or_expression: ExpOrStr,
6150    *,
6151    into: t.Optional[IntoType] = None,
6152    dialect: DialectType = None,
6153    prefix: t.Optional[str] = None,
6154    copy: bool = False,
6155    **opts,
6156) -> Expression:
6157    """Gracefully handle a possible string or expression.
6158
6159    Example:
6160        >>> maybe_parse("1")
6161        Literal(this=1, is_string=False)
6162        >>> maybe_parse(to_identifier("x"))
6163        Identifier(this=x, quoted=False)
6164
6165    Args:
6166        sql_or_expression: the SQL code string or an expression
6167        into: the SQLGlot Expression to parse into
6168        dialect: the dialect used to parse the input expressions (in the case that an
6169            input expression is a SQL string).
6170        prefix: a string to prefix the sql with before it gets parsed
6171            (automatically includes a space)
6172        copy: whether to copy the expression.
6173        **opts: other options to use to parse the input expressions (again, in the case
6174            that an input expression is a SQL string).
6175
6176    Returns:
6177        Expression: the parsed or given expression.
6178    """
6179    if isinstance(sql_or_expression, Expression):
6180        if copy:
6181            return sql_or_expression.copy()
6182        return sql_or_expression
6183
6184    if sql_or_expression is None:
6185        raise ParseError("SQL cannot be None")
6186
6187    import sqlglot
6188
6189    sql = str(sql_or_expression)
6190    if prefix:
6191        sql = f"{prefix} {sql}"
6192
6193    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):
6204def maybe_copy(instance, copy=True):
6205    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:
6425def union(
6426    left: ExpOrStr,
6427    right: ExpOrStr,
6428    distinct: bool = True,
6429    dialect: DialectType = None,
6430    copy: bool = True,
6431    **opts,
6432) -> Union:
6433    """
6434    Initializes a syntax tree from one UNION expression.
6435
6436    Example:
6437        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6438        'SELECT * FROM foo UNION SELECT * FROM bla'
6439
6440    Args:
6441        left: the SQL code string corresponding to the left-hand side.
6442            If an `Expression` instance is passed, it will be used as-is.
6443        right: the SQL code string corresponding to the right-hand side.
6444            If an `Expression` instance is passed, it will be used as-is.
6445        distinct: set the DISTINCT flag if and only if this is true.
6446        dialect: the dialect used to parse the input expression.
6447        copy: whether to copy the expression.
6448        opts: other options to use to parse the input expressions.
6449
6450    Returns:
6451        The new Union instance.
6452    """
6453    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6454    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6455
6456    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:
6459def intersect(
6460    left: ExpOrStr,
6461    right: ExpOrStr,
6462    distinct: bool = True,
6463    dialect: DialectType = None,
6464    copy: bool = True,
6465    **opts,
6466) -> Intersect:
6467    """
6468    Initializes a syntax tree from one INTERSECT expression.
6469
6470    Example:
6471        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6472        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6473
6474    Args:
6475        left: the SQL code string corresponding to the left-hand side.
6476            If an `Expression` instance is passed, it will be used as-is.
6477        right: the SQL code string corresponding to the right-hand side.
6478            If an `Expression` instance is passed, it will be used as-is.
6479        distinct: set the DISTINCT flag if and only if this is true.
6480        dialect: the dialect used to parse the input expression.
6481        copy: whether to copy the expression.
6482        opts: other options to use to parse the input expressions.
6483
6484    Returns:
6485        The new Intersect instance.
6486    """
6487    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6488    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6489
6490    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:
6493def except_(
6494    left: ExpOrStr,
6495    right: ExpOrStr,
6496    distinct: bool = True,
6497    dialect: DialectType = None,
6498    copy: bool = True,
6499    **opts,
6500) -> Except:
6501    """
6502    Initializes a syntax tree from one EXCEPT expression.
6503
6504    Example:
6505        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6506        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6507
6508    Args:
6509        left: the SQL code string corresponding to the left-hand side.
6510            If an `Expression` instance is passed, it will be used as-is.
6511        right: the SQL code string corresponding to the right-hand side.
6512            If an `Expression` instance is passed, it will be used as-is.
6513        distinct: set the DISTINCT flag if and only if this is true.
6514        dialect: the dialect used to parse the input expression.
6515        copy: whether to copy the expression.
6516        opts: other options to use to parse the input expressions.
6517
6518    Returns:
6519        The new Except instance.
6520    """
6521    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6522    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6523
6524    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:
6527def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6528    """
6529    Initializes a syntax tree from one or multiple SELECT expressions.
6530
6531    Example:
6532        >>> select("col1", "col2").from_("tbl").sql()
6533        'SELECT col1, col2 FROM tbl'
6534
6535    Args:
6536        *expressions: the SQL code string to parse as the expressions of a
6537            SELECT statement. If an Expression instance is passed, this is used as-is.
6538        dialect: the dialect used to parse the input expressions (in the case that an
6539            input expression is a SQL string).
6540        **opts: other options to use to parse the input expressions (again, in the case
6541            that an input expression is a SQL string).
6542
6543    Returns:
6544        Select: the syntax tree for the SELECT statement.
6545    """
6546    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:
6549def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6550    """
6551    Initializes a syntax tree from a FROM expression.
6552
6553    Example:
6554        >>> from_("tbl").select("col1", "col2").sql()
6555        'SELECT col1, col2 FROM tbl'
6556
6557    Args:
6558        *expression: the SQL code string to parse as the FROM expressions of a
6559            SELECT statement. If an Expression instance is passed, this is used as-is.
6560        dialect: the dialect used to parse the input expression (in the case that the
6561            input expression is a SQL string).
6562        **opts: other options to use to parse the input expressions (again, in the case
6563            that the input expression is a SQL string).
6564
6565    Returns:
6566        Select: the syntax tree for the SELECT statement.
6567    """
6568    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:
6571def update(
6572    table: str | Table,
6573    properties: dict,
6574    where: t.Optional[ExpOrStr] = None,
6575    from_: t.Optional[ExpOrStr] = None,
6576    dialect: DialectType = None,
6577    **opts,
6578) -> Update:
6579    """
6580    Creates an update statement.
6581
6582    Example:
6583        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6584        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6585
6586    Args:
6587        *properties: dictionary of properties to set which are
6588            auto converted to sql objects eg None -> NULL
6589        where: sql conditional parsed into a WHERE statement
6590        from_: sql statement parsed into a FROM statement
6591        dialect: the dialect used to parse the input expressions.
6592        **opts: other options to use to parse the input expressions.
6593
6594    Returns:
6595        Update: the syntax tree for the UPDATE statement.
6596    """
6597    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6598    update_expr.set(
6599        "expressions",
6600        [
6601            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6602            for k, v in properties.items()
6603        ],
6604    )
6605    if from_:
6606        update_expr.set(
6607            "from",
6608            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6609        )
6610    if isinstance(where, Condition):
6611        where = Where(this=where)
6612    if where:
6613        update_expr.set(
6614            "where",
6615            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6616        )
6617    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:
6620def delete(
6621    table: ExpOrStr,
6622    where: t.Optional[ExpOrStr] = None,
6623    returning: t.Optional[ExpOrStr] = None,
6624    dialect: DialectType = None,
6625    **opts,
6626) -> Delete:
6627    """
6628    Builds a delete statement.
6629
6630    Example:
6631        >>> delete("my_table", where="id > 1").sql()
6632        'DELETE FROM my_table WHERE id > 1'
6633
6634    Args:
6635        where: sql conditional parsed into a WHERE statement
6636        returning: sql conditional parsed into a RETURNING statement
6637        dialect: the dialect used to parse the input expressions.
6638        **opts: other options to use to parse the input expressions.
6639
6640    Returns:
6641        Delete: the syntax tree for the DELETE statement.
6642    """
6643    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6644    if where:
6645        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6646    if returning:
6647        delete_expr = t.cast(
6648            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6649        )
6650    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:
6653def insert(
6654    expression: ExpOrStr,
6655    into: ExpOrStr,
6656    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6657    overwrite: t.Optional[bool] = None,
6658    returning: t.Optional[ExpOrStr] = None,
6659    dialect: DialectType = None,
6660    copy: bool = True,
6661    **opts,
6662) -> Insert:
6663    """
6664    Builds an INSERT statement.
6665
6666    Example:
6667        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6668        'INSERT INTO tbl VALUES (1, 2, 3)'
6669
6670    Args:
6671        expression: the sql string or expression of the INSERT statement
6672        into: the tbl to insert data to.
6673        columns: optionally the table's column names.
6674        overwrite: whether to INSERT OVERWRITE or not.
6675        returning: sql conditional parsed into a RETURNING statement
6676        dialect: the dialect used to parse the input expressions.
6677        copy: whether to copy the expression.
6678        **opts: other options to use to parse the input expressions.
6679
6680    Returns:
6681        Insert: the syntax tree for the INSERT statement.
6682    """
6683    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6684    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6685
6686    if columns:
6687        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6688
6689    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6690
6691    if returning:
6692        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6693
6694    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:
6697def condition(
6698    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6699) -> Condition:
6700    """
6701    Initialize a logical condition expression.
6702
6703    Example:
6704        >>> condition("x=1").sql()
6705        'x = 1'
6706
6707        This is helpful for composing larger logical syntax trees:
6708        >>> where = condition("x=1")
6709        >>> where = where.and_("y=1")
6710        >>> Select().from_("tbl").select("*").where(where).sql()
6711        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6712
6713    Args:
6714        *expression: the SQL code string to parse.
6715            If an Expression instance is passed, this is used as-is.
6716        dialect: the dialect used to parse the input expression (in the case that the
6717            input expression is a SQL string).
6718        copy: Whether to copy `expression` (only applies to expressions).
6719        **opts: other options to use to parse the input expressions (again, in the case
6720            that the input expression is a SQL string).
6721
6722    Returns:
6723        The new Condition instance
6724    """
6725    return maybe_parse(
6726        expression,
6727        into=Condition,
6728        dialect=dialect,
6729        copy=copy,
6730        **opts,
6731    )

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:
6734def and_(
6735    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6736) -> Condition:
6737    """
6738    Combine multiple conditions with an AND logical operator.
6739
6740    Example:
6741        >>> and_("x=1", and_("y=1", "z=1")).sql()
6742        'x = 1 AND (y = 1 AND 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, 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:
6757def or_(
6758    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6759) -> Condition:
6760    """
6761    Combine multiple conditions with an OR logical operator.
6762
6763    Example:
6764        >>> or_("x=1", or_("y=1", "z=1")).sql()
6765        'x = 1 OR (y = 1 OR 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, 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:
6780def xor(
6781    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6782) -> Condition:
6783    """
6784    Combine multiple conditions with an XOR logical operator.
6785
6786    Example:
6787        >>> xor("x=1", xor("y=1", "z=1")).sql()
6788        'x = 1 XOR (y = 1 XOR z = 1)'
6789
6790    Args:
6791        *expressions: the SQL code strings to parse.
6792            If an Expression instance is passed, this is used as-is.
6793        dialect: the dialect used to parse the input expression.
6794        copy: whether to copy `expressions` (only applies to Expressions).
6795        **opts: other options to use to parse the input expressions.
6796
6797    Returns:
6798        The new condition
6799    """
6800    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:
6803def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6804    """
6805    Wrap a condition with a NOT operator.
6806
6807    Example:
6808        >>> not_("this_suit='black'").sql()
6809        "NOT this_suit = 'black'"
6810
6811    Args:
6812        expression: the SQL code string to parse.
6813            If an Expression instance is passed, this is used as-is.
6814        dialect: the dialect used to parse the input expression.
6815        copy: whether to copy the expression or not.
6816        **opts: other options to use to parse the input expressions.
6817
6818    Returns:
6819        The new condition.
6820    """
6821    this = condition(
6822        expression,
6823        dialect=dialect,
6824        copy=copy,
6825        **opts,
6826    )
6827    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:
6830def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6831    """
6832    Wrap an expression in parentheses.
6833
6834    Example:
6835        >>> paren("5 + 3").sql()
6836        '(5 + 3)'
6837
6838    Args:
6839        expression: the SQL code string to parse.
6840            If an Expression instance is passed, this is used as-is.
6841        copy: whether to copy the expression or not.
6842
6843    Returns:
6844        The wrapped expression.
6845    """
6846    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):
6862def to_identifier(name, quoted=None, copy=True):
6863    """Builds an identifier.
6864
6865    Args:
6866        name: The name to turn into an identifier.
6867        quoted: Whether to force quote the identifier.
6868        copy: Whether to copy name if it's an Identifier.
6869
6870    Returns:
6871        The identifier ast node.
6872    """
6873
6874    if name is None:
6875        return None
6876
6877    if isinstance(name, Identifier):
6878        identifier = maybe_copy(name, copy)
6879    elif isinstance(name, str):
6880        identifier = Identifier(
6881            this=name,
6882            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6883        )
6884    else:
6885        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6886    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:
6889def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6890    """
6891    Parses a given string into an identifier.
6892
6893    Args:
6894        name: The name to parse into an identifier.
6895        dialect: The dialect to parse against.
6896
6897    Returns:
6898        The identifier ast node.
6899    """
6900    try:
6901        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6902    except (ParseError, TokenError):
6903        expression = to_identifier(name)
6904
6905    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:
6911def to_interval(interval: str | Literal) -> Interval:
6912    """Builds an interval expression from a string like '1 day' or '5 months'."""
6913    if isinstance(interval, Literal):
6914        if not interval.is_string:
6915            raise ValueError("Invalid interval string.")
6916
6917        interval = interval.this
6918
6919    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6920
6921    if not interval_parts:
6922        raise ValueError("Invalid interval string.")
6923
6924    return Interval(
6925        this=Literal.string(interval_parts.group(1)),
6926        unit=Var(this=interval_parts.group(2).upper()),
6927    )

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

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:
7202def values(
7203    values: t.Iterable[t.Tuple[t.Any, ...]],
7204    alias: t.Optional[str] = None,
7205    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7206) -> Values:
7207    """Build VALUES statement.
7208
7209    Example:
7210        >>> values([(1, '2')]).sql()
7211        "VALUES (1, '2')"
7212
7213    Args:
7214        values: values statements that will be converted to SQL
7215        alias: optional alias
7216        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7217         If either are provided then an alias is also required.
7218
7219    Returns:
7220        Values: the Values expression object
7221    """
7222    if columns and not alias:
7223        raise ValueError("Alias is required when providing columns")
7224
7225    return Values(
7226        expressions=[convert(tup) for tup in values],
7227        alias=(
7228            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7229            if columns
7230            else (TableAlias(this=to_identifier(alias)) if alias else None)
7231        ),
7232    )

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:
7235def var(name: t.Optional[ExpOrStr]) -> Var:
7236    """Build a SQL variable.
7237
7238    Example:
7239        >>> repr(var('x'))
7240        'Var(this=x)'
7241
7242        >>> repr(var(column('x', table='y')))
7243        'Var(this=x)'
7244
7245    Args:
7246        name: The name of the var or an expression who's name will become the var.
7247
7248    Returns:
7249        The new variable node.
7250    """
7251    if not name:
7252        raise ValueError("Cannot convert empty name into var.")
7253
7254    if isinstance(name, Expression):
7255        name = name.name
7256    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:
7259def rename_table(
7260    old_name: str | Table,
7261    new_name: str | Table,
7262    dialect: DialectType = None,
7263) -> AlterTable:
7264    """Build ALTER TABLE... RENAME... expression
7265
7266    Args:
7267        old_name: The old name of the table
7268        new_name: The new name of the table
7269        dialect: The dialect to parse the table.
7270
7271    Returns:
7272        Alter table expression
7273    """
7274    old_table = to_table(old_name, dialect=dialect)
7275    new_table = to_table(new_name, dialect=dialect)
7276    return AlterTable(
7277        this=old_table,
7278        actions=[
7279            RenameTable(this=new_table),
7280        ],
7281    )

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:
7284def rename_column(
7285    table_name: str | Table,
7286    old_column_name: str | Column,
7287    new_column_name: str | Column,
7288    exists: t.Optional[bool] = None,
7289    dialect: DialectType = None,
7290) -> AlterTable:
7291    """Build ALTER TABLE... RENAME COLUMN... expression
7292
7293    Args:
7294        table_name: Name of the table
7295        old_column: The old name of the column
7296        new_column: The new name of the column
7297        exists: Whether to add the `IF EXISTS` clause
7298        dialect: The dialect to parse the table/column.
7299
7300    Returns:
7301        Alter table expression
7302    """
7303    table = to_table(table_name, dialect=dialect)
7304    old_column = to_column(old_column_name, dialect=dialect)
7305    new_column = to_column(new_column_name, dialect=dialect)
7306    return AlterTable(
7307        this=table,
7308        actions=[
7309            RenameColumn(this=old_column, to=new_column, exists=exists),
7310        ],
7311    )

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

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:
7445def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7446    """Get the full name of a table as a string.
7447
7448    Args:
7449        table: Table expression node or string.
7450        dialect: The dialect to generate the table name for.
7451        identify: Determines when an identifier should be quoted. Possible values are:
7452            False (default): Never quote, except in cases where it's mandatory by the dialect.
7453            True: Always quote.
7454
7455    Examples:
7456        >>> from sqlglot import exp, parse_one
7457        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7458        'a.b.c'
7459
7460    Returns:
7461        The table name.
7462    """
7463
7464    table = maybe_parse(table, into=Table, dialect=dialect)
7465
7466    if not table:
7467        raise ValueError(f"Cannot parse {table}")
7468
7469    return ".".join(
7470        (
7471            part.sql(dialect=dialect, identify=True, copy=False)
7472            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7473            else part.name
7474        )
7475        for part in table.parts
7476    )

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:
7479def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7480    """Returns a case normalized table name without quotes.
7481
7482    Args:
7483        table: the table to normalize
7484        dialect: the dialect to use for normalization rules
7485        copy: whether to copy the expression.
7486
7487    Examples:
7488        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7489        'A-B.c'
7490    """
7491    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7492
7493    return ".".join(
7494        p.name
7495        for p in normalize_identifiers(
7496            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7497        ).parts
7498    )

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

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:
7728def tuple_(
7729    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7730) -> Tuple:
7731    """
7732    Returns an tuple.
7733
7734    Examples:
7735        >>> tuple_(1, 'x').sql()
7736        '(1, x)'
7737
7738    Args:
7739        expressions: the expressions to add to the tuple.
7740        copy: whether to copy the argument expressions.
7741        dialect: the source dialect.
7742        kwargs: the kwargs used to instantiate the function of interest.
7743
7744    Returns:
7745        A tuple expression.
7746    """
7747    return Tuple(
7748        expressions=[
7749            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7750            for expression in expressions
7751        ]
7752    )

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:
7755def true() -> Boolean:
7756    """
7757    Returns a true Boolean expression.
7758    """
7759    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7762def false() -> Boolean:
7763    """
7764    Returns a false Boolean expression.
7765    """
7766    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7769def null() -> Null:
7770    """
7771    Returns a Null expression.
7772    """
7773    return Null()

Returns a Null expression.

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