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

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

Returns a Python object equivalent of the SQL node.

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

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

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

Returns the output names of the query's projections.

is_star: bool
3137    @property
3138    def is_star(self) -> bool:
3139        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3141    @property
3142    def selects(self) -> t.List[Expression]:
3143        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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:
3379    def select(
3380        self,
3381        *expressions: t.Optional[ExpOrStr],
3382        append: bool = True,
3383        dialect: DialectType = None,
3384        copy: bool = True,
3385        **opts,
3386    ) -> Select:
3387        return _apply_list_builder(
3388            *expressions,
3389            instance=self,
3390            arg="expressions",
3391            append=append,
3392            dialect=dialect,
3393            into=Expression,
3394            copy=copy,
3395            **opts,
3396        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3769    @property
3770    def selects(self) -> t.List[Expression]:
3771        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3857class Pivot(Expression):
3858    arg_types = {
3859        "this": False,
3860        "alias": False,
3861        "expressions": False,
3862        "field": False,
3863        "unpivot": False,
3864        "using": False,
3865        "group": False,
3866        "columns": False,
3867        "include_nulls": False,
3868        "default_on_null": False,
3869    }
3870
3871    @property
3872    def unpivot(self) -> bool:
3873        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
3871    @property
3872    def unpivot(self) -> bool:
3873        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3876class Window(Condition):
3877    arg_types = {
3878        "this": True,
3879        "partition_by": False,
3880        "order": False,
3881        "spec": False,
3882        "alias": False,
3883        "over": False,
3884        "first": False,
3885    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3888class WindowSpec(Expression):
3889    arg_types = {
3890        "kind": False,
3891        "start": False,
3892        "start_side": False,
3893        "end": False,
3894        "end_side": False,
3895    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3898class PreWhere(Expression):
3899    pass
key = 'prewhere'
class Where(Expression):
3902class Where(Expression):
3903    pass
key = 'where'
class Star(Expression):
3906class Star(Expression):
3907    arg_types = {"except": False, "replace": False, "rename": False}
3908
3909    @property
3910    def name(self) -> str:
3911        return "*"
3912
3913    @property
3914    def output_name(self) -> str:
3915        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3909    @property
3910    def name(self) -> str:
3911        return "*"
output_name: str
3913    @property
3914    def output_name(self) -> str:
3915        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):
3918class Parameter(Condition):
3919    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3922class SessionParameter(Condition):
3923    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3926class Placeholder(Condition):
3927    arg_types = {"this": False, "kind": False}
3928
3929    @property
3930    def name(self) -> str:
3931        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3929    @property
3930    def name(self) -> str:
3931        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3934class Null(Condition):
3935    arg_types: t.Dict[str, t.Any] = {}
3936
3937    @property
3938    def name(self) -> str:
3939        return "NULL"
3940
3941    def to_py(self) -> Lit[None]:
3942        return None
arg_types: Dict[str, Any] = {}
name: str
3937    @property
3938    def name(self) -> str:
3939        return "NULL"
def to_py(self) -> Literal[None]:
3941    def to_py(self) -> Lit[None]:
3942        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3945class Boolean(Condition):
3946    def to_py(self) -> bool:
3947        return self.this
def to_py(self) -> bool:
3946    def to_py(self) -> bool:
3947        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

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

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

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

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

key = 'kwarg'
class Like(Binary, Predicate):
4460class Like(Binary, Predicate):
4461    pass
key = 'like'
class LikeAny(Binary, Predicate):
4464class LikeAny(Binary, Predicate):
4465    pass
key = 'likeany'
class LT(Binary, Predicate):
4468class LT(Binary, Predicate):
4469    pass
key = 'lt'
class LTE(Binary, Predicate):
4472class LTE(Binary, Predicate):
4473    pass
key = 'lte'
class Mod(Binary):
4476class Mod(Binary):
4477    pass
key = 'mod'
class Mul(Binary):
4480class Mul(Binary):
4481    pass
key = 'mul'
class NEQ(Binary, Predicate):
4484class NEQ(Binary, Predicate):
4485    pass
key = 'neq'
class Operator(Binary):
4489class Operator(Binary):
4490    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4493class SimilarTo(Binary, Predicate):
4494    pass
key = 'similarto'
class Slice(Binary):
4497class Slice(Binary):
4498    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4501class Sub(Binary):
4502    pass
key = 'sub'
class Unary(Condition):
4507class Unary(Condition):
4508    pass
key = 'unary'
class BitwiseNot(Unary):
4511class BitwiseNot(Unary):
4512    pass
key = 'bitwisenot'
class Not(Unary):
4515class Not(Unary):
4516    pass
key = 'not'
class Paren(Unary):
4519class Paren(Unary):
4520    @property
4521    def output_name(self) -> str:
4522        return self.this.name
output_name: str
4520    @property
4521    def output_name(self) -> str:
4522        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):
4525class Neg(Unary):
4526    def to_py(self) -> int | Decimal:
4527        if self.is_number:
4528            return self.this.to_py() * -1
4529        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4526    def to_py(self) -> int | Decimal:
4527        if self.is_number:
4528            return self.this.to_py() * -1
4529        return super().to_py()

Returns a Python object equivalent of the SQL node.

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

Automatically converts unit arg into a var.

TimeUnit(**args)
4635    def __init__(self, **args):
4636        unit = args.get("unit")
4637        if isinstance(unit, self.VAR_LIKE):
4638            args["unit"] = Var(
4639                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4640            )
4641        elif isinstance(unit, Week):
4642            unit.set("this", Var(this=unit.this.name.upper()))
4643
4644        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]
4646    @property
4647    def unit(self) -> t.Optional[Var | IntervalSpan]:
4648        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4651class IntervalOp(TimeUnit):
4652    arg_types = {"unit": True, "expression": True}
4653
4654    def interval(self):
4655        return Interval(
4656            this=self.expression.copy(),
4657            unit=self.unit.copy(),
4658        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4654    def interval(self):
4655        return Interval(
4656            this=self.expression.copy(),
4657            unit=self.unit.copy(),
4658        )
key = 'intervalop'
class IntervalSpan(DataType):
4664class IntervalSpan(DataType):
4665    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4668class Interval(TimeUnit):
4669    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4672class IgnoreNulls(Expression):
4673    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4676class RespectNulls(Expression):
4677    pass
key = 'respectnulls'
class HavingMax(Expression):
4681class HavingMax(Expression):
4682    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4686class Func(Condition):
4687    """
4688    The base class for all function expressions.
4689
4690    Attributes:
4691        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4692            treated as a variable length argument and the argument's value will be stored as a list.
4693        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4694            function expression. These values are used to map this node to a name during parsing as
4695            well as to provide the function's name during SQL string generation. By default the SQL
4696            name is set to the expression's class name transformed to snake case.
4697    """
4698
4699    is_var_len_args = False
4700
4701    @classmethod
4702    def from_arg_list(cls, args):
4703        if cls.is_var_len_args:
4704            all_arg_keys = list(cls.arg_types)
4705            # If this function supports variable length argument treat the last argument as such.
4706            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4707            num_non_var = len(non_var_len_arg_keys)
4708
4709            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4710            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4711        else:
4712            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4713
4714        return cls(**args_dict)
4715
4716    @classmethod
4717    def sql_names(cls):
4718        if cls is Func:
4719            raise NotImplementedError(
4720                "SQL name is only supported by concrete function implementations"
4721            )
4722        if "_sql_names" not in cls.__dict__:
4723            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4724        return cls._sql_names
4725
4726    @classmethod
4727    def sql_name(cls):
4728        return cls.sql_names()[0]
4729
4730    @classmethod
4731    def default_parser_mappings(cls):
4732        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):
4701    @classmethod
4702    def from_arg_list(cls, args):
4703        if cls.is_var_len_args:
4704            all_arg_keys = list(cls.arg_types)
4705            # If this function supports variable length argument treat the last argument as such.
4706            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4707            num_non_var = len(non_var_len_arg_keys)
4708
4709            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4710            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4711        else:
4712            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4713
4714        return cls(**args_dict)
@classmethod
def sql_names(cls):
4716    @classmethod
4717    def sql_names(cls):
4718        if cls is Func:
4719            raise NotImplementedError(
4720                "SQL name is only supported by concrete function implementations"
4721            )
4722        if "_sql_names" not in cls.__dict__:
4723            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4724        return cls._sql_names
@classmethod
def sql_name(cls):
4726    @classmethod
4727    def sql_name(cls):
4728        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4730    @classmethod
4731    def default_parser_mappings(cls):
4732        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4735class AggFunc(Func):
4736    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4739class ParameterizedAgg(AggFunc):
4740    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4743class Abs(Func):
4744    pass
key = 'abs'
class ArgMax(AggFunc):
4747class ArgMax(AggFunc):
4748    arg_types = {"this": True, "expression": True, "count": False}
4749    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4752class ArgMin(AggFunc):
4753    arg_types = {"this": True, "expression": True, "count": False}
4754    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4757class ApproxTopK(AggFunc):
4758    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4761class Flatten(Func):
4762    pass
key = 'flatten'
class Transform(Func):
4766class Transform(Func):
4767    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4770class Anonymous(Func):
4771    arg_types = {"this": True, "expressions": False}
4772    is_var_len_args = True
4773
4774    @property
4775    def name(self) -> str:
4776        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
4774    @property
4775    def name(self) -> str:
4776        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4779class AnonymousAggFunc(AggFunc):
4780    arg_types = {"this": True, "expressions": False}
4781    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4785class CombinedAggFunc(AnonymousAggFunc):
4786    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4789class CombinedParameterizedAgg(ParameterizedAgg):
4790    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):
4795class Hll(AggFunc):
4796    arg_types = {"this": True, "expressions": False}
4797    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4800class ApproxDistinct(AggFunc):
4801    arg_types = {"this": True, "accuracy": False}
4802    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4805class Array(Func):
4806    arg_types = {"expressions": False, "bracket_notation": False}
4807    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4811class ToArray(Func):
4812    pass
key = 'toarray'
class List(Func):
4816class List(Func):
4817    arg_types = {"expressions": False}
4818    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4822class Pad(Func):
4823    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):
4828class ToChar(Func):
4829    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4834class ToNumber(Func):
4835    arg_types = {
4836        "this": True,
4837        "format": False,
4838        "nlsparam": False,
4839        "precision": False,
4840        "scale": False,
4841    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4845class Convert(Func):
4846    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4849class ConvertTimezone(Func):
4850    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):
4853class GenerateSeries(Func):
4854    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):
4860class ExplodingGenerateSeries(GenerateSeries):
4861    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4864class ArrayAgg(AggFunc):
4865    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4868class ArrayUniqueAgg(AggFunc):
4869    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4872class ArrayAll(Func):
4873    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4877class ArrayAny(Func):
4878    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4881class ArrayConcat(Func):
4882    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4883    arg_types = {"this": True, "expressions": False}
4884    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4887class ArrayConstructCompact(Func):
4888    arg_types = {"expressions": True}
4889    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4892class ArrayContains(Binary, Func):
4893    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4896class ArrayContainsAll(Binary, Func):
4897    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4900class ArrayFilter(Func):
4901    arg_types = {"this": True, "expression": True}
4902    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4905class ArrayToString(Func):
4906    arg_types = {"this": True, "expression": True, "null": False}
4907    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4910class StringToArray(Func):
4911    arg_types = {"this": True, "expression": True, "null": False}
4912    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4915class ArrayOverlaps(Binary, Func):
4916    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4919class ArraySize(Func):
4920    arg_types = {"this": True, "expression": False}
4921    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4924class ArraySort(Func):
4925    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4928class ArraySum(Func):
4929    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4932class ArrayUnionAgg(AggFunc):
4933    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4936class Avg(AggFunc):
4937    pass
key = 'avg'
class AnyValue(AggFunc):
4940class AnyValue(AggFunc):
4941    pass
key = 'anyvalue'
class Lag(AggFunc):
4944class Lag(AggFunc):
4945    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4948class Lead(AggFunc):
4949    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4954class First(AggFunc):
4955    pass
key = 'first'
class Last(AggFunc):
4958class Last(AggFunc):
4959    pass
key = 'last'
class FirstValue(AggFunc):
4962class FirstValue(AggFunc):
4963    pass
key = 'firstvalue'
class LastValue(AggFunc):
4966class LastValue(AggFunc):
4967    pass
key = 'lastvalue'
class NthValue(AggFunc):
4970class NthValue(AggFunc):
4971    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4974class Case(Func):
4975    arg_types = {"this": False, "ifs": True, "default": False}
4976
4977    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4978        instance = maybe_copy(self, copy)
4979        instance.append(
4980            "ifs",
4981            If(
4982                this=maybe_parse(condition, copy=copy, **opts),
4983                true=maybe_parse(then, copy=copy, **opts),
4984            ),
4985        )
4986        return instance
4987
4988    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4989        instance = maybe_copy(self, copy)
4990        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4991        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:
4977    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4978        instance = maybe_copy(self, copy)
4979        instance.append(
4980            "ifs",
4981            If(
4982                this=maybe_parse(condition, copy=copy, **opts),
4983                true=maybe_parse(then, copy=copy, **opts),
4984            ),
4985        )
4986        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4988    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4989        instance = maybe_copy(self, copy)
4990        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4991        return instance
key = 'case'
class Cast(Func):
4994class Cast(Func):
4995    arg_types = {
4996        "this": True,
4997        "to": True,
4998        "format": False,
4999        "safe": False,
5000        "action": False,
5001    }
5002
5003    @property
5004    def name(self) -> str:
5005        return self.this.name
5006
5007    @property
5008    def to(self) -> DataType:
5009        return self.args["to"]
5010
5011    @property
5012    def output_name(self) -> str:
5013        return self.name
5014
5015    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5016        """
5017        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5018        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5019        array<int> != array<float>.
5020
5021        Args:
5022            dtypes: the data types to compare this Cast's DataType to.
5023
5024        Returns:
5025            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5026        """
5027        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5003    @property
5004    def name(self) -> str:
5005        return self.this.name
to: DataType
5007    @property
5008    def to(self) -> DataType:
5009        return self.args["to"]
output_name: str
5011    @property
5012    def output_name(self) -> str:
5013        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:
5015    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5016        """
5017        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5018        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5019        array<int> != array<float>.
5020
5021        Args:
5022            dtypes: the data types to compare this Cast's DataType to.
5023
5024        Returns:
5025            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5026        """
5027        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):
5030class TryCast(Cast):
5031    pass
key = 'trycast'
class Try(Func):
5034class Try(Func):
5035    pass
key = 'try'
class CastToStrType(Func):
5038class CastToStrType(Func):
5039    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5042class Collate(Binary, Func):
5043    pass
key = 'collate'
class Ceil(Func):
5046class Ceil(Func):
5047    arg_types = {"this": True, "decimals": False}
5048    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5051class Coalesce(Func):
5052    arg_types = {"this": True, "expressions": False}
5053    is_var_len_args = True
5054    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5057class Chr(Func):
5058    arg_types = {"this": True, "charset": False, "expressions": False}
5059    is_var_len_args = True
5060    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5063class Concat(Func):
5064    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5065    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5068class ConcatWs(Concat):
5069    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5073class ConnectByRoot(Func):
5074    pass
key = 'connectbyroot'
class Count(AggFunc):
5077class Count(AggFunc):
5078    arg_types = {"this": False, "expressions": False}
5079    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5082class CountIf(AggFunc):
5083    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5087class Cbrt(Func):
5088    pass
key = 'cbrt'
class CurrentDate(Func):
5091class CurrentDate(Func):
5092    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5095class CurrentDatetime(Func):
5096    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5099class CurrentTime(Func):
5100    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5103class CurrentTimestamp(Func):
5104    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5107class CurrentUser(Func):
5108    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5111class DateAdd(Func, IntervalOp):
5112    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5115class DateSub(Func, IntervalOp):
5116    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5119class DateDiff(Func, TimeUnit):
5120    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5121    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5124class DateTrunc(Func):
5125    arg_types = {"unit": True, "this": True, "zone": False}
5126
5127    def __init__(self, **args):
5128        unit = args.get("unit")
5129        if isinstance(unit, TimeUnit.VAR_LIKE):
5130            args["unit"] = Literal.string(
5131                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5132            )
5133        elif isinstance(unit, Week):
5134            unit.set("this", Literal.string(unit.this.name.upper()))
5135
5136        super().__init__(**args)
5137
5138    @property
5139    def unit(self) -> Expression:
5140        return self.args["unit"]
DateTrunc(**args)
5127    def __init__(self, **args):
5128        unit = args.get("unit")
5129        if isinstance(unit, TimeUnit.VAR_LIKE):
5130            args["unit"] = Literal.string(
5131                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5132            )
5133        elif isinstance(unit, Week):
5134            unit.set("this", Literal.string(unit.this.name.upper()))
5135
5136        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5138    @property
5139    def unit(self) -> Expression:
5140        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5145class Datetime(Func):
5146    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5149class DatetimeAdd(Func, IntervalOp):
5150    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5153class DatetimeSub(Func, IntervalOp):
5154    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5157class DatetimeDiff(Func, TimeUnit):
5158    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5161class DatetimeTrunc(Func, TimeUnit):
5162    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5165class DayOfWeek(Func):
5166    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5169class DayOfMonth(Func):
5170    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5173class DayOfYear(Func):
5174    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5177class ToDays(Func):
5178    pass
key = 'todays'
class WeekOfYear(Func):
5181class WeekOfYear(Func):
5182    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5185class MonthsBetween(Func):
5186    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5189class LastDay(Func, TimeUnit):
5190    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5191    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5194class Extract(Func):
5195    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5198class Timestamp(Func):
5199    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5202class TimestampAdd(Func, TimeUnit):
5203    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5206class TimestampSub(Func, TimeUnit):
5207    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5210class TimestampDiff(Func, TimeUnit):
5211    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5212    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5215class TimestampTrunc(Func, TimeUnit):
5216    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5219class TimeAdd(Func, TimeUnit):
5220    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5223class TimeSub(Func, TimeUnit):
5224    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5227class TimeDiff(Func, TimeUnit):
5228    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5231class TimeTrunc(Func, TimeUnit):
5232    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5235class DateFromParts(Func):
5236    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5237    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5240class TimeFromParts(Func):
5241    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5242    arg_types = {
5243        "hour": True,
5244        "min": True,
5245        "sec": True,
5246        "nano": False,
5247        "fractions": False,
5248        "precision": False,
5249    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5252class DateStrToDate(Func):
5253    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5256class DateToDateStr(Func):
5257    pass
key = 'datetodatestr'
class DateToDi(Func):
5260class DateToDi(Func):
5261    pass
key = 'datetodi'
class Date(Func):
5265class Date(Func):
5266    arg_types = {"this": False, "zone": False, "expressions": False}
5267    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5270class Day(Func):
5271    pass
key = 'day'
class Decode(Func):
5274class Decode(Func):
5275    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5278class DiToDate(Func):
5279    pass
key = 'ditodate'
class Encode(Func):
5282class Encode(Func):
5283    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5286class Exp(Func):
5287    pass
key = 'exp'
class Explode(Func):
5291class Explode(Func):
5292    arg_types = {"this": True, "expressions": False}
5293    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5296class ExplodeOuter(Explode):
5297    pass
key = 'explodeouter'
class Posexplode(Explode):
5300class Posexplode(Explode):
5301    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5304class PosexplodeOuter(Posexplode, ExplodeOuter):
5305    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5308class Unnest(Func, UDTF):
5309    arg_types = {
5310        "expressions": True,
5311        "alias": False,
5312        "offset": False,
5313    }
5314
5315    @property
5316    def selects(self) -> t.List[Expression]:
5317        columns = super().selects
5318        offset = self.args.get("offset")
5319        if offset:
5320            columns = columns + [to_identifier("offset") if offset is True else offset]
5321        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5315    @property
5316    def selects(self) -> t.List[Expression]:
5317        columns = super().selects
5318        offset = self.args.get("offset")
5319        if offset:
5320            columns = columns + [to_identifier("offset") if offset is True else offset]
5321        return columns
key = 'unnest'
class Floor(Func):
5324class Floor(Func):
5325    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5328class FromBase64(Func):
5329    pass
key = 'frombase64'
class ToBase64(Func):
5332class ToBase64(Func):
5333    pass
key = 'tobase64'
class GapFill(Func):
5336class GapFill(Func):
5337    arg_types = {
5338        "this": True,
5339        "ts_column": True,
5340        "bucket_width": True,
5341        "partitioning_columns": False,
5342        "value_columns": False,
5343        "origin": False,
5344        "ignore_nulls": False,
5345    }
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):
5349class GenerateDateArray(Func):
5350    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5354class GenerateTimestampArray(Func):
5355    arg_types = {"start": True, "end": True, "interval": True}
arg_types = {'start': True, 'end': True, 'interval': True}
key = 'generatetimestamparray'
class Greatest(Func):
5358class Greatest(Func):
5359    arg_types = {"this": True, "expressions": False}
5360    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5363class GroupConcat(AggFunc):
5364    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5367class Hex(Func):
5368    pass
key = 'hex'
class LowerHex(Hex):
5371class LowerHex(Hex):
5372    pass
key = 'lowerhex'
class Xor(Connector, Func):
5375class Xor(Connector, Func):
5376    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5379class If(Func):
5380    arg_types = {"this": True, "true": True, "false": False}
5381    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5384class Nullif(Func):
5385    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5388class Initcap(Func):
5389    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5392class IsNan(Func):
5393    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5396class IsInf(Func):
5397    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5400class JSONPath(Expression):
5401    arg_types = {"expressions": True}
5402
5403    @property
5404    def output_name(self) -> str:
5405        last_segment = self.expressions[-1].this
5406        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5403    @property
5404    def output_name(self) -> str:
5405        last_segment = self.expressions[-1].this
5406        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):
5409class JSONPathPart(Expression):
5410    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5413class JSONPathFilter(JSONPathPart):
5414    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5417class JSONPathKey(JSONPathPart):
5418    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5421class JSONPathRecursive(JSONPathPart):
5422    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5425class JSONPathRoot(JSONPathPart):
5426    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5429class JSONPathScript(JSONPathPart):
5430    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5433class JSONPathSlice(JSONPathPart):
5434    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5437class JSONPathSelector(JSONPathPart):
5438    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5441class JSONPathSubscript(JSONPathPart):
5442    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5445class JSONPathUnion(JSONPathPart):
5446    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5449class JSONPathWildcard(JSONPathPart):
5450    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5453class FormatJson(Expression):
5454    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5457class JSONKeyValue(Expression):
5458    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5461class JSONObject(Func):
5462    arg_types = {
5463        "expressions": False,
5464        "null_handling": False,
5465        "unique_keys": False,
5466        "return_type": False,
5467        "encoding": False,
5468    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5471class JSONObjectAgg(AggFunc):
5472    arg_types = {
5473        "expressions": False,
5474        "null_handling": False,
5475        "unique_keys": False,
5476        "return_type": False,
5477        "encoding": False,
5478    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5482class JSONArray(Func):
5483    arg_types = {
5484        "expressions": True,
5485        "null_handling": False,
5486        "return_type": False,
5487        "strict": False,
5488    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5492class JSONArrayAgg(Func):
5493    arg_types = {
5494        "this": True,
5495        "order": False,
5496        "null_handling": False,
5497        "return_type": False,
5498        "strict": False,
5499    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5504class JSONColumnDef(Expression):
5505    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):
5508class JSONSchema(Expression):
5509    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5513class JSONTable(Func):
5514    arg_types = {
5515        "this": True,
5516        "schema": True,
5517        "path": False,
5518        "error_handling": False,
5519        "empty_handling": False,
5520    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5524class ObjectInsert(Func):
5525    arg_types = {
5526        "this": True,
5527        "key": True,
5528        "value": True,
5529        "update_flag": False,
5530    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5533class OpenJSONColumnDef(Expression):
5534    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):
5537class OpenJSON(Func):
5538    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5541class JSONBContains(Binary, Func):
5542    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5545class JSONExtract(Binary, Func):
5546    arg_types = {
5547        "this": True,
5548        "expression": True,
5549        "only_json_types": False,
5550        "expressions": False,
5551        "variant_extract": False,
5552    }
5553    _sql_names = ["JSON_EXTRACT"]
5554    is_var_len_args = True
5555
5556    @property
5557    def output_name(self) -> str:
5558        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
5556    @property
5557    def output_name(self) -> str:
5558        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):
5561class JSONExtractScalar(Binary, Func):
5562    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5563    _sql_names = ["JSON_EXTRACT_SCALAR"]
5564    is_var_len_args = True
5565
5566    @property
5567    def output_name(self) -> str:
5568        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
5566    @property
5567    def output_name(self) -> str:
5568        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):
5571class JSONBExtract(Binary, Func):
5572    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5575class JSONBExtractScalar(Binary, Func):
5576    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5579class JSONFormat(Func):
5580    arg_types = {"this": False, "options": False}
5581    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5585class JSONArrayContains(Binary, Predicate, Func):
5586    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5589class ParseJSON(Func):
5590    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5591    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5592    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5593    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5596class Least(Func):
5597    arg_types = {"this": True, "expressions": False}
5598    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5601class Left(Func):
5602    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5609class Length(Func):
5610    arg_types = {"this": True, "binary": False}
5611    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5614class Levenshtein(Func):
5615    arg_types = {
5616        "this": True,
5617        "expression": False,
5618        "ins_cost": False,
5619        "del_cost": False,
5620        "sub_cost": False,
5621    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5624class Ln(Func):
5625    pass
key = 'ln'
class Log(Func):
5628class Log(Func):
5629    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5632class LogicalOr(AggFunc):
5633    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5636class LogicalAnd(AggFunc):
5637    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5640class Lower(Func):
5641    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5644class Map(Func):
5645    arg_types = {"keys": False, "values": False}
5646
5647    @property
5648    def keys(self) -> t.List[Expression]:
5649        keys = self.args.get("keys")
5650        return keys.expressions if keys else []
5651
5652    @property
5653    def values(self) -> t.List[Expression]:
5654        values = self.args.get("values")
5655        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5647    @property
5648    def keys(self) -> t.List[Expression]:
5649        keys = self.args.get("keys")
5650        return keys.expressions if keys else []
values: List[Expression]
5652    @property
5653    def values(self) -> t.List[Expression]:
5654        values = self.args.get("values")
5655        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5659class ToMap(Func):
5660    pass
key = 'tomap'
class MapFromEntries(Func):
5663class MapFromEntries(Func):
5664    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5668class ScopeResolution(Expression):
5669    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5672class Stream(Expression):
5673    pass
key = 'stream'
class StarMap(Func):
5676class StarMap(Func):
5677    pass
key = 'starmap'
class VarMap(Func):
5680class VarMap(Func):
5681    arg_types = {"keys": True, "values": True}
5682    is_var_len_args = True
5683
5684    @property
5685    def keys(self) -> t.List[Expression]:
5686        return self.args["keys"].expressions
5687
5688    @property
5689    def values(self) -> t.List[Expression]:
5690        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5684    @property
5685    def keys(self) -> t.List[Expression]:
5686        return self.args["keys"].expressions
values: List[Expression]
5688    @property
5689    def values(self) -> t.List[Expression]:
5690        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5694class MatchAgainst(Func):
5695    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5698class Max(AggFunc):
5699    arg_types = {"this": True, "expressions": False}
5700    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5703class MD5(Func):
5704    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5708class MD5Digest(Func):
5709    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5712class Min(AggFunc):
5713    arg_types = {"this": True, "expressions": False}
5714    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5717class Month(Func):
5718    pass
key = 'month'
class AddMonths(Func):
5721class AddMonths(Func):
5722    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5725class Nvl2(Func):
5726    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5730class Predict(Func):
5731    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5734class Pow(Binary, Func):
5735    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5738class PercentileCont(AggFunc):
5739    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5742class PercentileDisc(AggFunc):
5743    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5746class Quantile(AggFunc):
5747    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5750class ApproxQuantile(Quantile):
5751    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):
5754class Quarter(Func):
5755    pass
key = 'quarter'
class Rand(Func):
5760class Rand(Func):
5761    _sql_names = ["RAND", "RANDOM"]
5762    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5765class Randn(Func):
5766    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5769class RangeN(Func):
5770    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5773class ReadCSV(Func):
5774    _sql_names = ["READ_CSV"]
5775    is_var_len_args = True
5776    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5779class Reduce(Func):
5780    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):
5783class RegexpExtract(Func):
5784    arg_types = {
5785        "this": True,
5786        "expression": True,
5787        "position": False,
5788        "occurrence": False,
5789        "parameters": False,
5790        "group": False,
5791    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5794class RegexpReplace(Func):
5795    arg_types = {
5796        "this": True,
5797        "expression": True,
5798        "replacement": False,
5799        "position": False,
5800        "occurrence": False,
5801        "modifiers": False,
5802    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5805class RegexpLike(Binary, Func):
5806    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5809class RegexpILike(Binary, Func):
5810    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5815class RegexpSplit(Func):
5816    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5819class Repeat(Func):
5820    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5825class Round(Func):
5826    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5829class RowNumber(Func):
5830    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5833class SafeDivide(Func):
5834    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5837class SHA(Func):
5838    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5841class SHA2(Func):
5842    _sql_names = ["SHA2"]
5843    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5846class Sign(Func):
5847    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5850class SortArray(Func):
5851    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5854class Split(Func):
5855    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5860class Substring(Func):
5861    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5864class StandardHash(Func):
5865    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5868class StartsWith(Func):
5869    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5870    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5873class StrPosition(Func):
5874    arg_types = {
5875        "this": True,
5876        "substr": True,
5877        "position": False,
5878        "instance": False,
5879    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5882class StrToDate(Func):
5883    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5886class StrToTime(Func):
5887    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):
5892class StrToUnix(Func):
5893    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5898class StrToMap(Func):
5899    arg_types = {
5900        "this": True,
5901        "pair_delim": False,
5902        "key_value_delim": False,
5903        "duplicate_resolution_callback": False,
5904    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5907class NumberToStr(Func):
5908    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5911class FromBase(Func):
5912    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5915class Struct(Func):
5916    arg_types = {"expressions": False}
5917    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5920class StructExtract(Func):
5921    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5926class Stuff(Func):
5927    _sql_names = ["STUFF", "INSERT"]
5928    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):
5931class Sum(AggFunc):
5932    pass
key = 'sum'
class Sqrt(Func):
5935class Sqrt(Func):
5936    pass
key = 'sqrt'
class Stddev(AggFunc):
5939class Stddev(AggFunc):
5940    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
5943class StddevPop(AggFunc):
5944    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5947class StddevSamp(AggFunc):
5948    pass
key = 'stddevsamp'
class Time(Func):
5952class Time(Func):
5953    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5956class TimeToStr(Func):
5957    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):
5960class TimeToTimeStr(Func):
5961    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5964class TimeToUnix(Func):
5965    pass
key = 'timetounix'
class TimeStrToDate(Func):
5968class TimeStrToDate(Func):
5969    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5972class TimeStrToTime(Func):
5973    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5976class TimeStrToUnix(Func):
5977    pass
key = 'timestrtounix'
class Trim(Func):
5980class Trim(Func):
5981    arg_types = {
5982        "this": True,
5983        "expression": False,
5984        "position": False,
5985        "collation": False,
5986    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5989class TsOrDsAdd(Func, TimeUnit):
5990    # return_type is used to correctly cast the arguments of this expression when transpiling it
5991    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5992
5993    @property
5994    def return_type(self) -> DataType:
5995        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
5993    @property
5994    def return_type(self) -> DataType:
5995        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5998class TsOrDsDiff(Func, TimeUnit):
5999    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6002class TsOrDsToDateStr(Func):
6003    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6006class TsOrDsToDate(Func):
6007    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6010class TsOrDsToTime(Func):
6011    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6014class TsOrDsToTimestamp(Func):
6015    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6018class TsOrDiToDi(Func):
6019    pass
key = 'tsorditodi'
class Unhex(Func):
6022class Unhex(Func):
6023    pass
key = 'unhex'
class UnixDate(Func):
6027class UnixDate(Func):
6028    pass
key = 'unixdate'
class UnixToStr(Func):
6031class UnixToStr(Func):
6032    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6037class UnixToTime(Func):
6038    arg_types = {
6039        "this": True,
6040        "scale": False,
6041        "zone": False,
6042        "hours": False,
6043        "minutes": False,
6044        "format": False,
6045    }
6046
6047    SECONDS = Literal.number(0)
6048    DECIS = Literal.number(1)
6049    CENTIS = Literal.number(2)
6050    MILLIS = Literal.number(3)
6051    DECIMILLIS = Literal.number(4)
6052    CENTIMILLIS = Literal.number(5)
6053    MICROS = Literal.number(6)
6054    DECIMICROS = Literal.number(7)
6055    CENTIMICROS = Literal.number(8)
6056    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):
6059class UnixToTimeStr(Func):
6060    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6063class TimestampFromParts(Func):
6064    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6065    arg_types = {
6066        "year": True,
6067        "month": True,
6068        "day": True,
6069        "hour": True,
6070        "min": True,
6071        "sec": True,
6072        "nano": False,
6073        "zone": False,
6074        "milli": False,
6075    }
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):
6078class Upper(Func):
6079    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6082class Corr(Binary, AggFunc):
6083    pass
key = 'corr'
class Variance(AggFunc):
6086class Variance(AggFunc):
6087    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6090class VariancePop(AggFunc):
6091    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6094class CovarSamp(Binary, AggFunc):
6095    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6098class CovarPop(Binary, AggFunc):
6099    pass
key = 'covarpop'
class Week(Func):
6102class Week(Func):
6103    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6106class XMLTable(Func):
6107    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):
6110class Year(Func):
6111    pass
key = 'year'
class Use(Expression):
6114class Use(Expression):
6115    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6118class Merge(Expression):
6119    arg_types = {
6120        "this": True,
6121        "using": True,
6122        "on": True,
6123        "expressions": True,
6124        "with": False,
6125    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6128class When(Func):
6129    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):
6134class NextValueFor(Func):
6135    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6140class Semicolon(Expression):
6141    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:
6181def maybe_parse(
6182    sql_or_expression: ExpOrStr,
6183    *,
6184    into: t.Optional[IntoType] = None,
6185    dialect: DialectType = None,
6186    prefix: t.Optional[str] = None,
6187    copy: bool = False,
6188    **opts,
6189) -> Expression:
6190    """Gracefully handle a possible string or expression.
6191
6192    Example:
6193        >>> maybe_parse("1")
6194        Literal(this=1, is_string=False)
6195        >>> maybe_parse(to_identifier("x"))
6196        Identifier(this=x, quoted=False)
6197
6198    Args:
6199        sql_or_expression: the SQL code string or an expression
6200        into: the SQLGlot Expression to parse into
6201        dialect: the dialect used to parse the input expressions (in the case that an
6202            input expression is a SQL string).
6203        prefix: a string to prefix the sql with before it gets parsed
6204            (automatically includes a space)
6205        copy: whether to copy the expression.
6206        **opts: other options to use to parse the input expressions (again, in the case
6207            that an input expression is a SQL string).
6208
6209    Returns:
6210        Expression: the parsed or given expression.
6211    """
6212    if isinstance(sql_or_expression, Expression):
6213        if copy:
6214            return sql_or_expression.copy()
6215        return sql_or_expression
6216
6217    if sql_or_expression is None:
6218        raise ParseError("SQL cannot be None")
6219
6220    import sqlglot
6221
6222    sql = str(sql_or_expression)
6223    if prefix:
6224        sql = f"{prefix} {sql}"
6225
6226    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):
6237def maybe_copy(instance, copy=True):
6238    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:
6458def union(
6459    left: ExpOrStr,
6460    right: ExpOrStr,
6461    distinct: bool = True,
6462    dialect: DialectType = None,
6463    copy: bool = True,
6464    **opts,
6465) -> Union:
6466    """
6467    Initializes a syntax tree from one UNION expression.
6468
6469    Example:
6470        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6471        'SELECT * FROM foo UNION SELECT * FROM bla'
6472
6473    Args:
6474        left: the SQL code string corresponding to the left-hand side.
6475            If an `Expression` instance is passed, it will be used as-is.
6476        right: the SQL code string corresponding to the right-hand side.
6477            If an `Expression` instance is passed, it will be used as-is.
6478        distinct: set the DISTINCT flag if and only if this is true.
6479        dialect: the dialect used to parse the input expression.
6480        copy: whether to copy the expression.
6481        opts: other options to use to parse the input expressions.
6482
6483    Returns:
6484        The new Union instance.
6485    """
6486    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6487    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6488
6489    return 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:
6492def intersect(
6493    left: ExpOrStr,
6494    right: ExpOrStr,
6495    distinct: bool = True,
6496    dialect: DialectType = None,
6497    copy: bool = True,
6498    **opts,
6499) -> Intersect:
6500    """
6501    Initializes a syntax tree from one INTERSECT expression.
6502
6503    Example:
6504        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6505        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6506
6507    Args:
6508        left: the SQL code string corresponding to the left-hand side.
6509            If an `Expression` instance is passed, it will be used as-is.
6510        right: the SQL code string corresponding to the right-hand side.
6511            If an `Expression` instance is passed, it will be used as-is.
6512        distinct: set the DISTINCT flag if and only if this is true.
6513        dialect: the dialect used to parse the input expression.
6514        copy: whether to copy the expression.
6515        opts: other options to use to parse the input expressions.
6516
6517    Returns:
6518        The new Intersect instance.
6519    """
6520    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6521    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6522
6523    return 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:
6526def except_(
6527    left: ExpOrStr,
6528    right: ExpOrStr,
6529    distinct: bool = True,
6530    dialect: DialectType = None,
6531    copy: bool = True,
6532    **opts,
6533) -> Except:
6534    """
6535    Initializes a syntax tree from one EXCEPT expression.
6536
6537    Example:
6538        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6539        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6540
6541    Args:
6542        left: the SQL code string corresponding to the left-hand side.
6543            If an `Expression` instance is passed, it will be used as-is.
6544        right: the SQL code string corresponding to the right-hand side.
6545            If an `Expression` instance is passed, it will be used as-is.
6546        distinct: set the DISTINCT flag if and only if this is true.
6547        dialect: the dialect used to parse the input expression.
6548        copy: whether to copy the expression.
6549        opts: other options to use to parse the input expressions.
6550
6551    Returns:
6552        The new Except instance.
6553    """
6554    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6555    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6556
6557    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:
6560def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6561    """
6562    Initializes a syntax tree from one or multiple SELECT expressions.
6563
6564    Example:
6565        >>> select("col1", "col2").from_("tbl").sql()
6566        'SELECT col1, col2 FROM tbl'
6567
6568    Args:
6569        *expressions: the SQL code string to parse as the expressions of a
6570            SELECT statement. If an Expression instance is passed, this is used as-is.
6571        dialect: the dialect used to parse the input expressions (in the case that an
6572            input expression is a SQL string).
6573        **opts: other options to use to parse the input expressions (again, in the case
6574            that an input expression is a SQL string).
6575
6576    Returns:
6577        Select: the syntax tree for the SELECT statement.
6578    """
6579    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:
6582def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6583    """
6584    Initializes a syntax tree from a FROM expression.
6585
6586    Example:
6587        >>> from_("tbl").select("col1", "col2").sql()
6588        'SELECT col1, col2 FROM tbl'
6589
6590    Args:
6591        *expression: the SQL code string to parse as the FROM expressions of a
6592            SELECT statement. If an Expression instance is passed, this is used as-is.
6593        dialect: the dialect used to parse the input expression (in the case that the
6594            input expression is a SQL string).
6595        **opts: other options to use to parse the input expressions (again, in the case
6596            that the input expression is a SQL string).
6597
6598    Returns:
6599        Select: the syntax tree for the SELECT statement.
6600    """
6601    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:
6604def update(
6605    table: str | Table,
6606    properties: dict,
6607    where: t.Optional[ExpOrStr] = None,
6608    from_: t.Optional[ExpOrStr] = None,
6609    dialect: DialectType = None,
6610    **opts,
6611) -> Update:
6612    """
6613    Creates an update statement.
6614
6615    Example:
6616        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6617        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6618
6619    Args:
6620        *properties: dictionary of properties to set which are
6621            auto converted to sql objects eg None -> NULL
6622        where: sql conditional parsed into a WHERE statement
6623        from_: sql statement parsed into a FROM statement
6624        dialect: the dialect used to parse the input expressions.
6625        **opts: other options to use to parse the input expressions.
6626
6627    Returns:
6628        Update: the syntax tree for the UPDATE statement.
6629    """
6630    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6631    update_expr.set(
6632        "expressions",
6633        [
6634            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6635            for k, v in properties.items()
6636        ],
6637    )
6638    if from_:
6639        update_expr.set(
6640            "from",
6641            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6642        )
6643    if isinstance(where, Condition):
6644        where = Where(this=where)
6645    if where:
6646        update_expr.set(
6647            "where",
6648            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6649        )
6650    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:
6653def delete(
6654    table: ExpOrStr,
6655    where: t.Optional[ExpOrStr] = None,
6656    returning: t.Optional[ExpOrStr] = None,
6657    dialect: DialectType = None,
6658    **opts,
6659) -> Delete:
6660    """
6661    Builds a delete statement.
6662
6663    Example:
6664        >>> delete("my_table", where="id > 1").sql()
6665        'DELETE FROM my_table WHERE id > 1'
6666
6667    Args:
6668        where: sql conditional parsed into a WHERE statement
6669        returning: sql conditional parsed into a RETURNING statement
6670        dialect: the dialect used to parse the input expressions.
6671        **opts: other options to use to parse the input expressions.
6672
6673    Returns:
6674        Delete: the syntax tree for the DELETE statement.
6675    """
6676    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6677    if where:
6678        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6679    if returning:
6680        delete_expr = t.cast(
6681            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6682        )
6683    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:
6686def insert(
6687    expression: ExpOrStr,
6688    into: ExpOrStr,
6689    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6690    overwrite: t.Optional[bool] = None,
6691    returning: t.Optional[ExpOrStr] = None,
6692    dialect: DialectType = None,
6693    copy: bool = True,
6694    **opts,
6695) -> Insert:
6696    """
6697    Builds an INSERT statement.
6698
6699    Example:
6700        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6701        'INSERT INTO tbl VALUES (1, 2, 3)'
6702
6703    Args:
6704        expression: the sql string or expression of the INSERT statement
6705        into: the tbl to insert data to.
6706        columns: optionally the table's column names.
6707        overwrite: whether to INSERT OVERWRITE or not.
6708        returning: sql conditional parsed into a RETURNING statement
6709        dialect: the dialect used to parse the input expressions.
6710        copy: whether to copy the expression.
6711        **opts: other options to use to parse the input expressions.
6712
6713    Returns:
6714        Insert: the syntax tree for the INSERT statement.
6715    """
6716    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6717    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6718
6719    if columns:
6720        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6721
6722    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6723
6724    if returning:
6725        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6726
6727    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:
6730def condition(
6731    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6732) -> Condition:
6733    """
6734    Initialize a logical condition expression.
6735
6736    Example:
6737        >>> condition("x=1").sql()
6738        'x = 1'
6739
6740        This is helpful for composing larger logical syntax trees:
6741        >>> where = condition("x=1")
6742        >>> where = where.and_("y=1")
6743        >>> Select().from_("tbl").select("*").where(where).sql()
6744        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6745
6746    Args:
6747        *expression: the SQL code string to parse.
6748            If an Expression instance is passed, this is used as-is.
6749        dialect: the dialect used to parse the input expression (in the case that the
6750            input expression is a SQL string).
6751        copy: Whether to copy `expression` (only applies to expressions).
6752        **opts: other options to use to parse the input expressions (again, in the case
6753            that the input expression is a SQL string).
6754
6755    Returns:
6756        The new Condition instance
6757    """
6758    return maybe_parse(
6759        expression,
6760        into=Condition,
6761        dialect=dialect,
6762        copy=copy,
6763        **opts,
6764    )

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

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

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

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:
7268def var(name: t.Optional[ExpOrStr]) -> Var:
7269    """Build a SQL variable.
7270
7271    Example:
7272        >>> repr(var('x'))
7273        'Var(this=x)'
7274
7275        >>> repr(var(column('x', table='y')))
7276        'Var(this=x)'
7277
7278    Args:
7279        name: The name of the var or an expression who's name will become the var.
7280
7281    Returns:
7282        The new variable node.
7283    """
7284    if not name:
7285        raise ValueError("Cannot convert empty name into var.")
7286
7287    if isinstance(name, Expression):
7288        name = name.name
7289    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7292def rename_table(
7293    old_name: str | Table,
7294    new_name: str | Table,
7295    dialect: DialectType = None,
7296) -> AlterTable:
7297    """Build ALTER TABLE... RENAME... expression
7298
7299    Args:
7300        old_name: The old name of the table
7301        new_name: The new name of the table
7302        dialect: The dialect to parse the table.
7303
7304    Returns:
7305        Alter table expression
7306    """
7307    old_table = to_table(old_name, dialect=dialect)
7308    new_table = to_table(new_name, dialect=dialect)
7309    return AlterTable(
7310        this=old_table,
7311        actions=[
7312            RenameTable(this=new_table),
7313        ],
7314    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse the table.
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7317def rename_column(
7318    table_name: str | Table,
7319    old_column_name: str | Column,
7320    new_column_name: str | Column,
7321    exists: t.Optional[bool] = None,
7322    dialect: DialectType = None,
7323) -> AlterTable:
7324    """Build ALTER TABLE... RENAME COLUMN... expression
7325
7326    Args:
7327        table_name: Name of the table
7328        old_column: The old name of the column
7329        new_column: The new name of the column
7330        exists: Whether to add the `IF EXISTS` clause
7331        dialect: The dialect to parse the table/column.
7332
7333    Returns:
7334        Alter table expression
7335    """
7336    table = to_table(table_name, dialect=dialect)
7337    old_column = to_column(old_column_name, dialect=dialect)
7338    new_column = to_column(new_column_name, dialect=dialect)
7339    return AlterTable(
7340        this=table,
7341        actions=[
7342            RenameColumn(this=old_column, to=new_column, exists=exists),
7343        ],
7344    )

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

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

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:
7512def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7513    """Returns a case normalized table name without quotes.
7514
7515    Args:
7516        table: the table to normalize
7517        dialect: the dialect to use for normalization rules
7518        copy: whether to copy the expression.
7519
7520    Examples:
7521        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7522        'A-B.c'
7523    """
7524    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7525
7526    return ".".join(
7527        p.name
7528        for p in normalize_identifiers(
7529            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7530        ).parts
7531    )

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

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:
7761def tuple_(
7762    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7763) -> Tuple:
7764    """
7765    Returns an tuple.
7766
7767    Examples:
7768        >>> tuple_(1, 'x').sql()
7769        '(1, x)'
7770
7771    Args:
7772        expressions: the expressions to add to the tuple.
7773        copy: whether to copy the argument expressions.
7774        dialect: the source dialect.
7775        kwargs: the kwargs used to instantiate the function of interest.
7776
7777    Returns:
7778        A tuple expression.
7779    """
7780    return Tuple(
7781        expressions=[
7782            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7783            for expression in expressions
7784        ]
7785    )

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:
7788def true() -> Boolean:
7789    """
7790    Returns a true Boolean expression.
7791    """
7792    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7795def false() -> Boolean:
7796    """
7797    Returns a false Boolean expression.
7798    """
7799    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7802def null() -> Null:
7803    """
7804    Returns a Null expression.
7805    """
7806    return Null()

Returns a Null expression.

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