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

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

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

Converts the column into a dot expression.

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

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

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

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):
2204class OnConflict(Expression):
2205    arg_types = {
2206        "duplicate": False,
2207        "expressions": False,
2208        "action": False,
2209        "conflict_keys": False,
2210        "constraint": False,
2211    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2214class Returning(Expression):
2215    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2219class Introducer(Expression):
2220    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2224class National(Expression):
2225    pass
key = 'national'
class LoadData(Expression):
2228class LoadData(Expression):
2229    arg_types = {
2230        "this": True,
2231        "local": False,
2232        "overwrite": False,
2233        "inpath": True,
2234        "partition": False,
2235        "input_format": False,
2236        "serde": False,
2237    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2240class Partition(Expression):
2241    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2244class PartitionRange(Expression):
2245    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2249class PartitionId(Expression):
2250    pass
key = 'partitionid'
class Fetch(Expression):
2253class Fetch(Expression):
2254    arg_types = {
2255        "direction": False,
2256        "count": False,
2257        "percent": False,
2258        "with_ties": False,
2259    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2262class Group(Expression):
2263    arg_types = {
2264        "expressions": False,
2265        "grouping_sets": False,
2266        "cube": False,
2267        "rollup": False,
2268        "totals": False,
2269        "all": False,
2270    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2273class Lambda(Expression):
2274    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2277class Limit(Expression):
2278    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):
2281class Literal(Condition):
2282    arg_types = {"this": True, "is_string": True}
2283
2284    @property
2285    def hashable_args(self) -> t.Any:
2286        return (self.this, self.args.get("is_string"))
2287
2288    @classmethod
2289    def number(cls, number) -> Literal:
2290        return cls(this=str(number), is_string=False)
2291
2292    @classmethod
2293    def string(cls, string) -> Literal:
2294        return cls(this=str(string), is_string=True)
2295
2296    @property
2297    def output_name(self) -> str:
2298        return self.name
2299
2300    def to_py(self) -> int | str | Decimal:
2301        if self.is_number:
2302            try:
2303                return int(self.this)
2304            except ValueError:
2305                return Decimal(self.this)
2306        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2284    @property
2285    def hashable_args(self) -> t.Any:
2286        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2288    @classmethod
2289    def number(cls, number) -> Literal:
2290        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2292    @classmethod
2293    def string(cls, string) -> Literal:
2294        return cls(this=str(string), is_string=True)
output_name: str
2296    @property
2297    def output_name(self) -> str:
2298        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:
2300    def to_py(self) -> int | str | Decimal:
2301        if self.is_number:
2302            try:
2303                return int(self.this)
2304            except ValueError:
2305                return Decimal(self.this)
2306        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2309class Join(Expression):
2310    arg_types = {
2311        "this": True,
2312        "on": False,
2313        "side": False,
2314        "kind": False,
2315        "using": False,
2316        "method": False,
2317        "global": False,
2318        "hint": False,
2319        "match_condition": False,  # Snowflake
2320    }
2321
2322    @property
2323    def method(self) -> str:
2324        return self.text("method").upper()
2325
2326    @property
2327    def kind(self) -> str:
2328        return self.text("kind").upper()
2329
2330    @property
2331    def side(self) -> str:
2332        return self.text("side").upper()
2333
2334    @property
2335    def hint(self) -> str:
2336        return self.text("hint").upper()
2337
2338    @property
2339    def alias_or_name(self) -> str:
2340        return self.this.alias_or_name
2341
2342    def on(
2343        self,
2344        *expressions: t.Optional[ExpOrStr],
2345        append: bool = True,
2346        dialect: DialectType = None,
2347        copy: bool = True,
2348        **opts,
2349    ) -> Join:
2350        """
2351        Append to or set the ON expressions.
2352
2353        Example:
2354            >>> import sqlglot
2355            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2356            'JOIN x ON y = 1'
2357
2358        Args:
2359            *expressions: the SQL code strings to parse.
2360                If an `Expression` instance is passed, it will be used as-is.
2361                Multiple expressions are combined with an AND operator.
2362            append: if `True`, AND the new expressions to any existing expression.
2363                Otherwise, this resets the expression.
2364            dialect: the dialect used to parse the input expressions.
2365            copy: if `False`, modify this expression instance in-place.
2366            opts: other options to use to parse the input expressions.
2367
2368        Returns:
2369            The modified Join expression.
2370        """
2371        join = _apply_conjunction_builder(
2372            *expressions,
2373            instance=self,
2374            arg="on",
2375            append=append,
2376            dialect=dialect,
2377            copy=copy,
2378            **opts,
2379        )
2380
2381        if join.kind == "CROSS":
2382            join.set("kind", None)
2383
2384        return join
2385
2386    def using(
2387        self,
2388        *expressions: t.Optional[ExpOrStr],
2389        append: bool = True,
2390        dialect: DialectType = None,
2391        copy: bool = True,
2392        **opts,
2393    ) -> Join:
2394        """
2395        Append to or set the USING expressions.
2396
2397        Example:
2398            >>> import sqlglot
2399            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2400            'JOIN x USING (foo, bla)'
2401
2402        Args:
2403            *expressions: the SQL code strings to parse.
2404                If an `Expression` instance is passed, it will be used as-is.
2405            append: if `True`, concatenate the new expressions to the existing "using" list.
2406                Otherwise, this resets the expression.
2407            dialect: the dialect used to parse the input expressions.
2408            copy: if `False`, modify this expression instance in-place.
2409            opts: other options to use to parse the input expressions.
2410
2411        Returns:
2412            The modified Join expression.
2413        """
2414        join = _apply_list_builder(
2415            *expressions,
2416            instance=self,
2417            arg="using",
2418            append=append,
2419            dialect=dialect,
2420            copy=copy,
2421            **opts,
2422        )
2423
2424        if join.kind == "CROSS":
2425            join.set("kind", None)
2426
2427        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
2322    @property
2323    def method(self) -> str:
2324        return self.text("method").upper()
kind: str
2326    @property
2327    def kind(self) -> str:
2328        return self.text("kind").upper()
side: str
2330    @property
2331    def side(self) -> str:
2332        return self.text("side").upper()
hint: str
2334    @property
2335    def hint(self) -> str:
2336        return self.text("hint").upper()
alias_or_name: str
2338    @property
2339    def alias_or_name(self) -> str:
2340        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:
2342    def on(
2343        self,
2344        *expressions: t.Optional[ExpOrStr],
2345        append: bool = True,
2346        dialect: DialectType = None,
2347        copy: bool = True,
2348        **opts,
2349    ) -> Join:
2350        """
2351        Append to or set the ON expressions.
2352
2353        Example:
2354            >>> import sqlglot
2355            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2356            'JOIN x ON y = 1'
2357
2358        Args:
2359            *expressions: the SQL code strings to parse.
2360                If an `Expression` instance is passed, it will be used as-is.
2361                Multiple expressions are combined with an AND operator.
2362            append: if `True`, AND the new expressions to any existing expression.
2363                Otherwise, this resets the expression.
2364            dialect: the dialect used to parse the input expressions.
2365            copy: if `False`, modify this expression instance in-place.
2366            opts: other options to use to parse the input expressions.
2367
2368        Returns:
2369            The modified Join expression.
2370        """
2371        join = _apply_conjunction_builder(
2372            *expressions,
2373            instance=self,
2374            arg="on",
2375            append=append,
2376            dialect=dialect,
2377            copy=copy,
2378            **opts,
2379        )
2380
2381        if join.kind == "CROSS":
2382            join.set("kind", None)
2383
2384        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:
2386    def using(
2387        self,
2388        *expressions: t.Optional[ExpOrStr],
2389        append: bool = True,
2390        dialect: DialectType = None,
2391        copy: bool = True,
2392        **opts,
2393    ) -> Join:
2394        """
2395        Append to or set the USING expressions.
2396
2397        Example:
2398            >>> import sqlglot
2399            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2400            'JOIN x USING (foo, bla)'
2401
2402        Args:
2403            *expressions: the SQL code strings to parse.
2404                If an `Expression` instance is passed, it will be used as-is.
2405            append: if `True`, concatenate the new expressions to the existing "using" list.
2406                Otherwise, this resets the expression.
2407            dialect: the dialect used to parse the input expressions.
2408            copy: if `False`, modify this expression instance in-place.
2409            opts: other options to use to parse the input expressions.
2410
2411        Returns:
2412            The modified Join expression.
2413        """
2414        join = _apply_list_builder(
2415            *expressions,
2416            instance=self,
2417            arg="using",
2418            append=append,
2419            dialect=dialect,
2420            copy=copy,
2421            **opts,
2422        )
2423
2424        if join.kind == "CROSS":
2425            join.set("kind", None)
2426
2427        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):
2430class Lateral(UDTF):
2431    arg_types = {
2432        "this": True,
2433        "view": False,
2434        "outer": False,
2435        "alias": False,
2436        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2437    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2440class MatchRecognizeMeasure(Expression):
2441    arg_types = {
2442        "this": True,
2443        "window_frame": False,
2444    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2447class MatchRecognize(Expression):
2448    arg_types = {
2449        "partition_by": False,
2450        "order": False,
2451        "measures": False,
2452        "rows": False,
2453        "after": False,
2454        "pattern": False,
2455        "define": False,
2456        "alias": False,
2457    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2462class Final(Expression):
2463    pass
key = 'final'
class Offset(Expression):
2466class Offset(Expression):
2467    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2470class Order(Expression):
2471    arg_types = {
2472        "this": False,
2473        "expressions": True,
2474        "interpolate": False,
2475        "siblings": False,
2476    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2480class WithFill(Expression):
2481    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2486class Cluster(Order):
2487    pass
key = 'cluster'
class Distribute(Order):
2490class Distribute(Order):
2491    pass
key = 'distribute'
class Sort(Order):
2494class Sort(Order):
2495    pass
key = 'sort'
class Ordered(Expression):
2498class Ordered(Expression):
2499    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):
2502class Property(Expression):
2503    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2506class AllowedValuesProperty(Expression):
2507    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2510class AlgorithmProperty(Property):
2511    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2514class AutoIncrementProperty(Property):
2515    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2519class AutoRefreshProperty(Property):
2520    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2523class BackupProperty(Property):
2524    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2527class BlockCompressionProperty(Property):
2528    arg_types = {
2529        "autotemp": False,
2530        "always": False,
2531        "default": False,
2532        "manual": False,
2533        "never": False,
2534    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2537class CharacterSetProperty(Property):
2538    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2541class ChecksumProperty(Property):
2542    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2545class CollateProperty(Property):
2546    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2549class CopyGrantsProperty(Property):
2550    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2553class DataBlocksizeProperty(Property):
2554    arg_types = {
2555        "size": False,
2556        "units": False,
2557        "minimum": False,
2558        "maximum": False,
2559        "default": False,
2560    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2563class DataDeletionProperty(Property):
2564    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):
2567class DefinerProperty(Property):
2568    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2571class DistKeyProperty(Property):
2572    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2575class DistStyleProperty(Property):
2576    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2579class EngineProperty(Property):
2580    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2583class HeapProperty(Property):
2584    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2587class ToTableProperty(Property):
2588    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2591class ExecuteAsProperty(Property):
2592    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2595class ExternalProperty(Property):
2596    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2599class FallbackProperty(Property):
2600    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2603class FileFormatProperty(Property):
2604    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2607class FreespaceProperty(Property):
2608    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2611class GlobalProperty(Property):
2612    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2615class IcebergProperty(Property):
2616    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2619class InheritsProperty(Property):
2620    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2623class InputModelProperty(Property):
2624    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2627class OutputModelProperty(Property):
2628    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2631class IsolatedLoadingProperty(Property):
2632    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2635class JournalProperty(Property):
2636    arg_types = {
2637        "no": False,
2638        "dual": False,
2639        "before": False,
2640        "local": False,
2641        "after": False,
2642    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2645class LanguageProperty(Property):
2646    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2650class ClusteredByProperty(Property):
2651    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2654class DictProperty(Property):
2655    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2658class DictSubProperty(Property):
2659    pass
key = 'dictsubproperty'
class DictRange(Property):
2662class DictRange(Property):
2663    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2666class DynamicProperty(Property):
2667    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2672class OnCluster(Property):
2673    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2677class EmptyProperty(Property):
2678    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2681class LikeProperty(Property):
2682    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2685class LocationProperty(Property):
2686    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2689class LockProperty(Property):
2690    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2693class LockingProperty(Property):
2694    arg_types = {
2695        "this": False,
2696        "kind": True,
2697        "for_or_in": False,
2698        "lock_type": True,
2699        "override": False,
2700    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2703class LogProperty(Property):
2704    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2707class MaterializedProperty(Property):
2708    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2711class MergeBlockRatioProperty(Property):
2712    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):
2715class NoPrimaryIndexProperty(Property):
2716    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2719class OnProperty(Property):
2720    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2723class OnCommitProperty(Property):
2724    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2727class PartitionedByProperty(Property):
2728    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2732class PartitionBoundSpec(Expression):
2733    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2734    arg_types = {
2735        "this": False,
2736        "expression": False,
2737        "from_expressions": False,
2738        "to_expressions": False,
2739    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2742class PartitionedOfProperty(Property):
2743    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2744    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2747class StreamingTableProperty(Property):
2748    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2751class RemoteWithConnectionModelProperty(Property):
2752    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2755class ReturnsProperty(Property):
2756    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):
2759class StrictProperty(Property):
2760    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2763class RowFormatProperty(Property):
2764    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2767class RowFormatDelimitedProperty(Property):
2768    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2769    arg_types = {
2770        "fields": False,
2771        "escaped": False,
2772        "collection_items": False,
2773        "map_keys": False,
2774        "lines": False,
2775        "null": False,
2776        "serde": False,
2777    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2780class RowFormatSerdeProperty(Property):
2781    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2785class QueryTransform(Expression):
2786    arg_types = {
2787        "expressions": True,
2788        "command_script": True,
2789        "schema": False,
2790        "row_format_before": False,
2791        "record_writer": False,
2792        "row_format_after": False,
2793        "record_reader": False,
2794    }
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):
2797class SampleProperty(Property):
2798    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2801class SchemaCommentProperty(Property):
2802    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2805class SerdeProperties(Property):
2806    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2809class SetProperty(Property):
2810    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2813class SharingProperty(Property):
2814    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2817class SetConfigProperty(Property):
2818    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2821class SettingsProperty(Property):
2822    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2825class SortKeyProperty(Property):
2826    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2829class SqlReadWriteProperty(Property):
2830    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2833class SqlSecurityProperty(Property):
2834    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2837class StabilityProperty(Property):
2838    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2841class TemporaryProperty(Property):
2842    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2845class SecureProperty(Property):
2846    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2849class TransformModelProperty(Property):
2850    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2853class TransientProperty(Property):
2854    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2857class UnloggedProperty(Property):
2858    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2862class ViewAttributeProperty(Property):
2863    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2866class VolatileProperty(Property):
2867    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2870class WithDataProperty(Property):
2871    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2874class WithJournalTableProperty(Property):
2875    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2878class WithSchemaBindingProperty(Property):
2879    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2882class WithSystemVersioningProperty(Property):
2883    arg_types = {
2884        "on": False,
2885        "this": False,
2886        "data_consistency": False,
2887        "retention_period": False,
2888        "with": True,
2889    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2892class Properties(Expression):
2893    arg_types = {"expressions": True}
2894
2895    NAME_TO_PROPERTY = {
2896        "ALGORITHM": AlgorithmProperty,
2897        "AUTO_INCREMENT": AutoIncrementProperty,
2898        "CHARACTER SET": CharacterSetProperty,
2899        "CLUSTERED_BY": ClusteredByProperty,
2900        "COLLATE": CollateProperty,
2901        "COMMENT": SchemaCommentProperty,
2902        "DEFINER": DefinerProperty,
2903        "DISTKEY": DistKeyProperty,
2904        "DISTSTYLE": DistStyleProperty,
2905        "ENGINE": EngineProperty,
2906        "EXECUTE AS": ExecuteAsProperty,
2907        "FORMAT": FileFormatProperty,
2908        "LANGUAGE": LanguageProperty,
2909        "LOCATION": LocationProperty,
2910        "LOCK": LockProperty,
2911        "PARTITIONED_BY": PartitionedByProperty,
2912        "RETURNS": ReturnsProperty,
2913        "ROW_FORMAT": RowFormatProperty,
2914        "SORTKEY": SortKeyProperty,
2915    }
2916
2917    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2918
2919    # CREATE property locations
2920    # Form: schema specified
2921    #   create [POST_CREATE]
2922    #     table a [POST_NAME]
2923    #     (b int) [POST_SCHEMA]
2924    #     with ([POST_WITH])
2925    #     index (b) [POST_INDEX]
2926    #
2927    # Form: alias selection
2928    #   create [POST_CREATE]
2929    #     table a [POST_NAME]
2930    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2931    #     index (c) [POST_INDEX]
2932    class Location(AutoName):
2933        POST_CREATE = auto()
2934        POST_NAME = auto()
2935        POST_SCHEMA = auto()
2936        POST_WITH = auto()
2937        POST_ALIAS = auto()
2938        POST_EXPRESSION = auto()
2939        POST_INDEX = auto()
2940        UNSUPPORTED = auto()
2941
2942    @classmethod
2943    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2944        expressions = []
2945        for key, value in properties_dict.items():
2946            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2947            if property_cls:
2948                expressions.append(property_cls(this=convert(value)))
2949            else:
2950                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2951
2952        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:
2942    @classmethod
2943    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2944        expressions = []
2945        for key, value in properties_dict.items():
2946            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2947            if property_cls:
2948                expressions.append(property_cls(this=convert(value)))
2949            else:
2950                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2951
2952        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2932    class Location(AutoName):
2933        POST_CREATE = auto()
2934        POST_NAME = auto()
2935        POST_SCHEMA = auto()
2936        POST_WITH = auto()
2937        POST_ALIAS = auto()
2938        POST_EXPRESSION = auto()
2939        POST_INDEX = auto()
2940        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):
2955class Qualify(Expression):
2956    pass
key = 'qualify'
class InputOutputFormat(Expression):
2959class InputOutputFormat(Expression):
2960    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2964class Return(Expression):
2965    pass
key = 'return'
class Reference(Expression):
2968class Reference(Expression):
2969    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2972class Tuple(Expression):
2973    arg_types = {"expressions": False}
2974
2975    def isin(
2976        self,
2977        *expressions: t.Any,
2978        query: t.Optional[ExpOrStr] = None,
2979        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2980        copy: bool = True,
2981        **opts,
2982    ) -> In:
2983        return In(
2984            this=maybe_copy(self, copy),
2985            expressions=[convert(e, copy=copy) for e in expressions],
2986            query=maybe_parse(query, copy=copy, **opts) if query else None,
2987            unnest=(
2988                Unnest(
2989                    expressions=[
2990                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2991                        for e in ensure_list(unnest)
2992                    ]
2993                )
2994                if unnest
2995                else None
2996            ),
2997        )
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:
2975    def isin(
2976        self,
2977        *expressions: t.Any,
2978        query: t.Optional[ExpOrStr] = None,
2979        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2980        copy: bool = True,
2981        **opts,
2982    ) -> In:
2983        return In(
2984            this=maybe_copy(self, copy),
2985            expressions=[convert(e, copy=copy) for e in expressions],
2986            query=maybe_parse(query, copy=copy, **opts) if query else None,
2987            unnest=(
2988                Unnest(
2989                    expressions=[
2990                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2991                        for e in ensure_list(unnest)
2992                    ]
2993                )
2994                if unnest
2995                else None
2996            ),
2997        )
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):
3028class QueryOption(Expression):
3029    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3033class WithTableHint(Expression):
3034    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3038class IndexTableHint(Expression):
3039    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3043class HistoricalData(Expression):
3044    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3047class Table(Expression):
3048    arg_types = {
3049        "this": False,
3050        "alias": False,
3051        "db": False,
3052        "catalog": False,
3053        "laterals": False,
3054        "joins": False,
3055        "pivots": False,
3056        "hints": False,
3057        "system_time": False,
3058        "version": False,
3059        "format": False,
3060        "pattern": False,
3061        "ordinality": False,
3062        "when": False,
3063        "only": False,
3064        "partition": False,
3065        "changes": False,
3066        "rows_from": False,
3067    }
3068
3069    @property
3070    def name(self) -> str:
3071        if isinstance(self.this, Func):
3072            return ""
3073        return self.this.name
3074
3075    @property
3076    def db(self) -> str:
3077        return self.text("db")
3078
3079    @property
3080    def catalog(self) -> str:
3081        return self.text("catalog")
3082
3083    @property
3084    def selects(self) -> t.List[Expression]:
3085        return []
3086
3087    @property
3088    def named_selects(self) -> t.List[str]:
3089        return []
3090
3091    @property
3092    def parts(self) -> t.List[Expression]:
3093        """Return the parts of a table in order catalog, db, table."""
3094        parts: t.List[Expression] = []
3095
3096        for arg in ("catalog", "db", "this"):
3097            part = self.args.get(arg)
3098
3099            if isinstance(part, Dot):
3100                parts.extend(part.flatten())
3101            elif isinstance(part, Expression):
3102                parts.append(part)
3103
3104        return parts
3105
3106    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3107        parts = self.parts
3108        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3109        alias = self.args.get("alias")
3110        if alias:
3111            col = alias_(col, alias.this, copy=copy)
3112        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
3069    @property
3070    def name(self) -> str:
3071        if isinstance(self.this, Func):
3072            return ""
3073        return self.this.name
db: str
3075    @property
3076    def db(self) -> str:
3077        return self.text("db")
catalog: str
3079    @property
3080    def catalog(self) -> str:
3081        return self.text("catalog")
selects: List[Expression]
3083    @property
3084    def selects(self) -> t.List[Expression]:
3085        return []
named_selects: List[str]
3087    @property
3088    def named_selects(self) -> t.List[str]:
3089        return []
parts: List[Expression]
3091    @property
3092    def parts(self) -> t.List[Expression]:
3093        """Return the parts of a table in order catalog, db, table."""
3094        parts: t.List[Expression] = []
3095
3096        for arg in ("catalog", "db", "this"):
3097            part = self.args.get(arg)
3098
3099            if isinstance(part, Dot):
3100                parts.extend(part.flatten())
3101            elif isinstance(part, Expression):
3102                parts.append(part)
3103
3104        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3144    @property
3145    def is_star(self) -> bool:
3146        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3148    @property
3149    def selects(self) -> t.List[Expression]:
3150        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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:
3386    def select(
3387        self,
3388        *expressions: t.Optional[ExpOrStr],
3389        append: bool = True,
3390        dialect: DialectType = None,
3391        copy: bool = True,
3392        **opts,
3393    ) -> Select:
3394        return _apply_list_builder(
3395            *expressions,
3396            instance=self,
3397            arg="expressions",
3398            append=append,
3399            dialect=dialect,
3400            into=Expression,
3401            copy=copy,
3402            **opts,
3403        )

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

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

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

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:
3581    def having(
3582        self,
3583        *expressions: t.Optional[ExpOrStr],
3584        append: bool = True,
3585        dialect: DialectType = None,
3586        copy: bool = True,
3587        **opts,
3588    ) -> Select:
3589        """
3590        Append to or set the HAVING expressions.
3591
3592        Example:
3593            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3594            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3595
3596        Args:
3597            *expressions: the SQL code strings to parse.
3598                If an `Expression` instance is passed, it will be used as-is.
3599                Multiple expressions are combined with an AND operator.
3600            append: if `True`, AND the new expressions to any existing expression.
3601                Otherwise, this resets the expression.
3602            dialect: the dialect used to parse the input expressions.
3603            copy: if `False`, modify this expression instance in-place.
3604            opts: other options to use to parse the input expressions.
3605
3606        Returns:
3607            The modified Select expression.
3608        """
3609        return _apply_conjunction_builder(
3610            *expressions,
3611            instance=self,
3612            arg="having",
3613            append=append,
3614            into=Having,
3615            dialect=dialect,
3616            copy=copy,
3617            **opts,
3618        )

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

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

Checks whether an expression is a star.

selects: List[Expression]
3776    @property
3777    def selects(self) -> t.List[Expression]:
3778        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3799    def unwrap(self) -> Subquery:
3800        expression = self
3801        while expression.same_parent and expression.is_wrapper:
3802            expression = t.cast(Subquery, expression.parent)
3803        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:
3805    def select(
3806        self,
3807        *expressions: t.Optional[ExpOrStr],
3808        append: bool = True,
3809        dialect: DialectType = None,
3810        copy: bool = True,
3811        **opts,
3812    ) -> Subquery:
3813        this = maybe_copy(self, copy)
3814        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3815        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
3817    @property
3818    def is_wrapper(self) -> bool:
3819        """
3820        Whether this Subquery acts as a simple wrapper around another expression.
3821
3822        SELECT * FROM (((SELECT * FROM t)))
3823                      ^
3824                      This corresponds to a "wrapper" Subquery node
3825        """
3826        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
3828    @property
3829    def is_star(self) -> bool:
3830        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3832    @property
3833    def output_name(self) -> str:
3834        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):
3837class TableSample(Expression):
3838    arg_types = {
3839        "this": False,
3840        "expressions": False,
3841        "method": False,
3842        "bucket_numerator": False,
3843        "bucket_denominator": False,
3844        "bucket_field": False,
3845        "percent": False,
3846        "rows": False,
3847        "size": False,
3848        "seed": False,
3849    }
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):
3852class Tag(Expression):
3853    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3854
3855    arg_types = {
3856        "this": False,
3857        "prefix": False,
3858        "postfix": False,
3859    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3864class Pivot(Expression):
3865    arg_types = {
3866        "this": False,
3867        "alias": False,
3868        "expressions": False,
3869        "field": False,
3870        "unpivot": False,
3871        "using": False,
3872        "group": False,
3873        "columns": False,
3874        "include_nulls": False,
3875        "default_on_null": False,
3876    }
3877
3878    @property
3879    def unpivot(self) -> bool:
3880        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False}
unpivot: bool
3878    @property
3879    def unpivot(self) -> bool:
3880        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3883class Window(Condition):
3884    arg_types = {
3885        "this": True,
3886        "partition_by": False,
3887        "order": False,
3888        "spec": False,
3889        "alias": False,
3890        "over": False,
3891        "first": False,
3892    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3895class WindowSpec(Expression):
3896    arg_types = {
3897        "kind": False,
3898        "start": False,
3899        "start_side": False,
3900        "end": False,
3901        "end_side": False,
3902    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3905class PreWhere(Expression):
3906    pass
key = 'prewhere'
class Where(Expression):
3909class Where(Expression):
3910    pass
key = 'where'
class Star(Expression):
3913class Star(Expression):
3914    arg_types = {"except": False, "replace": False, "rename": False}
3915
3916    @property
3917    def name(self) -> str:
3918        return "*"
3919
3920    @property
3921    def output_name(self) -> str:
3922        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3916    @property
3917    def name(self) -> str:
3918        return "*"
output_name: str
3920    @property
3921    def output_name(self) -> str:
3922        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):
3925class Parameter(Condition):
3926    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3929class SessionParameter(Condition):
3930    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3933class Placeholder(Condition):
3934    arg_types = {"this": False, "kind": False}
3935
3936    @property
3937    def name(self) -> str:
3938        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3936    @property
3937    def name(self) -> str:
3938        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3941class Null(Condition):
3942    arg_types: t.Dict[str, t.Any] = {}
3943
3944    @property
3945    def name(self) -> str:
3946        return "NULL"
3947
3948    def to_py(self) -> Lit[None]:
3949        return None
arg_types: Dict[str, Any] = {}
name: str
3944    @property
3945    def name(self) -> str:
3946        return "NULL"
def to_py(self) -> Literal[None]:
3948    def to_py(self) -> Lit[None]:
3949        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3952class Boolean(Condition):
3953    def to_py(self) -> bool:
3954        return self.this
def to_py(self) -> bool:
3953    def to_py(self) -> bool:
3954        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
4374    @property
4375    def name(self) -> str:
4376        return self.expression.name
output_name: str
4378    @property
4379    def output_name(self) -> str:
4380        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:
4382    @classmethod
4383    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4384        """Build a Dot object with a sequence of expressions."""
4385        if len(expressions) < 2:
4386            raise ValueError("Dot requires >= 2 expressions.")
4387
4388        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]
4390    @property
4391    def parts(self) -> t.List[Expression]:
4392        """Return the parts of a table / column in order catalog, db, table."""
4393        this, *parts = self.flatten()
4394
4395        parts.reverse()
4396
4397        for arg in COLUMN_PARTS:
4398            part = this.args.get(arg)
4399
4400            if isinstance(part, Expression):
4401                parts.append(part)
4402
4403        parts.reverse()
4404        return parts

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

key = 'dot'
class DPipe(Binary):
4407class DPipe(Binary):
4408    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4411class EQ(Binary, Predicate):
4412    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4415class NullSafeEQ(Binary, Predicate):
4416    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4419class NullSafeNEQ(Binary, Predicate):
4420    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4424class PropertyEQ(Binary):
4425    pass
key = 'propertyeq'
class Distance(Binary):
4428class Distance(Binary):
4429    pass
key = 'distance'
class Escape(Binary):
4432class Escape(Binary):
4433    pass
key = 'escape'
class Glob(Binary, Predicate):
4436class Glob(Binary, Predicate):
4437    pass
key = 'glob'
class GT(Binary, Predicate):
4440class GT(Binary, Predicate):
4441    pass
key = 'gt'
class GTE(Binary, Predicate):
4444class GTE(Binary, Predicate):
4445    pass
key = 'gte'
class ILike(Binary, Predicate):
4448class ILike(Binary, Predicate):
4449    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4452class ILikeAny(Binary, Predicate):
4453    pass
key = 'ilikeany'
class IntDiv(Binary):
4456class IntDiv(Binary):
4457    pass
key = 'intdiv'
class Is(Binary, Predicate):
4460class Is(Binary, Predicate):
4461    pass
key = 'is'
class Kwarg(Binary):
4464class Kwarg(Binary):
4465    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4468class Like(Binary, Predicate):
4469    pass
key = 'like'
class LikeAny(Binary, Predicate):
4472class LikeAny(Binary, Predicate):
4473    pass
key = 'likeany'
class LT(Binary, Predicate):
4476class LT(Binary, Predicate):
4477    pass
key = 'lt'
class LTE(Binary, Predicate):
4480class LTE(Binary, Predicate):
4481    pass
key = 'lte'
class Mod(Binary):
4484class Mod(Binary):
4485    pass
key = 'mod'
class Mul(Binary):
4488class Mul(Binary):
4489    pass
key = 'mul'
class NEQ(Binary, Predicate):
4492class NEQ(Binary, Predicate):
4493    pass
key = 'neq'
class Operator(Binary):
4497class Operator(Binary):
4498    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4501class SimilarTo(Binary, Predicate):
4502    pass
key = 'similarto'
class Slice(Binary):
4505class Slice(Binary):
4506    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4509class Sub(Binary):
4510    pass
key = 'sub'
class Unary(Condition):
4515class Unary(Condition):
4516    pass
key = 'unary'
class BitwiseNot(Unary):
4519class BitwiseNot(Unary):
4520    pass
key = 'bitwisenot'
class Not(Unary):
4523class Not(Unary):
4524    pass
key = 'not'
class Paren(Unary):
4527class Paren(Unary):
4528    @property
4529    def output_name(self) -> str:
4530        return self.this.name
output_name: str
4528    @property
4529    def output_name(self) -> str:
4530        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):
4533class Neg(Unary):
4534    def to_py(self) -> int | Decimal:
4535        if self.is_number:
4536            return self.this.to_py() * -1
4537        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4534    def to_py(self) -> int | Decimal:
4535        if self.is_number:
4536            return self.this.to_py() * -1
4537        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4540class Alias(Expression):
4541    arg_types = {"this": True, "alias": False}
4542
4543    @property
4544    def output_name(self) -> str:
4545        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4543    @property
4544    def output_name(self) -> str:
4545        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):
4550class PivotAlias(Alias):
4551    pass
key = 'pivotalias'
class PivotAny(Expression):
4556class PivotAny(Expression):
4557    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4560class Aliases(Expression):
4561    arg_types = {"this": True, "expressions": True}
4562
4563    @property
4564    def aliases(self):
4565        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4563    @property
4564    def aliases(self):
4565        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4569class AtIndex(Expression):
4570    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4573class AtTimeZone(Expression):
4574    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4577class FromTimeZone(Expression):
4578    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4581class Between(Predicate):
4582    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4585class Bracket(Condition):
4586    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4587    arg_types = {
4588        "this": True,
4589        "expressions": True,
4590        "offset": False,
4591        "safe": False,
4592        "returns_list_for_maps": False,
4593    }
4594
4595    @property
4596    def output_name(self) -> str:
4597        if len(self.expressions) == 1:
4598            return self.expressions[0].output_name
4599
4600        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4595    @property
4596    def output_name(self) -> str:
4597        if len(self.expressions) == 1:
4598            return self.expressions[0].output_name
4599
4600        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):
4603class Distinct(Expression):
4604    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4607class In(Predicate):
4608    arg_types = {
4609        "this": True,
4610        "expressions": False,
4611        "query": False,
4612        "unnest": False,
4613        "field": False,
4614        "is_global": False,
4615    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4619class ForIn(Expression):
4620    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4623class TimeUnit(Expression):
4624    """Automatically converts unit arg into a var."""
4625
4626    arg_types = {"unit": False}
4627
4628    UNABBREVIATED_UNIT_NAME = {
4629        "D": "DAY",
4630        "H": "HOUR",
4631        "M": "MINUTE",
4632        "MS": "MILLISECOND",
4633        "NS": "NANOSECOND",
4634        "Q": "QUARTER",
4635        "S": "SECOND",
4636        "US": "MICROSECOND",
4637        "W": "WEEK",
4638        "Y": "YEAR",
4639    }
4640
4641    VAR_LIKE = (Column, Literal, Var)
4642
4643    def __init__(self, **args):
4644        unit = args.get("unit")
4645        if isinstance(unit, self.VAR_LIKE):
4646            args["unit"] = Var(
4647                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4648            )
4649        elif isinstance(unit, Week):
4650            unit.set("this", Var(this=unit.this.name.upper()))
4651
4652        super().__init__(**args)
4653
4654    @property
4655    def unit(self) -> t.Optional[Var | IntervalSpan]:
4656        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4643    def __init__(self, **args):
4644        unit = args.get("unit")
4645        if isinstance(unit, self.VAR_LIKE):
4646            args["unit"] = Var(
4647                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4648            )
4649        elif isinstance(unit, Week):
4650            unit.set("this", Var(this=unit.this.name.upper()))
4651
4652        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]
4654    @property
4655    def unit(self) -> t.Optional[Var | IntervalSpan]:
4656        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4659class IntervalOp(TimeUnit):
4660    arg_types = {"unit": True, "expression": True}
4661
4662    def interval(self):
4663        return Interval(
4664            this=self.expression.copy(),
4665            unit=self.unit.copy(),
4666        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4662    def interval(self):
4663        return Interval(
4664            this=self.expression.copy(),
4665            unit=self.unit.copy(),
4666        )
key = 'intervalop'
class IntervalSpan(DataType):
4672class IntervalSpan(DataType):
4673    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4676class Interval(TimeUnit):
4677    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4680class IgnoreNulls(Expression):
4681    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4684class RespectNulls(Expression):
4685    pass
key = 'respectnulls'
class HavingMax(Expression):
4689class HavingMax(Expression):
4690    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4694class Func(Condition):
4695    """
4696    The base class for all function expressions.
4697
4698    Attributes:
4699        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4700            treated as a variable length argument and the argument's value will be stored as a list.
4701        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4702            function expression. These values are used to map this node to a name during parsing as
4703            well as to provide the function's name during SQL string generation. By default the SQL
4704            name is set to the expression's class name transformed to snake case.
4705    """
4706
4707    is_var_len_args = False
4708
4709    @classmethod
4710    def from_arg_list(cls, args):
4711        if cls.is_var_len_args:
4712            all_arg_keys = list(cls.arg_types)
4713            # If this function supports variable length argument treat the last argument as such.
4714            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4715            num_non_var = len(non_var_len_arg_keys)
4716
4717            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4718            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4719        else:
4720            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4721
4722        return cls(**args_dict)
4723
4724    @classmethod
4725    def sql_names(cls):
4726        if cls is Func:
4727            raise NotImplementedError(
4728                "SQL name is only supported by concrete function implementations"
4729            )
4730        if "_sql_names" not in cls.__dict__:
4731            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4732        return cls._sql_names
4733
4734    @classmethod
4735    def sql_name(cls):
4736        return cls.sql_names()[0]
4737
4738    @classmethod
4739    def default_parser_mappings(cls):
4740        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):
4709    @classmethod
4710    def from_arg_list(cls, args):
4711        if cls.is_var_len_args:
4712            all_arg_keys = list(cls.arg_types)
4713            # If this function supports variable length argument treat the last argument as such.
4714            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4715            num_non_var = len(non_var_len_arg_keys)
4716
4717            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4718            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4719        else:
4720            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4721
4722        return cls(**args_dict)
@classmethod
def sql_names(cls):
4724    @classmethod
4725    def sql_names(cls):
4726        if cls is Func:
4727            raise NotImplementedError(
4728                "SQL name is only supported by concrete function implementations"
4729            )
4730        if "_sql_names" not in cls.__dict__:
4731            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4732        return cls._sql_names
@classmethod
def sql_name(cls):
4734    @classmethod
4735    def sql_name(cls):
4736        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4738    @classmethod
4739    def default_parser_mappings(cls):
4740        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4743class AggFunc(Func):
4744    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4747class ParameterizedAgg(AggFunc):
4748    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4751class Abs(Func):
4752    pass
key = 'abs'
class ArgMax(AggFunc):
4755class ArgMax(AggFunc):
4756    arg_types = {"this": True, "expression": True, "count": False}
4757    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4760class ArgMin(AggFunc):
4761    arg_types = {"this": True, "expression": True, "count": False}
4762    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4765class ApproxTopK(AggFunc):
4766    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4769class Flatten(Func):
4770    pass
key = 'flatten'
class Transform(Func):
4774class Transform(Func):
4775    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4778class Anonymous(Func):
4779    arg_types = {"this": True, "expressions": False}
4780    is_var_len_args = True
4781
4782    @property
4783    def name(self) -> str:
4784        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
4782    @property
4783    def name(self) -> str:
4784        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4787class AnonymousAggFunc(AggFunc):
4788    arg_types = {"this": True, "expressions": False}
4789    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4793class CombinedAggFunc(AnonymousAggFunc):
4794    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4797class CombinedParameterizedAgg(ParameterizedAgg):
4798    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):
4803class Hll(AggFunc):
4804    arg_types = {"this": True, "expressions": False}
4805    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4808class ApproxDistinct(AggFunc):
4809    arg_types = {"this": True, "accuracy": False}
4810    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4813class Array(Func):
4814    arg_types = {"expressions": False, "bracket_notation": False}
4815    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4819class ToArray(Func):
4820    pass
key = 'toarray'
class List(Func):
4824class List(Func):
4825    arg_types = {"expressions": False}
4826    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4830class Pad(Func):
4831    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):
4836class ToChar(Func):
4837    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4842class ToNumber(Func):
4843    arg_types = {
4844        "this": True,
4845        "format": False,
4846        "nlsparam": False,
4847        "precision": False,
4848        "scale": False,
4849    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4853class Convert(Func):
4854    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4857class ConvertTimezone(Func):
4858    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
4861class GenerateSeries(Func):
4862    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ExplodingGenerateSeries(GenerateSeries):
4868class ExplodingGenerateSeries(GenerateSeries):
4869    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4872class ArrayAgg(AggFunc):
4873    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4876class ArrayUniqueAgg(AggFunc):
4877    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4880class ArrayAll(Func):
4881    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4885class ArrayAny(Func):
4886    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4889class ArrayConcat(Func):
4890    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4891    arg_types = {"this": True, "expressions": False}
4892    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4895class ArrayConstructCompact(Func):
4896    arg_types = {"expressions": True}
4897    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4900class ArrayContains(Binary, Func):
4901    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4904class ArrayContainsAll(Binary, Func):
4905    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4908class ArrayFilter(Func):
4909    arg_types = {"this": True, "expression": True}
4910    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4913class ArrayToString(Func):
4914    arg_types = {"this": True, "expression": True, "null": False}
4915    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4918class StringToArray(Func):
4919    arg_types = {"this": True, "expression": True, "null": False}
4920    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4923class ArrayOverlaps(Binary, Func):
4924    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4927class ArraySize(Func):
4928    arg_types = {"this": True, "expression": False}
4929    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4932class ArraySort(Func):
4933    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4936class ArraySum(Func):
4937    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4940class ArrayUnionAgg(AggFunc):
4941    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4944class Avg(AggFunc):
4945    pass
key = 'avg'
class AnyValue(AggFunc):
4948class AnyValue(AggFunc):
4949    pass
key = 'anyvalue'
class Lag(AggFunc):
4952class Lag(AggFunc):
4953    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4956class Lead(AggFunc):
4957    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4962class First(AggFunc):
4963    pass
key = 'first'
class Last(AggFunc):
4966class Last(AggFunc):
4967    pass
key = 'last'
class FirstValue(AggFunc):
4970class FirstValue(AggFunc):
4971    pass
key = 'firstvalue'
class LastValue(AggFunc):
4974class LastValue(AggFunc):
4975    pass
key = 'lastvalue'
class NthValue(AggFunc):
4978class NthValue(AggFunc):
4979    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4982class Case(Func):
4983    arg_types = {"this": False, "ifs": True, "default": False}
4984
4985    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4986        instance = maybe_copy(self, copy)
4987        instance.append(
4988            "ifs",
4989            If(
4990                this=maybe_parse(condition, copy=copy, **opts),
4991                true=maybe_parse(then, copy=copy, **opts),
4992            ),
4993        )
4994        return instance
4995
4996    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4997        instance = maybe_copy(self, copy)
4998        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4999        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:
4985    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4986        instance = maybe_copy(self, copy)
4987        instance.append(
4988            "ifs",
4989            If(
4990                this=maybe_parse(condition, copy=copy, **opts),
4991                true=maybe_parse(then, copy=copy, **opts),
4992            ),
4993        )
4994        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4996    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4997        instance = maybe_copy(self, copy)
4998        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4999        return instance
key = 'case'
class Cast(Func):
5002class Cast(Func):
5003    arg_types = {
5004        "this": True,
5005        "to": True,
5006        "format": False,
5007        "safe": False,
5008        "action": False,
5009    }
5010
5011    @property
5012    def name(self) -> str:
5013        return self.this.name
5014
5015    @property
5016    def to(self) -> DataType:
5017        return self.args["to"]
5018
5019    @property
5020    def output_name(self) -> str:
5021        return self.name
5022
5023    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5024        """
5025        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5026        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5027        array<int> != array<float>.
5028
5029        Args:
5030            dtypes: the data types to compare this Cast's DataType to.
5031
5032        Returns:
5033            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5034        """
5035        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5011    @property
5012    def name(self) -> str:
5013        return self.this.name
to: DataType
5015    @property
5016    def to(self) -> DataType:
5017        return self.args["to"]
output_name: str
5019    @property
5020    def output_name(self) -> str:
5021        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:
5023    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5024        """
5025        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5026        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5027        array<int> != array<float>.
5028
5029        Args:
5030            dtypes: the data types to compare this Cast's DataType to.
5031
5032        Returns:
5033            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5034        """
5035        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):
5038class TryCast(Cast):
5039    pass
key = 'trycast'
class Try(Func):
5042class Try(Func):
5043    pass
key = 'try'
class CastToStrType(Func):
5046class CastToStrType(Func):
5047    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5050class Collate(Binary, Func):
5051    pass
key = 'collate'
class Ceil(Func):
5054class Ceil(Func):
5055    arg_types = {"this": True, "decimals": False}
5056    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5059class Coalesce(Func):
5060    arg_types = {"this": True, "expressions": False}
5061    is_var_len_args = True
5062    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5065class Chr(Func):
5066    arg_types = {"this": True, "charset": False, "expressions": False}
5067    is_var_len_args = True
5068    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5071class Concat(Func):
5072    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5073    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5076class ConcatWs(Concat):
5077    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5081class ConnectByRoot(Func):
5082    pass
key = 'connectbyroot'
class Count(AggFunc):
5085class Count(AggFunc):
5086    arg_types = {"this": False, "expressions": False}
5087    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5090class CountIf(AggFunc):
5091    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5095class Cbrt(Func):
5096    pass
key = 'cbrt'
class CurrentDate(Func):
5099class CurrentDate(Func):
5100    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5103class CurrentDatetime(Func):
5104    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5107class CurrentTime(Func):
5108    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5111class CurrentTimestamp(Func):
5112    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5115class CurrentUser(Func):
5116    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5119class DateAdd(Func, IntervalOp):
5120    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5123class DateSub(Func, IntervalOp):
5124    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5127class DateDiff(Func, TimeUnit):
5128    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5129    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5132class DateTrunc(Func):
5133    arg_types = {"unit": True, "this": True, "zone": False}
5134
5135    def __init__(self, **args):
5136        unit = args.get("unit")
5137        if isinstance(unit, TimeUnit.VAR_LIKE):
5138            args["unit"] = Literal.string(
5139                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5140            )
5141        elif isinstance(unit, Week):
5142            unit.set("this", Literal.string(unit.this.name.upper()))
5143
5144        super().__init__(**args)
5145
5146    @property
5147    def unit(self) -> Expression:
5148        return self.args["unit"]
DateTrunc(**args)
5135    def __init__(self, **args):
5136        unit = args.get("unit")
5137        if isinstance(unit, TimeUnit.VAR_LIKE):
5138            args["unit"] = Literal.string(
5139                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5140            )
5141        elif isinstance(unit, Week):
5142            unit.set("this", Literal.string(unit.this.name.upper()))
5143
5144        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5146    @property
5147    def unit(self) -> Expression:
5148        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5153class Datetime(Func):
5154    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5157class DatetimeAdd(Func, IntervalOp):
5158    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5161class DatetimeSub(Func, IntervalOp):
5162    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5165class DatetimeDiff(Func, TimeUnit):
5166    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5169class DatetimeTrunc(Func, TimeUnit):
5170    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5173class DayOfWeek(Func):
5174    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5177class DayOfMonth(Func):
5178    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5181class DayOfYear(Func):
5182    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5185class ToDays(Func):
5186    pass
key = 'todays'
class WeekOfYear(Func):
5189class WeekOfYear(Func):
5190    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5193class MonthsBetween(Func):
5194    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5197class LastDay(Func, TimeUnit):
5198    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5199    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5202class Extract(Func):
5203    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5206class Timestamp(Func):
5207    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5210class TimestampAdd(Func, TimeUnit):
5211    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5214class TimestampSub(Func, TimeUnit):
5215    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5218class TimestampDiff(Func, TimeUnit):
5219    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5220    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5223class TimestampTrunc(Func, TimeUnit):
5224    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5227class TimeAdd(Func, TimeUnit):
5228    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5231class TimeSub(Func, TimeUnit):
5232    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5235class TimeDiff(Func, TimeUnit):
5236    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5239class TimeTrunc(Func, TimeUnit):
5240    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5243class DateFromParts(Func):
5244    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5245    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5248class TimeFromParts(Func):
5249    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5250    arg_types = {
5251        "hour": True,
5252        "min": True,
5253        "sec": True,
5254        "nano": False,
5255        "fractions": False,
5256        "precision": False,
5257    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5260class DateStrToDate(Func):
5261    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5264class DateToDateStr(Func):
5265    pass
key = 'datetodatestr'
class DateToDi(Func):
5268class DateToDi(Func):
5269    pass
key = 'datetodi'
class Date(Func):
5273class Date(Func):
5274    arg_types = {"this": False, "zone": False, "expressions": False}
5275    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5278class Day(Func):
5279    pass
key = 'day'
class Decode(Func):
5282class Decode(Func):
5283    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5286class DiToDate(Func):
5287    pass
key = 'ditodate'
class Encode(Func):
5290class Encode(Func):
5291    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5294class Exp(Func):
5295    pass
key = 'exp'
class Explode(Func):
5299class Explode(Func):
5300    arg_types = {"this": True, "expressions": False}
5301    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5304class ExplodeOuter(Explode):
5305    pass
key = 'explodeouter'
class Posexplode(Explode):
5308class Posexplode(Explode):
5309    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5312class PosexplodeOuter(Posexplode, ExplodeOuter):
5313    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5316class Unnest(Func, UDTF):
5317    arg_types = {
5318        "expressions": True,
5319        "alias": False,
5320        "offset": False,
5321    }
5322
5323    @property
5324    def selects(self) -> t.List[Expression]:
5325        columns = super().selects
5326        offset = self.args.get("offset")
5327        if offset:
5328            columns = columns + [to_identifier("offset") if offset is True else offset]
5329        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5323    @property
5324    def selects(self) -> t.List[Expression]:
5325        columns = super().selects
5326        offset = self.args.get("offset")
5327        if offset:
5328            columns = columns + [to_identifier("offset") if offset is True else offset]
5329        return columns
key = 'unnest'
class Floor(Func):
5332class Floor(Func):
5333    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5336class FromBase64(Func):
5337    pass
key = 'frombase64'
class ToBase64(Func):
5340class ToBase64(Func):
5341    pass
key = 'tobase64'
class GapFill(Func):
5344class GapFill(Func):
5345    arg_types = {
5346        "this": True,
5347        "ts_column": True,
5348        "bucket_width": True,
5349        "partitioning_columns": False,
5350        "value_columns": False,
5351        "origin": False,
5352        "ignore_nulls": False,
5353    }
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):
5357class GenerateDateArray(Func):
5358    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5362class GenerateTimestampArray(Func):
5363    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5366class Greatest(Func):
5367    arg_types = {"this": True, "expressions": False}
5368    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5371class GroupConcat(AggFunc):
5372    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5375class Hex(Func):
5376    pass
key = 'hex'
class LowerHex(Hex):
5379class LowerHex(Hex):
5380    pass
key = 'lowerhex'
class Xor(Connector, Func):
5383class Xor(Connector, Func):
5384    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5387class If(Func):
5388    arg_types = {"this": True, "true": True, "false": False}
5389    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5392class Nullif(Func):
5393    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5396class Initcap(Func):
5397    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5400class IsNan(Func):
5401    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5404class IsInf(Func):
5405    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5408class JSONPath(Expression):
5409    arg_types = {"expressions": True}
5410
5411    @property
5412    def output_name(self) -> str:
5413        last_segment = self.expressions[-1].this
5414        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5411    @property
5412    def output_name(self) -> str:
5413        last_segment = self.expressions[-1].this
5414        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):
5417class JSONPathPart(Expression):
5418    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5421class JSONPathFilter(JSONPathPart):
5422    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5425class JSONPathKey(JSONPathPart):
5426    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5429class JSONPathRecursive(JSONPathPart):
5430    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5433class JSONPathRoot(JSONPathPart):
5434    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5437class JSONPathScript(JSONPathPart):
5438    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5441class JSONPathSlice(JSONPathPart):
5442    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5445class JSONPathSelector(JSONPathPart):
5446    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5449class JSONPathSubscript(JSONPathPart):
5450    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5453class JSONPathUnion(JSONPathPart):
5454    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5457class JSONPathWildcard(JSONPathPart):
5458    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5461class FormatJson(Expression):
5462    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5465class JSONKeyValue(Expression):
5466    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5469class JSONObject(Func):
5470    arg_types = {
5471        "expressions": False,
5472        "null_handling": False,
5473        "unique_keys": False,
5474        "return_type": False,
5475        "encoding": False,
5476    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5479class JSONObjectAgg(AggFunc):
5480    arg_types = {
5481        "expressions": False,
5482        "null_handling": False,
5483        "unique_keys": False,
5484        "return_type": False,
5485        "encoding": False,
5486    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5490class JSONArray(Func):
5491    arg_types = {
5492        "expressions": True,
5493        "null_handling": False,
5494        "return_type": False,
5495        "strict": False,
5496    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5500class JSONArrayAgg(Func):
5501    arg_types = {
5502        "this": True,
5503        "order": False,
5504        "null_handling": False,
5505        "return_type": False,
5506        "strict": False,
5507    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5512class JSONColumnDef(Expression):
5513    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):
5516class JSONSchema(Expression):
5517    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5521class JSONTable(Func):
5522    arg_types = {
5523        "this": True,
5524        "schema": True,
5525        "path": False,
5526        "error_handling": False,
5527        "empty_handling": False,
5528    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5532class ObjectInsert(Func):
5533    arg_types = {
5534        "this": True,
5535        "key": True,
5536        "value": True,
5537        "update_flag": False,
5538    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5541class OpenJSONColumnDef(Expression):
5542    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):
5545class OpenJSON(Func):
5546    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5549class JSONBContains(Binary, Func):
5550    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5553class JSONExtract(Binary, Func):
5554    arg_types = {
5555        "this": True,
5556        "expression": True,
5557        "only_json_types": False,
5558        "expressions": False,
5559        "variant_extract": False,
5560    }
5561    _sql_names = ["JSON_EXTRACT"]
5562    is_var_len_args = True
5563
5564    @property
5565    def output_name(self) -> str:
5566        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
5564    @property
5565    def output_name(self) -> str:
5566        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):
5569class JSONExtractScalar(Binary, Func):
5570    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5571    _sql_names = ["JSON_EXTRACT_SCALAR"]
5572    is_var_len_args = True
5573
5574    @property
5575    def output_name(self) -> str:
5576        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
5574    @property
5575    def output_name(self) -> str:
5576        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):
5579class JSONBExtract(Binary, Func):
5580    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5583class JSONBExtractScalar(Binary, Func):
5584    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5587class JSONFormat(Func):
5588    arg_types = {"this": False, "options": False}
5589    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5593class JSONArrayContains(Binary, Predicate, Func):
5594    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5597class ParseJSON(Func):
5598    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5599    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5600    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5601    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5604class Least(Func):
5605    arg_types = {"this": True, "expressions": False}
5606    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5609class Left(Func):
5610    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5617class Length(Func):
5618    arg_types = {"this": True, "binary": False}
5619    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5622class Levenshtein(Func):
5623    arg_types = {
5624        "this": True,
5625        "expression": False,
5626        "ins_cost": False,
5627        "del_cost": False,
5628        "sub_cost": False,
5629    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5632class Ln(Func):
5633    pass
key = 'ln'
class Log(Func):
5636class Log(Func):
5637    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5640class LogicalOr(AggFunc):
5641    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5644class LogicalAnd(AggFunc):
5645    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5648class Lower(Func):
5649    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5652class Map(Func):
5653    arg_types = {"keys": False, "values": False}
5654
5655    @property
5656    def keys(self) -> t.List[Expression]:
5657        keys = self.args.get("keys")
5658        return keys.expressions if keys else []
5659
5660    @property
5661    def values(self) -> t.List[Expression]:
5662        values = self.args.get("values")
5663        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5655    @property
5656    def keys(self) -> t.List[Expression]:
5657        keys = self.args.get("keys")
5658        return keys.expressions if keys else []
values: List[Expression]
5660    @property
5661    def values(self) -> t.List[Expression]:
5662        values = self.args.get("values")
5663        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5667class ToMap(Func):
5668    pass
key = 'tomap'
class MapFromEntries(Func):
5671class MapFromEntries(Func):
5672    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5676class ScopeResolution(Expression):
5677    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5680class Stream(Expression):
5681    pass
key = 'stream'
class StarMap(Func):
5684class StarMap(Func):
5685    pass
key = 'starmap'
class VarMap(Func):
5688class VarMap(Func):
5689    arg_types = {"keys": True, "values": True}
5690    is_var_len_args = True
5691
5692    @property
5693    def keys(self) -> t.List[Expression]:
5694        return self.args["keys"].expressions
5695
5696    @property
5697    def values(self) -> t.List[Expression]:
5698        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5692    @property
5693    def keys(self) -> t.List[Expression]:
5694        return self.args["keys"].expressions
values: List[Expression]
5696    @property
5697    def values(self) -> t.List[Expression]:
5698        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5702class MatchAgainst(Func):
5703    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5706class Max(AggFunc):
5707    arg_types = {"this": True, "expressions": False}
5708    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5711class MD5(Func):
5712    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5716class MD5Digest(Func):
5717    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5720class Min(AggFunc):
5721    arg_types = {"this": True, "expressions": False}
5722    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5725class Month(Func):
5726    pass
key = 'month'
class AddMonths(Func):
5729class AddMonths(Func):
5730    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5733class Nvl2(Func):
5734    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5738class Predict(Func):
5739    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5742class Pow(Binary, Func):
5743    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5746class PercentileCont(AggFunc):
5747    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5750class PercentileDisc(AggFunc):
5751    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5754class Quantile(AggFunc):
5755    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5758class ApproxQuantile(Quantile):
5759    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):
5762class Quarter(Func):
5763    pass
key = 'quarter'
class Rand(Func):
5768class Rand(Func):
5769    _sql_names = ["RAND", "RANDOM"]
5770    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5773class Randn(Func):
5774    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5777class RangeN(Func):
5778    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5781class ReadCSV(Func):
5782    _sql_names = ["READ_CSV"]
5783    is_var_len_args = True
5784    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5787class Reduce(Func):
5788    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):
5791class RegexpExtract(Func):
5792    arg_types = {
5793        "this": True,
5794        "expression": True,
5795        "position": False,
5796        "occurrence": False,
5797        "parameters": False,
5798        "group": False,
5799    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5802class RegexpReplace(Func):
5803    arg_types = {
5804        "this": True,
5805        "expression": True,
5806        "replacement": False,
5807        "position": False,
5808        "occurrence": False,
5809        "modifiers": False,
5810    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5813class RegexpLike(Binary, Func):
5814    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5817class RegexpILike(Binary, Func):
5818    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5823class RegexpSplit(Func):
5824    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5827class Repeat(Func):
5828    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5833class Round(Func):
5834    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5837class RowNumber(Func):
5838    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5841class SafeDivide(Func):
5842    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5845class SHA(Func):
5846    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5849class SHA2(Func):
5850    _sql_names = ["SHA2"]
5851    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5854class Sign(Func):
5855    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5858class SortArray(Func):
5859    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5862class Split(Func):
5863    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5868class Substring(Func):
5869    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5872class StandardHash(Func):
5873    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5876class StartsWith(Func):
5877    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5878    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5881class StrPosition(Func):
5882    arg_types = {
5883        "this": True,
5884        "substr": True,
5885        "position": False,
5886        "instance": False,
5887    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5890class StrToDate(Func):
5891    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5894class StrToTime(Func):
5895    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):
5900class StrToUnix(Func):
5901    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5906class StrToMap(Func):
5907    arg_types = {
5908        "this": True,
5909        "pair_delim": False,
5910        "key_value_delim": False,
5911        "duplicate_resolution_callback": False,
5912    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5915class NumberToStr(Func):
5916    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5919class FromBase(Func):
5920    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5923class Struct(Func):
5924    arg_types = {"expressions": False}
5925    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5928class StructExtract(Func):
5929    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5934class Stuff(Func):
5935    _sql_names = ["STUFF", "INSERT"]
5936    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):
5939class Sum(AggFunc):
5940    pass
key = 'sum'
class Sqrt(Func):
5943class Sqrt(Func):
5944    pass
key = 'sqrt'
class Stddev(AggFunc):
5947class Stddev(AggFunc):
5948    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
5951class StddevPop(AggFunc):
5952    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5955class StddevSamp(AggFunc):
5956    pass
key = 'stddevsamp'
class Time(Func):
5960class Time(Func):
5961    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5964class TimeToStr(Func):
5965    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):
5968class TimeToTimeStr(Func):
5969    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5972class TimeToUnix(Func):
5973    pass
key = 'timetounix'
class TimeStrToDate(Func):
5976class TimeStrToDate(Func):
5977    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5980class TimeStrToTime(Func):
5981    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5984class TimeStrToUnix(Func):
5985    pass
key = 'timestrtounix'
class Trim(Func):
5988class Trim(Func):
5989    arg_types = {
5990        "this": True,
5991        "expression": False,
5992        "position": False,
5993        "collation": False,
5994    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5997class TsOrDsAdd(Func, TimeUnit):
5998    # return_type is used to correctly cast the arguments of this expression when transpiling it
5999    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6000
6001    @property
6002    def return_type(self) -> DataType:
6003        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
6001    @property
6002    def return_type(self) -> DataType:
6003        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6006class TsOrDsDiff(Func, TimeUnit):
6007    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6010class TsOrDsToDateStr(Func):
6011    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6014class TsOrDsToDate(Func):
6015    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6018class TsOrDsToTime(Func):
6019    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6022class TsOrDsToTimestamp(Func):
6023    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6026class TsOrDiToDi(Func):
6027    pass
key = 'tsorditodi'
class Unhex(Func):
6030class Unhex(Func):
6031    pass
key = 'unhex'
class UnixDate(Func):
6035class UnixDate(Func):
6036    pass
key = 'unixdate'
class UnixToStr(Func):
6039class UnixToStr(Func):
6040    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6045class UnixToTime(Func):
6046    arg_types = {
6047        "this": True,
6048        "scale": False,
6049        "zone": False,
6050        "hours": False,
6051        "minutes": False,
6052        "format": False,
6053    }
6054
6055    SECONDS = Literal.number(0)
6056    DECIS = Literal.number(1)
6057    CENTIS = Literal.number(2)
6058    MILLIS = Literal.number(3)
6059    DECIMILLIS = Literal.number(4)
6060    CENTIMILLIS = Literal.number(5)
6061    MICROS = Literal.number(6)
6062    DECIMICROS = Literal.number(7)
6063    CENTIMICROS = Literal.number(8)
6064    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):
6067class UnixToTimeStr(Func):
6068    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6071class TimestampFromParts(Func):
6072    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6073    arg_types = {
6074        "year": True,
6075        "month": True,
6076        "day": True,
6077        "hour": True,
6078        "min": True,
6079        "sec": True,
6080        "nano": False,
6081        "zone": False,
6082        "milli": False,
6083    }
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):
6086class Upper(Func):
6087    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6090class Corr(Binary, AggFunc):
6091    pass
key = 'corr'
class Variance(AggFunc):
6094class Variance(AggFunc):
6095    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6098class VariancePop(AggFunc):
6099    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6102class CovarSamp(Binary, AggFunc):
6103    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6106class CovarPop(Binary, AggFunc):
6107    pass
key = 'covarpop'
class Week(Func):
6110class Week(Func):
6111    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6114class XMLTable(Func):
6115    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):
6118class Year(Func):
6119    pass
key = 'year'
class Use(Expression):
6122class Use(Expression):
6123    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6126class Merge(Expression):
6127    arg_types = {
6128        "this": True,
6129        "using": True,
6130        "on": True,
6131        "expressions": True,
6132        "with": False,
6133    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6136class When(Func):
6137    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):
6142class NextValueFor(Func):
6143    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6148class Semicolon(Expression):
6149    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 'ConvertTimezone'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <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'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, '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:
6189def maybe_parse(
6190    sql_or_expression: ExpOrStr,
6191    *,
6192    into: t.Optional[IntoType] = None,
6193    dialect: DialectType = None,
6194    prefix: t.Optional[str] = None,
6195    copy: bool = False,
6196    **opts,
6197) -> Expression:
6198    """Gracefully handle a possible string or expression.
6199
6200    Example:
6201        >>> maybe_parse("1")
6202        Literal(this=1, is_string=False)
6203        >>> maybe_parse(to_identifier("x"))
6204        Identifier(this=x, quoted=False)
6205
6206    Args:
6207        sql_or_expression: the SQL code string or an expression
6208        into: the SQLGlot Expression to parse into
6209        dialect: the dialect used to parse the input expressions (in the case that an
6210            input expression is a SQL string).
6211        prefix: a string to prefix the sql with before it gets parsed
6212            (automatically includes a space)
6213        copy: whether to copy the expression.
6214        **opts: other options to use to parse the input expressions (again, in the case
6215            that an input expression is a SQL string).
6216
6217    Returns:
6218        Expression: the parsed or given expression.
6219    """
6220    if isinstance(sql_or_expression, Expression):
6221        if copy:
6222            return sql_or_expression.copy()
6223        return sql_or_expression
6224
6225    if sql_or_expression is None:
6226        raise ParseError("SQL cannot be None")
6227
6228    import sqlglot
6229
6230    sql = str(sql_or_expression)
6231    if prefix:
6232        sql = f"{prefix} {sql}"
6233
6234    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):
6245def maybe_copy(instance, copy=True):
6246    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:
6466def union(
6467    left: ExpOrStr,
6468    right: ExpOrStr,
6469    distinct: bool = True,
6470    dialect: DialectType = None,
6471    copy: bool = True,
6472    **opts,
6473) -> Union:
6474    """
6475    Initializes a syntax tree from one UNION expression.
6476
6477    Example:
6478        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6479        'SELECT * FROM foo UNION SELECT * FROM bla'
6480
6481    Args:
6482        left: the SQL code string corresponding to the left-hand side.
6483            If an `Expression` instance is passed, it will be used as-is.
6484        right: the SQL code string corresponding to the right-hand side.
6485            If an `Expression` instance is passed, it will be used as-is.
6486        distinct: set the DISTINCT flag if and only if this is true.
6487        dialect: the dialect used to parse the input expression.
6488        copy: whether to copy the expression.
6489        opts: other options to use to parse the input expressions.
6490
6491    Returns:
6492        The new Union instance.
6493    """
6494    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6495    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6496
6497    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:
6500def intersect(
6501    left: ExpOrStr,
6502    right: ExpOrStr,
6503    distinct: bool = True,
6504    dialect: DialectType = None,
6505    copy: bool = True,
6506    **opts,
6507) -> Intersect:
6508    """
6509    Initializes a syntax tree from one INTERSECT expression.
6510
6511    Example:
6512        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6513        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6514
6515    Args:
6516        left: the SQL code string corresponding to the left-hand side.
6517            If an `Expression` instance is passed, it will be used as-is.
6518        right: the SQL code string corresponding to the right-hand side.
6519            If an `Expression` instance is passed, it will be used as-is.
6520        distinct: set the DISTINCT flag if and only if this is true.
6521        dialect: the dialect used to parse the input expression.
6522        copy: whether to copy the expression.
6523        opts: other options to use to parse the input expressions.
6524
6525    Returns:
6526        The new Intersect instance.
6527    """
6528    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6529    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6530
6531    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:
6534def except_(
6535    left: ExpOrStr,
6536    right: ExpOrStr,
6537    distinct: bool = True,
6538    dialect: DialectType = None,
6539    copy: bool = True,
6540    **opts,
6541) -> Except:
6542    """
6543    Initializes a syntax tree from one EXCEPT expression.
6544
6545    Example:
6546        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6547        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6548
6549    Args:
6550        left: the SQL code string corresponding to the left-hand side.
6551            If an `Expression` instance is passed, it will be used as-is.
6552        right: the SQL code string corresponding to the right-hand side.
6553            If an `Expression` instance is passed, it will be used as-is.
6554        distinct: set the DISTINCT flag if and only if this is true.
6555        dialect: the dialect used to parse the input expression.
6556        copy: whether to copy the expression.
6557        opts: other options to use to parse the input expressions.
6558
6559    Returns:
6560        The new Except instance.
6561    """
6562    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6563    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6564
6565    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:
6568def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6569    """
6570    Initializes a syntax tree from one or multiple SELECT expressions.
6571
6572    Example:
6573        >>> select("col1", "col2").from_("tbl").sql()
6574        'SELECT col1, col2 FROM tbl'
6575
6576    Args:
6577        *expressions: the SQL code string to parse as the expressions of a
6578            SELECT statement. If an Expression instance is passed, this is used as-is.
6579        dialect: the dialect used to parse the input expressions (in the case that an
6580            input expression is a SQL string).
6581        **opts: other options to use to parse the input expressions (again, in the case
6582            that an input expression is a SQL string).
6583
6584    Returns:
6585        Select: the syntax tree for the SELECT statement.
6586    """
6587    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:
6590def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6591    """
6592    Initializes a syntax tree from a FROM expression.
6593
6594    Example:
6595        >>> from_("tbl").select("col1", "col2").sql()
6596        'SELECT col1, col2 FROM tbl'
6597
6598    Args:
6599        *expression: the SQL code string to parse as the FROM expressions of a
6600            SELECT statement. If an Expression instance is passed, this is used as-is.
6601        dialect: the dialect used to parse the input expression (in the case that the
6602            input expression is a SQL string).
6603        **opts: other options to use to parse the input expressions (again, in the case
6604            that the input expression is a SQL string).
6605
6606    Returns:
6607        Select: the syntax tree for the SELECT statement.
6608    """
6609    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:
6612def update(
6613    table: str | Table,
6614    properties: dict,
6615    where: t.Optional[ExpOrStr] = None,
6616    from_: t.Optional[ExpOrStr] = None,
6617    dialect: DialectType = None,
6618    **opts,
6619) -> Update:
6620    """
6621    Creates an update statement.
6622
6623    Example:
6624        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6625        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6626
6627    Args:
6628        *properties: dictionary of properties to set which are
6629            auto converted to sql objects eg None -> NULL
6630        where: sql conditional parsed into a WHERE statement
6631        from_: sql statement parsed into a FROM statement
6632        dialect: the dialect used to parse the input expressions.
6633        **opts: other options to use to parse the input expressions.
6634
6635    Returns:
6636        Update: the syntax tree for the UPDATE statement.
6637    """
6638    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6639    update_expr.set(
6640        "expressions",
6641        [
6642            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6643            for k, v in properties.items()
6644        ],
6645    )
6646    if from_:
6647        update_expr.set(
6648            "from",
6649            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6650        )
6651    if isinstance(where, Condition):
6652        where = Where(this=where)
6653    if where:
6654        update_expr.set(
6655            "where",
6656            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6657        )
6658    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:
6661def delete(
6662    table: ExpOrStr,
6663    where: t.Optional[ExpOrStr] = None,
6664    returning: t.Optional[ExpOrStr] = None,
6665    dialect: DialectType = None,
6666    **opts,
6667) -> Delete:
6668    """
6669    Builds a delete statement.
6670
6671    Example:
6672        >>> delete("my_table", where="id > 1").sql()
6673        'DELETE FROM my_table WHERE id > 1'
6674
6675    Args:
6676        where: sql conditional parsed into a WHERE statement
6677        returning: sql conditional parsed into a RETURNING statement
6678        dialect: the dialect used to parse the input expressions.
6679        **opts: other options to use to parse the input expressions.
6680
6681    Returns:
6682        Delete: the syntax tree for the DELETE statement.
6683    """
6684    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6685    if where:
6686        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6687    if returning:
6688        delete_expr = t.cast(
6689            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6690        )
6691    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:
6694def insert(
6695    expression: ExpOrStr,
6696    into: ExpOrStr,
6697    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6698    overwrite: t.Optional[bool] = None,
6699    returning: t.Optional[ExpOrStr] = None,
6700    dialect: DialectType = None,
6701    copy: bool = True,
6702    **opts,
6703) -> Insert:
6704    """
6705    Builds an INSERT statement.
6706
6707    Example:
6708        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6709        'INSERT INTO tbl VALUES (1, 2, 3)'
6710
6711    Args:
6712        expression: the sql string or expression of the INSERT statement
6713        into: the tbl to insert data to.
6714        columns: optionally the table's column names.
6715        overwrite: whether to INSERT OVERWRITE or not.
6716        returning: sql conditional parsed into a RETURNING statement
6717        dialect: the dialect used to parse the input expressions.
6718        copy: whether to copy the expression.
6719        **opts: other options to use to parse the input expressions.
6720
6721    Returns:
6722        Insert: the syntax tree for the INSERT statement.
6723    """
6724    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6725    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6726
6727    if columns:
6728        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6729
6730    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6731
6732    if returning:
6733        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6734
6735    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:
6738def condition(
6739    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6740) -> Condition:
6741    """
6742    Initialize a logical condition expression.
6743
6744    Example:
6745        >>> condition("x=1").sql()
6746        'x = 1'
6747
6748        This is helpful for composing larger logical syntax trees:
6749        >>> where = condition("x=1")
6750        >>> where = where.and_("y=1")
6751        >>> Select().from_("tbl").select("*").where(where).sql()
6752        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6753
6754    Args:
6755        *expression: the SQL code string to parse.
6756            If an Expression instance is passed, this is used as-is.
6757        dialect: the dialect used to parse the input expression (in the case that the
6758            input expression is a SQL string).
6759        copy: Whether to copy `expression` (only applies to expressions).
6760        **opts: other options to use to parse the input expressions (again, in the case
6761            that the input expression is a SQL string).
6762
6763    Returns:
6764        The new Condition instance
6765    """
6766    return maybe_parse(
6767        expression,
6768        into=Condition,
6769        dialect=dialect,
6770        copy=copy,
6771        **opts,
6772    )

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:
6775def and_(
6776    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6777) -> Condition:
6778    """
6779    Combine multiple conditions with an AND logical operator.
6780
6781    Example:
6782        >>> and_("x=1", and_("y=1", "z=1")).sql()
6783        'x = 1 AND (y = 1 AND z = 1)'
6784
6785    Args:
6786        *expressions: the SQL code strings to parse.
6787            If an Expression instance is passed, this is used as-is.
6788        dialect: the dialect used to parse the input expression.
6789        copy: whether to copy `expressions` (only applies to Expressions).
6790        **opts: other options to use to parse the input expressions.
6791
6792    Returns:
6793        The new condition
6794    """
6795    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:
6798def or_(
6799    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6800) -> Condition:
6801    """
6802    Combine multiple conditions with an OR logical operator.
6803
6804    Example:
6805        >>> or_("x=1", or_("y=1", "z=1")).sql()
6806        'x = 1 OR (y = 1 OR z = 1)'
6807
6808    Args:
6809        *expressions: the SQL code strings to parse.
6810            If an Expression instance is passed, this is used as-is.
6811        dialect: the dialect used to parse the input expression.
6812        copy: whether to copy `expressions` (only applies to Expressions).
6813        **opts: other options to use to parse the input expressions.
6814
6815    Returns:
6816        The new condition
6817    """
6818    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:
6821def xor(
6822    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6823) -> Condition:
6824    """
6825    Combine multiple conditions with an XOR logical operator.
6826
6827    Example:
6828        >>> xor("x=1", xor("y=1", "z=1")).sql()
6829        'x = 1 XOR (y = 1 XOR z = 1)'
6830
6831    Args:
6832        *expressions: the SQL code strings to parse.
6833            If an Expression instance is passed, this is used as-is.
6834        dialect: the dialect used to parse the input expression.
6835        copy: whether to copy `expressions` (only applies to Expressions).
6836        **opts: other options to use to parse the input expressions.
6837
6838    Returns:
6839        The new condition
6840    """
6841    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:
6844def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6845    """
6846    Wrap a condition with a NOT operator.
6847
6848    Example:
6849        >>> not_("this_suit='black'").sql()
6850        "NOT this_suit = 'black'"
6851
6852    Args:
6853        expression: the SQL code string to parse.
6854            If an Expression instance is passed, this is used as-is.
6855        dialect: the dialect used to parse the input expression.
6856        copy: whether to copy the expression or not.
6857        **opts: other options to use to parse the input expressions.
6858
6859    Returns:
6860        The new condition.
6861    """
6862    this = condition(
6863        expression,
6864        dialect=dialect,
6865        copy=copy,
6866        **opts,
6867    )
6868    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:
6871def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6872    """
6873    Wrap an expression in parentheses.
6874
6875    Example:
6876        >>> paren("5 + 3").sql()
6877        '(5 + 3)'
6878
6879    Args:
6880        expression: the SQL code string to parse.
6881            If an Expression instance is passed, this is used as-is.
6882        copy: whether to copy the expression or not.
6883
6884    Returns:
6885        The wrapped expression.
6886    """
6887    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):
6903def to_identifier(name, quoted=None, copy=True):
6904    """Builds an identifier.
6905
6906    Args:
6907        name: The name to turn into an identifier.
6908        quoted: Whether to force quote the identifier.
6909        copy: Whether to copy name if it's an Identifier.
6910
6911    Returns:
6912        The identifier ast node.
6913    """
6914
6915    if name is None:
6916        return None
6917
6918    if isinstance(name, Identifier):
6919        identifier = maybe_copy(name, copy)
6920    elif isinstance(name, str):
6921        identifier = Identifier(
6922            this=name,
6923            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6924        )
6925    else:
6926        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6927    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:
6930def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6931    """
6932    Parses a given string into an identifier.
6933
6934    Args:
6935        name: The name to parse into an identifier.
6936        dialect: The dialect to parse against.
6937
6938    Returns:
6939        The identifier ast node.
6940    """
6941    try:
6942        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6943    except (ParseError, TokenError):
6944        expression = to_identifier(name)
6945
6946    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:
6952def to_interval(interval: str | Literal) -> Interval:
6953    """Builds an interval expression from a string like '1 day' or '5 months'."""
6954    if isinstance(interval, Literal):
6955        if not interval.is_string:
6956            raise ValueError("Invalid interval string.")
6957
6958        interval = interval.this
6959
6960    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6961
6962    if not interval_parts:
6963        raise ValueError("Invalid interval string.")
6964
6965    return Interval(
6966        this=Literal.string(interval_parts.group(1)),
6967        unit=Var(this=interval_parts.group(2).upper()),
6968    )

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:
6971def to_table(
6972    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6973) -> Table:
6974    """
6975    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6976    If a table is passed in then that table is returned.
6977
6978    Args:
6979        sql_path: a `[catalog].[schema].[table]` string.
6980        dialect: the source dialect according to which the table name will be parsed.
6981        copy: Whether to copy a table if it is passed in.
6982        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6983
6984    Returns:
6985        A table expression.
6986    """
6987    if isinstance(sql_path, Table):
6988        return maybe_copy(sql_path, copy=copy)
6989
6990    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6991
6992    for k, v in kwargs.items():
6993        table.set(k, v)
6994
6995    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:
6998def to_column(
6999    sql_path: str | Column,
7000    quoted: t.Optional[bool] = None,
7001    dialect: DialectType = None,
7002    copy: bool = True,
7003    **kwargs,
7004) -> Column:
7005    """
7006    Create a column from a `[table].[column]` sql path. Table is optional.
7007    If a column is passed in then that column is returned.
7008
7009    Args:
7010        sql_path: a `[table].[column]` string.
7011        quoted: Whether or not to force quote identifiers.
7012        dialect: the source dialect according to which the column name will be parsed.
7013        copy: Whether to copy a column if it is passed in.
7014        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7015
7016    Returns:
7017        A column expression.
7018    """
7019    if isinstance(sql_path, Column):
7020        return maybe_copy(sql_path, copy=copy)
7021
7022    try:
7023        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7024    except ParseError:
7025        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7026
7027    for k, v in kwargs.items():
7028        col.set(k, v)
7029
7030    if quoted:
7031        for i in col.find_all(Identifier):
7032            i.set("quoted", True)
7033
7034    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):
7037def alias_(
7038    expression: ExpOrStr,
7039    alias: t.Optional[str | Identifier],
7040    table: bool | t.Sequence[str | Identifier] = False,
7041    quoted: t.Optional[bool] = None,
7042    dialect: DialectType = None,
7043    copy: bool = True,
7044    **opts,
7045):
7046    """Create an Alias expression.
7047
7048    Example:
7049        >>> alias_('foo', 'bar').sql()
7050        'foo AS bar'
7051
7052        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7053        '(SELECT 1, 2) AS bar(a, b)'
7054
7055    Args:
7056        expression: the SQL code strings to parse.
7057            If an Expression instance is passed, this is used as-is.
7058        alias: the alias name to use. If the name has
7059            special characters it is quoted.
7060        table: Whether to create a table alias, can also be a list of columns.
7061        quoted: whether to quote the alias
7062        dialect: the dialect used to parse the input expression.
7063        copy: Whether to copy the expression.
7064        **opts: other options to use to parse the input expressions.
7065
7066    Returns:
7067        Alias: the aliased expression
7068    """
7069    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7070    alias = to_identifier(alias, quoted=quoted)
7071
7072    if table:
7073        table_alias = TableAlias(this=alias)
7074        exp.set("alias", table_alias)
7075
7076        if not isinstance(table, bool):
7077            for column in table:
7078                table_alias.append("columns", to_identifier(column, quoted=quoted))
7079
7080        return exp
7081
7082    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7083    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7084    # for the complete Window expression.
7085    #
7086    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7087
7088    if "alias" in exp.arg_types and not isinstance(exp, Window):
7089        exp.set("alias", alias)
7090        return exp
7091    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:
7094def subquery(
7095    expression: ExpOrStr,
7096    alias: t.Optional[Identifier | str] = None,
7097    dialect: DialectType = None,
7098    **opts,
7099) -> Select:
7100    """
7101    Build a subquery expression that's selected from.
7102
7103    Example:
7104        >>> subquery('select x from tbl', 'bar').select('x').sql()
7105        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7106
7107    Args:
7108        expression: the SQL code strings to parse.
7109            If an Expression instance is passed, this is used as-is.
7110        alias: the alias name to use.
7111        dialect: the dialect used to parse the input expression.
7112        **opts: other options to use to parse the input expressions.
7113
7114    Returns:
7115        A new Select instance with the subquery expression included.
7116    """
7117
7118    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7119    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):
7150def column(
7151    col,
7152    table=None,
7153    db=None,
7154    catalog=None,
7155    *,
7156    fields=None,
7157    quoted=None,
7158    copy=True,
7159):
7160    """
7161    Build a Column.
7162
7163    Args:
7164        col: Column name.
7165        table: Table name.
7166        db: Database name.
7167        catalog: Catalog name.
7168        fields: Additional fields using dots.
7169        quoted: Whether to force quotes on the column's identifiers.
7170        copy: Whether to copy identifiers if passed in.
7171
7172    Returns:
7173        The new Column instance.
7174    """
7175    this = Column(
7176        this=to_identifier(col, quoted=quoted, copy=copy),
7177        table=to_identifier(table, quoted=quoted, copy=copy),
7178        db=to_identifier(db, quoted=quoted, copy=copy),
7179        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7180    )
7181
7182    if fields:
7183        this = Dot.build(
7184            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7185        )
7186    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:
7189def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7190    """Cast an expression to a data type.
7191
7192    Example:
7193        >>> cast('x + 1', 'int').sql()
7194        'CAST(x + 1 AS INT)'
7195
7196    Args:
7197        expression: The expression to cast.
7198        to: The datatype to cast to.
7199        copy: Whether to copy the supplied expressions.
7200
7201    Returns:
7202        The new Cast instance.
7203    """
7204    expr = maybe_parse(expression, copy=copy, **opts)
7205    data_type = DataType.build(to, copy=copy, **opts)
7206
7207    if expr.is_type(data_type):
7208        return expr
7209
7210    expr = Cast(this=expr, to=data_type)
7211    expr.type = data_type
7212
7213    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:
7216def table_(
7217    table: Identifier | str,
7218    db: t.Optional[Identifier | str] = None,
7219    catalog: t.Optional[Identifier | str] = None,
7220    quoted: t.Optional[bool] = None,
7221    alias: t.Optional[Identifier | str] = None,
7222) -> Table:
7223    """Build a Table.
7224
7225    Args:
7226        table: Table name.
7227        db: Database name.
7228        catalog: Catalog name.
7229        quote: Whether to force quotes on the table's identifiers.
7230        alias: Table's alias.
7231
7232    Returns:
7233        The new Table instance.
7234    """
7235    return Table(
7236        this=to_identifier(table, quoted=quoted) if table else None,
7237        db=to_identifier(db, quoted=quoted) if db else None,
7238        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7239        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7240    )

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:
7243def values(
7244    values: t.Iterable[t.Tuple[t.Any, ...]],
7245    alias: t.Optional[str] = None,
7246    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7247) -> Values:
7248    """Build VALUES statement.
7249
7250    Example:
7251        >>> values([(1, '2')]).sql()
7252        "VALUES (1, '2')"
7253
7254    Args:
7255        values: values statements that will be converted to SQL
7256        alias: optional alias
7257        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7258         If either are provided then an alias is also required.
7259
7260    Returns:
7261        Values: the Values expression object
7262    """
7263    if columns and not alias:
7264        raise ValueError("Alias is required when providing columns")
7265
7266    return Values(
7267        expressions=[convert(tup) for tup in values],
7268        alias=(
7269            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7270            if columns
7271            else (TableAlias(this=to_identifier(alias)) if alias else None)
7272        ),
7273    )

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:
7276def var(name: t.Optional[ExpOrStr]) -> Var:
7277    """Build a SQL variable.
7278
7279    Example:
7280        >>> repr(var('x'))
7281        'Var(this=x)'
7282
7283        >>> repr(var(column('x', table='y')))
7284        'Var(this=x)'
7285
7286    Args:
7287        name: The name of the var or an expression who's name will become the var.
7288
7289    Returns:
7290        The new variable node.
7291    """
7292    if not name:
7293        raise ValueError("Cannot convert empty name into var.")
7294
7295    if isinstance(name, Expression):
7296        name = name.name
7297    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) -> Alter:
7300def rename_table(
7301    old_name: str | Table,
7302    new_name: str | Table,
7303    dialect: DialectType = None,
7304) -> Alter:
7305    """Build ALTER TABLE... RENAME... expression
7306
7307    Args:
7308        old_name: The old name of the table
7309        new_name: The new name of the table
7310        dialect: The dialect to parse the table.
7311
7312    Returns:
7313        Alter table expression
7314    """
7315    old_table = to_table(old_name, dialect=dialect)
7316    new_table = to_table(new_name, dialect=dialect)
7317    return Alter(
7318        this=old_table,
7319        kind="TABLE",
7320        actions=[
7321            RenameTable(this=new_table),
7322        ],
7323    )

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) -> Alter:
7326def rename_column(
7327    table_name: str | Table,
7328    old_column_name: str | Column,
7329    new_column_name: str | Column,
7330    exists: t.Optional[bool] = None,
7331    dialect: DialectType = None,
7332) -> Alter:
7333    """Build ALTER TABLE... RENAME COLUMN... expression
7334
7335    Args:
7336        table_name: Name of the table
7337        old_column: The old name of the column
7338        new_column: The new name of the column
7339        exists: Whether to add the `IF EXISTS` clause
7340        dialect: The dialect to parse the table/column.
7341
7342    Returns:
7343        Alter table expression
7344    """
7345    table = to_table(table_name, dialect=dialect)
7346    old_column = to_column(old_column_name, dialect=dialect)
7347    new_column = to_column(new_column_name, dialect=dialect)
7348    return Alter(
7349        this=table,
7350        kind="TABLE",
7351        actions=[
7352            RenameColumn(this=old_column, to=new_column, exists=exists),
7353        ],
7354    )

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

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:
7488def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7489    """Get the full name of a table as a string.
7490
7491    Args:
7492        table: Table expression node or string.
7493        dialect: The dialect to generate the table name for.
7494        identify: Determines when an identifier should be quoted. Possible values are:
7495            False (default): Never quote, except in cases where it's mandatory by the dialect.
7496            True: Always quote.
7497
7498    Examples:
7499        >>> from sqlglot import exp, parse_one
7500        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7501        'a.b.c'
7502
7503    Returns:
7504        The table name.
7505    """
7506
7507    table = maybe_parse(table, into=Table, dialect=dialect)
7508
7509    if not table:
7510        raise ValueError(f"Cannot parse {table}")
7511
7512    return ".".join(
7513        (
7514            part.sql(dialect=dialect, identify=True, copy=False)
7515            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7516            else part.name
7517        )
7518        for part in table.parts
7519    )

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:
7522def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7523    """Returns a case normalized table name without quotes.
7524
7525    Args:
7526        table: the table to normalize
7527        dialect: the dialect to use for normalization rules
7528        copy: whether to copy the expression.
7529
7530    Examples:
7531        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7532        'A-B.c'
7533    """
7534    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7535
7536    return ".".join(
7537        p.name
7538        for p in normalize_identifiers(
7539            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7540        ).parts
7541    )

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

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:
7771def tuple_(
7772    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7773) -> Tuple:
7774    """
7775    Returns an tuple.
7776
7777    Examples:
7778        >>> tuple_(1, 'x').sql()
7779        '(1, x)'
7780
7781    Args:
7782        expressions: the expressions to add to the tuple.
7783        copy: whether to copy the argument expressions.
7784        dialect: the source dialect.
7785        kwargs: the kwargs used to instantiate the function of interest.
7786
7787    Returns:
7788        A tuple expression.
7789    """
7790    return Tuple(
7791        expressions=[
7792            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7793            for expression in expressions
7794        ]
7795    )

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:
7798def true() -> Boolean:
7799    """
7800    Returns a true Boolean expression.
7801    """
7802    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7805def false() -> Boolean:
7806    """
7807    Returns a false Boolean expression.
7808    """
7809    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7812def null() -> Null:
7813    """
7814    Returns a Null expression.
7815    """
7816    return Null()

Returns a Null expression.

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